diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/_locales/it/messages.json | 819 | ||||
-rw-r--r-- | app/_locales/ph/messages.json | 609 | ||||
-rw-r--r-- | app/scripts/controllers/transactions.js | 53 | ||||
-rw-r--r-- | app/scripts/lib/tx-state-manager.js | 42 |
4 files changed, 1492 insertions, 31 deletions
diff --git a/app/_locales/it/messages.json b/app/_locales/it/messages.json new file mode 100644 index 000000000..f54ef98ca --- /dev/null +++ b/app/_locales/it/messages.json @@ -0,0 +1,819 @@ +{ + "accept": { + "message": "Accetta" + }, + "account": { + "message": "Account" + }, + "accountDetails": { + "message": "Dettagli Account" + }, + "accountName": { + "message": "Nome Account" + }, + "address": { + "message": "Indirizzo" + }, + "addCustomToken": { + "message": "Aggiungi un token personalizzato" + }, + "addToken": { + "message": "Aggiungi Token" + }, + "addTokens": { + "message": "Aggiungi più token" + }, + "amount": { + "message": "Importo" + }, + "amountPlusGas": { + "message": "Importo + Gas" + }, + "appDescription": { + "message": "Ethereum Browser Extension", + "description": "La descrizione dell'applicazione" + }, + "appName": { + "message": "MetaMask", + "description": "Il nome dell'applicazione" + }, + "attemptingConnect": { + "message": "Tentativo di connessione alla blockchain." + }, + "attributions": { + "message": "Attribuzioni" + }, + "available": { + "message": "Disponibile" + }, + "back": { + "message": "Indietro" + }, + "balance": { + "message": "Bilancio:" + }, + "balances": { + "message": "I tuoi bilanci" + }, + "balanceIsInsufficientGas": { + "message": "Bilancio insufficiente per il gas totale corrente" + }, + "beta": { + "message": "BETA" + }, + "betweenMinAndMax": { + "message": "deve essere maggiore o uguale a $1 e minore o uguale a $2.", + "description": "aiuto per inserire un input esadecimale come decimale" + }, + "blockiesIdenticon": { + "message": "Usa le icone Blockie" + }, + "borrowDharma": { + "message": "Prendi in presisito con Dharma (Beta)" + }, + "builtInCalifornia": { + "message": "MetaMask è progettato e costruito in California." + }, + "buy": { + "message": "Compra" + }, + "buyCoinbase": { + "message": "Compra su Coinbase" + }, + "buyCoinbaseExplainer": { + "message": "Coinbase è il servizio più popolare al mondo per comprare e vendere bitcoin, ethereum e litecoin." + }, + "cancel": { + "message": "Cancella" + }, + "classicInterface": { + "message": "Usa l'interfaccia classica" + }, + "clickCopy": { + "message": "Clicca per Copiare" + }, + "confirm": { + "message": "Conferma" + }, + "confirmContract": { + "message": "Conferma Contratto" + }, + "confirmPassword": { + "message": "Conferma Password" + }, + "confirmTransaction": { + "message": "Conferma Transazione" + }, + "continue": { + "message": "Continua" + }, + "continueToCoinbase": { + "message": "Continua su Coinbase" + }, + "contractDeployment": { + "message": "Distribuzione Contratto" + }, + "conversionProgress": { + "message": "Conversione in corso" + }, + "copiedButton": { + "message": "Copiato" + }, + "copiedClipboard": { + "message": "Copiato negli Appunti" + }, + "copiedExclamation": { + "message": "Copiato!" + }, + "copiedSafe": { + "message": "Le ho copiate in un posto sicuro" + }, + "copy": { + "message": "Copia" + }, + "copyToClipboard": { + "message": "Copia negli appunti" + }, + "copyButton": { + "message": " Copia " + }, + "copyPrivateKey": { + "message": "Questa è la tua chiave privata (clicca per copiare)" + }, + "create": { + "message": "Crea" + }, + "createAccount": { + "message": "Crea Account" + }, + "createDen": { + "message": "Crea" + }, + "crypto": { + "message": "Crypto", + "description": "Tipo di exchange (cryptomonete)" + }, + "currentConversion": { + "message": "Cambio Corrente" + }, + "currentNetwork": { + "message": "Rete Corrente" + }, + "customGas": { + "message": "Personalizza Gas" + }, + "customize": { + "message": "Personalizza" + }, + "customRPC": { + "message": "RPC Personalizzata" + }, + "decimalsMustZerotoTen": { + "message": "Il numero di decimali deve essere almeno 0, e non oltre 36." + }, + "decimal": { + "message": "Precisione Decimali" + }, + "defaultNetwork": { + "message": "La rete predefinita per transazioni in Ether è la Rete Ethereum Principale." + }, + "denExplainer": { + "message": "Il DEN è il tuo archivio crittato con password dentro Metamask." + }, + "deposit": { + "message": "Deposita" + }, + "depositBTC": { + "message": "Deposita i tuoi BTC all'indirizzo sotto:" + }, + "depositCoin": { + "message": "Deposita $1 all'indirizzo sotto", + "description": "Dice all'utente quale moneta ha selezionato per depositare con Shapeshift" + }, + "depositEth": { + "message": "Deposita Eth" + }, + "depositEther": { + "message": "Deposita Ether" + }, + "depositFiat": { + "message": "Deposita con moneta Fiat" + }, + "depositFromAccount": { + "message": "Deposita da un altro account" + }, + "depositShapeShift": { + "message": "Deposita con ShapeShift" + }, + "depositShapeShiftExplainer": { + "message": "Se possiedi altre criptomonete, puoi scambiare e depositare Ether direttamente nel tuo portafoglio MetaMask. Nessun account richiesto." + }, + "details": { + "message": "Dettagli" + }, + "directDeposit": { + "message": "Deposito Diretto" + }, + "directDepositEther": { + "message": "Deposita Direttamente Ether" + }, + "directDepositEtherExplainer": { + "message": "Se possiedi già degli Ether, questa è la via più veloce per aggiungere Ether al tuo portafoglio con un deposito diretto." + }, + "done": { + "message": "Finito" + }, + "downloadStatelogs": { + "message": "Scarica i log di Stato" + }, + "edit": { + "message": "Modifica" + }, + "editAccountName": { + "message": "Modifica Nome Account" + }, + "emailUs": { + "message": "Mandaci una mail!" + }, + "encryptNewDen": { + "message": "Cripta il tuo nuovo DEN" + }, + "enterPassword": { + "message": "Inserisci password" + }, + "enterPasswordConfirm": { + "message": "Inserisci la tua password per confermare" + }, + "etherscanView": { + "message": "Vedi account su Etherscan" + }, + "exchangeRate": { + "message": "Tasso di cambio" + }, + "exportPrivateKey": { + "message": "Esporta Chiave Privata" + }, + "exportPrivateKeyWarning": { + "message": "Esporta chiave privata a tuo rischio." + }, + "failed": { + "message": "Fallito" + }, + "fiat": { + "message": "FIAT", + "description": "Tipo di scambio" + }, + "fileImportFail": { + "message": "Importazione file non funziona? Clicca qui!", + "description": "Aiuta gli utenti a importare il loro account da un file JSON" + }, + "followTwitter": { + "message": "Seguici su Twitter" + }, + "from": { + "message": "Da" + }, + "fromToSame": { + "message": "Gli indirizzi Da e A non possono essere uguali" + }, + "fromShapeShift": { + "message": "Da ShapeShift" + }, + "gas": { + "message": "Gas", + "description": "Piccola indicazione del costo del gas" + }, + "gasFee": { + "message": "Costo Gas" + }, + "gasLimit": { + "message": "Gas Limite" + }, + "gasLimitCalculation": { + "message": "Calcoliamo il gas limite suggerito in base al successo delle transazioni in rete." + }, + "gasLimitRequired": { + "message": "Gas Limite Richiesto" + }, + "gasLimitTooLow": { + "message": "Il Gas Limite deve essere almeno 21000" + }, + "generatingSeed": { + "message": "Generando la frase seed..." + }, + "gasPrice": { + "message": "Prezzo del Gas (GWEI)" + }, + "gasPriceCalculation": { + "message": "Calcoliamo il gas limite suggerito in base al successo delle transazioni in rete." + }, + "gasPriceRequired": { + "message": "Prezzo Gas Richiesto" + }, + "getEther": { + "message": "Ottieni Ether" + }, + "getEtherFromFaucet": { + "message": "Ottieni Get Ether da un faucet per $1", + "description": "Visualizza il nome della rete per il faucet Ether" + }, + "greaterThanMin": { + "message": "deve essere maggiore o uguale a $1.", + "description": "aiuto per inserire un input esadecimale come decimale" + }, + "here": { + "message": "qui", + "description": "per intendere -clicca qui- per maggiori informazioni (va con troubleTokenBalances)" + }, + "hereList": { + "message": "Questa è una lista!!!!" + }, + "hide": { + "message": "Nascondi" + }, + "hideToken": { + "message": "Nascondi Token" + }, + "hideTokenPrompt": { + "message": "Nascondi Token?" + }, + "howToDeposit": { + "message": "Come vuoi depositare Ether?" + }, + "holdEther": { + "message": "Ti permette di tenere ether & token, e serve da ponte per le applicazioni decentralizzate." + }, + "import": { + "message": "Importa", + "description": "Tasto per importare un account da un file selezionato" + }, + "importAccount": { + "message": "Importa Account" + }, + "importAccountMsg": { + "message":" Gli account importati non saranno associati alla frase seed originariamente creata con MetaMask. Impara di più sugli account importati " + }, + "importAnAccount": { + "message": "Importa un account" + }, + "importDen": { + "message": "Importa un DEN Esistente" + }, + "imported": { + "message": "Importato", + "description": "stato che conferma che un account è stato totalmente caricato nel portachiavi" + }, + "infoHelp": { + "message": "Informazioni & Aiuto" + }, + "insufficientFunds": { + "message": "Fondi non sufficienti." + }, + "insufficientTokens": { + "message": "Token non sufficienti." + }, + "invalidAddress": { + "message": "Indirizzo non valido" + }, + "invalidAddressRecipient": { + "message": "Indirizzo destinatario invalido" + }, + "invalidGasParams": { + "message": "Parametri del Gas non validi" + }, + "invalidInput": { + "message": "Input non valido." + }, + "invalidRequest": { + "message": "Richiesta non Valida" + }, + "invalidRPC": { + "message": "URI RPC invalido" + }, + "jsonFail": { + "message": "Qualcosa è andato storto. Assicurati che il file JSON sia formattato correttamente." + }, + "jsonFile": { + "message": "File JSON", + "description": "formato per importare un account" + }, + "kovan": { + "message": "Rete di test Kovan" + }, + "knowledgeDataBase": { + "message": "Visita la nostra Knowledge Base" + }, + "lessThanMax": { + "message": "deve essere minore o uguale a $1.", + "description": "aiuto per inserire un input esadecimale come decimale" + }, + "likeToAddTokens": { + "message": "Vorresti aggiungere questi token?" + }, + "limit": { + "message": "Limite" + }, + "loading": { + "message": "Caricamento..." + }, + "loadingTokens": { + "message": "Caricamento Tokens..." + }, + "localhost": { + "message": "Localhost 8545" + }, + "login": { + "message": "Connetti" + }, + "logout": { + "message": "Disconnetti" + }, + "loose": { + "message": "Libero" + }, + "loweCaseWords": { + "message": "le frasi seed hanno solo lettere minuscole" + }, + "mainnet": { + "message": "Rete Ethereum Principale" + }, + "message": { + "message": "Messaggio" + }, + "metamaskDescription": { + "message": "MetaMask è una cassaforte sicura per identità su Ethereum." + }, + "min": { + "message": "Minimo" + }, + "myAccounts": { + "message": "Account Miei" + }, + "mustSelectOne": { + "message": "Devi selezionare almeno un token." + }, + "needEtherInWallet": { + "message": "Per interagire con applicazioni decentralizzate con MetaMask, devi possedere Ether nel tuo portafoglio." + }, + "needImportFile": { + "message": "Devi selezionare un file da importare.", + "description": "L'utente sta importando un account e deve aggiungere un file per continuare" + }, + "needImportPassword": { + "message": "Dei inserire una password per il file selezionato.", + "description": "Password e file necessari per importare un account" + }, + "negativeETH": { + "message": "Non puoi inviare una quantità di ETH negativa." + }, + "networks": { + "message": "Reti" + }, + "newAccount": { + "message": "Nuovo Account" + }, + "newAccountNumberName": { + "message": "Account $1", + "description": "Nome predefinito per il prossimo account da creare nella schermata di creazione account" + }, + "newContract": { + "message": "Nuovo Contratto" + }, + "newPassword": { + "message": "Nuova Password (minimo 8 caratteri)" + }, + "newRecipient": { + "message": "Nuovo Destinatario" + }, + "newRPC": { + "message": "Nuovo URL RPC" + }, + "next": { + "message": "Prossimo" + }, + "noAddressForName": { + "message": "Nessun indirizzo è stato impostato per questo nome." + }, + "noDeposits": { + "message": "Nessun deposito ricevuto" + }, + "noTransactionHistory": { + "message": "Nessuna cronologia delle transazioni." + }, + "noTransactions": { + "message": "Nessuna Transazione" + }, + "notStarted": { + "message": "Non Iniziato" + }, + "oldUI": { + "message": "Vecchia interfaccia" + }, + "oldUIMessage": { + "message": "Sei ritornato alla vecchia interfaccia. Puoi ritornare alla nuova interfaccia tramite l'opzione nel menu a discesa in alto a destra." + }, + "or": { + "message": "o", + "description": "scelta tra creare o importare un nuovo account" + }, + "passwordCorrect": { + "message": "Assicurati che la password sia corretta." + }, + "passwordMismatch": { + "message": "le password non corrispondono", + "description": "nella creazione della password, le due password all'interno dei campi non corrispondono" + }, + "passwordShort": { + "message": "password non sufficientemente lunga", + "description": "nella creazione della password, la password non è lunga abbastanza" + }, + "pastePrivateKey": { + "message": "Incolla la tua chiave privata qui:", + "description": "Per importare un account da una chiave privata" + }, + "pasteSeed": { + "message": "Incolla la tua frase seed qui!" + }, + "personalAddressDetected": { + "message": "Rilevato indirizzo personale. Inserisci l'indirizzo del contratto del token." + }, + "pleaseReviewTransaction": { + "message": "Ricontrolla la tua transazione." + }, + "privacyMsg": { + "message": "Politica sulla Privacy" + }, + "privateKey": { + "message": "Chiave Privata", + "description": "seleziona questo tipo di file per importare un account" + }, + "privateKeyWarning": { + "message": "Attenzione: non dire a nessuno questa chiave! Chiunque con la tua chiave privata può rubare qualsiasi moneta contenuta nel tuo account." + }, + "privateNetwork": { + "message": "Rete Privata" + }, + "qrCode": { + "message": "Mostra Codice QR" + }, + "readdToken": { + "message": "Puoi aggiungere nuovamente questo token in futuro andando in “Aggiungi token” nel menu delle opzioni del tuo account." + }, + "readMore": { + "message": "Leggi di più qui." + }, + "readMore2": { + "message": "Leggi di più." + }, + "receive": { + "message": "Ricevi" + }, + "recipientAddress": { + "message": "Indirizzo Destinatario" + }, + "refundAddress": { + "message": "Indirizzo di Rimborso" + }, + "rejected": { + "message": "Respinta" + }, + "resetAccount": { + "message": "Resetta Account" + }, + "restoreFromSeed": { + "message": "Ripristina da una frase seed" + }, + "required": { + "message": "Richiesto" + }, + "retryWithMoreGas": { + "message": "Riprova con un prezzo del Gas maggiore qui" + }, + "revealSeedWords": { + "message": "Rivela Frase Seed" + }, + "revealSeedWordsWarning": { + "message": "Non ripristinare la tua frase seed in pubblico!. Queste parole possono essere usate per rubare il tuo account." + }, + "revert": { + "message": "Annulla" + }, + "rinkeby": { + "message": "Rete di test Rinkeby" + }, + "ropsten": { + "message": "Rete di test Ropsten" + }, + "sampleAccountName": { + "message": "Es: Il mio nuovo account", + "description": "Aiuta l'utente a capire il concetto di aggiungere un nome leggibile al loro account" + }, + "save": { + "message": "Salva" + }, + "saveAsFile": { + "message": "Salva come File", + "description": "Processo per esportare un account" + }, + "saveSeedAsFile": { + "message": "Salva la Frase Seed come File" + }, + "search": { + "message": "Cerca" + }, + "secretPhrase": { + "message": "Inserisci la tua frase segreta di dodici parole per ripristinare la cassaforte." + }, + "seedPhraseReq": { + "message": "le frasi seed sono lunghe 12 parole" + }, + "select": { + "message": "Seleziona" + }, + "selectCurrency": { + "message": "Seleziona Moneta" + }, + "selectService": { + "message": "Seleziona Servizio" + }, + "selectType": { + "message": "Seleziona Tipo" + }, + "send": { + "message": "Invia" + }, + "sendETH": { + "message": "Invia ETH" + }, + "sendTokens": { + "message": "Invia Tokens" + }, + "sendTokensAnywhere": { + "message": "Invia Tokens a chiunque abbia un account Ethereum" + }, + "settings": { + "message": "Impostazioni" + }, + "shapeshiftBuy": { + "message": "Compra con Shapeshift" + }, + "showPrivateKeys": { + "message": "Mostra Chiave Privata" + }, + "showQRCode": { + "message": "Mostra Codie QR" + }, + "sign": { + "message": "Firma" + }, + "signMessage": { + "message": "Firma Messaggio" + }, + "signNotice": { + "message": "Firmare questo messaggio può avere effetti collaterali pericolosi. \nFirma messaggi da siti di cui ti fidi totalmente. \nQuesto metodo pericoloso sarà rimosso in versioni future." + }, + "sigRequest": { + "message": "Firma Richiesta" + }, + "sigRequested": { + "message": "Richiesta Firma" + }, + "spaceBetween": { + "message": "ci può essere solo uno spazio tra le parole" + }, + "status": { + "message": "Stato" + }, + "stateLogs": { + "message": "Log di Stato" + }, + "stateLogsDescription": { + "message": "I log di stato contengono i tuoi indirizzi pubblici e le transazioni effettuate." + }, + "submit": { + "message": "Invia" + }, + "supportCenter": { + "message": "Visita il nostro Centro di Supporto" + }, + "symbolBetweenZeroTen": { + "message": "Il simbolo deve essere lungo tra 0 e 10 caratteri." + }, + "takesTooLong": { + "message": "Ci sta mettendo troppo?" + }, + "terms": { + "message": "Termini di Uso" + }, + "testFaucet": { + "message": "Prova Faucet" + }, + "to": { + "message": "A" + }, + "toETHviaShapeShift": { + "message": "$1 a ETH via ShapeShift", + "description": "il sistema riempirà il tipo di deposito all'inizio del messaggio" + }, + "tokenAddress": { + "message": "Indirizzo Token" + }, + "tokenAlreadyAdded": { + "message": "Il token è già stato aggiunto." + }, + "tokenBalance": { + "message": "Bilancio Token:" + }, + "tokenSelection": { + "message": "Cerca un token o seleziona dalla lista di token più popolari." + }, + "tokenSymbol": { + "message": "Simbolo Token" + }, + "tokenWarning1": { + "message": "Tieni traccia dei token che hai acquistato con il tuo account MetaMask. Se hai acquistato token con un account diverso, quei token non appariranno qui." + }, + "total": { + "message": "Totale" + }, + "transactions": { + "message": "transazioni" + }, + "transactionMemo": { + "message": "Promemoria Transazione (opzionale)" + }, + "transactionNumber": { + "message": "Numero Transazione" + }, + "transfers": { + "message": "Trasferimenti" + }, + "troubleTokenBalances": { + "message": "Abbiamo avuto un problema a caricare il bilancio dei tuoi token. Puoi vederlo ", + "description": "Seguito da un link (qui) per vedere il bilancio dei token" + }, + "twelveWords": { + "message": "Queste 12 parole sono l'unico modo per ripristinare i tuoi account MetaMask. \nSalvale in un posto sicuro e segreto." + }, + "typePassword": { + "message": "Inserisci Password" + }, + "uiWelcome": { + "message": "Benvenuto alla nuova interfaccia (Beta)" + }, + "uiWelcomeMessage": { + "message": "Stai utilizzanto la nuova interfaccia di MetaMask. Guarda in giro, prova nuove funzionalità come inviare token, e facci sapere se hai dei problemi." + }, + "unavailable": { + "message": "Non Disponibile" + }, + "unknown": { + "message": "Sconosciuto" + }, + "unknownNetwork": { + "message": "Rete Privata Sconosciuta" + }, + "unknownNetworkId": { + "message": "ID rete sconosciuto" + }, + "uriErrorMsg": { + "message": "Gli URI richiedono un prefisso HTTP/HTTPS." + }, + "usaOnly": { + "message": "Solo USA", + "description": "Usare questo sito di scambio è possibile solo per persone residenti in USA." + }, + "usedByClients": { + "message": "Usato da una varietà di clients diversi" + }, + "useOldUI": { + "message": "Use la vecchia UI" + }, + "validFileImport": { + "message": "Devi selezionare un file valido da importare." + }, + "vaultCreated": { + "message": "Cassaforte Creata" + }, + "viewAccount": { + "message": "Vedi Account" + }, + "visitWebSite": { + "message": "Visita il nostro sito web" + }, + "warning": { + "message": "Attenzione" + }, + "welcomeBeta": { + "message": "Benvenuto nella Beta di MetaMask" + }, + "whatsThis": { + "message": "Cos'è questo?" + }, + "yourSigRequested": { + "message": "E' richiesta la tua firma" + }, + "youSign": { + "message": "Ti stai connettendo" + } +}
\ No newline at end of file diff --git a/app/_locales/ph/messages.json b/app/_locales/ph/messages.json new file mode 100644 index 000000000..29d63be02 --- /dev/null +++ b/app/_locales/ph/messages.json @@ -0,0 +1,609 @@ +{ + "accept": { + "message": "Tanggapin" + }, + "account": { + "message": "Account" + }, + "accountDetails": { + "message": "Detalye ng Account" + }, + "accountName": { + "message": "Pangalan ng Account" + }, + "address": { + "message": "Address" + }, + "addToken": { + "message": "Magdagdag ng Token" + }, + "amount": { + "message": "Halaga" + }, + "amountPlusGas": { + "message": "Halaga + Gas" + }, + "appDescription": { + "message": "Ethereum Browser Extension", + "description": "Ang deskripsyon ng application" + }, + "appName": { + "message": "MetaMask", + "description": "Ang pangalan ng application" + }, + "attemptingConnect": { + "message": "Sinusubukang kumonekta sa blockchain." + }, + "available": { + "message": "Magagamit" + }, + "back": { + "message": "Bumalik" + }, + "balance": { + "message": "Balanse:" + }, + "balanceIsInsufficientGas": { + "message": "Kulang ang balanse para sa kasalukuyang gas total" + }, + "beta": { + "message": "BETA" + }, + "betweenMinAndMax": { + "message": "dapat mas malaki o katumbas ng $1 at mas mababa o katumbas ng $2.", + "description": "helper para sa pag-input ng hex bilang decimal input" + }, + "borrowDharma": { + "message": "Humiram sa Dharma (Beta)" + }, + "buy": { + "message": "Bumili" + }, + "buyCoinbase": { + "message": "Bumili sa Coinbase" + }, + "buyCoinbaseExplainer": { + "message": "Ang Coinbase ang pinakasikat na paraan upang bumili at magbenta ng bitcoin, ethereum, at litecoin sa buong mundo." + }, + "cancel": { + "message": "Kanselahin" + }, + "clickCopy": { + "message": "I-click upang Makopya" + }, + "confirm": { + "message": "Tiyakin" + }, + "confirmContract": { + "message": "Tiyakin ang Contract" + }, + "confirmPassword": { + "message": "Tiyakin ang Password" + }, + "confirmTransaction": { + "message": "Tiyakin ang Transaksyon" + }, + "continueToCoinbase": { + "message": "Magpatuloy sa Coinbase" + }, + "contractDeployment": { + "message": "Pag-deploy ng Contract" + }, + "conversionProgress": { + "message": "Isinasagawa ang conversion" + }, + "copiedButton": { + "message": "Kinopya" + }, + "copiedClipboard": { + "message": "Kinopya sa Clipboard" + }, + "copiedExclamation": { + "message": "Kinopya!" + }, + "copy": { + "message": "Kinopya" + }, + "copyToClipboard": { + "message": "Kinopya sa clipboard" + }, + "copyButton": { + "message": " Kinopya " + }, + "copyPrivateKey": { + "message": "Ito ang iyong private key (i-click upang makopya)" + }, + "create": { + "message": "Gumawa" + }, + "createAccount": { + "message": "Gumawa ng Account" + }, + "createDen": { + "message": "Gumawa" + }, + "crypto": { + "message": "Crypto", + "description": "Type ng exchange (cryptocurrencies)" + }, + "customGas": { + "message": "I-customize ang Gas" + }, + "customize": { + "message": "I-customize" + }, + "customRPC": { + "message": "Custom RPC" + }, + "defaultNetwork": { + "message": "Ang default network para sa Ether transactions ay ang Main Net." + }, + "denExplainer": { + "message": "Ang iyong DEN ang nagsisilbing password-encrypted storage mo sa loob ng MetaMask." + }, + "deposit": { + "message": "Deposito" + }, + "depositBTC": { + "message": "I-deposito ang iyong BTC sa address na ito:" + }, + "depositCoin": { + "message": "I-deposito ang iyong $1 sa address na ito", + "description": "Sinasabihan ang user kung ano ang coin na kanilang pinili para I-deposito gamit ang shapeshift" + }, + "depositEth": { + "message": "I-deposito ang Eth" + }, + "depositEther": { + "message": "I-deposito ang Ether" + }, + "depositFiat": { + "message": "I-deposito ang Fiat" + }, + "depositFromAccount": { + "message": "I-deposito mula sa ibang account" + }, + "depositShapeShift": { + "message": "I-deposito gamit ang ShapeShift" + }, + "depositShapeShiftExplainer": { + "message": "Kung ikaw ay nagmamay-ari ng iba pang cryptocurrencies, pwede kang mag-trade at mag-deposito ng Ether diretso sa iyong MetaMask wallet. Hindi mo na kailangan ng account." + }, + "details": { + "message": "Detalye" + }, + "directDeposit": { + "message": "Direktang Deposito" + }, + "directDepositEther": { + "message": "Direktang I-deposito ang Ether" + }, + "directDepositEtherExplainer": { + "message": "Kung ika ay mayroon nang Ether, ang pinakamabilis na paraan upang makuha ang Ether sa iyong bagong wallet ay sa pamamagitan ng direktang deposito." + }, + "done": { + "message": "Tapos na" + }, + "edit": { + "message": "I-edit" + }, + "editAccountName": { + "message": "I-edit ang Pangalang ng Account" + }, + "encryptNewDen": { + "message": "I-encrypt ang iyong bagong DEN" + }, + "enterPassword": { + "message": "I-enter ang password" + }, + "etherscanView": { + "message": "Tingnan ang account sa Etherscan" + }, + "exchangeRate": { + "message": "Exchange Rate" + }, + "exportPrivateKey": { + "message": "I-export ang Private Key" + }, + "exportPrivateKeyWarning": { + "message": "I-export ang private keys at intindihin ang panganib na kasama nito." + }, + "failed": { + "message": "Nabigo" + }, + "fiat": { + "message": "FIAT", + "description": "Type ng exchange" + }, + "fileImportFail": { + "message": "Hindi gumagana ang file import? I-click ito!", + "description": "Tinutulungan ang user na i-import ang kanilang account mula sa JSON file" + }, + "from": { + "message": "Mula sa" + }, + "fromShapeShift": { + "message": "Mula sa ShapeShift" + }, + "gas": { + "message": "Gas", + "description": "Maikling indikasyon ng gas cost" + }, + "gasFee": { + "message": "Gas Fee" + }, + "gasLimit": { + "message": "Gas Limit" + }, + "gasLimitCalculation": { + "message": "Kinalkula namin ang iminungkahing gas limit base sa network success rates." + }, + "gasLimitRequired": { + "message": "Kailangan ang Gas Limit" + }, + "gasLimitTooLow": { + "message": "Ang gas limit ay hindi dabat bababa sa 21000" + }, + "gasPrice": { + "message": "Gas Price (GWEI)" + }, + "gasPriceCalculation": { + "message": "Kinalkula namin ang iminungkahing gas prices base sa network success rates." + }, + "gasPriceRequired": { + "message": "Kailangan ang Gas Price" + }, + "getEther": { + "message": "Kumuha ng Ether" + }, + "getEtherFromFaucet": { + "message": "Kumuha ng Ether mula sa faucet para sa $1", + "description": "Ipinapakita ang pangalan ng network para sa Ether faucet" + }, + "greaterThanMin": { + "message": "dapat mas malaki o katumbas ng $1.", + "description": "helper para sa pag-input ng hex bilang decimal input" + }, + "here": { + "message": "i-click ito", + "description": "tulad ng -i-click dito- para sa mas maraming impormasyon (kasama ng troubleTokenBalances)" + }, + "hide": { + "message": "Itago" + }, + "hideToken": { + "message": "Itago ang Token" + }, + "hideTokenPrompt": { + "message": "Itago ang Token?" + }, + "howToDeposit": { + "message": "Paano mo gustong mag-deposito ng Ether?" + }, + "import": { + "message": "I-import", + "description": "Button para i-import ang account mula sa napiling file" + }, + "importAccount": { + "message": "I-import ang Account" + }, + "importAnAccount": { + "message": "I-import ang account" + }, + "importDen": { + "message": "I-import ang Existing DEN" + }, + "imported": { + "message": "Na-import na", + "description": "status na nagpapakita na ang account ay lubos na na-load sa keyring" + }, + "infoHelp": { + "message": "Impormasyon at Tulong" + }, + "invalidAddress": { + "message": "Invalid ang address" + }, + "invalidGasParams": { + "message": "Invalid ang Gas Parameters" + }, + "invalidInput": { + "message": "Invalid ang input." + }, + "invalidRequest": { + "message": "Invalid ang Request" + }, + "jsonFile": { + "message": "JSON File", + "description": "format para sa pag-import ng account" + }, + "kovan": { + "message": "Kovan Test Network" + }, + "lessThanMax": { + "message": "dapat mas mababa o katumbas ng $1.", + "description": "helper para sa pag-input ng hex bilang decimal input" + }, + "limit": { + "message": "Limitasyon" + }, + "loading": { + "message": "Naglo-load..." + }, + "loadingTokens": { + "message": "Naglo-load ang Tokens..." + }, + "localhost": { + "message": "Localhost 8545" + }, + "logout": { + "message": "Log out" + }, + "loose": { + "message": "Loose" + }, + "mainnet": { + "message": "Main Ethereum Network" + }, + "message": { + "message": "Mensahe" + }, + "min": { + "message": "Minimum" + }, + "myAccounts": { + "message": "Aking mga Account" + }, + "needEtherInWallet": { + "message": "Upang makipag-ugnayan sa decentralized applications gamit ang MetaMask, kakailanganin mo ng Ether sa iyong wallet." + }, + "needImportFile": { + "message": "Dapat kang pumili ng file para i-import.", + "description": "Ang user ay nag-iimport ng account at kailangan magdagdag ng file upang tumuloy" + }, + "needImportPassword": { + "message": "Dapat mong i-enter ang password para sa napiling file.", + "description": "Password at file na kailangan upang ma-import ang account" + }, + "networks": { + "message": "Networks" + }, + "newAccount": { + "message": "Bagong Account" + }, + "newAccountNumberName": { + "message": "Account $1", + "description": "Ang default na pangalan ng susunod na account na gagawin sa create account screen" + }, + "newContract": { + "message": "Bagong Contract" + }, + "newPassword": { + "message": "Bagong Password (min 8 chars)" + }, + "newRecipient": { + "message": "Bagong Recipient" + }, + "next": { + "message": "Sunod" + }, + "noAddressForName": { + "message": "Walang naka-set na address para sa pangalang ito." + }, + "noDeposits": { + "message": "Walang natanggap na mga deposito" + }, + "noTransactionHistory": { + "message": "Walang kasaysayan ng transaksyon." + }, + "noTransactions": { + "message": "Walang mga Transaksyon" + }, + "notStarted": { + "message": "Hindi Sinimulan" + }, + "oldUI": { + "message": "Lumang UI" + }, + "oldUIMessage": { + "message": "Ikaw ay bumalik sa lumang UI. Maaari kang bumalik sa bagong UI mula sa isang opsyon sa dropdown menu na matatagpuan sa bandang taas at kanan." + }, + "or": { + "message": "o", + "description": "Pagpili sa pagitan ng paggawa of pag-import ng bagong account" + }, + "passwordMismatch": { + "message": "hindi nagtugma ang mga password", + "description": "Sa proseso ng paggawa ng password, ang dalawang password fields ay hindi nagtugma" + }, + "passwordShort": { + "message": "hindi sapat ang haba ng password", + "description": "Sa proseso ng paggawa ng password, ang password ay hindi in password creation process, hind sapat ang haba ng password upang maging ligtas" + }, + "pastePrivateKey": { + "message": "I-paste dito ang iyong private key string:", + "description": "Para sa pag-import ng account mula sa private key" + }, + "pasteSeed": { + "message": "I-paste dito ang iyong seed phrase!" + }, + "pleaseReviewTransaction": { + "message": "Mangyaring suriin ang iyong transaksyon." + }, + "privateKey": { + "message": "Private Key", + "description": "Piliin ang ganitong type ng file upang gamitin sa pag-import ng account" + }, + "privateKeyWarning": { + "message": "Babala: Huwag sabihin sa kahit na sino ang key na ito. Maaring makuha at manakaw ng sinumang nakakaalam ng iyong private key ang mga assets sa iyong account." + }, + "privateNetwork": { + "message": "Pribadong Network" + }, + "qrCode": { + "message": "Ipakita ang QR Code" + }, + "readdToken": { + "message": "Upang muling idagdag ang token na ito, pumunta sa “Magdagdag ng Token” sa options menu ng iyong account." + }, + "readMore": { + "message": "Alamin ang iba pang impormasyon dito." + }, + "receive": { + "message": "Tanggapin" + }, + "recipientAddress": { + "message": "Address ng Tatanggap" + }, + "refundAddress": { + "message": "Ang Iyong Refund Address" + }, + "rejected": { + "message": "Tinanggihan" + }, + "required": { + "message": "Kailangan" + }, + "retryWithMoreGas": { + "message": "Muling subukan ng may mas mataas na gas price dito" + }, + "revert": { + "message": "Ibalik" + }, + "rinkeby": { + "message": "Rinkeby Test Network" + }, + "ropsten": { + "message": "Ropsten Test Network" + }, + "sampleAccountName": { + "message": "Halimbawa: Ang aking bagong account", + "description": "Tulungan ang user na intindihin ang konsepto ng pagdagdag ng human-readable name sa kanilang account" + }, + "save": { + "message": "I-save" + }, + "saveAsFile": { + "message": "I-save bilang File", + "description": "Proseso sa pag-export ng Account" + }, + "selectService": { + "message": "Piliin ang Service" + }, + "send": { + "message": "Magpadala" + }, + "sendTokens": { + "message": "Magpadala ng Tokens" + }, + "sendTokensAnywhere": { + "message": "Magpadala ng Tokens sa sinumang may Ethereum account" + }, + "settings": { + "message": "Mga Setting" + }, + "shapeshiftBuy": { + "message": "Bumili gamit ang Shapeshift" + }, + "showPrivateKeys": { + "message": "Ipakita ang Private Keys" + }, + "showQRCode": { + "message": "Ipakita ang QR Code" + }, + "sign": { + "message": "I-sign" + }, + "signMessage": { + "message": "I-sign ang mensahe" + }, + "signNotice": { + "message": "Ang pag-sign ng mensaheng ito ay maaring magdulot ng mapanganib na epekto. I-sign lamang ang mga mensahe mula sa mga site na pinagkakatiwalaan mo ng iyong account. Ang mapanganib na paraang ito ay aalisin sa isa sa mga susunod na bersyon. " + }, + "sigRequest": { + "message": "Hiling na Signature" + }, + "sigRequested": { + "message": "Hiniling ang Signature" + }, + "status": { + "message": "Istado" + }, + "submit": { + "message": "I-submit" + }, + "takesTooLong": { + "message": "Masyadong matagal?" + }, + "testFaucet": { + "message": "Test Faucet" + }, + "to": { + "message": "To" + }, + "toETHviaShapeShift": { + "message": "$1 sa ETH sa pamamagitan ng ShapeShift", + "description": "Pupunan ng system ang deposit type sa simula ng mensahe" + }, + "tokenBalance": { + "message": "Ang iyong Token Balance ay:" + }, + "total": { + "message": "Kabuuan" + }, + "transactionMemo": { + "message": "Memo ng transaksyon (opsyonal)" + }, + "transactionNumber": { + "message": "Numero ng Transaksyon" + }, + "transfers": { + "message": "Mga Inilipat" + }, + "troubleTokenBalances": { + "message": "Nagkaroon kami ng problema sa paglo-load ng iyong mga balanseng token. Tingnan ito dito ", + "description": "Susundan ng link (dito) para tingnan ang token balances" + }, + "typePassword": { + "message": "I-type ang iyong Password" + }, + "uiWelcome": { + "message": "Maligayang pagdating sa Bagong UI (Beta)" + }, + "uiWelcomeMessage": { + "message": "Ginagamit mo na ngayon ang bagong MetaMask UI. I-explore at subukan ang mga bagong features tulad ng pagpapadala ng mga token, at ipaalam sa amin kung mayroon kang anumang mga isyu." + }, + "unavailable": { + "message": "Hindi Magagamit" + }, + "unknown": { + "message": "Hindi Alam" + }, + "unknownNetwork": { + "message": "Hindi Alam ang Pribadong Network" + }, + "unknownNetworkId": { + "message": "Hindi alam ang network ID" + }, + "usaOnly": { + "message": "USA lamang", + "description": "Ang paggamit ng exchange na ito ay limitado sa mga tao sa loob ng Estados Unidos" + }, + "usedByClients": { + "message": "Ginagamit ng iba't ibang mga clients" + }, + "viewAccount": { + "message": "Tingnan ang Account" + }, + "warning": { + "message": "Babala" + }, + "whatsThis": { + "message": "Ano ito?" + }, + "yourSigRequested": { + "message": "Hinihiling ang iyong signature" + }, + "youSign": { + "message": "Ikaw ay nagsa-sign" + } +} diff --git a/app/scripts/controllers/transactions.js b/app/scripts/controllers/transactions.js index 9c2ca0dc8..3e3909361 100644 --- a/app/scripts/controllers/transactions.js +++ b/app/scripts/controllers/transactions.js @@ -6,7 +6,6 @@ const EthQuery = require('ethjs-query') const TransactionStateManager = require('../lib/tx-state-manager') const TxGasUtil = require('../lib/tx-gas-utils') const PendingTransactionTracker = require('../lib/pending-tx-tracker') -const createId = require('../lib/random-id') const NonceTracker = require('../lib/nonce-tracker') /* @@ -92,8 +91,8 @@ module.exports = class TransactionController extends EventEmitter { this.pendingTxTracker.on('tx:warning', (txMeta) => { this.txStateManager.updateTx(txMeta, 'transactions/pending-tx-tracker#event: tx:warning') }) + this.pendingTxTracker.on('tx:confirmed', (txId) => this._markNonceDuplicatesDropped(txId)) this.pendingTxTracker.on('tx:failed', this.txStateManager.setTxStatusFailed.bind(this.txStateManager)) - this.pendingTxTracker.on('tx:confirmed', this.txStateManager.setTxStatusConfirmed.bind(this.txStateManager)) this.pendingTxTracker.on('tx:block-update', (txMeta, latestBlockNumber) => { if (!txMeta.firstRetryBlockNumber) { txMeta.firstRetryBlockNumber = latestBlockNumber @@ -186,14 +185,7 @@ module.exports = class TransactionController extends EventEmitter { // validate await this.txGasUtil.validateTxParams(txParams) // construct txMeta - const txMeta = { - id: createId(), - time: (new Date()).getTime(), - status: 'unapproved', - metamaskNetworkId: this.getNetwork(), - txParams: txParams, - loadingDefaults: true, - } + const txMeta = this.txStateManager.generateTxMeta({txParams}) this.addTx(txMeta) this.emit('newUnapprovedTx', txMeta) // add default tx params @@ -215,7 +207,6 @@ module.exports = class TransactionController extends EventEmitter { const txParams = txMeta.txParams // ensure value txMeta.gasPriceSpecified = Boolean(txParams.gasPrice) - txMeta.nonceSpecified = Boolean(txParams.nonce) let gasPrice = txParams.gasPrice if (!gasPrice) { gasPrice = this.getGasPrice ? this.getGasPrice() : await this.query.gasPrice() @@ -226,11 +217,17 @@ module.exports = class TransactionController extends EventEmitter { return await this.txGasUtil.analyzeGasUsage(txMeta) } - async retryTransaction (txId) { - this.txStateManager.setTxStatusUnapproved(txId) - const txMeta = this.txStateManager.getTx(txId) - txMeta.lastGasPrice = txMeta.txParams.gasPrice - this.txStateManager.updateTx(txMeta, 'retryTransaction: manual retry') + async retryTransaction (originalTxId) { + const originalTxMeta = this.txStateManager.getTx(originalTxId) + const lastGasPrice = originalTxMeta.txParams.gasPrice + const txMeta = this.txStateManager.generateTxMeta({ + txParams: originalTxMeta.txParams, + lastGasPrice, + loadingDefaults: false, + }) + this.addTx(txMeta) + this.emit('newUnapprovedTx', txMeta) + return txMeta } async updateTransaction (txMeta) { @@ -253,11 +250,9 @@ module.exports = class TransactionController extends EventEmitter { // wait for a nonce nonceLock = await this.nonceTracker.getNonceLock(fromAddress) // add nonce to txParams - const nonce = txMeta.nonceSpecified ? txMeta.txParams.nonce : nonceLock.nextNonce - if (nonce > nonceLock.nextNonce) { - const message = `Specified nonce may not be larger than account's next valid nonce.` - throw new Error(message) - } + // if txMeta has lastGasPrice then it is a retry at same nonce with higher + // gas price transaction and their for the nonce should not be calculated + const nonce = txMeta.lastGasPrice ? txMeta.txParams.nonce : nonceLock.nextNonce txMeta.txParams.nonce = ethUtil.addHexPrefix(nonce.toString(16)) // add nonce debugging information to txMeta txMeta.nonceDetails = nonceLock.nonceDetails @@ -314,6 +309,22 @@ module.exports = class TransactionController extends EventEmitter { // PRIVATE METHODS // + _markNonceDuplicatesDropped (txId) { + this.txStateManager.setTxStatusConfirmed(txId) + // get the confirmed transactions nonce and from address + const txMeta = this.txStateManager.getTx(txId) + const { nonce, from } = txMeta.txParams + const sameNonceTxs = this.txStateManager.getFilteredTxList({nonce, from}) + if (!sameNonceTxs.length) return + // mark all same nonce transactions as dropped and give i a replacedBy hash + sameNonceTxs.forEach((otherTxMeta) => { + if (otherTxMeta.id === txId) return + otherTxMeta.replacedBy = txMeta.hash + this.txStateManager.updateTx(txMeta, 'transactions/pending-tx-tracker#event: tx:confirmed reference to confirmed txHash with same nonce') + this.txStateManager.setTxStatusDropped(otherTxMeta.id) + }) + } + _updateMemstore () { const unapprovedTxs = this.txStateManager.getUnapprovedTxList() const selectedAddressTxList = this.txStateManager.getFilteredTxList({ diff --git a/app/scripts/lib/tx-state-manager.js b/app/scripts/lib/tx-state-manager.js index 2eb006380..ad07c813f 100644 --- a/app/scripts/lib/tx-state-manager.js +++ b/app/scripts/lib/tx-state-manager.js @@ -1,9 +1,21 @@ const extend = require('xtend') const EventEmitter = require('events') const ObservableStore = require('obs-store') +const createId = require('./random-id') const ethUtil = require('ethereumjs-util') const txStateHistoryHelper = require('./tx-state-history-helper') +// STATUS METHODS + // statuses: + // - `'unapproved'` the user has not responded + // - `'rejected'` the user has responded no! + // - `'approved'` the user has approved the tx + // - `'signed'` the tx is signed + // - `'submitted'` the tx is sent to a server + // - `'confirmed'` the tx has been included in a block. + // - `'failed'` the tx failed for some reason, included on tx data. + // - `'dropped'` the tx nonce was already used + module.exports = class TransactionStateManager extends EventEmitter { constructor ({ initState, txHistoryLimit, getNetwork }) { super() @@ -16,6 +28,16 @@ module.exports = class TransactionStateManager extends EventEmitter { this.getNetwork = getNetwork } + generateTxMeta (opts) { + return extend({ + id: createId(), + time: (new Date()).getTime(), + status: 'unapproved', + metamaskNetworkId: this.getNetwork(), + loadingDefaults: true, + }, opts) + } + // Returns the number of txs for the current network. getTxCount () { return this.getTxList().length @@ -164,16 +186,6 @@ module.exports = class TransactionStateManager extends EventEmitter { }) } - // STATUS METHODS - // statuses: - // - `'unapproved'` the user has not responded - // - `'rejected'` the user has responded no! - // - `'approved'` the user has approved the tx - // - `'signed'` the tx is signed - // - `'submitted'` the tx is sent to a server - // - `'confirmed'` the tx has been included in a block. - // - `'failed'` the tx failed for some reason, included on tx data. - // get::set status // should return the status of the tx. @@ -202,7 +214,11 @@ module.exports = class TransactionStateManager extends EventEmitter { } // should update the status of the tx to 'submitted'. + // and add a time stamp for when it was called setTxStatusSubmitted (txId) { + const txMeta = this.getTx(txId) + txMeta.submittedTime = (new Date()).getTime() + this.updateTx(txMeta, 'txStateManager - add submitted time stamp') this._setTxStatus(txId, 'submitted') } @@ -211,6 +227,12 @@ module.exports = class TransactionStateManager extends EventEmitter { this._setTxStatus(txId, 'confirmed') } + // should update the status dropped + setTxStatusDropped (txId) { + this._setTxStatus(txId, 'dropped') + } + + setTxStatusFailed (txId, err) { const txMeta = this.getTx(txId) txMeta.err = { |