diff --git a/.babelrc b/.babelrc index 9d8d51656..3ca197980 100644 --- a/.babelrc +++ b/.babelrc @@ -1 +1,4 @@ -{ "presets": ["es2015"] } +{ + "presets": ["es2015"], + "plugins": ["transform-runtime"] +} diff --git a/.eslintrc b/.eslintrc index 91c95874e..a57a93cdc 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,7 +1,7 @@ { "parserOptions": { "sourceType": "module", - "ecmaVersion": 6, + "ecmaVersion": 2017, "ecmaFeatures": { "experimentalObjectRestSpread": true, "impliedStrict": true, diff --git a/CHANGELOG.md b/CHANGELOG.md index 40ba4d34d..371b348ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,17 @@ ## Current Master +## 3.6.5 2017-5-17 + +- Fix bug where edited gas parameters would not take effect. +- Trim currency list. +- Fix event filter bug introduced by newer versions of Geth. +- Fix bug where decimals in gas inputs could result in strange values. + +## 3.6.4 2017-5-8 + +- Fix main-net ENS resolution. + ## 3.6.3 2017-5-8 - Fix bug that could stop newer versions of Geth from working with MetaMask. diff --git a/app/currencies.json b/app/currencies.json deleted file mode 100644 index 07889798b..000000000 --- a/app/currencies.json +++ /dev/null @@ -1 +0,0 @@ -{"rows":[{"code":"007","name":"007","statuses":["primary"]},{"code":"1337","name":"1337","statuses":["primary"]},{"code":"1CR","name":"1CR","statuses":["primary"]},{"code":"256","name":"256","statuses":["primary"]},{"code":"2FLAV","name":"2FLAV","statuses":["primary"]},{"code":"2GIVE","name":"2GIVE","statuses":["primary"]},{"code":"404","name":"404","statuses":["primary"]},{"code":"611","name":"611","statuses":["primary"]},{"code":"888","name":"888","statuses":["primary"]},{"code":"8BIT","name":"8Bit","statuses":["primary"]},{"code":"ACLR","name":"ACLR","statuses":["primary"]},{"code":"ACOIN","name":"ACOIN","statuses":["primary"]},{"code":"ACP","name":"ACP","statuses":["primary"]},{"code":"ADC","name":"ADC","statuses":["primary"]},{"code":"ADZ","name":"Adzcoin","statuses":["primary"]},{"code":"AEC","name":"AEC","statuses":["primary"]},{"code":"AEON","name":"Aeon","statuses":["primary"]},{"code":"AGRS","name":"Agoras Tokens","statuses":["primary"]},{"code":"AIB","name":"AIB","statuses":["primary"]},{"code":"ADN","name":"Aiden","statuses":["primary"]},{"code":"AIR","name":"AIR","statuses":["primary"]},{"code":"ALC","name":"ALC","statuses":["primary"]},{"code":"ALTC","name":"ALTC","statuses":["primary"]},{"code":"AM","name":"AM","statuses":["primary"]},{"code":"AMBER","name":"AMBER","statuses":["primary"]},{"code":"AMS","name":"AMS","statuses":["primary"]},{"code":"ANAL","name":"ANAL","statuses":["primary"]},{"code":"AND","name":"AND","statuses":["primary"]},{"code":"ANI","name":"ANI","statuses":["primary"]},{"code":"ANC","name":"Anoncoin","statuses":["primary"]},{"code":"ANTI","name":"AntiBitcoin","statuses":["primary"]},{"code":"APEX","name":"APEX","statuses":["primary"]},{"code":"APC","name":"Applecoin","statuses":["primary"]},{"code":"APT","name":"APT","statuses":["primary"]},{"code":"AR2","name":"AR2","statuses":["primary"]},{"code":"ARB","name":"ARB","statuses":["primary"]},{"code":"ARC","name":"ARC","statuses":["primary"]},{"code":"ARCH","name":"ARCH","statuses":["primary"]},{"code":"ABY","name":"ArtByte","statuses":["primary"]},{"code":"ARTC","name":"ARTC","statuses":["primary"]},{"code":"ADCN","name":"Asiadigicoin","statuses":["primary"]},{"code":"ATEN","name":"ATEN","statuses":["primary"]},{"code":"REP","name":"Augur","statuses":["primary"]},{"code":"AUR","name":"Auroracoin","statuses":["primary"]},{"code":"AUD","name":"Australian Dollar","statuses":["secondary"]},{"code":"AV","name":"AV","statuses":["primary"]},{"code":"BA","name":"BA","statuses":["primary"]},{"code":"BAC","name":"BAC","statuses":["primary"]},{"code":"BTA","name":"Bata","statuses":["primary"]},{"code":"BAY","name":"BAY","statuses":["primary"]},{"code":"BBCC","name":"BBCC","statuses":["primary"]},{"code":"BQC","name":"BBQCoin","statuses":["primary"]},{"code":"BDC","name":"BDC","statuses":["primary"]},{"code":"BEC","name":"BEC","statuses":["primary"]},{"code":"BEEZ","name":"BEEZ","statuses":["primary"]},{"code":"BELA","name":"BellaCoin","statuses":["primary"]},{"code":"BERN","name":"BERNcash","statuses":["primary"]},{"code":"BILL","name":"BILL","statuses":["primary"]},{"code":"BILS","name":"BILS","statuses":["primary"]},{"code":"BIOS","name":"BiosCrypto","statuses":["primary"]},{"code":"BIT","name":"BIT","statuses":["primary"]},{"code":"BIT16","name":"BIT16","statuses":["primary"]},{"code":"BITB","name":"BitBean","statuses":["primary"]},{"code":"BTC","name":"Bitcoin","statuses":["primary","secondary"]},{"code":"XBC","name":"Bitcoin Plus","statuses":["primary"]},{"code":"BTCD","name":"BitcoinDark","statuses":["primary"]},{"code":"BCY","name":"Bitcrystals","statuses":["primary"]},{"code":"BTM","name":"Bitmark","statuses":["primary"]},{"code":"BTQ","name":"BitQuark","statuses":["primary"]},{"code":"BITS","name":"BITS","statuses":["primary"]},{"code":"BSD","name":"BitSend","statuses":["primary"]},{"code":"BTS","name":"BitShares","statuses":["primary"]},{"code":"PTS","name":"BitShares PTS","statuses":["primary"]},{"code":"SWIFT","name":"BitSwift","statuses":["primary"]},{"code":"BITZ","name":"Bitz","statuses":["primary"]},{"code":"BLK","name":"Blackcoin","statuses":["primary"]},{"code":"JACK","name":"BlackJack","statuses":["primary"]},{"code":"BLC","name":"Blakecoin","statuses":["primary"]},{"code":"BLEU","name":"BLEU","statuses":["primary"]},{"code":"BLITZ","name":"Blitzcoin","statuses":["primary"]},{"code":"BLOCK","name":"Blocknet","statuses":["primary"]},{"code":"BLRY","name":"BLRY","statuses":["primary"]},{"code":"BLU","name":"BLU","statuses":["primary"]},{"code":"BM","name":"BM","statuses":["primary"]},{"code":"BNT","name":"BNT","statuses":["primary"]},{"code":"BOB","name":"BOB","statuses":["primary"]},{"code":"BON","name":"BON","statuses":["primary"]},{"code":"BBR","name":"Boolberry","statuses":["primary"]},{"code":"BOST","name":"BoostCoin","statuses":["primary"]},{"code":"BOSS","name":"BOSS","statuses":["primary"]},{"code":"BPOK","name":"BPOK","statuses":["primary"]},{"code":"BRAIN","name":"BRAIN","statuses":["primary"]},{"code":"BRC","name":"BRC","statuses":["primary"]},{"code":"BRDD","name":"BRDD","statuses":["primary"]},{"code":"BRIT","name":"BRIT","statuses":["primary"]},{"code":"GBP","name":"British Pound Sterling","statuses":["secondary"]},{"code":"BRK","name":"BRK","statuses":["primary"]},{"code":"BRX","name":"BRX","statuses":["primary"]},{"code":"BSC","name":"BSC","statuses":["primary"]},{"code":"BST","name":"BST","statuses":["primary"]},{"code":"BTCHC","name":"BTCHC","statuses":["primary"]},{"code":"BTCR","name":"BTCR","statuses":["primary"]},{"code":"BTCS","name":"BTCS","statuses":["primary"]},{"code":"BTCU","name":"BTCU","statuses":["primary"]},{"code":"BTTF","name":"BTTF","statuses":["primary"]},{"code":"BTX","name":"BTX","statuses":["primary"]},{"code":"BUCKS","name":"BUCKS","statuses":["primary"]},{"code":"BUN","name":"BUN","statuses":["primary"]},{"code":"BURST","name":"Burst","statuses":["primary"]},{"code":"BUZZ","name":"BUZZ","statuses":["primary"]},{"code":"BVC","name":"BVC","statuses":["primary"]},{"code":"BYC","name":"Bytecent","statuses":["primary"]},{"code":"BCN","name":"Bytecoin","statuses":["primary"]},{"code":"XCT","name":"C-Bit","statuses":["primary"]},{"code":"C0C0","name":"C0C0","statuses":["primary"]},{"code":"CAB","name":"Cabbage Unit","statuses":["primary"]},{"code":"CAD","name":"CAD","statuses":["primary","secondary"]},{"code":"CAGE","name":"CAGE","statuses":["primary"]},{"code":"CANN","name":"CannabisCoin","statuses":["primary"]},{"code":"CCN","name":"Cannacoin","statuses":["primary"]},{"code":"CPC","name":"Capricoin","statuses":["primary"]},{"code":"DIEM","name":"CarpeDiemCoin","statuses":["primary"]},{"code":"CASH","name":"CASH","statuses":["primary"]},{"code":"CBIT","name":"CBIT","statuses":["primary"]},{"code":"CC","name":"CC","statuses":["primary"]},{"code":"CCB","name":"CCB","statuses":["primary"]},{"code":"CD","name":"CD","statuses":["primary"]},{"code":"CDN","name":"CDN","statuses":["primary"]},{"code":"CF","name":"CF","statuses":["primary"]},{"code":"CFC","name":"CFC","statuses":["primary"]},{"code":"CGA","name":"CGA","statuses":["primary"]},{"code":"CHC","name":"CHC","statuses":["primary"]},{"code":"CKC","name":"Checkcoin","statuses":["primary"]},{"code":"CHEMX","name":"CHEMX","statuses":["primary"]},{"code":"CHESS","name":"CHESS","statuses":["primary"]},{"code":"CHF","name":"CHF","statuses":["primary","secondary"]},{"code":"CNY","name":"Chinese Yuan","statuses":["secondary"]},{"code":"CHRG","name":"CHRG","statuses":["primary"]},{"code":"CJ","name":"CJ","statuses":["primary"]},{"code":"CLAM","name":"Clams","statuses":["primary"]},{"code":"CLICK","name":"CLICK","statuses":["primary"]},{"code":"CLINT","name":"CLINT","statuses":["primary"]},{"code":"CLOAK","name":"Cloakcoin","statuses":["primary"]},{"code":"CLR","name":"CLR","statuses":["primary"]},{"code":"CLUB","name":"CLUB","statuses":["primary"]},{"code":"CLUD","name":"CLUD","statuses":["primary"]},{"code":"CMT","name":"CMT","statuses":["primary"]},{"code":"CNC","name":"CNC","statuses":["primary"]},{"code":"COXST","name":"CoExistCoin","statuses":["primary"]},{"code":"COIN","name":"COIN","statuses":["primary"]},{"code":"C2","name":"Coin2.1","statuses":["primary"]},{"code":"CNMT","name":"Coinomat","statuses":["primary"]},{"code":"CV2","name":"Colossuscoin2.0","statuses":["primary"]},{"code":"CON","name":"CON","statuses":["primary"]},{"code":"XCP","name":"Counterparty","statuses":["primary"]},{"code":"COV","name":"COV","statuses":["primary"]},{"code":"CRAFT","name":"CRAFT","statuses":["primary"]},{"code":"CRAVE","name":"CRAVE","statuses":["primary"]},{"code":"CRC","name":"CRC","statuses":["primary"]},{"code":"CRE","name":"CRE","statuses":["primary"]},{"code":"CRBIT","name":"Creditbit","statuses":["primary"]},{"code":"CREVA","name":"CrevaCoin","statuses":["primary"]},{"code":"CRIME","name":"CRIME","statuses":["primary"]},{"code":"CRT","name":"CRT","statuses":["primary"]},{"code":"CRW","name":"CRW","statuses":["primary"]},{"code":"CRY","name":"CRY","statuses":["primary"]},{"code":"XCR","name":"Crypti","statuses":["primary"]},{"code":"CBX","name":"Crypto Bullion","statuses":["primary"]},{"code":"CESC","name":"CryptoEscudo","statuses":["primary"]},{"code":"XCN","name":"Cryptonite","statuses":["primary"]},{"code":"CSMIC","name":"CSMIC","statuses":["primary"]},{"code":"CST","name":"CST","statuses":["primary"]},{"code":"CTC","name":"CTC","statuses":["primary"]},{"code":"CTO","name":"CTO","statuses":["primary"]},{"code":"CURE","name":"Curecoin","statuses":["primary"]},{"code":"CYP","name":"Cypher","statuses":["primary"]},{"code":"CZC","name":"CZC","statuses":["primary"]},{"code":"CZECO","name":"CZECO","statuses":["primary"]},{"code":"CZR","name":"CZR","statuses":["primary"]},{"code":"DAO","name":"DAO","statuses":["primary"]},{"code":"DGD","name":"DarkGoldCoin","statuses":["primary"]},{"code":"DNET","name":"Darknet","statuses":["primary"]},{"code":"DASH","name":"Dash","statuses":["primary"]},{"code":"DTC","name":"Datacoin","statuses":["primary"]},{"code":"DBG","name":"DBG","statuses":["primary"]},{"code":"DBLK","name":"DBLK","statuses":["primary"]},{"code":"DBTC","name":"DBTC","statuses":["primary"]},{"code":"DCK","name":"DCK","statuses":["primary"]},{"code":"DCR","name":"Decred","statuses":["primary"]},{"code":"DES","name":"Destiny","statuses":["primary"]},{"code":"DETH","name":"DETH","statuses":["primary"]},{"code":"DEUR","name":"DEUR","statuses":["primary"]},{"code":"DEM","name":"Deutsche eMark","statuses":["primary"]},{"code":"DVC","name":"Devcoin","statuses":["primary"]},{"code":"DGCS","name":"DGCS","statuses":["primary"]},{"code":"DGMS","name":"DGMS","statuses":["primary"]},{"code":"DGORE","name":"DGORE","statuses":["primary"]},{"code":"DMD","name":"Diamond","statuses":["primary"]},{"code":"DGB","name":"Digibyte","statuses":["primary"]},{"code":"CUBE","name":"DigiCube","statuses":["primary"]},{"code":"DGC","name":"Digitalcoin","statuses":["primary"]},{"code":"XDN","name":"DigitalNote","statuses":["primary"]},{"code":"DP","name":"DigitalPrice","statuses":["primary"]},{"code":"DIGS","name":"DIGS","statuses":["primary"]},{"code":"DIME","name":"Dimecoin","statuses":["primary"]},{"code":"DISK","name":"DISK","statuses":["primary"]},{"code":"DLISK","name":"DLISK","statuses":["primary"]},{"code":"NOTE","name":"DNotes","statuses":["primary"]},{"code":"DOGE","name":"DOGE","statuses":["primary","secondary"]},{"code":"DOGE","name":"Dogecoin","statuses":["primary","secondary"]},{"code":"DON","name":"DON","statuses":["primary"]},{"code":"DOPE","name":"DopeCoin","statuses":["primary"]},{"code":"DOX","name":"DOX","statuses":["primary"]},{"code":"DRACO","name":"DRACO","statuses":["primary"]},{"code":"DRM","name":"DRM","statuses":["primary"]},{"code":"DROP","name":"DROP","statuses":["primary"]},{"code":"DRZ","name":"DRZ","statuses":["primary"]},{"code":"DSH","name":"DSH","statuses":["primary"]},{"code":"DBIC","name":"DubaiCoin","statuses":["primary"]},{"code":"DUO","name":"DUO","statuses":["primary"]},{"code":"DUST","name":"DUST","statuses":["primary"]},{"code":"EAC","name":"Earthcoin","statuses":["primary"]},{"code":"ECCHI","name":"ECCHI","statuses":["primary"]},{"code":"ECC","name":"ECCoin","statuses":["primary"]},{"code":"ECOS","name":"ECOS","statuses":["primary"]},{"code":"EDC","name":"EDC","statuses":["primary"]},{"code":"EDRC","name":"EDRC","statuses":["primary"]},{"code":"EGG","name":"EGG","statuses":["primary"]},{"code":"EMC2","name":"Einsteinium","statuses":["primary"]},{"code":"EKO","name":"EKO","statuses":["primary"]},{"code":"EL","name":"EL","statuses":["primary"]},{"code":"ELCO","name":"ELcoin","statuses":["primary"]},{"code":"ELE","name":"ELE","statuses":["primary"]},{"code":"EFL","name":"Electronic Gulden","statuses":["primary"]},{"code":"EMC","name":"Emercoin","statuses":["primary"]},{"code":"EMIRG","name":"EMIRG","statuses":["primary"]},{"code":"ENE","name":"ENE","statuses":["primary"]},{"code":"ENRG","name":"Energycoin","statuses":["primary"]},{"code":"EPC","name":"EPC","statuses":["primary"]},{"code":"EPY","name":"EPY","statuses":["primary"]},{"code":"ERC","name":"ERC","statuses":["primary"]},{"code":"ERC3","name":"ERC3","statuses":["primary"]},{"code":"ESC","name":"ESC","statuses":["primary"]},{"code":"ETH","name":"Ethereum","statuses":["primary","secondary"]},{"code":"ETC","name":"Ethereum Classic","statuses":["primary"]},{"code":"ETHS","name":"ETHS","statuses":["primary"]},{"code":"EURC","name":"EURC","statuses":["primary"]},{"code":"EUR","name":"Euro","statuses":["primary","secondary"]},{"code":"EGC","name":"EvergreenCoin","statuses":["primary"]},{"code":"EVIL","name":"EVIL","statuses":["primary"]},{"code":"EVO","name":"EVO","statuses":["primary"]},{"code":"EXCL","name":"EXCL","statuses":["primary"]},{"code":"EXIT","name":"EXIT","statuses":["primary"]},{"code":"EXP","name":"Expanse","statuses":["primary"]},{"code":"FCT","name":"Factom","statuses":["primary"]},{"code":"FAIR","name":"Faircoin","statuses":["primary"]},{"code":"FC2","name":"FC2","statuses":["primary"]},{"code":"FCN","name":"FCN","statuses":["primary"]},{"code":"FTC","name":"Feathercoin","statuses":["primary"]},{"code":"TIPS","name":"Fedoracoin","statuses":["primary"]},{"code":"FFC","name":"FFC","statuses":["primary"]},{"code":"FIBRE","name":"Fibre","statuses":["primary"]},{"code":"FIT","name":"FIT","statuses":["primary"]},{"code":"FJC","name":"FJC","statuses":["primary"]},{"code":"FLO","name":"Florincoin","statuses":["primary"]},{"code":"FLOZ","name":"FLOZ","statuses":["primary"]},{"code":"FLT","name":"FlutterCoin","statuses":["primary"]},{"code":"FLX","name":"FLX","statuses":["primary"]},{"code":"FLY","name":"Flycoin","statuses":["primary"]},{"code":"FLDC","name":"FoldingCoin","statuses":["primary"]},{"code":"FONZ","name":"FONZ","statuses":["primary"]},{"code":"FRK","name":"Franko","statuses":["primary"]},{"code":"FRC","name":"Freicoin","statuses":["primary"]},{"code":"FRN","name":"FRN","statuses":["primary"]},{"code":"FRWC","name":"FRWC","statuses":["primary"]},{"code":"FSC2","name":"FSC2","statuses":["primary"]},{"code":"FST","name":"FST","statuses":["primary"]},{"code":"FTP","name":"FTP","statuses":["primary"]},{"code":"FUN","name":"FUN","statuses":["primary"]},{"code":"FUTC","name":"FUTC","statuses":["primary"]},{"code":"FUZZ","name":"FUZZ","statuses":["primary"]},{"code":"GAIA","name":"GAIA","statuses":["primary"]},{"code":"GAIN","name":"GAIN","statuses":["primary"]},{"code":"GAKH","name":"GAKH","statuses":["primary"]},{"code":"GAM","name":"GAM","statuses":["primary"]},{"code":"GBT","name":"GameBet Coin","statuses":["primary"]},{"code":"GAME","name":"GameCredits","statuses":["primary"]},{"code":"GAP","name":"Gapcoin","statuses":["primary"]},{"code":"GARY","name":"GARY","statuses":["primary"]},{"code":"GB","name":"GB","statuses":["primary"]},{"code":"GBC","name":"GBC","statuses":["primary"]},{"code":"GBIT","name":"GBIT","statuses":["primary"]},{"code":"GCC","name":"GCC","statuses":["primary"]},{"code":"GCN","name":"GCN","statuses":["primary"]},{"code":"GEO","name":"GeoCoin","statuses":["primary"]},{"code":"GEMZ","name":"GetGems","statuses":["primary"]},{"code":"GHOST","name":"GHOST","statuses":["primary"]},{"code":"GHS","name":"GHS","statuses":["primary"]},{"code":"GIFT","name":"GIFT","statuses":["primary"]},{"code":"GIG","name":"GIG","statuses":["primary"]},{"code":"GLC","name":"GLC","statuses":["primary"]},{"code":"BSTY","name":"GlobalBoost-Y","statuses":["primary"]},{"code":"GML","name":"GML","statuses":["primary"]},{"code":"GMX","name":"GMX","statuses":["primary"]},{"code":"GCR","name":"GoCoineR","statuses":["primary"]},{"code":"GLD","name":"GoldCoin","statuses":["primary"]},{"code":"GOON","name":"GOON","statuses":["primary"]},{"code":"GP","name":"GP","statuses":["primary"]},{"code":"GPU","name":"GPU","statuses":["primary"]},{"code":"GRAM","name":"GRAM","statuses":["primary"]},{"code":"GRT","name":"Grantcoin","statuses":["primary"]},{"code":"GRE","name":"GRE","statuses":["primary"]},{"code":"GRC","name":"Gridcoin","statuses":["primary"]},{"code":"GRN","name":"GRN","statuses":["primary"]},{"code":"GRS","name":"Groestlcoin","statuses":["primary"]},{"code":"GRW","name":"GRW","statuses":["primary"]},{"code":"GSM","name":"GSM","statuses":["primary"]},{"code":"GSX","name":"GSX","statuses":["primary"]},{"code":"GUA","name":"GUA","statuses":["primary"]},{"code":"NLG","name":"Gulden","statuses":["primary"]},{"code":"GUN","name":"GUN","statuses":["primary"]},{"code":"HAM","name":"HAM","statuses":["primary"]},{"code":"HAWK","name":"HAWK","statuses":["primary"]},{"code":"HCC","name":"HCC","statuses":["primary"]},{"code":"HEAT","name":"HEAT","statuses":["primary"]},{"code":"HMP","name":"HempCoin","statuses":["primary"]},{"code":"XHI","name":"HiCoin","statuses":["primary"]},{"code":"HIFUN","name":"HIFUN","statuses":["primary"]},{"code":"HILL","name":"HILL","statuses":["primary"]},{"code":"HIRE","name":"HIRE","statuses":["primary"]},{"code":"HNC","name":"HNC","statuses":["primary"]},{"code":"HODL","name":"HOdlcoin","statuses":["primary"]},{"code":"HKD","name":"Hong Kong Dollar","statuses":["secondary"]},{"code":"HZ","name":"Horizon","statuses":["primary"]},{"code":"HTC","name":"HTC","statuses":["primary"]},{"code":"HTML5","name":"HTMLCOIN","statuses":["primary"]},{"code":"HUC","name":"HUC","statuses":["primary"]},{"code":"HVCO","name":"HVCO","statuses":["primary"]},{"code":"HYPER","name":"Hyper","statuses":["primary"]},{"code":"HYP","name":"HyperStake","statuses":["primary"]},{"code":"I0C","name":"I0C","statuses":["primary"]},{"code":"IBANK","name":"IBANK","statuses":["primary"]},{"code":"ICASH","name":"iCash","statuses":["primary"]},{"code":"ICN","name":"ICN","statuses":["primary"]},{"code":"IEC","name":"IEC","statuses":["primary"]},{"code":"IFC","name":"Infinitecoin","statuses":["primary"]},{"code":"INFX","name":"Influxcoin","statuses":["primary"]},{"code":"INV","name":"INV","statuses":["primary"]},{"code":"IOC","name":"IO Coin","statuses":["primary"]},{"code":"ION","name":"ION","statuses":["primary"]},{"code":"IRL","name":"IRL","statuses":["primary"]},{"code":"ISL","name":"IslaCoin","statuses":["primary"]},{"code":"IVZ","name":"IVZ","statuses":["primary"]},{"code":"IXC","name":"IXC","statuses":["primary"]},{"code":"JIF","name":"JIF","statuses":["primary"]},{"code":"JPC","name":"JPC","statuses":["primary"]},{"code":"JPY","name":"JPY","statuses":["primary","secondary"]},{"code":"JBS","name":"Jumbucks","statuses":["primary"]},{"code":"KAT","name":"KAT","statuses":["primary"]},{"code":"KGC","name":"KGC","statuses":["primary"]},{"code":"KNC","name":"KhanCoin","statuses":["primary"]},{"code":"KLC","name":"KLC","statuses":["primary"]},{"code":"KOBO","name":"KOBO","statuses":["primary"]},{"code":"KORE","name":"KoreCoin","statuses":["primary"]},{"code":"KRAK","name":"KRAK","statuses":["primary"]},{"code":"KRYP","name":"KRYP","statuses":["primary"]},{"code":"KR","name":"Krypton","statuses":["primary"]},{"code":"KTK","name":"KTK","statuses":["primary"]},{"code":"KUBO","name":"KUBO","statuses":["primary"]},{"code":"LANA","name":"LANA","statuses":["primary"]},{"code":"LBC","name":"LBC","statuses":["primary"]},{"code":"LC","name":"LC","statuses":["primary"]},{"code":"LEA","name":"LeaCoin","statuses":["primary"]},{"code":"LEMON","name":"LEMON","statuses":["primary"]},{"code":"LEO","name":"LEO","statuses":["primary"]},{"code":"LFC","name":"LFC","statuses":["primary"]},{"code":"LFO","name":"LFO","statuses":["primary"]},{"code":"LFTC","name":"LFTC","statuses":["primary"]},{"code":"LQD","name":"LIQUID","statuses":["primary"]},{"code":"LIR","name":"LIR","statuses":["primary"]},{"code":"LSK","name":"Lisk","statuses":["primary"]},{"code":"LTC","name":"Litecoin","statuses":["primary","secondary"]},{"code":"LTCR","name":"Litecred","statuses":["primary"]},{"code":"LDOGE","name":"LiteDoge","statuses":["primary"]},{"code":"LKC","name":"LKC","statuses":["primary"]},{"code":"LOC","name":"LOC","statuses":["primary"]},{"code":"LOOT","name":"LOOT","statuses":["primary"]},{"code":"LTBC","name":"LTBcoin","statuses":["primary"]},{"code":"LTC","name":"LTC","statuses":["primary","secondary"]},{"code":"LTH","name":"LTH","statuses":["primary"]},{"code":"LTS","name":"LTS","statuses":["primary"]},{"code":"LUN","name":"LUN","statuses":["primary"]},{"code":"LXC","name":"LXC","statuses":["primary"]},{"code":"LYB","name":"LYB","statuses":["primary"]},{"code":"M1","name":"M1","statuses":["primary"]},{"code":"MAD","name":"MAD","statuses":["primary"]},{"code":"XMG","name":"Magi","statuses":["primary"]},{"code":"MAID","name":"MaidSafeCoin","statuses":["primary"]},{"code":"MXT","name":"MarteXcoin","statuses":["primary"]},{"code":"MARV","name":"MARV","statuses":["primary"]},{"code":"MARYJ","name":"MARYJ","statuses":["primary"]},{"code":"OMNI","name":"Mastercoin (Omni)","statuses":["primary"]},{"code":"MTR","name":"MasterTraderCoin","statuses":["primary"]},{"code":"MAX","name":"Maxcoin","statuses":["primary"]},{"code":"MZC","name":"Mazacoin","statuses":["primary"]},{"code":"MBL","name":"MBL","statuses":["primary"]},{"code":"MCAR","name":"MCAR","statuses":["primary"]},{"code":"MCN","name":"MCN","statuses":["primary"]},{"code":"MCZ","name":"MCZ","statuses":["primary"]},{"code":"MED","name":"MediterraneanCoin","statuses":["primary"]},{"code":"MEC","name":"Megacoin","statuses":["primary"]},{"code":"MEME","name":"Memetic","statuses":["primary"]},{"code":"METAL","name":"METAL","statuses":["primary"]},{"code":"MND","name":"MindCoin","statuses":["primary"]},{"code":"MINT","name":"Mintcoin","statuses":["primary"]},{"code":"MIS","name":"MIS","statuses":["primary"]},{"code":"MM","name":"MM","statuses":["primary"]},{"code":"MMC","name":"MMC","statuses":["primary"]},{"code":"MMNXT","name":"MMNXT","statuses":["primary"]},{"code":"MMXVI","name":"MMXVI","statuses":["primary"]},{"code":"MNM","name":"MNM","statuses":["primary"]},{"code":"MOIN","name":"MOIN","statuses":["primary"]},{"code":"MOJO","name":"MojoCoin","statuses":["primary"]},{"code":"MONA","name":"MonaCoin","statuses":["primary"]},{"code":"XMR","name":"Monero","statuses":["primary","secondary"]},{"code":"MNTA","name":"Moneta","statuses":["primary"]},{"code":"MUE","name":"MonetaryUnit","statuses":["primary"]},{"code":"MOON","name":"Mooncoin","statuses":["primary"]},{"code":"MOOND","name":"MOOND","statuses":["primary"]},{"code":"MOTO","name":"MOTO","statuses":["primary"]},{"code":"MPRO","name":"MPRO","statuses":["primary"]},{"code":"MRB","name":"MRB","statuses":["primary"]},{"code":"MRP","name":"MRP","statuses":["primary"]},{"code":"MSC","name":"MSC","statuses":["primary"]},{"code":"MYR","name":"Myriadcoin","statuses":["primary"]},{"code":"NMC","name":"Namecoin","statuses":["primary"]},{"code":"NAUT","name":"Nautiluscoin","statuses":["primary"]},{"code":"NAV","name":"NAV Coin","statuses":["primary"]},{"code":"NCS","name":"NCS","statuses":["primary"]},{"code":"XEM","name":"NEM","statuses":["primary"]},{"code":"NEOS","name":"NeosCoin","statuses":["primary"]},{"code":"NETC","name":"NETC","statuses":["primary"]},{"code":"NET","name":"NetCoin","statuses":["primary"]},{"code":"NEU","name":"NeuCoin","statuses":["primary"]},{"code":"NTRN","name":"Neutron","statuses":["primary"]},{"code":"NEVA","name":"NevaCoin","statuses":["primary"]},{"code":"NEWB","name":"NEWB","statuses":["primary"]},{"code":"NIRO","name":"Nexus","statuses":["primary"]},{"code":"NIC","name":"NIC","statuses":["primary"]},{"code":"NKA","name":"NKA","statuses":["primary"]},{"code":"NKC","name":"NKC","statuses":["primary"]},{"code":"NOBL","name":"NobleCoin","statuses":["primary"]},{"code":"NODE","name":"NODE","statuses":["primary"]},{"code":"NODES","name":"NODES","statuses":["primary"]},{"code":"NOO","name":"NOO","statuses":["primary"]},{"code":"NVC","name":"Novacoin","statuses":["primary"]},{"code":"NRC","name":"NRC","statuses":["primary"]},{"code":"NRS","name":"NRS","statuses":["primary"]},{"code":"NUBIS","name":"NUBIS","statuses":["primary"]},{"code":"NBT","name":"NuBits","statuses":["primary"]},{"code":"NUM","name":"NUM","statuses":["primary"]},{"code":"NSR","name":"NuShares","statuses":["primary"]},{"code":"NXE","name":"NXE","statuses":["primary"]},{"code":"NXT","name":"NXT","statuses":["primary"]},{"code":"NXTTY","name":"Nxttycoin","statuses":["primary"]},{"code":"NYC","name":"NYC","statuses":["primary"]},{"code":"NZC","name":"NZC","statuses":["primary"]},{"code":"NZD","name":"NZD","statuses":["primary","secondary"]},{"code":"OC","name":"OC","statuses":["primary"]},{"code":"OCOW","name":"OCOW","statuses":["primary"]},{"code":"OK","name":"OKCash","statuses":["primary"]},{"code":"OMA","name":"OMA","statuses":["primary"]},{"code":"ONE","name":"ONE","statuses":["primary"]},{"code":"ONEC","name":"ONEC","statuses":["primary"]},{"code":"OP","name":"OP","statuses":["primary"]},{"code":"OPAL","name":"OPAL","statuses":["primary"]},{"code":"OPES","name":"OPES","statuses":["primary"]},{"code":"ORB","name":"Orbitcoin","statuses":["primary"]},{"code":"ORLY","name":"Orlycoin","statuses":["primary"]},{"code":"OS76","name":"OS76","statuses":["primary"]},{"code":"OZC","name":"OZC","statuses":["primary"]},{"code":"PAC","name":"PAC","statuses":["primary"]},{"code":"PAK","name":"PAK","statuses":["primary"]},{"code":"PND","name":"Pandacoin","statuses":["primary"]},{"code":"PAPAF","name":"PAPAF","statuses":["primary"]},{"code":"XPY","name":"Paycoin","statuses":["primary"]},{"code":"PBC","name":"PBC","statuses":["primary"]},{"code":"PDC","name":"PDC","statuses":["primary"]},{"code":"XPB","name":"Pebblecoin","statuses":["primary"]},{"code":"PPC","name":"Peercoin","statuses":["primary"]},{"code":"PEN","name":"PEN","statuses":["primary"]},{"code":"PHR","name":"PHR","statuses":["primary"]},{"code":"PIGGY","name":"Piggycoin","statuses":["primary"]},{"code":"PC","name":"Pinkcoin","statuses":["primary"]},{"code":"PKB","name":"PKB","statuses":["primary"]},{"code":"PLN","name":"PLN","statuses":["primary","secondary"]},{"code":"PLNC","name":"PLNC","statuses":["primary"]},{"code":"PNC","name":"PNC","statuses":["primary"]},{"code":"PNK","name":"PNK","statuses":["primary"]},{"code":"POKE","name":"POKE","statuses":["primary"]},{"code":"PONZ2","name":"PONZ2","statuses":["primary"]},{"code":"PONZI","name":"PONZI","statuses":["primary"]},{"code":"PEX","name":"PosEx","statuses":["primary"]},{"code":"POST","name":"POST","statuses":["primary"]},{"code":"POT","name":"Potcoin","statuses":["primary"]},{"code":"PRES","name":"PRES","statuses":["primary"]},{"code":"PXI","name":"Prime-XI","statuses":["primary"]},{"code":"PRIME","name":"PrimeChain","statuses":["primary"]},{"code":"XPM","name":"Primecoin","statuses":["primary"]},{"code":"PRM","name":"PRM","statuses":["primary"]},{"code":"PRT","name":"PRT","statuses":["primary"]},{"code":"PSP","name":"PSP","statuses":["primary"]},{"code":"PTC","name":"PTC","statuses":["primary"]},{"code":"PULSE","name":"PULSE","statuses":["primary"]},{"code":"PURE","name":"PURE","statuses":["primary"]},{"code":"PUTIN","name":"PUTIN","statuses":["primary"]},{"code":"PWR","name":"PWR","statuses":["primary"]},{"code":"PXL","name":"PXL","statuses":["primary"]},{"code":"QBC","name":"QBC","statuses":["primary"]},{"code":"QBK","name":"QBK","statuses":["primary"]},{"code":"QCN","name":"QCN","statuses":["primary"]},{"code":"QORA","name":"Qora","statuses":["primary"]},{"code":"QTZ","name":"QTZ","statuses":["primary"]},{"code":"QRK","name":"Quark","statuses":["primary"]},{"code":"QTL","name":"Quatloo","statuses":["primary"]},{"code":"RADI","name":"RADI","statuses":["primary"]},{"code":"RADS","name":"Radium","statuses":["primary"]},{"code":"RED","name":"RED","statuses":["primary"]},{"code":"RDD","name":"Reddcoin","statuses":["primary"]},{"code":"REE","name":"REE","statuses":["primary"]},{"code":"REV","name":"Revenu","statuses":["primary"]},{"code":"RBR","name":"RibbitRewards","statuses":["primary"]},{"code":"RICHX","name":"RICHX","statuses":["primary"]},{"code":"RIC","name":"Riecoin","statuses":["primary"]},{"code":"RBT","name":"Rimbit","statuses":["primary"]},{"code":"RIO","name":"RIO","statuses":["primary"]},{"code":"XRP","name":"Ripple","statuses":["primary"]},{"code":"RISE","name":"RISE","statuses":["primary"]},{"code":"RMS","name":"RMS","statuses":["primary"]},{"code":"RONIN","name":"RONIN","statuses":["primary"]},{"code":"ROOT","name":"ROOT","statuses":["primary"]},{"code":"ROS","name":"RosCoin","statuses":["primary"]},{"code":"RPC","name":"RPC","statuses":["primary"]},{"code":"RBIES","name":"Rubies","statuses":["primary"]},{"code":"RUBIT","name":"RUBIT","statuses":["primary"]},{"code":"RUR","name":"Ruble","statuses":["secondary"]},{"code":"RBY","name":"Rubycoin","statuses":["primary"]},{"code":"RUST","name":"RUST","statuses":["primary"]},{"code":"SEC","name":"Safe Exchange Coin","statuses":["primary"]},{"code":"SAK","name":"SAK","statuses":["primary"]},{"code":"SAR","name":"SAR","statuses":["primary"]},{"code":"SBD","name":"SBD","statuses":["primary"]},{"code":"SBIT","name":"SBIT","statuses":["primary"]},{"code":"SCAN","name":"SCAN","statuses":["primary"]},{"code":"SCOT","name":"Scotcoin","statuses":["primary"]},{"code":"SCRPT","name":"SCRPT","statuses":["primary"]},{"code":"SCRT","name":"SCRT","statuses":["primary"]},{"code":"SRC","name":"SecureCoin","statuses":["primary"]},{"code":"SXC","name":"Sexcoin","statuses":["primary"]},{"code":"SFE","name":"SFE","statuses":["primary"]},{"code":"SFR","name":"SFR","statuses":["primary"]},{"code":"SGD","name":"SGD","statuses":["primary","secondary"]},{"code":"SDC","name":"ShadowCash","statuses":["primary"]},{"code":"SHELL","name":"SHELL","statuses":["primary"]},{"code":"SHF","name":"SHF","statuses":["primary"]},{"code":"SHI","name":"SHI","statuses":["primary"]},{"code":"SHIFT","name":"Shift","statuses":["primary"]},{"code":"SHREK","name":"SHREK","statuses":["primary"]},{"code":"SC","name":"Siacoin","statuses":["primary"]},{"code":"SIB","name":"Siberian chervonets","statuses":["primary"]},{"code":"SIC","name":"SIC","statuses":["primary"]},{"code":"SIGU","name":"SIGU","statuses":["primary"]},{"code":"SILK","name":"Silkcoin","statuses":["primary"]},{"code":"SIX","name":"SIX","statuses":["primary"]},{"code":"SLING","name":"Sling","statuses":["primary"]},{"code":"SLS","name":"SLS","statuses":["primary"]},{"code":"SMBR","name":"SMBR","statuses":["primary"]},{"code":"SMC","name":"SMC","statuses":["primary"]},{"code":"SMLY","name":"SmileyCoin","statuses":["primary"]},{"code":"SNRG","name":"SNRG","statuses":["primary"]},{"code":"SOIL","name":"SOILcoin","statuses":["primary"]},{"code":"SLR","name":"Solarcoin","statuses":["primary"]},{"code":"SOLO","name":"SOLO","statuses":["primary"]},{"code":"SONG","name":"SongCoin","statuses":["primary"]},{"code":"SOON","name":"SOON","statuses":["primary"]},{"code":"SPC","name":"SPC","statuses":["primary"]},{"code":"SPEX","name":"SPEX","statuses":["primary"]},{"code":"SPHR","name":"Sphere","statuses":["primary"]},{"code":"SPM","name":"SPM","statuses":["primary"]},{"code":"SPN","name":"SPN","statuses":["primary"]},{"code":"SPOTS","name":"SPOTS","statuses":["primary"]},{"code":"SPR","name":"SpreadCoin","statuses":["primary"]},{"code":"SPRTS","name":"Sprouts","statuses":["primary"]},{"code":"SQC","name":"SQC","statuses":["primary"]},{"code":"SSC","name":"SSC","statuses":["primary"]},{"code":"SSTC","name":"SSTC","statuses":["primary"]},{"code":"STA","name":"STA","statuses":["primary"]},{"code":"START","name":"Startcoin","statuses":["primary"]},{"code":"XST","name":"Stealthcoin","statuses":["primary"]},{"code":"STEEM","name":"Steem","statuses":["primary"]},{"code":"XLM","name":"Stellar","statuses":["primary"]},{"code":"STR","name":"Stellar","statuses":["primary"]},{"code":"STEPS","name":"Steps","statuses":["primary"]},{"code":"SLG","name":"Sterlingcoin","statuses":["primary"]},{"code":"STL","name":"STL","statuses":["primary"]},{"code":"SJCX","name":"Storjcoin X","statuses":["primary"]},{"code":"STP","name":"STP","statuses":["primary"]},{"code":"STRB","name":"STRB","statuses":["primary"]},{"code":"STS","name":"Stress","statuses":["primary"]},{"code":"STRP","name":"STRP","statuses":["primary"]},{"code":"STV","name":"STV","statuses":["primary"]},{"code":"SUB","name":"Subcriptio","statuses":["primary"]},{"code":"SUPER","name":"SUPER","statuses":["primary"]},{"code":"UNITY","name":"SuperNET","statuses":["primary"]},{"code":"SWARM","name":"Swarm","statuses":["primary"]},{"code":"SWING","name":"SWING","statuses":["primary"]},{"code":"SDP","name":"SydPak Coin","statuses":["primary"]},{"code":"SYNC","name":"SYNC","statuses":["primary"]},{"code":"AMP","name":"Synereo","statuses":["primary"]},{"code":"SYS","name":"Syscoin","statuses":["primary"]},{"code":"TAG","name":"TagCoin","statuses":["primary"]},{"code":"TAJ","name":"TAJ","statuses":["primary"]},{"code":"TAK","name":"TAK","statuses":["primary"]},{"code":"TAM","name":"TAM","statuses":["primary"]},{"code":"TAO","name":"TAO","statuses":["primary"]},{"code":"TBC","name":"TBC","statuses":["primary"]},{"code":"TBCX","name":"TBCX","statuses":["primary"]},{"code":"TCR","name":"TCR","statuses":["primary"]},{"code":"TDFB","name":"TDFB","statuses":["primary"]},{"code":"TDY","name":"TDY","statuses":["primary"]},{"code":"TEK","name":"TEKcoin","statuses":["primary"]},{"code":"TRC","name":"Terracoin","statuses":["primary"]},{"code":"TESLA","name":"TESLA","statuses":["primary"]},{"code":"TES","name":"TeslaCoin","statuses":["primary"]},{"code":"TET","name":"TET","statuses":["primary"]},{"code":"USDT","name":"Tether","statuses":["primary","secondary"]},{"code":"THC","name":"THC","statuses":["primary"]},{"code":"THS","name":"THS","statuses":["primary"]},{"code":"TIX","name":"Tickets","statuses":["primary"]},{"code":"XTC","name":"TileCoin","statuses":["primary"]},{"code":"TIT","name":"Titcoin","statuses":["primary"]},{"code":"TTC","name":"TittieCoin","statuses":["primary"]},{"code":"TMC","name":"TMC","statuses":["primary"]},{"code":"TODAY","name":"TODAY","statuses":["primary"]},{"code":"TOKEN","name":"TOKEN","statuses":["primary"]},{"code":"TP1","name":"TP1","statuses":["primary"]},{"code":"TPC","name":"TPC","statuses":["primary"]},{"code":"TPG","name":"TPG","statuses":["primary"]},{"code":"TX","name":"Transfercoin","statuses":["primary"]},{"code":"TRAP","name":"TRAP","statuses":["primary"]},{"code":"TRICK","name":"TRICK","statuses":["primary"]},{"code":"TROLL","name":"TROLL","statuses":["primary"]},{"code":"TRK","name":"Truckcoin","statuses":["primary"]},{"code":"TRUMP","name":"TrumpCoin","statuses":["primary"]},{"code":"TRUST","name":"TRUST","statuses":["primary"]},{"code":"UAE","name":"UAE","statuses":["primary"]},{"code":"UFO","name":"UFO Coin","statuses":["primary"]},{"code":"UIS","name":"UIS","statuses":["primary"]},{"code":"UTC","name":"UltraCoin","statuses":["primary"]},{"code":"UNC","name":"UNC","statuses":["primary"]},{"code":"UNIQ","name":"UNIQ","statuses":["primary"]},{"code":"UNIT","name":"Universal Currency","statuses":["primary"]},{"code":"UNO","name":"Unobtanium","statuses":["primary"]},{"code":"URO","name":"Uro","statuses":["primary"]},{"code":"USD","name":"US Dollar","statuses":["primary","secondary"]},{"code":"USDE","name":"USDE","statuses":["primary"]},{"code":"UTH","name":"UTH","statuses":["primary"]},{"code":"VAL","name":"VAL","statuses":["primary"]},{"code":"XVC","name":"Vcash","statuses":["primary"]},{"code":"VCN","name":"VCN","statuses":["primary"]},{"code":"VEG","name":"VEG","statuses":["primary"]},{"code":"VENE","name":"VENE","statuses":["primary"]},{"code":"XVG","name":"Verge","statuses":["primary"]},{"code":"VRC","name":"VeriCoin","statuses":["primary"]},{"code":"VTC","name":"Vertcoin","statuses":["primary"]},{"code":"VIA","name":"Viacoin","statuses":["primary"]},{"code":"VIOR","name":"Viorcoin","statuses":["primary"]},{"code":"VIP","name":"VIP Tokens","statuses":["primary"]},{"code":"VIRAL","name":"Viral","statuses":["primary"]},{"code":"VOOT","name":"VootCoin","statuses":["primary"]},{"code":"VOX","name":"Voxels","statuses":["primary"]},{"code":"VOYA","name":"VOYA","statuses":["primary"]},{"code":"VPN","name":"VPNCoin","statuses":["primary"]},{"code":"VPRC","name":"VPRC","statuses":["primary"]},{"code":"VTA","name":"VTA","statuses":["primary"]},{"code":"VTN","name":"VTN","statuses":["primary"]},{"code":"VTR","name":"VTR","statuses":["primary"]},{"code":"WAC","name":"WAC","statuses":["primary"]},{"code":"WARP","name":"WARP","statuses":["primary"]},{"code":"WAVES","name":"WAVES","statuses":["primary"]},{"code":"WGC","name":"WGC","statuses":["primary"]},{"code":"XWC","name":"Whitecoin","statuses":["primary"]},{"code":"WBB","name":"Wild Beast Block","statuses":["primary"]},{"code":"WLC","name":"WLC","statuses":["primary"]},{"code":"WMC","name":"WMC","statuses":["primary"]},{"code":"LOG","name":"Woodcoin","statuses":["primary"]},{"code":"WOP","name":"WOP","statuses":["primary"]},{"code":"WDC","name":"Worldcoin","statuses":["primary"]},{"code":"XAB","name":"XAB","statuses":["primary"]},{"code":"XAI","name":"XAI","statuses":["primary"]},{"code":"XAU","name":"Xaurum","statuses":["primary"]},{"code":"XBS","name":"XBS","statuses":["primary"]},{"code":"XBU","name":"XBU","statuses":["primary"]},{"code":"XCO","name":"XCO","statuses":["primary"]},{"code":"XC","name":"XCurrency","statuses":["primary"]},{"code":"XDB","name":"XDB","statuses":["primary"]},{"code":"XEMP","name":"XEMP","statuses":["primary"]},{"code":"XFC","name":"XFC","statuses":["primary"]},{"code":"MI","name":"Xiaomicoin","statuses":["primary"]},{"code":"XID","name":"XID","statuses":["primary"]},{"code":"XJO","name":"XJO","statuses":["primary"]},{"code":"XLTCG","name":"XLTCG","statuses":["primary"]},{"code":"XMS","name":"XMS","statuses":["primary"]},{"code":"XNX","name":"XNX","statuses":["primary"]},{"code":"XPD","name":"XPD","statuses":["primary"]},{"code":"XPOKE","name":"XPOKE","statuses":["primary"]},{"code":"XPRO","name":"XPRO","statuses":["primary"]},{"code":"XQN","name":"XQN","statuses":["primary"]},{"code":"XSEED","name":"XSEED","statuses":["primary"]},{"code":"XSP","name":"XSP","statuses":["primary"]},{"code":"XT","name":"XT","statuses":["primary"]},{"code":"XTP","name":"XTP","statuses":["primary"]},{"code":"XUSD","name":"XUSD","statuses":["primary"]},{"code":"YACC","name":"YACC","statuses":["primary"]},{"code":"YAC","name":"Yacoin","statuses":["primary"]},{"code":"YAY","name":"YAY","statuses":["primary"]},{"code":"YBC","name":"Ybcoin","statuses":["primary"]},{"code":"YOC","name":"YOC","statuses":["primary"]},{"code":"YOVI","name":"YOVI","statuses":["primary"]},{"code":"YUM","name":"YUM","statuses":["primary"]},{"code":"ZCC","name":"ZCC","statuses":["primary"]},{"code":"ZEIT","name":"Zeitcoin","statuses":["primary"]},{"code":"ZET","name":"Zetacoin","statuses":["primary"]},{"code":"ZRC","name":"ZiftrCOIN","statuses":["primary"]},{"code":"ZMC","name":"ZMC","statuses":["primary"]},{"code":"ZNY","name":"ZNY","statuses":["primary"]},{"code":"ZS","name":"ZS","statuses":["primary"]}]} \ No newline at end of file diff --git a/app/manifest.json b/app/manifest.json index cef44446e..31e4598c7 100644 --- a/app/manifest.json +++ b/app/manifest.json @@ -1,7 +1,7 @@ { "name": "MetaMask", "short_name": "Metamask", - "version": "3.6.3", + "version": "3.6.5", "manifest_version": 2, "author": "https://metamask.io", "description": "Ethereum Browser Extension", diff --git a/app/scripts/background.js b/app/scripts/background.js index 58f8e7556..63c8a7252 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -1,6 +1,5 @@ const urlUtil = require('url') const endOfStream = require('end-of-stream') -const asyncQ = require('async-q') const pipe = require('pump') const LocalStorageStore = require('obs-store/lib/localStorage') const storeTransform = require('obs-store/lib/transform') @@ -30,34 +29,29 @@ let popupIsOpen = false const diskStore = new LocalStorageStore({ storageKey: STORAGE_KEY }) // initialization flow -asyncQ.waterfall([ - () => loadStateFromPersistence(), - (initState) => setupController(initState), -]) -.then(() => console.log('MetaMask initialization complete.')) -.catch((err) => { console.error(err) }) +initialize().catch(console.error) + +async function initialize() { + const initState = await loadStateFromPersistence() + await setupController(initState) + console.log('MetaMask initialization complete.') +} // // State and Persistence // -function loadStateFromPersistence () { +async function loadStateFromPersistence () { // migrations const migrator = new Migrator({ migrations }) - const initialState = migrator.generateInitialState(firstTimeState) - return asyncQ.waterfall([ - // read from disk - () => Promise.resolve(diskStore.getState() || initialState), - // migrate data - (versionedData) => migrator.migrateData(versionedData), - // write to disk - (versionedData) => { - diskStore.putState(versionedData) - return Promise.resolve(versionedData) - }, - // resolve to just data - (versionedData) => Promise.resolve(versionedData.data), - ]) + // read from disk + let versionedData = diskStore.getState() || migrator.generateInitialState(firstTimeState) + // migrate data + versionedData = await migrator.migrateData(versionedData) + // write to disk + diskStore.putState(versionedData) + // return just the data + return versionedData.data } function setupController (initState) { @@ -120,13 +114,13 @@ function setupController (initState) { // updateBadge() - controller.txManager.on('updateBadge', updateBadge) + controller.txController.on('updateBadge', updateBadge) controller.messageManager.on('updateBadge', updateBadge) // plugin badge text function updateBadge () { var label = '' - var unapprovedTxCount = controller.txManager.unapprovedTxCount + var unapprovedTxCount = controller.txController.unapprovedTxCount var unapprovedMsgCount = controller.messageManager.unapprovedMsgCount var count = unapprovedTxCount + unapprovedMsgCount if (count) { diff --git a/app/scripts/config.js b/app/scripts/config.js index 391c67230..8e28db80e 100644 --- a/app/scripts/config.js +++ b/app/scripts/config.js @@ -1,17 +1,14 @@ const MAINET_RPC_URL = 'https://mainnet.infura.io/metamask' -const TESTNET_RPC_URL = 'https://ropsten.infura.io/metamask' +const ROPSTEN_RPC_URL = 'https://ropsten.infura.io/metamask' const KOVAN_RPC_URL = 'https://kovan.infura.io/metamask' const RINKEBY_RPC_URL = 'https://rinkeby.infura.io/metamask' -const DEFAULT_RPC_URL = TESTNET_RPC_URL global.METAMASK_DEBUG = 'GULP_METAMASK_DEBUG' module.exports = { network: { - default: DEFAULT_RPC_URL, mainnet: MAINET_RPC_URL, - testnet: TESTNET_RPC_URL, - morden: TESTNET_RPC_URL, + ropsten: ROPSTEN_RPC_URL, kovan: KOVAN_RPC_URL, rinkeby: RINKEBY_RPC_URL, }, diff --git a/app/scripts/transaction-manager.js b/app/scripts/controllers/transactions.js similarity index 98% rename from app/scripts/transaction-manager.js rename to app/scripts/controllers/transactions.js index 1e15128f9..cfeeab6e6 100644 --- a/app/scripts/transaction-manager.js +++ b/app/scripts/controllers/transactions.js @@ -4,8 +4,9 @@ const extend = require('xtend') const Semaphore = require('semaphore') const ObservableStore = require('obs-store') const ethUtil = require('ethereumjs-util') -const TxProviderUtil = require('./lib/tx-utils') -const createId = require('./lib/random-id') +const EthQuery = require('eth-query') +const TxProviderUtil = require('../lib/tx-utils') +const createId = require('../lib/random-id') module.exports = class TransactionManager extends EventEmitter { constructor (opts) { diff --git a/app/scripts/first-time-state.js b/app/scripts/first-time-state.js index 87a7bb7b5..29ec1d8d3 100644 --- a/app/scripts/first-time-state.js +++ b/app/scripts/first-time-state.js @@ -5,7 +5,7 @@ module.exports = { config: { provider: { - type: 'testnet', + type: 'rinkeby', }, }, } diff --git a/app/scripts/lib/config-manager.js b/app/scripts/lib/config-manager.js index 1098cc474..6ca9bd9ea 100644 --- a/app/scripts/lib/config-manager.js +++ b/app/scripts/lib/config-manager.js @@ -1,6 +1,14 @@ const ethUtil = require('ethereumjs-util') const normalize = require('eth-sig-util').normalize +<<<<<<< HEAD +======= +const MAINNET_RPC = MetamaskConfig.network.mainnet +const ROPSTEN_RPC = MetamaskConfig.network.ropsten +const KOVAN_RPC = MetamaskConfig.network.kovan +const RINKEBY_RPC = MetamaskConfig.network.rinkeby + +>>>>>>> master /* The config-manager is a convenience object * wrapping a pojo-migrator. * @@ -101,6 +109,32 @@ ConfigManager.prototype.getSeedWords = function () { return data.seedWords } +ConfigManager.prototype.getCurrentRpcAddress = function () { + var provider = this.getProvider() + if (!provider) return null + switch (provider.type) { + + case 'mainnet': + return MAINNET_RPC + + case 'ropsten': + return ROPSTEN_RPC + + case 'kovan': + return KOVAN_RPC + + case 'rinkeby': + return RINKEBY_RPC + + default: + return provider && provider.rpcTarget ? provider.rpcTarget : RINKEBY_RPC + } +} + +// +// Tx +// + ConfigManager.prototype.getTxList = function () { var data = this.getData() if (data.transactions !== undefined) { diff --git a/app/scripts/lib/migrator/index.js b/app/scripts/lib/migrator/index.js index c40c347b5..de6f5d5cd 100644 --- a/app/scripts/lib/migrator/index.js +++ b/app/scripts/lib/migrator/index.js @@ -1,42 +1,35 @@ -const asyncQ = require('async-q') - class Migrator { constructor (opts = {}) { const migrations = opts.migrations || [] + // sort migrations by version this.migrations = migrations.sort((a, b) => a.version - b.version) + // grab migration with highest version const lastMigration = this.migrations.slice(-1)[0] // use specified defaultVersion or highest migration version this.defaultVersion = opts.defaultVersion || (lastMigration && lastMigration.version) || 0 } // run all pending migrations on meta in place - migrateData (versionedData = this.generateInitialState()) { - const remaining = this.migrations.filter(migrationIsPending) + async migrateData (versionedData = this.generateInitialState()) { + const pendingMigrations = this.migrations.filter(migrationIsPending) - return ( - asyncQ.eachSeries(remaining, (migration) => this.runMigration(versionedData, migration)) - .then(() => versionedData) - ) + for (let index in pendingMigrations) { + let migration = pendingMigrations[index] + versionedData = await migration.migrate(versionedData) + if (!versionedData.data) throw new Error('Migrator - migration returned empty data') + if (versionedData.version !== undefined && versionedData.meta.version !== migration.version) throw new Error('Migrator - Migration did not update version number correctly') + } - // migration is "pending" if hit has a higher + return versionedData + + // migration is "pending" if it has a higher // version number than currentVersion function migrationIsPending (migration) { return migration.version > versionedData.meta.version } } - runMigration (versionedData, migration) { - return ( - migration.migrate(versionedData) - .then((versionedData) => { - if (!versionedData.data) return Promise.reject(new Error('Migrator - Migration returned empty data')) - if (migration.version !== undefined && versionedData.meta.version !== migration.version) return Promise.reject(new Error('Migrator - Migration did not update version number correctly')) - return Promise.resolve(versionedData) - }) - ) - } - generateInitialState (initState) { return { meta: { diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 71293d05f..b93f627bb 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -17,7 +17,7 @@ const ShapeShiftController = require('./controllers/shapeshift') const AddressBookController = require('./controllers/address-book') const MessageManager = require('./lib/message-manager') const PersonalMessageManager = require('./lib/personal-message-manager') -const TxManager = require('./transaction-manager') +const TransactionController = require('./controllers/transactions') const ConfigManager = require('./lib/config-manager') const autoFaucet = require('./lib/auto-faucet') const nodeify = require('./lib/nodeify') @@ -89,8 +89,8 @@ module.exports = class MetamaskController extends EventEmitter { }, this.keyringController) // tx mgmt - this.txManager = new TxManager({ - initState: initState.TransactionManager, + this.txController = new TransactionController({ + initState: initState.TransactionController || initState.TransactionManager, networkStore: this.networkController.networkStore, preferencesStore: this.preferencesController.store, txHistoryLimit: 40, @@ -144,8 +144,8 @@ module.exports = class MetamaskController extends EventEmitter { this.publicConfigStore = this.initPublicConfigStore() // manual disk state subscriptions - this.txManager.store.subscribe((state) => { - this.store.updateState({ TransactionManager: state }) + this.txController.store.subscribe((state) => { + this.store.updateState({ TransactionController: state }) }) this.keyringController.store.subscribe((state) => { this.store.updateState({ KeyringController: state }) @@ -172,7 +172,7 @@ module.exports = class MetamaskController extends EventEmitter { // manual mem state subscriptions this.networkController.subscribe(this.sendUpdate.bind(this)) this.ethStore.subscribe(this.sendUpdate.bind(this)) - this.txManager.memStore.subscribe(this.sendUpdate.bind(this)) + this.txController.memStore.subscribe(this.sendUpdate.bind(this)) this.messageManager.memStore.subscribe(this.sendUpdate.bind(this)) this.personalMessageManager.memStore.subscribe(this.sendUpdate.bind(this)) this.keyringController.memStore.subscribe(this.sendUpdate.bind(this)) @@ -251,7 +251,7 @@ module.exports = class MetamaskController extends EventEmitter { }, this.networkController.getState(), this.ethStore.getState(), - this.txManager.memStore.getState(), + this.txController.memStore.getState(), this.messageManager.memStore.getState(), this.personalMessageManager.memStore.getState(), this.keyringController.memStore.getState(), @@ -276,7 +276,7 @@ module.exports = class MetamaskController extends EventEmitter { getApi () { const keyringController = this.keyringController const preferencesController = this.preferencesController - const txManager = this.txManager + const txController = this.txController const noticeController = this.noticeController const addressBookController = this.addressBookController @@ -317,9 +317,9 @@ module.exports = class MetamaskController extends EventEmitter { saveAccountLabel: nodeify(keyringController.saveAccountLabel).bind(keyringController), exportAccount: nodeify(keyringController.exportAccount).bind(keyringController), - // txManager - approveTransaction: txManager.approveTransaction.bind(txManager), - cancelTransaction: txManager.cancelTransaction.bind(txManager), + // txController + approveTransaction: txController.approveTransaction.bind(txController), + cancelTransaction: txController.cancelTransaction.bind(txController), updateAndApproveTransaction: this.updateAndApproveTx.bind(this), // messageManager @@ -449,12 +449,12 @@ module.exports = class MetamaskController extends EventEmitter { newUnapprovedTransaction (txParams, cb) { log.debug(`MetaMaskController newUnapprovedTransaction ${JSON.stringify(txParams)}`) const self = this - self.txManager.addUnapprovedTransaction(txParams, (err, txMeta) => { + self.txController.addUnapprovedTransaction(txParams, (err, txMeta) => { if (err) return cb(err) self.sendUpdate() self.opts.showUnapprovedTx(txMeta) // listen for tx completion (success, fail) - self.txManager.once(`${txMeta.id}:finished`, (completedTx) => { + self.txController.once(`${txMeta.id}:finished`, (completedTx) => { switch (completedTx.status) { case 'submitted': return cb(null, completedTx.hash) @@ -505,9 +505,9 @@ module.exports = class MetamaskController extends EventEmitter { updateAndApproveTx (txMeta, cb) { log.debug(`MetaMaskController - updateAndApproveTx: ${JSON.stringify(txMeta)}`) - const txManager = this.txManager - txManager.updateTx(txMeta) - txManager.approveTransaction(txMeta.id, cb) + const txController = this.txController + txController.updateTx(txMeta) + txController.approveTransaction(txMeta.id, cb) } signMessage (msgParams, cb) { diff --git a/app/scripts/migrations/013.js b/app/scripts/migrations/013.js new file mode 100644 index 000000000..8f11e510e --- /dev/null +++ b/app/scripts/migrations/013.js @@ -0,0 +1,34 @@ +const version = 13 + +/* + +This migration modifies the network config from ambiguous 'testnet' to explicit 'ropsten' + +*/ + +const clone = require('clone') + +module.exports = { + version, + + migrate: function (originalVersionedData) { + const versionedData = clone(originalVersionedData) + versionedData.meta.version = version + try { + const state = versionedData.data + const newState = transformState(state) + versionedData.data = newState + } catch (err) { + console.warn(`MetaMask Migration #${version}` + err.stack) + } + return Promise.resolve(versionedData) + }, +} + +function transformState (state) { + const newState = state + if (newState.config.provider.type === 'testnet') { + newState.config.provider.type = 'ropsten' + } + return newState +} diff --git a/app/scripts/migrations/index.js b/app/scripts/migrations/index.js index 019b4d13d..3a95cf88e 100644 --- a/app/scripts/migrations/index.js +++ b/app/scripts/migrations/index.js @@ -23,4 +23,5 @@ module.exports = [ require('./010'), require('./011'), require('./012'), + require('./013'), ] diff --git a/circle.yml b/circle.yml index c9ea787ff..4305ca3b4 100644 --- a/circle.yml +++ b/circle.yml @@ -1,6 +1,6 @@ machine: node: - version: 6.0.0 + version: 7.6.0 dependencies: pre: - "npm i -g testem" diff --git a/mascara/README.md b/mascara/README.md index db5b4f404..6e3bfe96b 100644 --- a/mascara/README.md +++ b/mascara/README.md @@ -3,7 +3,7 @@ start the dual servers (dapp + mascara) npm run mascara ``` -## First time use: +### First time use: - navigate to: http://localhost:9001 - Create an Account @@ -11,7 +11,7 @@ npm run mascara - open devTools - click Sync Tx -## Tests: +### Tests: ``` npm run testMascara @@ -22,3 +22,12 @@ Test will run in browser, you will have to have these browsers installed: - Chrome - Firefox - Opera + + +### Deploy: + +Will build and deploy mascara via docker + +``` +docker-compose build && docker-compose stop && docker-compose up -d && docker-compose logs --tail 200 -f +``` \ No newline at end of file diff --git a/mascara/ui/index.html b/mascara/ui/index.html index c5eeb05ef..eac8e4898 100644 --- a/mascara/ui/index.html +++ b/mascara/ui/index.html @@ -2,7 +2,8 @@ - MetaMask Plugin + MetaMascara Alpha +
diff --git a/package.json b/package.json index e2268d20a..14ddd2886 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,8 @@ "babelify", { "presets": [ - "es2015" + "es2015", + "stage-0" ] } ], @@ -44,7 +45,7 @@ }, "dependencies": { "async": "^1.5.2", - "async-q": "^0.3.1", + "babel-runtime": "^6.23.0", "bip39": "^2.2.0", "bluebird": "^3.5.0", "browser-passworder": "^2.0.3", @@ -55,6 +56,7 @@ "debounce": "^1.0.0", "deep-extend": "^0.4.1", "denodeify": "^1.2.1", + "detect-node": "^2.0.3", "disc": "^1.3.2", "dnode": "^1.2.2", "end-of-stream": "^1.1.0", @@ -119,12 +121,14 @@ "valid-url": "^1.0.9", "vreme": "^3.0.2", "web3": "0.18.2", - "web3-provider-engine": "^12.0.3", + "web3-provider-engine": "^12.0.6", "web3-stream-provider": "^2.0.6", "xtend": "^4.0.1" }, "devDependencies": { "babel-eslint": "^6.0.5", + "babel-plugin-transform-runtime": "^6.23.0", + "babel-preset-stage-0": "^6.24.1", "babel-register": "^6.7.2", "babelify": "^7.2.0", "beefy": "^2.1.5", @@ -135,6 +139,7 @@ "deep-freeze-strict": "^1.1.1", "del": "^2.2.0", "envify": "^4.0.0", + "enzyme": "^2.8.2", "eslint-plugin-chai": "0.0.1", "eslint-plugin-mocha": "^4.9.0", "fs-promise": "^1.0.0", @@ -161,6 +166,10 @@ "prompt": "^1.0.0", "qs": "^6.2.0", "qunit": "^0.9.1", + "react-addons-test-utils": "^15.5.1", + "react-dom": "^15.5.4", + "react-test-renderer": "^15.5.4", + "react-testutils-additions": "^15.2.0", "sinon": "^1.17.3", "tape": "^4.5.1", "testem": "^1.10.3", diff --git a/test/lib/migrations/001.json b/test/lib/migrations/001.json index 2fe6dd836..7bd55a50e 100644 --- a/test/lib/migrations/001.json +++ b/test/lib/migrations/001.json @@ -1 +1,14 @@ -{"version":0,"data":{"wallet":"{\"encSeed\":{\"encStr\":\"rT1C1jjkFRfmrwefscFcwZohl4f+HfIFlBZ9AM4ZD8atJmfKDIQCVK11NYDKYv8ZMIY03f3t8MuoZvfzBL8IJsWnZUhpzVTNNiARQJD2WpGA19eNBzgZm4vd0GwkIUruUDeJXu0iv2j9wU8hOQUqPbOePPy2Am5ro97iuvMAroRTnEKD60qFVg==\",\"nonce\":\"YUY2mwNq2v3FV0Fi94QnSiKFOLYfDR95\"},\"ksData\":{\"m/44'/60'/0'/0\":{\"info\":{\"curve\":\"secp256k1\",\"purpose\":\"sign\"},\"encHdPathPriv\":{\"encStr\":\"Iyi7ft4JQ9UtwrSXRT6ZIHPtZqJhe99rh0uWhNc6QLan6GanY2ZQeU0tt76CBealEWJyrJReSxGQdqDmSDYjpjH3m4JO5l0DfPLPseCqzXV/W+dzM0ubJ8lztLwpwi0L+vULNMqCx4dQtoNbNBq1QZUnjtpm6O8mWpScspboww==\",\"nonce\":\"Z7RqtjNjC6FrLUj5wVW1+HkjOW6Hib6K\"},\"hdIndex\":3,\"encPrivKeys\":{\"edb81c10122f34040cc4bef719a272fbbb1cf897\":{\"key\":\"8ab81tKBd4+CLAbzvS7SBFRTd6VWXBs86uBE43lgcmBu2U7UB22xdH64Q2hUf9eB\",\"nonce\":\"aGUEqI033FY39zKjWmZSI6PQrCLvkiRP\"},\"8bd7d5c000cf05284e98356370dc5ccaa3dbfc38\":{\"key\":\"+i3wmf4b+B898QtlOBfL0Ixirjg59/LLPX61vQ2L0xRPjXzNog0O4Wn15RemM5mY\",\"nonce\":\"imKrlkuoC5uuFkzJBbuDBluGCPJXNTKm\"},\"2340695474656e3124b8eba1172fbfb00eeac8f8\":{\"key\":\"pi+H9D8LYKsdCQKrfaJtsGFjE+X9s74xN675tsoIKrbPXhtpxMLOIQVtSqYveF62\",\"nonce\":\"49g80wDTovHwbguVVYf2FsYbp7Db5OAR\"}},\"addresses\":[\"edb81c10122f34040cc4bef719a272fbbb1cf897\",\"8bd7d5c000cf05284e98356370dc5ccaa3dbfc38\",\"2340695474656e3124b8eba1172fbfb00eeac8f8\"]}},\"version\":2}","config":{"provider":{"type":"etherscan"}}},"meta":{"version":0}} \ No newline at end of file +{ + "version": 0, + "data": { + "wallet": "{\"encSeed\":{\"encStr\":\"rT1C1jjkFRfmrwefscFcwZohl4f+HfIFlBZ9AM4ZD8atJmfKDIQCVK11NYDKYv8ZMIY03f3t8MuoZvfzBL8IJsWnZUhpzVTNNiARQJD2WpGA19eNBzgZm4vd0GwkIUruUDeJXu0iv2j9wU8hOQUqPbOePPy2Am5ro97iuvMAroRTnEKD60qFVg==\",\"nonce\":\"YUY2mwNq2v3FV0Fi94QnSiKFOLYfDR95\"},\"ksData\":{\"m/44'/60'/0'/0\":{\"info\":{\"curve\":\"secp256k1\",\"purpose\":\"sign\"},\"encHdPathPriv\":{\"encStr\":\"Iyi7ft4JQ9UtwrSXRT6ZIHPtZqJhe99rh0uWhNc6QLan6GanY2ZQeU0tt76CBealEWJyrJReSxGQdqDmSDYjpjH3m4JO5l0DfPLPseCqzXV/W+dzM0ubJ8lztLwpwi0L+vULNMqCx4dQtoNbNBq1QZUnjtpm6O8mWpScspboww==\",\"nonce\":\"Z7RqtjNjC6FrLUj5wVW1+HkjOW6Hib6K\"},\"hdIndex\":3,\"encPrivKeys\":{\"edb81c10122f34040cc4bef719a272fbbb1cf897\":{\"key\":\"8ab81tKBd4+CLAbzvS7SBFRTd6VWXBs86uBE43lgcmBu2U7UB22xdH64Q2hUf9eB\",\"nonce\":\"aGUEqI033FY39zKjWmZSI6PQrCLvkiRP\"},\"8bd7d5c000cf05284e98356370dc5ccaa3dbfc38\":{\"key\":\"+i3wmf4b+B898QtlOBfL0Ixirjg59/LLPX61vQ2L0xRPjXzNog0O4Wn15RemM5mY\",\"nonce\":\"imKrlkuoC5uuFkzJBbuDBluGCPJXNTKm\"},\"2340695474656e3124b8eba1172fbfb00eeac8f8\":{\"key\":\"pi+H9D8LYKsdCQKrfaJtsGFjE+X9s74xN675tsoIKrbPXhtpxMLOIQVtSqYveF62\",\"nonce\":\"49g80wDTovHwbguVVYf2FsYbp7Db5OAR\"}},\"addresses\":[\"edb81c10122f34040cc4bef719a272fbbb1cf897\",\"8bd7d5c000cf05284e98356370dc5ccaa3dbfc38\",\"2340695474656e3124b8eba1172fbfb00eeac8f8\"]}},\"version\":2}", + "config": { + "provider": { + "type": "etherscan" + } + } + }, + "meta": { + "version": 0 + } +} \ No newline at end of file diff --git a/test/lib/mock-store.js b/test/lib/mock-store.js new file mode 100644 index 000000000..4714c3485 --- /dev/null +++ b/test/lib/mock-store.js @@ -0,0 +1,18 @@ +const createStore = require('redux').createStore +const applyMiddleware = require('redux').applyMiddleware +const thunkMiddleware = require('redux-thunk') +const createLogger = require('redux-logger') +const rootReducer = function() {} + +module.exports = configureStore + +const loggerMiddleware = createLogger() + +const createStoreWithMiddleware = applyMiddleware( + thunkMiddleware, + loggerMiddleware +)(createStore) + +function configureStore (initialState) { + return createStoreWithMiddleware(rootReducer, initialState) +} diff --git a/test/unit/components/pending-tx-test.js b/test/unit/components/pending-tx-test.js new file mode 100644 index 000000000..9ff948604 --- /dev/null +++ b/test/unit/components/pending-tx-test.js @@ -0,0 +1,81 @@ +const assert = require('assert') +const additions = require('react-testutils-additions') +const h = require('react-hyperscript') +const PendingTx = require('../../../ui/app/components/pending-tx') +const ReactTestUtils = require('react-addons-test-utils') +const ethUtil = require('ethereumjs-util') + +describe('PendingTx', function () { + + const identities = { + '0xfdea65c8e26263f6d9a1b5de9555d2931a33b826': { + name: 'Main Account 1', + balance: '0x00000000000000056bc75e2d63100000', + }, + } + + const gasPrice = '0x4A817C800' // 20 Gwei + const txData = { + 'id':5021615666270214, + 'time':1494458763011, + 'status':'unapproved', + 'metamaskNetworkId':'1494442339676', + 'txParams':{ + 'from':'0xfdea65c8e26263f6d9a1b5de9555d2931a33b826', + 'to':'0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb', + 'value':'0xde0b6b3a7640000', + gasPrice, + 'gas':'0x7b0c'}, + 'gasLimitSpecified':false, + 'estimatedGas':'0x5208', + } + + + it('should use updated values when edited.', function (done) { + + const renderer = ReactTestUtils.createRenderer() + const newGasPrice = '0x77359400' + + const props = { + identities, + accounts: identities, + txData, + sendTransaction: (txMeta, event) => { + + // Assert changes: + const result = ethUtil.addHexPrefix(txMeta.txParams.gasPrice) + assert.notEqual(result, gasPrice, 'gas price should change') + assert.equal(result, newGasPrice, 'gas price assigned.') + done() + }, + } + + const pendingTxComponent = h(PendingTx, props) + const component = additions.renderIntoDocument(pendingTxComponent) + renderer.render(pendingTxComponent) + const result = renderer.getRenderOutput() + assert.equal(result.type, 'div', 'should create a div') + + try { + const input = additions.find(component, '.cell.row input[type="number"]')[1] + ReactTestUtils.Simulate.change(input, { + target: { + value: 2, + checkValidity() { return true }, + }, + }) + + const form = additions.find(component, 'form')[0] + form.checkValidity = () => true + form.getFormEl = () => { return { checkValidity() { return true } } } + ReactTestUtils.Simulate.submit(form, { preventDefault() {}, target: { checkValidity() { + return true + } } }) + + } catch (e) { + console.log('WHAAAA') + console.error(e) + } + }) +}) + diff --git a/test/unit/migrations-test.js b/test/unit/migrations-test.js index 324e4d056..5bad25a45 100644 --- a/test/unit/migrations-test.js +++ b/test/unit/migrations-test.js @@ -16,6 +16,7 @@ const migration9 = require(path.join('..', '..', 'app', 'scripts', 'migrations', const migration10 = require(path.join('..', '..', 'app', 'scripts', 'migrations', '010')) const migration11 = require(path.join('..', '..', 'app', 'scripts', 'migrations', '011')) const migration12 = require(path.join('..', '..', 'app', 'scripts', 'migrations', '012')) +const migration13 = require(path.join('..', '..', 'app', 'scripts', 'migrations', '013')) const oldTestRpc = 'https://rawtestrpc.metamask.io/' @@ -97,6 +98,11 @@ describe('wallet1 is migrated successfully', () => { }).then((twelfthResult) => { assert.equal(twelfthResult.data.NoticeController.noticesList[0].body, '', 'notices that have been read should have an empty body.') assert.equal(twelfthResult.data.NoticeController.noticesList[1].body, 'nonempty', 'notices that have not been read should not have an empty body.') + + assert.equal(twelfthResult.data.config.provider.type, 'testnet', 'network is originally testnet.') + return migration13.migrate(twelfthResult) + }).then((thirteenthResult) => { + assert.equal(thirteenthResult.data.config.provider.type, 'ropsten', 'network has been changed to ropsten.') }) }) }) diff --git a/test/unit/migrator-test.js b/test/unit/migrator-test.js new file mode 100644 index 000000000..ece95b9f6 --- /dev/null +++ b/test/unit/migrator-test.js @@ -0,0 +1,41 @@ +const assert = require('assert') +const clone = require('clone') +const Migrator = require('../../app/scripts/lib/migrator/') +const migrations = [ + { + version: 1, + migrate: (data) => { + // clone the data just like we do in migrations + const clonedData = clone(data) + clonedData.meta.version = 1 + return Promise.resolve(clonedData) + }, + }, + { + version: 2, + migrate: (data) => { + const clonedData = clone(data) + clonedData.meta.version = 2 + return Promise.resolve(clonedData) + }, + }, + { + version: 3, + migrate: (data) => { + const clonedData = clone(data) + clonedData.meta.version = 3 + return Promise.resolve(clonedData) + }, + }, +] +const versionedData = {meta: {version: 0}, data:{hello:'world'}} +describe('Migrator', () => { + const migrator = new Migrator({ migrations }) + it('migratedData version should be version 3', (done) => { + migrator.migrateData(versionedData) + .then((migratedData) => { + assert.equal(migratedData.meta.version, migrations[2].version) + done() + }).catch(done) + }) +}) diff --git a/test/unit/tx-manager-test.js b/test/unit/tx-controller-test.js similarity index 54% rename from test/unit/tx-manager-test.js rename to test/unit/tx-controller-test.js index b5d148723..d4e8d79f0 100644 --- a/test/unit/tx-manager-test.js +++ b/test/unit/tx-controller-test.js @@ -3,17 +3,19 @@ const EventEmitter = require('events') const ethUtil = require('ethereumjs-util') const EthTx = require('ethereumjs-tx') const ObservableStore = require('obs-store') -const TransactionManager = require('../../app/scripts/transaction-manager') +const clone = require('clone') +const sinon = require('sinon') +const TransactionController = require('../../app/scripts/controllers/transactions') const noop = () => true const currentNetworkId = 42 const otherNetworkId = 36 const privKey = new Buffer('8718b9618a37d1fc78c436511fc6df3c8258d3250635bba617f33003270ec03e', 'hex') -describe('Transaction Manager', function () { - let txManager +describe('Transaction Controller', function () { + let txController beforeEach(function () { - txManager = new TransactionManager({ + txController = new TransactionController({ networkStore: new ObservableStore({ network: currentNetworkId }), txHistoryLimit: 10, blockTracker: new EventEmitter(), @@ -29,7 +31,7 @@ describe('Transaction Manager', function () { var sample = { value: '0x01', } - txManager.txProviderUtils.validateTxParams(sample, (err) => { + txController.txProviderUtils.validateTxParams(sample, (err) => { assert.equal(err, null, 'no error') }) }) @@ -38,7 +40,7 @@ describe('Transaction Manager', function () { var sample = { value: '-0x01', } - txManager.txProviderUtils.validateTxParams(sample, (err) => { + txController.txProviderUtils.validateTxParams(sample, (err) => { assert.ok(err, 'error') }) }) @@ -46,7 +48,7 @@ describe('Transaction Manager', function () { describe('#getTxList', function () { it('when new should return empty array', function () { - var result = txManager.getTxList() + var result = txController.getTxList() assert.ok(Array.isArray(result)) assert.equal(result.length, 0) }) @@ -58,8 +60,8 @@ describe('Transaction Manager', function () { describe('#addTx', function () { it('adds a tx returned in getTxList', function () { var tx = { id: 1, status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams: {} } - txManager.addTx(tx, noop) - var result = txManager.getTxList() + txController.addTx(tx, noop) + var result = txController.getTxList() assert.ok(Array.isArray(result)) assert.equal(result.length, 1) assert.equal(result[0].id, 1) @@ -68,45 +70,45 @@ describe('Transaction Manager', function () { it('does not override txs from other networks', function () { var tx = { id: 1, status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams: {} } var tx2 = { id: 2, status: 'confirmed', metamaskNetworkId: otherNetworkId, txParams: {} } - txManager.addTx(tx, noop) - txManager.addTx(tx2, noop) - var result = txManager.getFullTxList() - var result2 = txManager.getTxList() + txController.addTx(tx, noop) + txController.addTx(tx2, noop) + var result = txController.getFullTxList() + var result2 = txController.getTxList() assert.equal(result.length, 2, 'txs were deleted') assert.equal(result2.length, 1, 'incorrect number of txs on network.') }) it('cuts off early txs beyond a limit', function () { - const limit = txManager.txHistoryLimit + const limit = txController.txHistoryLimit for (let i = 0; i < limit + 1; i++) { const tx = { id: i, time: new Date(), status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams: {} } - txManager.addTx(tx, noop) + txController.addTx(tx, noop) } - var result = txManager.getTxList() + var result = txController.getTxList() assert.equal(result.length, limit, `limit of ${limit} txs enforced`) assert.equal(result[0].id, 1, 'early txs truncted') }) it('cuts off early txs beyond a limit whether or not it is confirmed or rejected', function () { - const limit = txManager.txHistoryLimit + const limit = txController.txHistoryLimit for (let i = 0; i < limit + 1; i++) { const tx = { id: i, time: new Date(), status: 'rejected', metamaskNetworkId: currentNetworkId, txParams: {} } - txManager.addTx(tx, noop) + txController.addTx(tx, noop) } - var result = txManager.getTxList() + var result = txController.getTxList() assert.equal(result.length, limit, `limit of ${limit} txs enforced`) assert.equal(result[0].id, 1, 'early txs truncted') }) it('cuts off early txs beyond a limit but does not cut unapproved txs', function () { var unconfirmedTx = { id: 0, time: new Date(), status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} } - txManager.addTx(unconfirmedTx, noop) - const limit = txManager.txHistoryLimit + txController.addTx(unconfirmedTx, noop) + const limit = txController.txHistoryLimit for (let i = 1; i < limit + 1; i++) { const tx = { id: i, time: new Date(), status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams: {} } - txManager.addTx(tx, noop) + txController.addTx(tx, noop) } - var result = txManager.getTxList() + var result = txController.getTxList() assert.equal(result.length, limit, `limit of ${limit} txs enforced`) assert.equal(result[0].id, 0, 'first tx should still be there') assert.equal(result[0].status, 'unapproved', 'first tx should be unapproved') @@ -117,9 +119,9 @@ describe('Transaction Manager', function () { describe('#setTxStatusSigned', function () { it('sets the tx status to signed', function () { var tx = { id: 1, status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} } - txManager.addTx(tx, noop) - txManager.setTxStatusSigned(1) - var result = txManager.getTxList() + txController.addTx(tx, noop) + txController.setTxStatusSigned(1) + var result = txController.getTxList() assert.ok(Array.isArray(result)) assert.equal(result.length, 1) assert.equal(result[0].status, 'signed') @@ -132,18 +134,18 @@ describe('Transaction Manager', function () { assert(true, 'event listener has been triggered and noop executed') done() } - txManager.addTx(tx) - txManager.on('1:signed', noop) - txManager.setTxStatusSigned(1) + txController.addTx(tx) + txController.on('1:signed', noop) + txController.setTxStatusSigned(1) }) }) describe('#setTxStatusRejected', function () { it('sets the tx status to rejected', function () { var tx = { id: 1, status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} } - txManager.addTx(tx) - txManager.setTxStatusRejected(1) - var result = txManager.getTxList() + txController.addTx(tx) + txController.setTxStatusRejected(1) + var result = txController.getTxList() assert.ok(Array.isArray(result)) assert.equal(result.length, 1) assert.equal(result[0].status, 'rejected') @@ -152,31 +154,53 @@ describe('Transaction Manager', function () { it('should emit a rejected event to signal the exciton of callback', (done) => { this.timeout(10000) var tx = { id: 1, status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} } - txManager.addTx(tx) + txController.addTx(tx) const noop = function (err, txId) { assert(true, 'event listener has been triggered and noop executed') done() } - txManager.on('1:rejected', noop) - txManager.setTxStatusRejected(1) + txController.on('1:rejected', noop) + txController.setTxStatusRejected(1) }) }) describe('#updateTx', function () { it('replaces the tx with the same id', function () { - txManager.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} }, noop) - txManager.addTx({ id: '2', status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams: {} }, noop) - txManager.updateTx({ id: '1', status: 'blah', hash: 'foo', metamaskNetworkId: currentNetworkId, txParams: {} }) - var result = txManager.getTx('1') + txController.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} }, noop) + txController.addTx({ id: '2', status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams: {} }, noop) + txController.updateTx({ id: '1', status: 'blah', hash: 'foo', metamaskNetworkId: currentNetworkId, txParams: {} }) + var result = txController.getTx('1') assert.equal(result.hash, 'foo') }) + + it('updates gas price', function () { + const originalGasPrice = '0x01' + const desiredGasPrice = '0x02' + + const txMeta = { + id: '1', + status: 'unapproved', + metamaskNetworkId: currentNetworkId, + txParams: { + gasPrice: originalGasPrice, + }, + } + + const updatedMeta = clone(txMeta) + + txController.addTx(txMeta) + updatedMeta.txParams.gasPrice = desiredGasPrice + txController.updateTx(updatedMeta) + var result = txController.getTx('1') + assert.equal(result.txParams.gasPrice, desiredGasPrice, 'gas price updated') + }) }) describe('#getUnapprovedTxList', function () { it('returns unapproved txs in a hash', function () { - txManager.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} }, noop) - txManager.addTx({ id: '2', status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams: {} }, noop) - const result = txManager.getUnapprovedTxList() + txController.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} }, noop) + txController.addTx({ id: '2', status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams: {} }, noop) + const result = txController.getUnapprovedTxList() assert.equal(typeof result, 'object') assert.equal(result['1'].status, 'unapproved') assert.equal(result['2'], undefined) @@ -185,10 +209,10 @@ describe('Transaction Manager', function () { describe('#getTx', function () { it('returns a tx with the requested id', function () { - txManager.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} }, noop) - txManager.addTx({ id: '2', status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams: {} }, noop) - assert.equal(txManager.getTx('1').status, 'unapproved') - assert.equal(txManager.getTx('2').status, 'confirmed') + txController.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} }, noop) + txController.addTx({ id: '2', status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams: {} }, noop) + assert.equal(txController.getTx('1').status, 'unapproved') + assert.equal(txController.getTx('2').status, 'confirmed') }) }) @@ -206,32 +230,93 @@ describe('Transaction Manager', function () { { id: 8, status: 'confirmed', txParams: { from: '0xbb', to: '0xaa' }, metamaskNetworkId: currentNetworkId }, { id: 9, status: 'confirmed', txParams: { from: '0xbb', to: '0xaa' }, metamaskNetworkId: currentNetworkId }, ] - txMetas.forEach((txMeta) => txManager.addTx(txMeta, noop)) + txMetas.forEach((txMeta) => txController.addTx(txMeta, noop)) let filterParams filterParams = { status: 'unapproved', from: '0xaa' } - assert.equal(txManager.getFilteredTxList(filterParams).length, 3, `getFilteredTxList - ${JSON.stringify(filterParams)}`) + assert.equal(txController.getFilteredTxList(filterParams).length, 3, `getFilteredTxList - ${JSON.stringify(filterParams)}`) filterParams = { status: 'unapproved', to: '0xaa' } - assert.equal(txManager.getFilteredTxList(filterParams).length, 2, `getFilteredTxList - ${JSON.stringify(filterParams)}`) + assert.equal(txController.getFilteredTxList(filterParams).length, 2, `getFilteredTxList - ${JSON.stringify(filterParams)}`) filterParams = { status: 'confirmed', from: '0xbb' } - assert.equal(txManager.getFilteredTxList(filterParams).length, 3, `getFilteredTxList - ${JSON.stringify(filterParams)}`) + assert.equal(txController.getFilteredTxList(filterParams).length, 3, `getFilteredTxList - ${JSON.stringify(filterParams)}`) filterParams = { status: 'confirmed' } - assert.equal(txManager.getFilteredTxList(filterParams).length, 5, `getFilteredTxList - ${JSON.stringify(filterParams)}`) + assert.equal(txController.getFilteredTxList(filterParams).length, 5, `getFilteredTxList - ${JSON.stringify(filterParams)}`) filterParams = { from: '0xaa' } - assert.equal(txManager.getFilteredTxList(filterParams).length, 5, `getFilteredTxList - ${JSON.stringify(filterParams)}`) + assert.equal(txController.getFilteredTxList(filterParams).length, 5, `getFilteredTxList - ${JSON.stringify(filterParams)}`) filterParams = { to: '0xaa' } - assert.equal(txManager.getFilteredTxList(filterParams).length, 5, `getFilteredTxList - ${JSON.stringify(filterParams)}`) + assert.equal(txController.getFilteredTxList(filterParams).length, 5, `getFilteredTxList - ${JSON.stringify(filterParams)}`) + }) + }) + + describe('#approveTransaction', function () { + let txMeta, originalValue + + beforeEach(function () { + originalValue = '0x01' + txMeta = { + id: '1', + status: 'unapproved', + metamaskNetworkId: currentNetworkId, + txParams: { + nonce: originalValue, + gas: originalValue, + gasPrice: originalValue, + }, + } + }) + + + it('does not overwrite set values', function (done) { + const wrongValue = '0x05' + + txController.addTx(txMeta) + + const estimateStub = sinon.stub(txController.txProviderUtils.query, 'estimateGas') + .callsArgWith(1, null, wrongValue) + + const priceStub = sinon.stub(txController.txProviderUtils.query, 'gasPrice') + .callsArgWith(0, null, wrongValue) + + const nonceStub = sinon.stub(txController.txProviderUtils.query, 'getTransactionCount') + .callsArgWith(2, null, wrongValue) + + const signStub = sinon.stub(txController, 'signTransaction') + .callsArgWith(1, null, noop) + + const pubStub = sinon.stub(txController.txProviderUtils, 'publishTransaction') + .callsArgWith(1, null, originalValue) + + txController.approveTransaction(txMeta.id, (err) => { + assert.ifError(err, 'should not error') + + const result = txController.getTx(txMeta.id) + const params = result.txParams + + assert.equal(params.gas, originalValue, 'gas unmodified') + assert.equal(params.gasPrice, originalValue, 'gas price unmodified') + assert.equal(params.nonce, originalValue, 'nonce unmodified') + assert.equal(result.hash, originalValue, 'hash was set') + + estimateStub.restore() + priceStub.restore() + signStub.restore() + nonceStub.restore() + pubStub.restore() + + done() + }) }) }) describe('#sign replay-protected tx', function () { it('prepares a tx with the chainId set', function () { - txManager.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} }, noop) - txManager.signTransaction('1', (err, rawTx) => { + txController.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} }, noop) + txController.signTransaction('1', (err, rawTx) => { if (err) return assert.fail('it should not fail') const ethTx = new EthTx(ethUtil.toBuffer(rawTx)) assert.equal(ethTx.getChainId(), currentNetworkId) }) }) }) + }) diff --git a/ui/app/account-detail.js b/ui/app/account-detail.js index d592a5ad6..7a78a360c 100644 --- a/ui/app/account-detail.js +++ b/ui/app/account-detail.js @@ -29,6 +29,8 @@ function mapStateToProps (state) { unapprovedMsgs: valuesFor(state.metamask.unapprovedMsgs), shapeShiftTxList: state.metamask.shapeShiftTxList, transactions: state.metamask.selectedAddressTxList || [], + conversionRate: state.metamask.conversionRate, + currentCurrency: state.metamask.currentCurrency, } } @@ -43,7 +45,7 @@ AccountDetailScreen.prototype.render = function () { var checksumAddress = selected && ethUtil.toChecksumAddress(selected) var identity = props.identities[selected] var account = props.accounts[selected] - const { network } = props + const { network, conversionRate, currentCurrency } = props return ( @@ -182,6 +184,8 @@ AccountDetailScreen.prototype.render = function () { h(EthBalance, { value: account && account.balance, + conversionRate, + currentCurrency, style: { lineHeight: '7px', marginTop: '10px', @@ -243,11 +247,13 @@ AccountDetailScreen.prototype.subview = function () { } AccountDetailScreen.prototype.transactionList = function () { - const {transactions, unapprovedMsgs, address, network, shapeShiftTxList } = this.props + const {transactions, unapprovedMsgs, address, + network, shapeShiftTxList, conversionRate } = this.props return h(TransactionList, { transactions: transactions.sort((a, b) => b.time - a.time), network, unapprovedMsgs, + conversionRate, address, shapeShiftTxList, viewPendingTx: (txId) => { diff --git a/ui/app/accounts/account-list-item.js b/ui/app/accounts/account-list-item.js index 2a3c13d05..10a0b6cc7 100644 --- a/ui/app/accounts/account-list-item.js +++ b/ui/app/accounts/account-list-item.js @@ -15,7 +15,8 @@ function AccountListItem () { } AccountListItem.prototype.render = function () { - const { identity, selectedAddress, accounts, onShowDetail } = this.props + const { identity, selectedAddress, accounts, onShowDetail, + conversionRate, currentCurrency } = this.props const checksumAddress = identity && identity.address && ethUtil.toChecksumAddress(identity.address) const isSelected = selectedAddress === identity.address @@ -52,6 +53,8 @@ AccountListItem.prototype.render = function () { }, checksumAddress), h(EthBalance, { value: account && account.balance, + currentCurrency, + conversionRate, style: { lineHeight: '7px', marginTop: '10px', diff --git a/ui/app/accounts/index.js b/ui/app/accounts/index.js index 9584ebad9..ac2615cd7 100644 --- a/ui/app/accounts/index.js +++ b/ui/app/accounts/index.js @@ -23,6 +23,8 @@ function mapStateToProps (state) { scrollToBottom: state.appState.scrollToBottom, pending, keyrings: state.metamask.keyrings, + conversionRate: state.metamask.conversionRate, + currentCurrency: state.metamask.currentCurrency, } } @@ -33,7 +35,7 @@ function AccountsScreen () { AccountsScreen.prototype.render = function () { const props = this.props - const { keyrings } = props + const { keyrings, conversionRate, currentCurrency } = props const identityList = valuesFor(props.identities) const unapprovedTxList = valuesFor(props.unapprovedTxs) @@ -81,6 +83,8 @@ AccountsScreen.prototype.render = function () { key: `acct-panel-${identity.address}`, identity, selectedAddress: this.props.selectedAddress, + conversionRate, + currentCurrency, accounts: this.props.accounts, onShowDetail: this.onShowDetail.bind(this), pending, diff --git a/ui/app/app.js b/ui/app/app.js index bbfd58588..6e5aa57cd 100644 --- a/ui/app/app.js +++ b/ui/app/app.js @@ -249,7 +249,7 @@ App.prototype.renderNetworkDropdown = function () { h(DropMenuItem, { label: 'Ropsten Test Network', closeMenu: () => this.setState({ isNetworkMenuOpen: false }), - action: () => props.dispatch(actions.setProviderType('testnet')), + action: () => props.dispatch(actions.setProviderType('ropsten')), icon: h('.menu-icon.red-dot'), activeNetworkRender: props.network, provider: props.provider, diff --git a/ui/app/components/drop-menu-item.js b/ui/app/components/drop-menu-item.js index bd9d8f597..e42948209 100644 --- a/ui/app/components/drop-menu-item.js +++ b/ui/app/components/drop-menu-item.js @@ -42,7 +42,7 @@ DropMenuItem.prototype.activeNetworkRender = function () { if (providerType === 'mainnet') return h('.check', '✓') break case 'Ropsten Test Network': - if (providerType === 'testnet') return h('.check', '✓') + if (providerType === 'ropsten') return h('.check', '✓') break case 'Kovan Test Network': if (providerType === 'kovan') return h('.check', '✓') diff --git a/ui/app/components/ens-input.js b/ui/app/components/ens-input.js index ec3cd60ed..3e44d83af 100644 --- a/ui/app/components/ens-input.js +++ b/ui/app/components/ens-input.js @@ -5,11 +5,9 @@ const extend = require('xtend') const debounce = require('debounce') const copyToClipboard = require('copy-to-clipboard') const ENS = require('ethjs-ens') +const networkMap = require('ethjs-ens/lib/network-map.json') const ensRE = /.+\.eth$/ -const networkResolvers = { - '3': '112234455c3a32fd11230c42e7bccd4a84e02010', -} module.exports = EnsInput @@ -24,8 +22,8 @@ EnsInput.prototype.render = function () { list: 'addresses', onChange: () => { const network = this.props.network - const resolverAddress = networkResolvers[network] - if (!resolverAddress) return + const networkHasEnsSupport = getNetworkEnsSupport(network) + if (!networkHasEnsSupport) return const recipient = document.querySelector('input[name="address"]').value if (recipient.match(ensRE) === null) { @@ -73,9 +71,9 @@ EnsInput.prototype.render = function () { EnsInput.prototype.componentDidMount = function () { const network = this.props.network - const resolverAddress = networkResolvers[network] + const networkHasEnsSupport = getNetworkEnsSupport(network) - if (resolverAddress) { + if (networkHasEnsSupport) { const provider = global.ethereumProvider this.ens = new ENS({ provider, network }) this.checkName = debounce(this.lookupEnsName.bind(this), 200) @@ -169,3 +167,8 @@ EnsInput.prototype.ensIconContents = function (recipient) { }) } } + +function getNetworkEnsSupport (network) { + return Boolean(networkMap[network]) +} + diff --git a/ui/app/components/eth-balance.js b/ui/app/components/eth-balance.js index 57ca84564..4f538fd31 100644 --- a/ui/app/components/eth-balance.js +++ b/ui/app/components/eth-balance.js @@ -16,20 +16,19 @@ function EthBalanceComponent () { EthBalanceComponent.prototype.render = function () { var props = this.props let { value } = props - var style = props.style + const { style, width } = props var needsParse = this.props.needsParse !== undefined ? this.props.needsParse : true value = value ? formatBalance(value, 6, needsParse) : '...' - var width = props.width return ( h('.ether-balance.ether-balance-amount', { - style: style, + style, }, [ h('div', { style: { display: 'inline', - width: width, + width, }, }, this.renderBalance(value)), ]) @@ -38,16 +37,17 @@ EthBalanceComponent.prototype.render = function () { } EthBalanceComponent.prototype.renderBalance = function (value) { var props = this.props + const { conversionRate, shorten, incoming, currentCurrency } = props if (value === 'None') return value if (value === '...') return value - var balanceObj = generateBalanceObject(value, props.shorten ? 1 : 3) + var balanceObj = generateBalanceObject(value, shorten ? 1 : 3) var balance var splitBalance = value.split(' ') var ethNumber = splitBalance[0] var ethSuffix = splitBalance[1] const showFiat = 'showFiat' in props ? props.showFiat : true - if (props.shorten) { + if (shorten) { balance = balanceObj.shortBalance } else { balance = balanceObj.balance @@ -73,7 +73,7 @@ EthBalanceComponent.prototype.renderBalance = function (value) { width: '100%', textAlign: 'right', }, - }, this.props.incoming ? `+${balance}` : balance), + }, incoming ? `+${balance}` : balance), h('div', { style: { color: ' #AEAEAE', @@ -83,7 +83,7 @@ EthBalanceComponent.prototype.renderBalance = function (value) { }, label), ]), - showFiat ? h(FiatValue, { value: props.value }) : null, + showFiat ? h(FiatValue, { value: props.value, conversionRate, currentCurrency }) : null, ])) ) } diff --git a/ui/app/components/fiat-value.js b/ui/app/components/fiat-value.js index 298809b30..8a64a1cfc 100644 --- a/ui/app/components/fiat-value.js +++ b/ui/app/components/fiat-value.js @@ -1,17 +1,9 @@ const Component = require('react').Component const h = require('react-hyperscript') const inherits = require('util').inherits -const connect = require('react-redux').connect const formatBalance = require('../util').formatBalance -module.exports = connect(mapStateToProps)(FiatValue) - -function mapStateToProps (state) { - return { - conversionRate: state.metamask.conversionRate, - currentCurrency: state.metamask.currentCurrency, - } -} +module.exports = FiatValue inherits(FiatValue, Component) function FiatValue () { @@ -20,23 +12,23 @@ function FiatValue () { FiatValue.prototype.render = function () { const props = this.props + const { conversionRate, currentCurrency } = props + const value = formatBalance(props.value, 6) if (value === 'None') return value var fiatDisplayNumber, fiatTooltipNumber var splitBalance = value.split(' ') - if (props.conversionRate !== 0) { - fiatTooltipNumber = Number(splitBalance[0]) * props.conversionRate + if (conversionRate !== 0) { + fiatTooltipNumber = Number(splitBalance[0]) * conversionRate fiatDisplayNumber = fiatTooltipNumber.toFixed(2) } else { fiatDisplayNumber = 'N/A' fiatTooltipNumber = 'Unknown' } - var fiatSuffix = props.currentCurrency - - return fiatDisplay(fiatDisplayNumber, fiatSuffix) + return fiatDisplay(fiatDisplayNumber, currentCurrency) } function fiatDisplay (fiatDisplayNumber, fiatSuffix) { diff --git a/ui/app/components/hex-as-decimal-input.js b/ui/app/components/hex-as-decimal-input.js index e37aaa8c3..4a71e9585 100644 --- a/ui/app/components/hex-as-decimal-input.js +++ b/ui/app/components/hex-as-decimal-input.js @@ -139,7 +139,7 @@ HexAsDecimalInput.prototype.constructWarning = function () { } function hexify (decimalString) { - const hexBN = new BN(decimalString, 10) + const hexBN = new BN(parseInt(decimalString), 10) return '0x' + hexBN.toString('hex') } diff --git a/ui/app/components/identicon.js b/ui/app/components/identicon.js index 6d4871d02..9de854b54 100644 --- a/ui/app/components/identicon.js +++ b/ui/app/components/identicon.js @@ -1,6 +1,7 @@ const Component = require('react').Component const h = require('react-hyperscript') const inherits = require('util').inherits +const isNode = require('detect-node') const findDOMNode = require('react-dom').findDOMNode const jazzicon = require('jazzicon') const iconFactoryGen = require('../../lib/icon-factory') @@ -40,8 +41,10 @@ IdenticonComponent.prototype.componentDidMount = function () { var container = findDOMNode(this) var diameter = props.diameter || this.defaultDiameter - var img = iconFactory.iconForAddress(address, diameter, false) - container.appendChild(img) + if (!isNode) { + var img = iconFactory.iconForAddress(address, diameter, false) + container.appendChild(img) + } } IdenticonComponent.prototype.componentDidUpdate = function () { @@ -58,6 +61,8 @@ IdenticonComponent.prototype.componentDidUpdate = function () { } var diameter = props.diameter || this.defaultDiameter - var img = iconFactory.iconForAddress(address, diameter, false) - container.appendChild(img) + if (!isNode) { + var img = iconFactory.iconForAddress(address, diameter, false) + container.appendChild(img) + } } diff --git a/ui/app/components/network.js b/ui/app/components/network.js index f7ea8c49e..31a8fc17c 100644 --- a/ui/app/components/network.js +++ b/ui/app/components/network.js @@ -34,7 +34,7 @@ Network.prototype.render = function () { } else if (providerName === 'mainnet') { hoverText = 'Main Ethereum Network' iconName = 'ethereum-network' - } else if (providerName === 'testnet') { + } else if (providerName === 'ropsten') { hoverText = 'Ropsten Test Network' iconName = 'ropsten-test-network' } else if (parseInt(networkNumber) === 3) { @@ -90,7 +90,7 @@ Network.prototype.render = function () { h('.menu-icon.golden-square'), h('.network-name', { style: { - color: '#550077', + color: '#e7a218', }}, 'Rinkeby Test Net'), ]) diff --git a/ui/app/components/pending-tx.js b/ui/app/components/pending-tx.js index 5ea885195..0d1f06ba6 100644 --- a/ui/app/components/pending-tx.js +++ b/ui/app/components/pending-tx.js @@ -1,5 +1,4 @@ const Component = require('react').Component -const connect = require('react-redux').connect const h = require('react-hyperscript') const inherits = require('util').inherits const actions = require('../actions') @@ -20,12 +19,7 @@ const GWEI_FACTOR = new BN(1e9) const MIN_GAS_PRICE_BN = MIN_GAS_PRICE_GWEI_BN.mul(GWEI_FACTOR) const MIN_GAS_LIMIT_BN = new BN(21000) -module.exports = connect(mapStateToProps)(PendingTx) - -function mapStateToProps (state) { - return {} -} - +module.exports = PendingTx inherits(PendingTx, Component) function PendingTx () { Component.call(this) @@ -37,7 +31,9 @@ function PendingTx () { PendingTx.prototype.render = function () { const props = this.props + const { currentCurrency } = props + const conversionRate = props.conversionRate const txMeta = this.gatherTxMeta() const txParams = txMeta.txParams || {} @@ -61,7 +57,6 @@ PendingTx.prototype.render = function () { const maxCost = txFeeBn.add(valueBn) const dataLength = txParams.data ? (txParams.data.length - 2) / 2 : 0 - const imageify = props.imageifyIdenticons === undefined ? true : props.imageifyIdenticons const balanceBn = hexToBn(balance) const insufficientBalance = balanceBn.lt(maxCost) @@ -75,18 +70,8 @@ PendingTx.prototype.render = function () { }, [ h('form#pending-tx-form', { - onSubmit: (event) => { - const txMeta = this.gatherTxMeta() - event.preventDefault() - const form = document.querySelector('form#pending-tx-form') - const valid = form.checkValidity() - this.setState({ valid }) - if (valid && this.verifyGasParams()) { - props.sendTransaction(txMeta, event) - } else { - this.props.dispatch(actions.displayWarning('Invalid Gas Parameters')) - } - }, + onSubmit: this.onSubmit.bind(this), + }, [ // tx info @@ -100,7 +85,6 @@ PendingTx.prototype.render = function () { h(MiniAccountPanel, { imageSeed: address, - imageifyIdenticons: imageify, picOrder: 'right', }, [ h('span.font-small', { @@ -121,6 +105,8 @@ PendingTx.prototype.render = function () { }, [ h(EthBalance, { value: balance, + conversionRate, + currentCurrency, inline: true, labelColor: '#F7861C', }), @@ -158,7 +144,7 @@ PendingTx.prototype.render = function () { // in the way that gas and gasLimit currently are. h('.row', [ h('.cell.label', 'Amount'), - h(EthBalance, { value: txParams.value }), + h(EthBalance, { value: txParams.value, currentCurrency, conversionRate }), ]), // Gas Limit (customizable) @@ -176,12 +162,8 @@ PendingTx.prototype.render = function () { position: 'relative', top: '5px', }, - onChange: (newHex) => { - log.info(`Gas limit changed to ${newHex}`) - const txMeta = this.gatherTxMeta() - txMeta.txParams.gas = newHex - this.setState({ txData: txMeta }) - }, + onChange: this.gasLimitChanged.bind(this), + ref: (hexInput) => { this.inputs.push(hexInput) }, }), ]), @@ -201,13 +183,7 @@ PendingTx.prototype.render = function () { position: 'relative', top: '5px', }, - onChange: (newHex) => { - log.info(`Gas price changed to: ${newHex}`) - const inWei = hexToBn(newHex).mul(GWEI_FACTOR) - const txMeta = this.gatherTxMeta() - txMeta.txParams.gasPrice = inWei.toString(16) - this.setState({ txData: txMeta }) - }, + onChange: this.gasPriceChanged.bind(this), ref: (hexInput) => { this.inputs.push(hexInput) }, }), ]), @@ -216,7 +192,7 @@ PendingTx.prototype.render = function () { // Max Transaction Fee (calculated) h('.cell.row', [ h('.cell.label', 'Max Transaction Fee'), - h(EthBalance, { value: txFeeBn.toString(16) }), + h(EthBalance, { value: txFeeBn.toString(16), currentCurrency, conversionRate }), ]), h('.cell.row', { @@ -235,6 +211,8 @@ PendingTx.prototype.render = function () { }, [ h(EthBalance, { value: maxCost.toString(16), + currentCurrency, + conversionRate, inline: true, labelColor: 'black', fontSize: '16px', @@ -331,13 +309,11 @@ PendingTx.prototype.miniAccountPanelForRecipient = function () { const txData = props.txData const txParams = txData.txParams || {} const isContractDeploy = !('to' in txParams) - const imageify = props.imageifyIdenticons === undefined ? true : props.imageifyIdenticons // If it's not a contract deploy, send to the account if (!isContractDeploy) { return h(MiniAccountPanel, { imageSeed: txParams.to, - imageifyIdenticons: imageify, picOrder: 'left', }, [ h('span.font-small', { @@ -353,7 +329,6 @@ PendingTx.prototype.miniAccountPanelForRecipient = function () { ]) } else { return h(MiniAccountPanel, { - imageifyIdenticons: imageify, picOrder: 'left', }, [ @@ -367,6 +342,21 @@ PendingTx.prototype.miniAccountPanelForRecipient = function () { } } +PendingTx.prototype.gasPriceChanged = function (newHex) { + log.info(`Gas price changed to: ${newHex}`) + const inWei = hexToBn(newHex).mul(GWEI_FACTOR) + const txMeta = this.gatherTxMeta() + txMeta.txParams.gasPrice = inWei.toString(16) + this.setState({ txData: txMeta }) +} + +PendingTx.prototype.gasLimitChanged = function (newHex) { + log.info(`Gas limit changed to ${newHex}`) + const txMeta = this.gatherTxMeta() + txMeta.txParams.gas = newHex + this.setState({ txData: txMeta }) +} + PendingTx.prototype.resetGasFields = function () { log.debug(`pending-tx resetGasFields`) @@ -382,6 +372,33 @@ PendingTx.prototype.resetGasFields = function () { }) } +PendingTx.prototype.onSubmit = function (event) { + event.preventDefault() + const txMeta = this.gatherTxMeta() + const valid = this.checkValidity() + this.setState({ valid }) + if (valid && this.verifyGasParams()) { + this.props.sendTransaction(txMeta, event) + } else { + this.props.dispatch(actions.displayWarning('Invalid Gas Parameters')) + } +} + +PendingTx.prototype.checkValidity = function () { + const form = this.getFormEl() + const valid = form.checkValidity() + return valid +} + +PendingTx.prototype.getFormEl = function () { + const form = document.querySelector('form#pending-tx-form') + // Stub out form for unit tests: + if (!form) { + return { checkValidity () { return true } } + } + return form +} + // After a customizable state value has been updated, PendingTx.prototype.gatherTxMeta = function () { log.debug(`pending-tx gatherTxMeta`) diff --git a/ui/app/components/shift-list-item.js b/ui/app/components/shift-list-item.js index 96a7cba6e..32bfbeda4 100644 --- a/ui/app/components/shift-list-item.js +++ b/ui/app/components/shift-list-item.js @@ -8,14 +8,17 @@ const actions = require('../actions') const addressSummary = require('../util').addressSummary const CopyButton = require('./copyButton') -const EtherBalance = require('./eth-balance') +const EthBalance = require('./eth-balance') const Tooltip = require('./tooltip') module.exports = connect(mapStateToProps)(ShiftListItem) function mapStateToProps (state) { - return {} + return { + conversionRate: state.metamask.conversionRate, + currentCurrency: state.metamask.currentCurrency, + } } inherits(ShiftListItem, Component) @@ -64,6 +67,7 @@ function formatDate (date) { ShiftListItem.prototype.renderUtilComponents = function () { var props = this.props + const { conversionRate, currentCurrency } = props switch (props.response.status) { case 'no_deposits': @@ -94,8 +98,10 @@ ShiftListItem.prototype.renderUtilComponents = function () { h(CopyButton, { value: this.props.response.transaction, }), - h(EtherBalance, { + h(EthBalance, { value: `${props.response.outgoingCoin}`, + conversionRate, + currentCurrency, width: '55px', shorten: true, needsParse: false, diff --git a/ui/app/components/transaction-list-item.js b/ui/app/components/transaction-list-item.js index 7fb2e88d9..c2a585003 100644 --- a/ui/app/components/transaction-list-item.js +++ b/ui/app/components/transaction-list-item.js @@ -2,7 +2,7 @@ const Component = require('react').Component const h = require('react-hyperscript') const inherits = require('util').inherits -const EtherBalance = require('./eth-balance') +const EthBalance = require('./eth-balance') const addressSummary = require('../util').addressSummary const explorerLink = require('../../lib/explorer-link') const CopyButton = require('./copyButton') @@ -19,7 +19,7 @@ function TransactionListItem () { } TransactionListItem.prototype.render = function () { - const { transaction, network } = this.props + const { transaction, network, conversionRate, currentCurrency } = this.props if (transaction.key === 'shapeshift') { if (network === '1') return h(ShiftListItem, transaction) } @@ -78,8 +78,10 @@ TransactionListItem.prototype.render = function () { // Places a copy button if tx is successful, else places a placeholder empty div. transaction.hash ? h(CopyButton, { value: transaction.hash }) : h('div', {style: { display: 'flex', alignItems: 'center', width: '26px' }}), - isTx ? h(EtherBalance, { + isTx ? h(EthBalance, { value: txParams.value, + conversionRate, + currentCurrency, width: '55px', shorten: true, showFiat: false, diff --git a/ui/app/components/transaction-list.js b/ui/app/components/transaction-list.js index 3ae953637..37a757309 100644 --- a/ui/app/components/transaction-list.js +++ b/ui/app/components/transaction-list.js @@ -13,7 +13,7 @@ function TransactionList () { } TransactionList.prototype.render = function () { - const { transactions, network, unapprovedMsgs } = this.props + const { transactions, network, unapprovedMsgs, conversionRate } = this.props var shapeShiftTxList if (network === '1') { @@ -69,6 +69,7 @@ TransactionList.prototype.render = function () { } return h(TransactionListItem, { transaction, i, network, key, + conversionRate, showTx: (txId) => { this.props.viewPendingTx(txId) }, diff --git a/ui/app/conf-tx.js b/ui/app/conf-tx.js index 83ac5a4fd..008627ce6 100644 --- a/ui/app/conf-tx.js +++ b/ui/app/conf-tx.js @@ -27,6 +27,8 @@ function mapStateToProps (state) { warning: state.appState.warning, network: state.metamask.network, provider: state.metamask.provider, + conversionRate: state.metamask.conversionRate, + currentCurrency: state.metamask.currentCurrency, } } @@ -37,8 +39,8 @@ function ConfirmTxScreen () { ConfirmTxScreen.prototype.render = function () { const props = this.props - const { network, provider, unapprovedTxs, - unapprovedMsgs, unapprovedPersonalMsgs } = props + const { network, provider, unapprovedTxs, currentCurrency, + unapprovedMsgs, unapprovedPersonalMsgs, conversionRate } = props var unconfTxList = txHelper(unapprovedTxs, unapprovedMsgs, unapprovedPersonalMsgs, network) @@ -102,9 +104,11 @@ ConfirmTxScreen.prototype.render = function () { selectedAddress: props.selectedAddress, accounts: props.accounts, identities: props.identities, + conversionRate, + currentCurrency, // Actions buyEth: this.buyEth.bind(this, txParams.from || props.selectedAddress), - sendTransaction: this.sendTransaction.bind(this, txData), + sendTransaction: this.sendTransaction.bind(this), cancelTransaction: this.cancelTransaction.bind(this, txData), signMessage: this.signMessage.bind(this, txData), signPersonalMessage: this.signPersonalMessage.bind(this, txData), diff --git a/ui/app/config.js b/ui/app/config.js index 26cfe663f..d7be26757 100644 --- a/ui/app/config.js +++ b/ui/app/config.js @@ -156,7 +156,7 @@ function currentProviderDisplay (metamaskState) { value = 'Main Ethereum Network' break - case 'testnet': + case 'ropsten': title = 'Current Network' value = 'Ropsten Test Network' break diff --git a/ui/app/conversion.json b/ui/app/conversion.json index eeca164ce..155ffc4fc 100644 --- a/ui/app/conversion.json +++ b/ui/app/conversion.json @@ -1,5730 +1,207 @@ -{ - "rows":[ - { - "code":"007", - "name":"007", - "statuses":[ - "primary" - ] - }, - { - "code":"1337", - "name":"1337", - "statuses":[ - "primary" - ] - }, - { - "code":"1CR", - "name":"1CR", - "statuses":[ - "primary" - ] - }, - { - "code":"256", - "name":"256", - "statuses":[ - "primary" - ] - }, - { - "code":"2FLAV", - "name":"2FLAV", - "statuses":[ - "primary" - ] - }, - { - "code":"2GIVE", - "name":"2GIVE", - "statuses":[ - "primary" - ] - }, - { - "code":"32BIT", - "name":"32BIT", - "statuses":[ - "primary" - ] - }, - { - "code":"404", - "name":"404", - "statuses":[ - "primary" - ] - }, - { - "code":"611", - "name":"611", - "statuses":[ - "primary" - ] - }, - { - "code":"888", - "name":"888", - "statuses":[ - "primary" - ] - }, - { - "code":"8BIT", - "name":"8Bit", - "statuses":[ - "primary" - ] - }, - { - "code":"ACES", - "name":"ACES", - "statuses":[ - "primary" - ] - }, - { - "code":"ACID", - "name":"ACID", - "statuses":[ - "primary" - ] - }, - { - "code":"ACLR", - "name":"ACLR", - "statuses":[ - "primary" - ] - }, - { - "code":"ACP", - "name":"ACP", - "statuses":[ - "primary" - ] - }, - { - "code":"ADC", - "name":"ADC", - "statuses":[ - "primary" - ] - }, - { - "code":"ADZ", - "name":"Adzcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"AEON", - "name":"Aeon", - "statuses":[ - "primary" - ] - }, - { - "code":"AGRS", - "name":"Agoras Tokens", - "statuses":[ - "primary" - ] - }, - { - "code":"AIB", - "name":"AIB", - "statuses":[ - "primary" - ] - }, - { - "code":"ALC", - "name":"ALC", - "statuses":[ - "primary" - ] - }, - { - "code":"ALTC", - "name":"ALTC", - "statuses":[ - "primary" - ] - }, - { - "code":"AM", - "name":"AM", - "statuses":[ - "primary" - ] - }, - { - "code":"AMBER", - "name":"AMBER", - "statuses":[ - "primary" - ] - }, - { - "code":"AMS", - "name":"AMS", - "statuses":[ - "primary" - ] - }, - { - "code":"ANAL", - "name":"ANAL", - "statuses":[ - "primary" - ] - }, - { - "code":"ANI", - "name":"ANI", - "statuses":[ - "primary" - ] - }, - { - "code":"ANC", - "name":"Anoncoin", - "statuses":[ - "primary" - ] - }, - { - "code":"ANS", - "name":"ANS", - "statuses":[ - "primary" - ] - }, - { - "code":"ANTI", - "name":"AntiBitcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"APEX", - "name":"APEX", - "statuses":[ - "primary" - ] - }, - { - "code":"APC", - "name":"Applecoin", - "statuses":[ - "primary" - ] - }, - { - "code":"APT", - "name":"APT", - "statuses":[ - "primary" - ] - }, - { - "code":"AR2", - "name":"AR2", - "statuses":[ - "primary" - ] - }, - { - "code":"ARB", - "name":"ARB", - "statuses":[ - "primary" - ] - }, - { - "code":"ARC", - "name":"ARC", - "statuses":[ - "primary" - ] - }, - { - "code":"ARCH", - "name":"ARCH", - "statuses":[ - "primary" - ] - }, - { - "code":"ARD", - "name":"ARD", - "statuses":[ - "primary" - ] - }, - { - "code":"ARDR", - "name":"ARDR", - "statuses":[ - "primary" - ] - }, - { - "code":"ABY", - "name":"ArtByte", - "statuses":[ - "primary" - ] - }, - { - "code":"ARTC", - "name":"ARTC", - "statuses":[ - "primary" - ] - }, - { - "code":"ASAFE", - "name":"ASAFE", - "statuses":[ - "primary" - ] - }, - { - "code":"ADCN", - "name":"Asiadigicoin", - "statuses":[ - "primary" - ] - }, - { - "code":"ASN", - "name":"ASN", - "statuses":[ - "primary" - ] - }, - { - "code":"ATEN", - "name":"ATEN", - "statuses":[ - "primary" - ] - }, - { - "code":"ATOM", - "name":"ATOM", - "statuses":[ - "primary" - ] - }, - { - "code":"ATX", - "name":"ATX", - "statuses":[ - "primary" - ] - }, - { - "code":"REP", - "name":"Augur", - "statuses":[ - "primary" - ] - }, - { - "code":"AUR", - "name":"Auroracoin", - "statuses":[ - "primary" - ] - }, - { - "code":"AUD", - "name":"Australian Dollar", - "statuses":[ - "secondary" - ] - }, - { - "code":"AV", - "name":"AV", - "statuses":[ - "primary" - ] - }, - { - "code":"B2", - "name":"B2", - "statuses":[ - "primary" - ] - }, - { - "code":"B3", - "name":"B3", - "statuses":[ - "primary" - ] - }, - { - "code":"BA", - "name":"BA", - "statuses":[ - "primary" - ] - }, - { - "code":"BAC", - "name":"BAC", - "statuses":[ - "primary" - ] - }, - { - "code":"BASH", - "name":"BASH", - "statuses":[ - "primary" - ] - }, - { - "code":"BTA", - "name":"Bata", - "statuses":[ - "primary" - ] - }, - { - "code":"BAY", - "name":"BAY", - "statuses":[ - "primary" - ] - }, - { - "code":"BBCC", - "name":"BBCC", - "statuses":[ - "primary" - ] - }, - { - "code":"BQC", - "name":"BBQCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"BEC", - "name":"BEC", - "statuses":[ - "primary" - ] - }, - { - "code":"BEEP", - "name":"BEEP", - "statuses":[ - "primary" - ] - }, - { - "code":"BELA", - "name":"BellaCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"BERN", - "name":"BERNcash", - "statuses":[ - "primary" - ] - }, - { - "code":"BHC", - "name":"BHC", - "statuses":[ - "primary" - ] - }, - { - "code":"BILL", - "name":"BILL", - "statuses":[ - "primary" - ] - }, - { - "code":"BILS", - "name":"BILS", - "statuses":[ - "primary" - ] - }, - { - "code":"BIOS", - "name":"BiosCrypto", - "statuses":[ - "primary" - ] - }, - { - "code":"BIT", - "name":"BIT", - "statuses":[ - "primary" - ] - }, - { - "code":"BIT16", - "name":"BIT16", - "statuses":[ - "primary" - ] - }, - { - "code":"BITB", - "name":"BitBean", - "statuses":[ - "primary" - ] - }, - { - "code":"BTC", - "name":"Bitcoin", - "statuses":[ - "primary", - "secondary" - ] - }, - { - "code":"XBC", - "name":"Bitcoin Plus", - "statuses":[ - "primary" - ] - }, - { - "code":"BTCD", - "name":"BitcoinDark", - "statuses":[ - "primary" - ] - }, - { - "code":"BCY", - "name":"Bitcrystals", - "statuses":[ - "primary" - ] - }, - { - "code":"BFX", - "name":"Bitfinex Debt token", - "statuses":[ - "primary" - ] - }, - { - "code":"BTM", - "name":"Bitmark", - "statuses":[ - "primary" - ] - }, - { - "code":"BITON", - "name":"BITON", - "statuses":[ - "primary" - ] - }, - { - "code":"BTQ", - "name":"BitQuark", - "statuses":[ - "primary" - ] - }, - { - "code":"BITS", - "name":"BITS", - "statuses":[ - "primary" - ] - }, - { - "code":"BSD", - "name":"BitSend", - "statuses":[ - "primary" - ] - }, - { - "code":"BTS", - "name":"BitShares", - "statuses":[ - "primary" - ] - }, - { - "code":"SWIFT", - "name":"BitSwift", - "statuses":[ - "primary" - ] - }, - { - "code":"BITZ", - "name":"Bitz", - "statuses":[ - "primary" - ] - }, - { - "code":"BLK", - "name":"Blackcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"BLC", - "name":"Blakecoin", - "statuses":[ - "primary" - ] - }, - { - "code":"BLEU", - "name":"BLEU", - "statuses":[ - "primary" - ] - }, - { - "code":"BLITZ", - "name":"Blitzcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"BLOCK", - "name":"Blocknet", - "statuses":[ - "primary" - ] - }, - { - "code":"BLRY", - "name":"BLRY", - "statuses":[ - "primary" - ] - }, - { - "code":"BLU", - "name":"BLU", - "statuses":[ - "primary" - ] - }, - { - "code":"BLUS", - "name":"BLUS", - "statuses":[ - "primary" - ] - }, - { - "code":"BNT", - "name":"BNT", - "statuses":[ - "primary" - ] - }, - { - "code":"BOLI", - "name":"Bolivarcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"BBR", - "name":"Boolberry", - "statuses":[ - "primary" - ] - }, - { - "code":"BOOM", - "name":"BOOM", - "statuses":[ - "primary" - ] - }, - { - "code":"BOST", - "name":"BoostCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"BOSS", - "name":"BOSS", - "statuses":[ - "primary" - ] - }, - { - "code":"BPOK", - "name":"BPOK", - "statuses":[ - "primary" - ] - }, - { - "code":"BRAIN", - "name":"BRAIN", - "statuses":[ - "primary" - ] - }, - { - "code":"BRC", - "name":"BRC", - "statuses":[ - "primary" - ] - }, - { - "code":"BRDD", - "name":"BRDD", - "statuses":[ - "primary" - ] - }, - { - "code":"BRIT", - "name":"BRIT", - "statuses":[ - "primary" - ] - }, - { - "code":"GBP", - "name":"British Pound Sterling", - "statuses":[ - "secondary" - ] - }, - { - "code":"BRK", - "name":"BRK", - "statuses":[ - "primary" - ] - }, - { - "code":"BRX", - "name":"BRX", - "statuses":[ - "primary" - ] - }, - { - "code":"BS", - "name":"BS", - "statuses":[ - "primary" - ] - }, - { - "code":"BSC", - "name":"BSC", - "statuses":[ - "primary" - ] - }, - { - "code":"BST", - "name":"BST", - "statuses":[ - "primary" - ] - }, - { - "code":"BTCHC", - "name":"BTCHC", - "statuses":[ - "primary" - ] - }, - { - "code":"BTCR", - "name":"BTCR", - "statuses":[ - "primary" - ] - }, - { - "code":"BTCS", - "name":"BTCS", - "statuses":[ - "primary" - ] - }, - { - "code":"BTD", - "name":"BTD", - "statuses":[ - "primary" - ] - }, - { - "code":"BTLC", - "name":"BTLC", - "statuses":[ - "primary" - ] - }, - { - "code":"BTTF", - "name":"BTTF", - "statuses":[ - "primary" - ] - }, - { - "code":"BTZ", - "name":"BTZ", - "statuses":[ - "primary" - ] - }, - { - "code":"BUCKS", - "name":"BUCKS", - "statuses":[ - "primary" - ] - }, - { - "code":"BUN", - "name":"BUN", - "statuses":[ - "primary" - ] - }, - { - "code":"BURST", - "name":"Burst", - "statuses":[ - "primary" - ] - }, - { - "code":"BUZZ", - "name":"BUZZ", - "statuses":[ - "primary" - ] - }, - { - "code":"BVC", - "name":"BVC", - "statuses":[ - "primary" - ] - }, - { - "code":"BXT", - "name":"BXT", - "statuses":[ - "primary" - ] - }, - { - "code":"BYC", - "name":"Bytecent", - "statuses":[ - "primary" - ] - }, - { - "code":"BCN", - "name":"Bytecoin", - "statuses":[ - "primary" - ] - }, - { - "code":"CAB", - "name":"Cabbage Unit", - "statuses":[ - "primary" - ] - }, - { - "code":"CAGE", - "name":"CAGE", - "statuses":[ - "primary" - ] - }, - { - "code":"CAID", - "name":"CAID", - "statuses":[ - "primary" - ] - }, - { - "code":"CAD", - "name":"Canadian Dollar", - "statuses":[ - "secondary" - ] - }, - { - "code":"CANN", - "name":"CannabisCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"CCN", - "name":"Cannacoin", - "statuses":[ - "primary" - ] - }, - { - "code":"CPC", - "name":"Capricoin", - "statuses":[ - "primary" - ] - }, - { - "code":"CAPT", - "name":"CAPT", - "statuses":[ - "primary" - ] - }, - { - "code":"DIEM", - "name":"CarpeDiemCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"CASH", - "name":"CASH", - "statuses":[ - "primary" - ] - }, - { - "code":"CBD", - "name":"CBD", - "statuses":[ - "primary" - ] - }, - { - "code":"CBIT", - "name":"CBIT", - "statuses":[ - "primary" - ] - }, - { - "code":"CCX", - "name":"CCX", - "statuses":[ - "primary" - ] - }, - { - "code":"CD", - "name":"CD", - "statuses":[ - "primary" - ] - }, - { - "code":"CDN", - "name":"CDN", - "statuses":[ - "primary" - ] - }, - { - "code":"CF", - "name":"CF", - "statuses":[ - "primary" - ] - }, - { - "code":"CGA", - "name":"CGA", - "statuses":[ - "primary" - ] - }, - { - "code":"CKC", - "name":"Checkcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"CHEMX", - "name":"CHEMX", - "statuses":[ - "primary" - ] - }, - { - "code":"CHESS", - "name":"CHESS", - "statuses":[ - "primary" - ] - }, - { - "code":"CHF", - "name":"CHF", - "statuses":[ - "primary", - "secondary" - ] - }, - { - "code":"CNY", - "name":"Chinese Yuan", - "statuses":[ - "secondary" - ] - }, - { - "code":"CHOOF", - "name":"CHOOF", - "statuses":[ - "primary" - ] - }, - { - "code":"CJ", - "name":"CJ", - "statuses":[ - "primary" - ] - }, - { - "code":"CLAM", - "name":"Clams", - "statuses":[ - "primary" - ] - }, - { - "code":"CLICK", - "name":"CLICK", - "statuses":[ - "primary" - ] - }, - { - "code":"CLINT", - "name":"CLINT", - "statuses":[ - "primary" - ] - }, - { - "code":"CLOAK", - "name":"Cloakcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"CLR", - "name":"CLR", - "statuses":[ - "primary" - ] - }, - { - "code":"CLUB", - "name":"CLUB", - "statuses":[ - "primary" - ] - }, - { - "code":"CLUD", - "name":"CLUD", - "statuses":[ - "primary" - ] - }, - { - "code":"CLV", - "name":"CLV", - "statuses":[ - "primary" - ] - }, - { - "code":"CME", - "name":"CME", - "statuses":[ - "primary" - ] - }, - { - "code":"CMT", - "name":"CMT", - "statuses":[ - "primary" - ] - }, - { - "code":"CNC", - "name":"CNC", - "statuses":[ - "primary" - ] - }, - { - "code":"COC", - "name":"COC", - "statuses":[ - "primary" - ] - }, - { - "code":"COXST", - "name":"CoExistCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"COIN", - "name":"COIN", - "statuses":[ - "primary" - ] - }, - { - "code":"C2", - "name":"Coin2.1", - "statuses":[ - "primary" - ] - }, - { - "code":"CV2", - "name":"Colossuscoin2.0", - "statuses":[ - "primary" - ] - }, - { - "code":"CON", - "name":"CON", - "statuses":[ - "primary" - ] - }, - { - "code":"XCP", - "name":"Counterparty", - "statuses":[ - "primary" - ] - }, - { - "code":"COVAL", - "name":"COVAL", - "statuses":[ - "primary" - ] - }, - { - "code":"COX", - "name":"COX", - "statuses":[ - "primary" - ] - }, - { - "code":"CRAB", - "name":"CRAB", - "statuses":[ - "primary" - ] - }, - { - "code":"CRC", - "name":"CRC", - "statuses":[ - "primary" - ] - }, - { - "code":"CRE", - "name":"CRE", - "statuses":[ - "primary" - ] - }, - { - "code":"CRBIT", - "name":"Creditbit", - "statuses":[ - "primary" - ] - }, - { - "code":"CREVA", - "name":"CrevaCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"CRNK", - "name":"CRNK", - "statuses":[ - "primary" - ] - }, - { - "code":"CRPC", - "name":"CRPC", - "statuses":[ - "primary" - ] - }, - { - "code":"CRPS", - "name":"CRPS", - "statuses":[ - "primary" - ] - }, - { - "code":"CRT", - "name":"CRT", - "statuses":[ - "primary" - ] - }, - { - "code":"CRW", - "name":"CRW", - "statuses":[ - "primary" - ] - }, - { - "code":"CRX", - "name":"CRX", - "statuses":[ - "primary" - ] - }, - { - "code":"CRY", - "name":"CRY", - "statuses":[ - "primary" - ] - }, - { - "code":"CBX", - "name":"Crypto Bullion", - "statuses":[ - "primary" - ] - }, - { - "code":"CESC", - "name":"CryptoEscudo", - "statuses":[ - "primary" - ] - }, - { - "code":"XCN", - "name":"Cryptonite", - "statuses":[ - "primary" - ] - }, - { - "code":"CSH", - "name":"CSH", - "statuses":[ - "primary" - ] - }, - { - "code":"CST", - "name":"CST", - "statuses":[ - "primary" - ] - }, - { - "code":"CTK", - "name":"CTK", - "statuses":[ - "primary" - ] - }, - { - "code":"CTL", - "name":"CTL", - "statuses":[ - "primary" - ] - }, - { - "code":"CTO", - "name":"CTO", - "statuses":[ - "primary" - ] - }, - { - "code":"CURE", - "name":"Curecoin", - "statuses":[ - "primary" - ] - }, - { - "code":"CYC", - "name":"CYC", - "statuses":[ - "primary" - ] - }, - { - "code":"CYP", - "name":"Cypher", - "statuses":[ - "primary" - ] - }, - { - "code":"CZC", - "name":"CZC", - "statuses":[ - "primary" - ] - }, - { - "code":"CZR", - "name":"CZR", - "statuses":[ - "primary" - ] - }, - { - "code":"DGD", - "name":"DarkGoldCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"DNET", - "name":"Darknet", - "statuses":[ - "primary" - ] - }, - { - "code":"DAS", - "name":"DAS", - "statuses":[ - "primary" - ] - }, - { - "code":"DASH", - "name":"Dash", - "statuses":[ - "primary" - ] - }, - { - "code":"DTC", - "name":"Datacoin", - "statuses":[ - "primary" - ] - }, - { - "code":"DB", - "name":"DB", - "statuses":[ - "primary" - ] - }, - { - "code":"DBG", - "name":"DBG", - "statuses":[ - "primary" - ] - }, - { - "code":"DBLK", - "name":"DBLK", - "statuses":[ - "primary" - ] - }, - { - "code":"DBTC", - "name":"DBTC", - "statuses":[ - "primary" - ] - }, - { - "code":"DC", - "name":"DC", - "statuses":[ - "primary" - ] - }, - { - "code":"DCK", - "name":"DCK", - "statuses":[ - "primary" - ] - }, - { - "code":"DCRE", - "name":"DCRE", - "statuses":[ - "primary" - ] - }, - { - "code":"DCT", - "name":"DCT", - "statuses":[ - "primary" - ] - }, - { - "code":"DCYP", - "name":"DCYP", - "statuses":[ - "primary" - ] - }, - { - "code":"DCR", - "name":"Decred", - "statuses":[ - "primary" - ] - }, - { - "code":"DES", - "name":"Destiny", - "statuses":[ - "primary" - ] - }, - { - "code":"DEUR", - "name":"DEUR", - "statuses":[ - "primary" - ] - }, - { - "code":"DEM", - "name":"Deutsche eMark", - "statuses":[ - "primary" - ] - }, - { - "code":"DVC", - "name":"Devcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"DGMS", - "name":"DGMS", - "statuses":[ - "primary" - ] - }, - { - "code":"DGORE", - "name":"DGORE", - "statuses":[ - "primary" - ] - }, - { - "code":"DMD", - "name":"Diamond", - "statuses":[ - "primary" - ] - }, - { - "code":"DGB", - "name":"Digibyte", - "statuses":[ - "primary" - ] - }, - { - "code":"CUBE", - "name":"DigiCube", - "statuses":[ - "primary" - ] - }, - { - "code":"DGC", - "name":"Digitalcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"XDN", - "name":"DigitalNote", - "statuses":[ - "primary" - ] - }, - { - "code":"DP", - "name":"DigitalPrice", - "statuses":[ - "primary" - ] - }, - { - "code":"DIME", - "name":"Dimecoin", - "statuses":[ - "primary" - ] - }, - { - "code":"DISK", - "name":"DISK", - "statuses":[ - "primary" - ] - }, - { - "code":"DKC", - "name":"DKC", - "statuses":[ - "primary" - ] - }, - { - "code":"DLC", - "name":"DLC", - "statuses":[ - "primary" - ] - }, - { - "code":"DLISK", - "name":"DLISK", - "statuses":[ - "primary" - ] - }, - { - "code":"DMC", - "name":"DMC", - "statuses":[ - "primary" - ] - }, - { - "code":"NOTE", - "name":"DNotes", - "statuses":[ - "primary" - ] - }, - { - "code":"DOGE", - "name":"Dogecoin", - "statuses":[ - "primary", - "secondary" - ] - }, - { - "code":"DOPE", - "name":"DopeCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"DOV", - "name":"DOV", - "statuses":[ - "primary" - ] - }, - { - "code":"DOX", - "name":"DOX", - "statuses":[ - "primary" - ] - }, - { - "code":"DPAY", - "name":"DPAY", - "statuses":[ - "primary" - ] - }, - { - "code":"DRACO", - "name":"DRACO", - "statuses":[ - "primary" - ] - }, - { - "code":"DRM8", - "name":"DRM8", - "statuses":[ - "primary" - ] - }, - { - "code":"DROP", - "name":"DROP", - "statuses":[ - "primary" - ] - }, - { - "code":"DRZ", - "name":"DRZ", - "statuses":[ - "primary" - ] - }, - { - "code":"DSH", - "name":"DSH", - "statuses":[ - "primary" - ] - }, - { - "code":"DTT", - "name":"DTT", - "statuses":[ - "primary" - ] - }, - { - "code":"DBIC", - "name":"DubaiCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"DUO", - "name":"DUO", - "statuses":[ - "primary" - ] - }, - { - "code":"DUST", - "name":"DUST", - "statuses":[ - "primary" - ] - }, - { - "code":"EAGS", - "name":"EAGS", - "statuses":[ - "primary" - ] - }, - { - "code":"EAC", - "name":"Earthcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"EBST", - "name":"EBST", - "statuses":[ - "primary" - ] - }, - { - "code":"EC", - "name":"EC", - "statuses":[ - "primary" - ] - }, - { - "code":"ECC", - "name":"ECCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"ECLI", - "name":"ECLI", - "statuses":[ - "primary" - ] - }, - { - "code":"EDC", - "name":"EDC", - "statuses":[ - "primary" - ] - }, - { - "code":"EDRC", - "name":"EDRC", - "statuses":[ - "primary" - ] - }, - { - "code":"EDR", - "name":"EDRCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"EGG", - "name":"EGG", - "statuses":[ - "primary" - ] - }, - { - "code":"EGO", - "name":"EGO", - "statuses":[ - "primary" - ] - }, - { - "code":"EMC2", - "name":"Einsteinium", - "statuses":[ - "primary" - ] - }, - { - "code":"EL", - "name":"EL", - "statuses":[ - "primary" - ] - }, - { - "code":"ELE", - "name":"ELE", - "statuses":[ - "primary" - ] - }, - { - "code":"EFL", - "name":"Electronic Gulden", - "statuses":[ - "primary" - ] - }, - { - "code":"EMB", - "name":"EMB", - "statuses":[ - "secondary" - ] - }, - { - "code":"EME", - "name":"EME", - "statuses":[ - "secondary" - ] - }, - { - "code":"EMC", - "name":"Emercoin", - "statuses":[ - "primary" - ] - }, - { - "code":"EMIRG", - "name":"EMIRG", - "statuses":[ - "primary" - ] - }, - { - "code":"EMP", - "name":"EMP", - "statuses":[ - "primary" - ] - }, - { - "code":"EMPC", - "name":"EMPC", - "statuses":[ - "primary" - ] - }, - { - "code":"ENRG", - "name":"Energycoin", - "statuses":[ - "primary" - ] - }, - { - "code":"ENT", - "name":"ENT", - "statuses":[ - "primary" - ] - }, - { - "code":"EPC", - "name":"EPC", - "statuses":[ - "primary" - ] - }, - { - "code":"EQM", - "name":"EQM", - "statuses":[ - "primary" - ] - }, - { - "code":"EQUAL", - "name":"EQUAL", - "statuses":[ - "primary" - ] - }, - { - "code":"ERC", - "name":"ERC", - "statuses":[ - "primary" - ] - }, - { - "code":"ERC3", - "name":"ERC3", - "statuses":[ - "primary" - ] - }, - { - "code":"ESB", - "name":"ESB", - "statuses":[ - "secondary" - ] - }, - { - "code":"ESC", - "name":"ESC", - "statuses":[ - "primary" - ] - }, - { - "code":"ESP", - "name":"ESP", - "statuses":[ - "primary" - ] - }, - { - "code":"ETCO", - "name":"ETCO", - "statuses":[ - "primary" - ] - }, - { - "code":"ETH", - "name":"Ethereum", - "statuses":[ - "primary", - "secondary" - ] - }, - { - "code":"ETC", - "name":"Ethereum Classic", - "statuses":[ - "primary" - ] - }, - { - "code":"ETHS", - "name":"ETHS", - "statuses":[ - "primary" - ] - }, - { - "code":"EUC", - "name":"EUC", - "statuses":[ - "primary" - ] - }, - { - "code":"EUR", - "name":"Euro", - "statuses":[ - "primary", - "secondary" - ] - }, - { - "code":"EGC", - "name":"EvergreenCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"EVIL", - "name":"EVIL", - "statuses":[ - "primary" - ] - }, - { - "code":"EXCL", - "name":"EXCL", - "statuses":[ - "primary" - ] - }, - { - "code":"EXP", - "name":"Expanse", - "statuses":[ - "primary" - ] - }, - { - "code":"FCT", - "name":"Factom", - "statuses":[ - "primary" - ] - }, - { - "code":"FAIR", - "name":"Faircoin", - "statuses":[ - "primary" - ] - }, - { - "code":"FC2", - "name":"FC2", - "statuses":[ - "primary" - ] - }, - { - "code":"FCH", - "name":"FCH", - "statuses":[ - "primary" - ] - }, - { - "code":"FCN", - "name":"FCN", - "statuses":[ - "primary" - ] - }, - { - "code":"FCP", - "name":"FCP", - "statuses":[ - "primary" - ] - }, - { - "code":"FTC", - "name":"Feathercoin", - "statuses":[ - "primary" - ] - }, - { - "code":"TIPS", - "name":"Fedoracoin", - "statuses":[ - "primary" - ] - }, - { - "code":"FIND", - "name":"FIND", - "statuses":[ - "primary" - ] - }, - { - "code":"FIT", - "name":"FIT", - "statuses":[ - "primary" - ] - }, - { - "code":"FJC", - "name":"FJC", - "statuses":[ - "primary" - ] - }, - { - "code":"FLO", - "name":"Florincoin", - "statuses":[ - "primary" - ] - }, - { - "code":"FLOZ", - "name":"FLOZ", - "statuses":[ - "primary" - ] - }, - { - "code":"FLT", - "name":"FlutterCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"FLY", - "name":"Flycoin", - "statuses":[ - "primary" - ] - }, - { - "code":"FLDC", - "name":"FoldingCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"FOREX", - "name":"FOREX", - "statuses":[ - "primary" - ] - }, - { - "code":"FRK", - "name":"Franko", - "statuses":[ - "primary" - ] - }, - { - "code":"FRDC", - "name":"FRDC", - "statuses":[ - "primary" - ] - }, - { - "code":"FRC", - "name":"Freicoin", - "statuses":[ - "primary" - ] - }, - { - "code":"FRN", - "name":"FRN", - "statuses":[ - "primary" - ] - }, - { - "code":"FRWC", - "name":"FRWC", - "statuses":[ - "primary" - ] - }, - { - "code":"FSN", - "name":"FSN", - "statuses":[ - "primary" - ] - }, - { - "code":"FST", - "name":"FST", - "statuses":[ - "primary" - ] - }, - { - "code":"FTP", - "name":"FTP", - "statuses":[ - "primary" - ] - }, - { - "code":"FUEL", - "name":"FUEL", - "statuses":[ - "primary" - ] - }, - { - "code":"FUN", - "name":"FUN", - "statuses":[ - "primary" - ] - }, - { - "code":"FUTC", - "name":"FUTC", - "statuses":[ - "primary" - ] - }, - { - "code":"FUZZ", - "name":"FUZZ", - "statuses":[ - "primary" - ] - }, - { - "code":"FX", - "name":"FX", - "statuses":[ - "primary" - ] - }, - { - "code":"GAIA", - "name":"GAIA", - "statuses":[ - "primary" - ] - }, - { - "code":"GAIN", - "name":"GAIN", - "statuses":[ - "primary" - ] - }, - { - "code":"GAKH", - "name":"GAKH", - "statuses":[ - "primary" - ] - }, - { - "code":"GAM", - "name":"GAM", - "statuses":[ - "primary" - ] - }, - { - "code":"GBT", - "name":"GameBet Coin", - "statuses":[ - "primary" - ] - }, - { - "code":"GAME", - "name":"GameCredits", - "statuses":[ - "primary" - ] - }, - { - "code":"GAP", - "name":"Gapcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"GARY", - "name":"GARY", - "statuses":[ - "primary" - ] - }, - { - "code":"GB", - "name":"GB", - "statuses":[ - "primary" - ] - }, - { - "code":"GBC", - "name":"GBC", - "statuses":[ - "primary" - ] - }, - { - "code":"GBIT", - "name":"GBIT", - "statuses":[ - "primary" - ] - }, - { - "code":"GBRC", - "name":"GBRC", - "statuses":[ - "primary" - ] - }, - { - "code":"GCN", - "name":"GCN", - "statuses":[ - "primary" - ] - }, - { - "code":"GENE", - "name":"GENE", - "statuses":[ - "primary" - ] - }, - { - "code":"GEO", - "name":"GeoCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"GEMZ", - "name":"GetGems", - "statuses":[ - "primary" - ] - }, - { - "code":"GHOST", - "name":"GHOST", - "statuses":[ - "primary" - ] - }, - { - "code":"GHS", - "name":"GHS", - "statuses":[ - "primary" - ] - }, - { - "code":"GLC", - "name":"GLC", - "statuses":[ - "primary" - ] - }, - { - "code":"BSTY", - "name":"GlobalBoost-Y", - "statuses":[ - "primary" - ] - }, - { - "code":"GMCX", - "name":"GMCX", - "statuses":[ - "primary" - ] - }, - { - "code":"GML", - "name":"GML", - "statuses":[ - "primary" - ] - }, - { - "code":"GMX", - "name":"GMX", - "statuses":[ - "primary" - ] - }, - { - "code":"GOAT", - "name":"GOAT", - "statuses":[ - "primary" - ] - }, - { - "code":"GCR", - "name":"GoCoineR", - "statuses":[ - "primary" - ] - }, - { - "code":"GLD", - "name":"GoldCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"GOON", - "name":"GOON", - "statuses":[ - "primary" - ] - }, - { - "code":"GOTX", - "name":"GOTX", - "statuses":[ - "primary" - ] - }, - { - "code":"GP", - "name":"GP", - "statuses":[ - "primary" - ] - }, - { - "code":"GPU", - "name":"GPU", - "statuses":[ - "primary" - ] - }, - { - "code":"GRF", - "name":"Graffiti", - "statuses":[ - "primary" - ] - }, - { - "code":"GRAM", - "name":"GRAM", - "statuses":[ - "primary" - ] - }, - { - "code":"GRT", - "name":"Grantcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"GREED", - "name":"GREED", - "statuses":[ - "primary" - ] - }, - { - "code":"GRC", - "name":"Gridcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"GRN", - "name":"GRN", - "statuses":[ - "primary" - ] - }, - { - "code":"GRS", - "name":"Groestlcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"GROW", - "name":"GrowCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"GRW", - "name":"GRW", - "statuses":[ - "primary" - ] - }, - { - "code":"GSY", - "name":"GSY", - "statuses":[ - "primary" - ] - }, - { - "code":"GUA", - "name":"GUA", - "statuses":[ - "primary" - ] - }, - { - "code":"NLG", - "name":"Gulden", - "statuses":[ - "primary" - ] - }, - { - "code":"GUM", - "name":"GUM", - "statuses":[ - "primary" - ] - }, - { - "code":"GUN", - "name":"GUN", - "statuses":[ - "primary" - ] - }, - { - "code":"GYC", - "name":"GYC", - "statuses":[ - "primary" - ] - }, - { - "code":"HALLO", - "name":"HALLO", - "statuses":[ - "primary" - ] - }, - { - "code":"HAM", - "name":"HAM", - "statuses":[ - "primary" - ] - }, - { - "code":"HBT", - "name":"HBT", - "statuses":[ - "secondary" - ] - }, - { - "code":"HCC", - "name":"HCC", - "statuses":[ - "primary" - ] - }, - { - "code":"HEAT", - "name":"HEAT", - "statuses":[ - "primary" - ] - }, - { - "code":"HMP", - "name":"HempCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"XHI", - "name":"HiCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"HILL", - "name":"HILL", - "statuses":[ - "primary" - ] - }, - { - "code":"HODL", - "name":"HOdlcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"HKD", - "name":"Hong Kong Dollar", - "statuses":[ - "secondary" - ] - }, - { - "code":"HZ", - "name":"Horizon", - "statuses":[ - "primary" - ] - }, - { - "code":"HSP", - "name":"HSP", - "statuses":[ - "primary" - ] - }, - { - "code":"HTC", - "name":"HTC", - "statuses":[ - "primary" - ] - }, - { - "code":"HTML5", - "name":"HTMLCOIN", - "statuses":[ - "primary" - ] - }, - { - "code":"HUC", - "name":"HUC", - "statuses":[ - "primary" - ] - }, - { - "code":"HVCO", - "name":"HVCO", - "statuses":[ - "primary" - ] - }, - { - "code":"HXX", - "name":"HXX", - "statuses":[ - "primary" - ] - }, - { - "code":"HYPER", - "name":"Hyper", - "statuses":[ - "primary" - ] - }, - { - "code":"HYP", - "name":"HyperStake", - "statuses":[ - "primary" - ] - }, - { - "code":"IBANK", - "name":"IBANK", - "statuses":[ - "primary" - ] - }, - { - "code":"ICASH", - "name":"iCash", - "statuses":[ - "primary" - ] - }, - { - "code":"ICN", - "name":"iCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"IFLT", - "name":"IFLT", - "statuses":[ - "primary" - ] - }, - { - "code":"IMPS", - "name":"IMPS", - "statuses":[ - "primary" - ] - }, - { - "code":"INCP", - "name":"INCP", - "statuses":[ - "primary" - ] - }, - { - "code":"IFC", - "name":"Infinitecoin", - "statuses":[ - "primary" - ] - }, - { - "code":"INFX", - "name":"Influxcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"IOC", - "name":"IO Coin", - "statuses":[ - "primary" - ] - }, - { - "code":"ION", - "name":"ION", - "statuses":[ - "primary" - ] - }, - { - "code":"ISL", - "name":"IslaCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"IVZ", - "name":"IVZ", - "statuses":[ - "primary" - ] - }, - { - "code":"IXC", - "name":"IXC", - "statuses":[ - "primary" - ] - }, - { - "code":"JPY", - "name":"Japanese Yen", - "statuses":[ - "secondary" - ] - }, - { - "code":"JOBS", - "name":"JOBS", - "statuses":[ - "primary" - ] - }, - { - "code":"JPC", - "name":"JPC", - "statuses":[ - "primary" - ] - }, - { - "code":"JBS", - "name":"Jumbucks", - "statuses":[ - "primary" - ] - }, - { - "code":"JW", - "name":"JW", - "statuses":[ - "primary" - ] - }, - { - "code":"JWL", - "name":"JWL", - "statuses":[ - "primary" - ] - }, - { - "code":"KAT", - "name":"KAT", - "statuses":[ - "primary" - ] - }, - { - "code":"KC", - "name":"KC", - "statuses":[ - "primary" - ] - }, - { - "code":"KNC", - "name":"KhanCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"KLC", - "name":"KLC", - "statuses":[ - "primary" - ] - }, - { - "code":"KOBO", - "name":"KOBO", - "statuses":[ - "primary" - ] - }, - { - "code":"KORE", - "name":"KoreCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"KRAK", - "name":"KRAK", - "statuses":[ - "primary" - ] - }, - { - "code":"KRB", - "name":"KRB", - "statuses":[ - "primary" - ] - }, - { - "code":"KRC", - "name":"KRC", - "statuses":[ - "primary" - ] - }, - { - "code":"KRYP", - "name":"KRYP", - "statuses":[ - "primary" - ] - }, - { - "code":"KR", - "name":"Krypton", - "statuses":[ - "primary" - ] - }, - { - "code":"KTK", - "name":"KTK", - "statuses":[ - "primary" - ] - }, - { - "code":"LANA", - "name":"LANA", - "statuses":[ - "primary" - ] - }, - { - "code":"LAZ", - "name":"LAZ", - "statuses":[ - "primary" - ] - }, - { - "code":"LBC", - "name":"LBC", - "statuses":[ - "primary" - ] - }, - { - "code":"LC", - "name":"LC", - "statuses":[ - "primary" - ] - }, - { - "code":"LEA", - "name":"LeaCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"LEAF", - "name":"LEAF", - "statuses":[ - "primary" - ] - }, - { - "code":"LEO", - "name":"LEO", - "statuses":[ - "primary", - "secondary" - ] - }, - { - "code":"LFC", - "name":"LFC", - "statuses":[ - "primary" - ] - }, - { - "code":"LFO", - "name":"LFO", - "statuses":[ - "primary" - ] - }, - { - "code":"LFTC", - "name":"LFTC", - "statuses":[ - "primary" - ] - }, - { - "code":"LGBTQ", - "name":"LGBTQ", - "statuses":[ - "primary" - ] - }, - { - "code":"LIR", - "name":"LIR", - "statuses":[ - "primary" - ] - }, - { - "code":"LSK", - "name":"Lisk", - "statuses":[ - "primary" - ] - }, - { - "code":"LTC", - "name":"Litecoin", - "statuses":[ - "primary", - "secondary" - ] - }, - { - "code":"LTCR", - "name":"Litecred", - "statuses":[ - "primary" - ] - }, - { - "code":"LIV", - "name":"LIV", - "statuses":[ - "primary" - ] - }, - { - "code":"LKC", - "name":"LKC", - "statuses":[ - "primary" - ] - }, - { - "code":"LOC", - "name":"LOC", - "statuses":[ - "primary" - ] - }, - { - "code":"LOOT", - "name":"LOOT", - "statuses":[ - "primary" - ] - }, - { - "code":"LTBC", - "name":"LTBcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"LTH", - "name":"LTH", - "statuses":[ - "primary" - ] - }, - { - "code":"LTS", - "name":"LTS", - "statuses":[ - "primary" - ] - }, - { - "code":"LUCKY", - "name":"LUCKY", - "statuses":[ - "primary" - ] - }, - { - "code":"LUN", - "name":"LUN", - "statuses":[ - "primary" - ] - }, - { - "code":"LXC", - "name":"LXC", - "statuses":[ - "primary" - ] - }, - { - "code":"MAD", - "name":"MAD", - "statuses":[ - "primary" - ] - }, - { - "code":"XMG", - "name":"Magi", - "statuses":[ - "primary" - ] - }, - { - "code":"MAID", - "name":"MaidSafeCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"MXT", - "name":"MarteXcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"OMNI", - "name":"Mastercoin (Omni)", - "statuses":[ - "primary" - ] - }, - { - "code":"MTR", - "name":"MasterTraderCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"MAX", - "name":"Maxcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"MZC", - "name":"Mazacoin", - "statuses":[ - "primary" - ] - }, - { - "code":"MBL", - "name":"MBL", - "statuses":[ - "primary" - ] - }, - { - "code":"MCZ", - "name":"MCZ", - "statuses":[ - "primary" - ] - }, - { - "code":"MED", - "name":"MediterraneanCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"MEGA", - "name":"MEGA", - "statuses":[ - "primary" - ] - }, - { - "code":"MEC", - "name":"Megacoin", - "statuses":[ - "primary" - ] - }, - { - "code":"MEME", - "name":"Memetic", - "statuses":[ - "primary" - ] - }, - { - "code":"METAL", - "name":"METAL", - "statuses":[ - "primary" - ] - }, - { - "code":"MG", - "name":"MG", - "statuses":[ - "primary" - ] - }, - { - "code":"MND", - "name":"MindCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"MINT", - "name":"Mintcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"MIS", - "name":"MIS", - "statuses":[ - "primary" - ] - }, - { - "code":"MMNXT", - "name":"MMNXT", - "statuses":[ - "primary" - ] - }, - { - "code":"MMXVI", - "name":"MMXVI", - "statuses":[ - "primary" - ] - }, - { - "code":"MNM", - "name":"MNM", - "statuses":[ - "primary" - ] - }, - { - "code":"MOIN", - "name":"MOIN", - "statuses":[ - "primary" - ] - }, - { - "code":"MOJO", - "name":"MojoCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"MONA", - "name":"MonaCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"XMR", - "name":"Monero", - "statuses":[ - "primary", - "secondary" - ] - }, - { - "code":"MUE", - "name":"MonetaryUnit", - "statuses":[ - "primary" - ] - }, - { - "code":"MOON", - "name":"Mooncoin", - "statuses":[ - "primary" - ] - }, - { - "code":"MOOND", - "name":"MOOND", - "statuses":[ - "primary" - ] - }, - { - "code":"MPRO", - "name":"MPRO", - "statuses":[ - "primary" - ] - }, - { - "code":"MRB", - "name":"MRB", - "statuses":[ - "primary" - ] - }, - { - "code":"MUDRA", - "name":"MUDRA", - "statuses":[ - "primary" - ] - }, - { - "code":"MYR", - "name":"Myriadcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"N2O", - "name":"N2O", - "statuses":[ - "primary" - ] - }, - { - "code":"N7", - "name":"N7", - "statuses":[ - "primary" - ] - }, - { - "code":"NMC", - "name":"Namecoin", - "statuses":[ - "primary" - ] - }, - { - "code":"NAT", - "name":"NAT", - "statuses":[ - "primary" - ] - }, - { - "code":"NAUT", - "name":"Nautiluscoin", - "statuses":[ - "primary" - ] - }, - { - "code":"NAV", - "name":"NAV Coin", - "statuses":[ - "primary" - ] - }, - { - "code":"NBIT", - "name":"NBIT", - "statuses":[ - "primary" - ] - }, - { - "code":"NCS", - "name":"NCS", - "statuses":[ - "primary" - ] - }, - { - "code":"NDOGE", - "name":"NDOGE", - "statuses":[ - "primary" - ] - }, - { - "code":"XEM", - "name":"NEM", - "statuses":[ - "primary" - ] - }, - { - "code":"NEOS", - "name":"NeosCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"NET", - "name":"NetCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"NEU", - "name":"NeuCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"NTRN", - "name":"Neutron", - "statuses":[ - "primary" - ] - }, - { - "code":"NEVA", - "name":"NevaCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"NEWB", - "name":"NEWB", - "statuses":[ - "primary" - ] - }, - { - "code":"NXS", - "name":"Nexus", - "statuses":[ - "primary" - ] - }, - { - "code":"NIC", - "name":"NIC", - "statuses":[ - "primary" - ] - }, - { - "code":"NICE", - "name":"NICE", - "statuses":[ - "primary" - ] - }, - { - "code":"NKC", - "name":"NKC", - "statuses":[ - "primary" - ] - }, - { - "code":"NLC", - "name":"NLC", - "statuses":[ - "primary" - ] - }, - { - "code":"NOBL", - "name":"NobleCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"NODES", - "name":"NODES", - "statuses":[ - "primary" - ] - }, - { - "code":"NVC", - "name":"Novacoin", - "statuses":[ - "primary" - ] - }, - { - "code":"NRS", - "name":"NRS", - "statuses":[ - "primary" - ] - }, - { - "code":"NTC", - "name":"NTC", - "statuses":[ - "primary" - ] - }, - { - "code":"NBT", - "name":"NuBits", - "statuses":[ - "primary" - ] - }, - { - "code":"NUKE", - "name":"NUKE", - "statuses":[ - "primary" - ] - }, - { - "code":"NUM", - "name":"NUM", - "statuses":[ - "primary" - ] - }, - { - "code":"NSR", - "name":"NuShares", - "statuses":[ - "primary" - ] - }, - { - "code":"NXE", - "name":"NXE", - "statuses":[ - "primary" - ] - }, - { - "code":"NXT", - "name":"NXT", - "statuses":[ - "primary" - ] - }, - { - "code":"NXTTY", - "name":"Nxttycoin", - "statuses":[ - "primary" - ] - }, - { - "code":"NYC", - "name":"NYC", - "statuses":[ - "primary" - ] - }, - { - "code":"NZC", - "name":"NZC", - "statuses":[ - "primary" - ] - }, - { - "code":"NZD", - "name":"NZD", - "statuses":[ - "primary", - "secondary" - ] - }, - { - "code":"OBS", - "name":"OBS", - "statuses":[ - "primary" - ] - }, - { - "code":"OCOW", - "name":"OCOW", - "statuses":[ - "primary" - ] - }, - { - "code":"OK", - "name":"OKCash", - "statuses":[ - "primary" - ] - }, - { - "code":"OLYMP", - "name":"OLYMP", - "statuses":[ - "primary" - ] - }, - { - "code":"OMC", - "name":"OMC", - "statuses":[ - "primary" - ] - }, - { - "code":"ONE", - "name":"ONE", - "statuses":[ - "primary" - ] - }, - { - "code":"OP", - "name":"OP", - "statuses":[ - "primary" - ] - }, - { - "code":"OPAL", - "name":"OPAL", - "statuses":[ - "primary" - ] - }, - { - "code":"ORB", - "name":"Orbitcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"OZC", - "name":"OZC", - "statuses":[ - "primary" - ] - }, - { - "code":"PAC", - "name":"PAC", - "statuses":[ - "primary" - ] - }, - { - "code":"PAL", - "name":"PAL", - "statuses":[ - "primary" - ] - }, - { - "code":"PND", - "name":"Pandacoin", - "statuses":[ - "primary" - ] - }, - { - "code":"PARA", - "name":"PARA", - "statuses":[ - "primary" - ] - }, - { - "code":"PAY", - "name":"PAY", - "statuses":[ - "primary" - ] - }, - { - "code":"XPY", - "name":"Paycoin", - "statuses":[ - "primary" - ] - }, - { - "code":"PBC", - "name":"PBC", - "statuses":[ - "primary" - ] - }, - { - "code":"PCM", - "name":"PCM", - "statuses":[ - "primary" - ] - }, - { - "code":"PCS", - "name":"PCS", - "statuses":[ - "primary" - ] - }, - { - "code":"PDC", - "name":"PDC", - "statuses":[ - "primary" - ] - }, - { - "code":"PEC", - "name":"PEC", - "statuses":[ - "primary" - ] - }, - { - "code":"PPC", - "name":"Peercoin", - "statuses":[ - "primary" - ] - }, - { - "code":"PEN", - "name":"PEN", - "statuses":[ - "primary" - ] - }, - { - "code":"PHR", - "name":"PHR", - "statuses":[ - "primary" - ] - }, - { - "code":"PIN", - "name":"PIN", - "statuses":[ - "primary" - ] - }, - { - "code":"PC", - "name":"Pinkcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"PIO", - "name":"PIO", - "statuses":[ - "primary" - ] - }, - { - "code":"PIZZA", - "name":"PIZZA", - "statuses":[ - "primary" - ] - }, - { - "code":"PKB", - "name":"PKB", - "statuses":[ - "primary" - ] - }, - { - "code":"PLN", - "name":"PLN", - "statuses":[ - "primary", - "secondary" - ] - }, - { - "code":"PLNC", - "name":"PLNC", - "statuses":[ - "primary" - ] - }, - { - "code":"PNK", - "name":"PNK", - "statuses":[ - "primary" - ] - }, - { - "code":"POKE", - "name":"POKE", - "statuses":[ - "primary" - ] - }, - { - "code":"PONZ2", - "name":"PONZ2", - "statuses":[ - "primary" - ] - }, - { - "code":"PONZI", - "name":"PONZI", - "statuses":[ - "primary" - ] - }, - { - "code":"PEX", - "name":"PosEx", - "statuses":[ - "primary" - ] - }, - { - "code":"POST", - "name":"POST", - "statuses":[ - "primary" - ] - }, - { - "code":"POT", - "name":"Potcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"PRE", - "name":"PRE", - "statuses":[ - "primary" - ] - }, - { - "code":"PRES", - "name":"PRES", - "statuses":[ - "primary" - ] - }, - { - "code":"PXI", - "name":"Prime-XI", - "statuses":[ - "primary" - ] - }, - { - "code":"PRIME", - "name":"PrimeChain", - "statuses":[ - "primary" - ] - }, - { - "code":"XPM", - "name":"Primecoin", - "statuses":[ - "primary" - ] - }, - { - "code":"PRM", - "name":"PRM", - "statuses":[ - "primary" - ] - }, - { - "code":"PRT", - "name":"PRT", - "statuses":[ - "primary" - ] - }, - { - "code":"PSB", - "name":"PSB", - "statuses":[ - "primary" - ] - }, - { - "code":"PSP", - "name":"PSP", - "statuses":[ - "primary" - ] - }, - { - "code":"PSY", - "name":"PSY", - "statuses":[ - "primary" - ] - }, - { - "code":"PTC", - "name":"PTC", - "statuses":[ - "primary" - ] - }, - { - "code":"PURE", - "name":"PURE", - "statuses":[ - "primary" - ] - }, - { - "code":"PUTIN", - "name":"PUTIN", - "statuses":[ - "primary" - ] - }, - { - "code":"PWR", - "name":"PWR", - "statuses":[ - "primary" - ] - }, - { - "code":"PX", - "name":"PX", - "statuses":[ - "primary" - ] - }, - { - "code":"PXL", - "name":"PXL", - "statuses":[ - "primary" - ] - }, - { - "code":"QBC", - "name":"QBC", - "statuses":[ - "primary" - ] - }, - { - "code":"QBK", - "name":"QBK", - "statuses":[ - "primary" - ] - }, - { - "code":"QCN", - "name":"QCN", - "statuses":[ - "primary" - ] - }, - { - "code":"QORA", - "name":"Qora", - "statuses":[ - "primary" - ] - }, - { - "code":"QTZ", - "name":"QTZ", - "statuses":[ - "primary" - ] - }, - { - "code":"QRK", - "name":"Quark", - "statuses":[ - "primary" - ] - }, - { - "code":"QTL", - "name":"Quatloo", - "statuses":[ - "primary" - ] - }, - { - "code":"RADI", - "name":"RADI", - "statuses":[ - "primary" - ] - }, - { - "code":"RADS", - "name":"Radium", - "statuses":[ - "primary" - ] - }, - { - "code":"XRA", - "name":"RateCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"RBIT", - "name":"RBIT", - "statuses":[ - "primary" - ] - }, - { - "code":"RCN", - "name":"RCN", - "statuses":[ - "primary" - ] - }, - { - "code":"RED", - "name":"RED", - "statuses":[ - "primary" - ] - }, - { - "code":"RDD", - "name":"Reddcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"REE", - "name":"REE", - "statuses":[ - "primary" - ] - }, - { - "code":"REV", - "name":"Revenu", - "statuses":[ - "primary" - ] - }, - { - "code":"RICHX", - "name":"RICHX", - "statuses":[ - "primary" - ] - }, - { - "code":"RIC", - "name":"Riecoin", - "statuses":[ - "primary" - ] - }, - { - "code":"RBT", - "name":"Rimbit", - "statuses":[ - "primary", - "secondary" - ] - }, - { - "code":"RIO", - "name":"RIO", - "statuses":[ - "primary" - ] - }, - { - "code":"XRP", - "name":"Ripple", - "statuses":[ - "primary" - ] - }, - { - "code":"RISE", - "name":"RISE", - "statuses":[ - "primary" - ] - }, - { - "code":"RMS", - "name":"RMS", - "statuses":[ - "primary" - ] - }, - { - "code":"RONIN", - "name":"RONIN", - "statuses":[ - "primary" - ] - }, - { - "code":"ROYAL", - "name":"ROYAL", - "statuses":[ - "primary" - ] - }, - { - "code":"RPC", - "name":"RPC", - "statuses":[ - "primary" - ] - }, - { - "code":"RRT", - "name":"RRT", - "statuses":[ - "primary" - ] - }, - { - "code":"RBIES", - "name":"Rubies", - "statuses":[ - "primary" - ] - }, - { - "code":"RUBIT", - "name":"RUBIT", - "statuses":[ - "primary" - ] - }, - { - "code":"RUR", - "name":"Ruble", - "statuses":[ - "secondary" - ] - }, - { - "code":"RBY", - "name":"Rubycoin", - "statuses":[ - "primary" - ] - }, - { - "code":"RUST", - "name":"RUST", - "statuses":[ - "primary" - ] - }, - { - "code":"RYCN", - "name":"RYCN", - "statuses":[ - "primary" - ] - }, - { - "code":"SEC", - "name":"Safe Exchange Coin", - "statuses":[ - "primary" - ] - }, - { - "code":"SAK", - "name":"SAK", - "statuses":[ - "primary" - ] - }, - { - "code":"SAR", - "name":"SAR", - "statuses":[ - "primary" - ] - }, - { - "code":"SBD", - "name":"SBD", - "statuses":[ - "primary" - ] - }, - { - "code":"SCAN", - "name":"SCAN", - "statuses":[ - "primary" - ] - }, - { - "code":"SCB", - "name":"SCB", - "statuses":[ - "primary" - ] - }, - { - "code":"SCN", - "name":"SCN", - "statuses":[ - "primary" - ] - }, - { - "code":"SCOT", - "name":"Scotcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"SCRPT", - "name":"SCRPT", - "statuses":[ - "primary" - ] - }, - { - "code":"SCRT", - "name":"SCRT", - "statuses":[ - "primary" - ] - }, - { - "code":"SCT", - "name":"SCT", - "statuses":[ - "primary" - ] - }, - { - "code":"SRC", - "name":"SecureCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"SED", - "name":"SED", - "statuses":[ - "primary" - ] - }, - { - "code":"SXC", - "name":"Sexcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"SGD", - "name":"SGD", - "statuses":[ - "primary", - "secondary" - ] - }, - { - "code":"SH", - "name":"SH", - "statuses":[ - "primary" - ] - }, - { - "code":"SDC", - "name":"ShadowCash", - "statuses":[ - "primary" - ] - }, - { - "code":"SHELL", - "name":"SHELL", - "statuses":[ - "primary" - ] - }, - { - "code":"SHI", - "name":"SHI", - "statuses":[ - "primary" - ] - }, - { - "code":"SHIFT", - "name":"Shift", - "statuses":[ - "primary" - ] - }, - { - "code":"SC", - "name":"Siacoin", - "statuses":[ - "primary" - ] - }, - { - "code":"SIB", - "name":"Siberian chervonets", - "statuses":[ - "primary" - ] - }, - { - "code":"SIGU", - "name":"SIGU", - "statuses":[ - "primary" - ] - }, - { - "code":"SLFI", - "name":"SLFI", - "statuses":[ - "primary" - ] - }, - { - "code":"SLING", - "name":"Sling", - "statuses":[ - "primary" - ] - }, - { - "code":"SLK", - "name":"SLK", - "statuses":[ - "primary" - ] - }, - { - "code":"SLS", - "name":"SLS", - "statuses":[ - "primary" - ] - }, - { - "code":"SMC", - "name":"SMC", - "statuses":[ - "primary" - ] - }, - { - "code":"SMLY", - "name":"SmileyCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"SNGLS", - "name":"SNGLS", - "statuses":[ - "primary" - ] - }, - { - "code":"SNRG", - "name":"SNRG", - "statuses":[ - "primary" - ] - }, - { - "code":"SOIL", - "name":"SOILcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"SLR", - "name":"Solarcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"SONG", - "name":"SongCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"SOON", - "name":"SOON", - "statuses":[ - "primary" - ] - }, - { - "code":"SP", - "name":"SP", - "statuses":[ - "primary" - ] - }, - { - "code":"SPACE", - "name":"SPACE", - "statuses":[ - "primary" - ] - }, - { - "code":"SPEX", - "name":"SPEX", - "statuses":[ - "primary" - ] - }, - { - "code":"SPHR", - "name":"Sphere", - "statuses":[ - "primary" - ] - }, - { - "code":"SPKTR", - "name":"SPKTR", - "statuses":[ - "primary" - ] - }, - { - "code":"SPN", - "name":"SPN", - "statuses":[ - "primary" - ] - }, - { - "code":"SPORT", - "name":"SPORT", - "statuses":[ - "primary" - ] - }, - { - "code":"SPR", - "name":"SpreadCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"SPT", - "name":"SPT", - "statuses":[ - "primary" - ] - }, - { - "code":"SPX", - "name":"SPX", - "statuses":[ - "primary" - ] - }, - { - "code":"SSC", - "name":"SSC", - "statuses":[ - "primary" - ] - }, - { - "code":"STA", - "name":"STA", - "statuses":[ - "primary" - ] - }, - { - "code":"STAR", - "name":"STAR", - "statuses":[ - "primary" - ] - }, - { - "code":"START", - "name":"Startcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"STE", - "name":"STE", - "statuses":[ - "primary" - ] - }, - { - "code":"XST", - "name":"Stealthcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"STEEM", - "name":"Steem", - "statuses":[ - "primary" - ] - }, - { - "code":"XLM", - "name":"Stellar", - "statuses":[ - "primary" - ] - }, - { - "code":"STR", - "name":"Stellar", - "statuses":[ - "primary" - ] - }, - { - "code":"STEPS", - "name":"Steps", - "statuses":[ - "primary" - ] - }, - { - "code":"SLG", - "name":"Sterlingcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"STHR", - "name":"STHR", - "statuses":[ - "primary" - ] - }, - { - "code":"STL", - "name":"STL", - "statuses":[ - "primary" - ] - }, - { - "code":"STO", - "name":"STO", - "statuses":[ - "primary" - ] - }, - { - "code":"SJCX", - "name":"Storjcoin X", - "statuses":[ - "primary" - ] - }, - { - "code":"STP", - "name":"STP", - "statuses":[ - "primary" - ] - }, - { - "code":"STRAT", - "name":"STRAT", - "statuses":[ - "primary" - ] - }, - { - "code":"STS", - "name":"Stress", - "statuses":[ - "primary" - ] - }, - { - "code":"STV", - "name":"STV", - "statuses":[ - "primary" - ] - }, - { - "code":"SUB", - "name":"Subcriptio", - "statuses":[ - "primary" - ] - }, - { - "code":"UNITY", - "name":"SuperNET", - "statuses":[ - "primary" - ] - }, - { - "code":"SWEET", - "name":"SWEET", - "statuses":[ - "primary" - ] - }, - { - "code":"SWING", - "name":"SWING", - "statuses":[ - "primary" - ] - }, - { - "code":"SYNC", - "name":"SYNC", - "statuses":[ - "primary" - ] - }, - { - "code":"AMP", - "name":"Synereo", - "statuses":[ - "primary" - ] - }, - { - "code":"SYNX", - "name":"SYNX", - "statuses":[ - "primary" - ] - }, - { - "code":"SYS", - "name":"Syscoin", - "statuses":[ - "primary" - ] - }, - { - "code":"TAB", - "name":"TAB", - "statuses":[ - "primary" - ] - }, - { - "code":"TAG", - "name":"TagCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"TAJ", - "name":"TAJ", - "statuses":[ - "primary" - ] - }, - { - "code":"TAK", - "name":"TAK", - "statuses":[ - "primary" - ] - }, - { - "code":"TAO", - "name":"TAO", - "statuses":[ - "primary" - ] - }, - { - "code":"TBC", - "name":"TBC", - "statuses":[ - "primary" - ] - }, - { - "code":"TC", - "name":"TC", - "statuses":[ - "secondary" - ] - }, - { - "code":"TCOIN", - "name":"TCOIN", - "statuses":[ - "primary" - ] - }, - { - "code":"TCR", - "name":"TCR", - "statuses":[ - "primary" - ] - }, - { - "code":"TDFB", - "name":"TDFB", - "statuses":[ - "primary" - ] - }, - { - "code":"TDY", - "name":"TDY", - "statuses":[ - "primary" - ] - }, - { - "code":"TEAM", - "name":"TEAM", - "statuses":[ - "primary" - ] - }, - { - "code":"TEC", - "name":"TEC", - "statuses":[ - "primary" - ] - }, - { - "code":"TECH", - "name":"TECH", - "statuses":[ - "primary" - ] - }, - { - "code":"TEK", - "name":"TEKcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"TRC", - "name":"Terracoin", - "statuses":[ - "primary" - ] - }, - { - "code":"TESLA", - "name":"TESLA", - "statuses":[ - "primary" - ] - }, - { - "code":"TES", - "name":"TeslaCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"TET", - "name":"TET", - "statuses":[ - "primary" - ] - }, - { - "code":"THC", - "name":"THC", - "statuses":[ - "primary" - ] - }, - { - "code":"DAO", - "name":"The DAO", - "statuses":[ - "primary" - ] - }, - { - "code":"TIA", - "name":"TIA", - "statuses":[ - "primary" - ] - }, - { - "code":"TIX", - "name":"Tickets", - "statuses":[ - "primary" - ] - }, - { - "code":"XTC", - "name":"TileCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"TIT", - "name":"Titcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"TMC", - "name":"TMC", - "statuses":[ - "primary" - ] - }, - { - "code":"TNG", - "name":"TNG", - "statuses":[ - "primary" - ] - }, - { - "code":"TODAY", - "name":"TODAY", - "statuses":[ - "primary" - ] - }, - { - "code":"TOKEN", - "name":"TOKEN", - "statuses":[ - "primary" - ] - }, - { - "code":"TP1", - "name":"TP1", - "statuses":[ - "primary" - ] - }, - { - "code":"TPC", - "name":"TPC", - "statuses":[ - "primary" - ] - }, - { - "code":"TPG", - "name":"TPG", - "statuses":[ - "primary" - ] - }, - { - "code":"TX", - "name":"Transfercoin", - "statuses":[ - "primary" - ] - }, - { - "code":"TRAP", - "name":"TRAP", - "statuses":[ - "primary" - ] - }, - { - "code":"TRICK", - "name":"TRICK", - "statuses":[ - "primary" - ] - }, - { - "code":"TRIG", - "name":"TRIG", - "statuses":[ - "primary" - ] - }, - { - "code":"TROLL", - "name":"TROLL", - "statuses":[ - "primary" - ] - }, - { - "code":"TRK", - "name":"Truckcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"TRUMP", - "name":"TrumpCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"TRUST", - "name":"TRUST", - "statuses":[ - "primary" - ] - }, - { - "code":"TSC", - "name":"TSC", - "statuses":[ - "primary" - ] - }, - { - "code":"TWERK", - "name":"TWERK", - "statuses":[ - "primary" - ] - }, - { - "code":"TWIST", - "name":"TWIST", - "statuses":[ - "primary" - ] - }, - { - "code":"TWO", - "name":"TWO", - "statuses":[ - "primary" - ] - }, - { - "code":"UAE", - "name":"UAE", - "statuses":[ - "primary" - ] - }, - { - "code":"UB", - "name":"UB", - "statuses":[ - "primary" - ] - }, - { - "code":"UFO", - "name":"UFO Coin", - "statuses":[ - "primary" - ] - }, - { - "code":"UIS", - "name":"UIS", - "statuses":[ - "primary" - ] - }, - { - "code":"UAH", - "name":"Ukrainian Hryvnia", - "statuses":[ - "secondary" - ] - }, - { - "code":"UTC", - "name":"UltraCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"UNB", - "name":"UNB", - "statuses":[ - "primary" - ] - }, - { - "code":"UNC", - "name":"UNC", - "statuses":[ - "primary" - ] - }, - { - "code":"UNF", - "name":"Unfed", - "statuses":[ - "primary" - ] - }, - { - "code":"UNIQ", - "name":"UNIQ", - "statuses":[ - "primary" - ] - }, - { - "code":"UNIT", - "name":"Universal Currency", - "statuses":[ - "primary" - ] - }, - { - "code":"UNO", - "name":"Unobtanium", - "statuses":[ - "primary" - ] - }, - { - "code":"URC", - "name":"URC", - "statuses":[ - "primary" - ] - }, - { - "code":"URO", - "name":"Uro", - "statuses":[ - "primary" - ] - }, - { - "code":"USD", - "name":"US Dollar", - "statuses":[ - "primary", - "secondary" - ] - }, - { - "code":"USDE", - "name":"USDE", - "statuses":[ - "primary" - ] - }, - { - "code":"XVC", - "name":"Vcash", - "statuses":[ - "primary" - ] - }, - { - "code":"VCN", - "name":"VCN", - "statuses":[ - "primary" - ] - }, - { - "code":"VCOIN", - "name":"VCOIN", - "statuses":[ - "primary" - ] - }, - { - "code":"VEC", - "name":"VEC", - "statuses":[ - "primary" - ] - }, - { - "code":"VEG", - "name":"VEG", - "statuses":[ - "primary" - ] - }, - { - "code":"XVG", - "name":"Verge", - "statuses":[ - "primary" - ] - }, - { - "code":"VRC", - "name":"VeriCoin", - "statuses":[ - "primary", - "secondary" - ] - }, - { - "code":"VTC", - "name":"Vertcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"VIA", - "name":"Viacoin", - "statuses":[ - "primary" - ] - }, - { - "code":"VIP", - "name":"VIP Tokens", - "statuses":[ - "primary" - ] - }, - { - "code":"VIRAL", - "name":"Viral", - "statuses":[ - "primary" - ] - }, - { - "code":"VLT", - "name":"VLT", - "statuses":[ - "primary" - ] - }, - { - "code":"VOOT", - "name":"VootCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"VOX", - "name":"Voxels", - "statuses":[ - "primary" - ] - }, - { - "code":"VOYA", - "name":"VOYA", - "statuses":[ - "primary" - ] - }, - { - "code":"VPN", - "name":"VPNCoin", - "statuses":[ - "primary" - ] - }, - { - "code":"VRM", - "name":"VRM", - "statuses":[ - "primary" - ] - }, - { - "code":"VRS", - "name":"VRS", - "statuses":[ - "primary" - ] - }, - { - "code":"VTA", - "name":"VTA", - "statuses":[ - "primary" - ] - }, - { - "code":"VTN", - "name":"VTN", - "statuses":[ - "primary" - ] - }, - { - "code":"VTR", - "name":"VTR", - "statuses":[ - "primary" - ] - }, - { - "code":"VTY", - "name":"VTY", - "statuses":[ - "primary" - ] - }, - { - "code":"WA", - "name":"WA", - "statuses":[ - "primary" - ] - }, - { - "code":"WAC", - "name":"WAC", - "statuses":[ - "primary" - ] - }, - { - "code":"WARP", - "name":"WARP", - "statuses":[ - "primary" - ] - }, - { - "code":"WASH", - "name":"WASH", - "statuses":[ - "primary" - ] - }, - { - "code":"WAV", - "name":"WAV", - "statuses":[ - "primary" - ] - }, - { - "code":"WAVES", - "name":"WAVES", - "statuses":[ - "primary" - ] - }, - { - "code":"WAY", - "name":"WAY", - "statuses":[ - "primary" - ] - }, - { - "code":"WCN", - "name":"WCN", - "statuses":[ - "primary" - ] - }, - { - "code":"WEX", - "name":"WEX", - "statuses":[ - "primary" - ] - }, - { - "code":"WGC", - "name":"WGC", - "statuses":[ - "primary" - ] - }, - { - "code":"XWC", - "name":"Whitecoin", - "statuses":[ - "primary" - ] - }, - { - "code":"WBB", - "name":"Wild Beast Block", - "statuses":[ - "primary" - ] - }, - { - "code":"WINE", - "name":"WINE", - "statuses":[ - "primary" - ] - }, - { - "code":"WLC", - "name":"WLC", - "statuses":[ - "primary" - ] - }, - { - "code":"WMC", - "name":"WMC", - "statuses":[ - "primary" - ] - }, - { - "code":"LOG", - "name":"Woodcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"WDC", - "name":"Worldcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"WRP", - "name":"WRP", - "statuses":[ - "primary" - ] - }, - { - "code":"X2", - "name":"X2", - "statuses":[ - "primary" - ] - }, - { - "code":"X2C", - "name":"X2C", - "statuses":[ - "primary" - ] - }, - { - "code":"XAB", - "name":"XAB", - "statuses":[ - "primary" - ] - }, - { - "code":"XAUR", - "name":"XAUR", - "statuses":[ - "primary" - ] - }, - { - "code":"XAU", - "name":"Xaurum", - "statuses":[ - "primary" - ] - }, - { - "code":"XBS", - "name":"XBS", - "statuses":[ - "primary" - ] - }, - { - "code":"XBTS", - "name":"XBTS", - "statuses":[ - "primary" - ] - }, - { - "code":"XBU", - "name":"XBU", - "statuses":[ - "primary" - ] - }, - { - "code":"XCO", - "name":"XCO", - "statuses":[ - "primary" - ] - }, - { - "code":"XC", - "name":"XCurrency", - "statuses":[ - "primary" - ] - }, - { - "code":"XDB", - "name":"XDB", - "statuses":[ - "primary" - ] - }, - { - "code":"XDE2", - "name":"XDE2", - "statuses":[ - "primary" - ] - }, - { - "code":"MI", - "name":"Xiaomicoin", - "statuses":[ - "primary" - ] - }, - { - "code":"XID", - "name":"XID", - "statuses":[ - "primary" - ] - }, - { - "code":"XJO", - "name":"XJO", - "statuses":[ - "primary" - ] - }, - { - "code":"XLTCG", - "name":"XLTCG", - "statuses":[ - "primary" - ] - }, - { - "code":"XMINE", - "name":"XMINE", - "statuses":[ - "primary" - ] - }, - { - "code":"XMS", - "name":"XMS", - "statuses":[ - "primary" - ] - }, - { - "code":"XNG", - "name":"XNG", - "statuses":[ - "primary" - ] - }, - { - "code":"XODUS", - "name":"XODUS", - "statuses":[ - "primary" - ] - }, - { - "code":"XPC", - "name":"XPC", - "statuses":[ - "primary" - ] - }, - { - "code":"XPO", - "name":"XPO", - "statuses":[ - "primary" - ] - }, - { - "code":"XPOKE", - "name":"XPOKE", - "statuses":[ - "primary" - ] - }, - { - "code":"XPRO", - "name":"XPRO", - "statuses":[ - "primary" - ] - }, - { - "code":"XPTX", - "name":"XPTX", - "statuses":[ - "primary" - ] - }, - { - "code":"XQN", - "name":"XQN", - "statuses":[ - "primary" - ] - }, - { - "code":"XRC", - "name":"XRC", - "statuses":[ - "primary" - ] - }, - { - "code":"XSEED", - "name":"XSEED", - "statuses":[ - "primary" - ] - }, - { - "code":"XSY", - "name":"XSY", - "statuses":[ - "primary" - ] - }, - { - "code":"XTP", - "name":"XTP", - "statuses":[ - "primary" - ] - }, - { - "code":"XUP", - "name":"XUP", - "statuses":[ - "primary" - ] - }, - { - "code":"YAC", - "name":"Yacoin", - "statuses":[ - "primary" - ] - }, - { - "code":"YAY", - "name":"YAY", - "statuses":[ - "primary" - ] - }, - { - "code":"YBC", - "name":"Ybcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"YMC", - "name":"YMC", - "statuses":[ - "primary" - ] - }, - { - "code":"YOC", - "name":"YOC", - "statuses":[ - "primary" - ] - }, - { - "code":"YOVI", - "name":"YOVI", - "statuses":[ - "primary" - ] - }, - { - "code":"YUM", - "name":"YUM", - "statuses":[ - "primary" - ] - }, - { - "code":"ZEC", - "name":"Zcash", - "statuses":[ - "primary" - ] - }, - { - "code":"ZCL", - "name":"Zcash classic", - "statuses":[ - "primary" - ] - }, - { - "code":"ZCC", - "name":"ZCC", - "statuses":[ - "primary" - ] - }, - { - "code":"ZCOIN", - "name":"ZCOIN", - "statuses":[ - "primary" - ] - }, - { - "code":"XZC", - "name":"Zcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"ZECD", - "name":"ZECD", - "statuses":[ - "primary" - ] - }, - { - "code":"ZEIT", - "name":"Zeitcoin", - "statuses":[ - "primary" - ] - }, - { - "code":"ZET2", - "name":"ZET2", - "statuses":[ - "primary" - ] - }, - { - "code":"ZET", - "name":"Zetacoin", - "statuses":[ - "primary" - ] - }, - { - "code":"ZRC", - "name":"ZiftrCOIN", - "statuses":[ - "primary" - ] - }, - { - "code":"ZLQ", - "name":"ZLQ", - "statuses":[ - "primary" - ] - }, - { - "code":"ZMC", - "name":"ZMC", - "statuses":[ - "primary" - ] - }, - { - "code":"ZNE", - "name":"ZNE", - "statuses":[ - "primary" - ] - }, - { - "code":"ZNY", - "name":"ZNY", - "statuses":[ - "primary" - ] - }, - { - "code":"ZS", - "name":"ZS", - "statuses":[ - "primary" - ] - }, - { - "code":"ZUR", - "name":"ZUR", - "statuses":[ - "primary" - ] - }, - { - "code":"ZXT", - "name":"ZXT", - "statuses":[ - "primary" - ] - }, - { - "code":"ZYD", - "name":"ZYD", - "statuses":[ - "primary" - ] - } - ] -} \ No newline at end of file +{ + "rows": [ + { + "code": "REP", + "name": "Augur", + "statuses": [ + "primary" + ] + }, + { + "code": "BCN", + "name": "Bytecoin", + "statuses": [ + "primary" + ] + }, + { + "code": "BTC", + "name": "Bitcoin", + "statuses": [ + "primary", + "secondary" + ] + }, + { + "code": "BTS", + "name": "BitShares", + "statuses": [ + "primary", + "secondary" + ] + }, + { + "code": "BLK", + "name": "Blackcoin", + "statuses": [ + "primary" + ] + }, + { + "code": "GBP", + "name": "British Pound Sterling", + "statuses": [ + "secondary" + ] + }, + { + "code": "CAD", + "name": "Canadian Dollar", + "statuses": [ + "secondary" + ] + }, + { + "code": "CNY", + "name": "Chinese Yuan", + "statuses": [ + "secondary" + ] + }, + { + "code": "DSH", + "name": "Dashcoin", + "statuses": [ + "primary" + ] + }, + { + "code": "DOGE", + "name": "Dogecoin", + "statuses": [ + "primary", + "secondary" + ] + }, + { + "code": "ETC", + "name": "Ethereum Classic", + "statuses": [ + "primary" + ] + }, + { + "code": "EUR", + "name": "Euro", + "statuses": [ + "primary", + "secondary" + ] + }, + { + "code": "GNO", + "name": "GNO", + "statuses": [ + "primary" + ] + }, + { + "code": "GNT", + "name": "GNT", + "statuses": [ + "primary" + ] + }, + { + "code": "JPY", + "name": "Japanese Yen", + "statuses": [ + "secondary" + ] + }, + { + "code": "LTC", + "name": "Litecoin", + "statuses": [ + "primary", + "secondary" + ] + }, + { + "code": "MAID", + "name": "MaidSafeCoin", + "statuses": [ + "primary" + ] + }, + { + "code": "XEM", + "name": "NEM", + "statuses": [ + "primary" + ] + }, + { + "code": "XLM", + "name": "Stellar", + "statuses": [ + "primary" + ] + }, + { + "code": "XMR", + "name": "Monero", + "statuses": [ + "primary", + "secondary" + ] + }, + { + "code": "XRP", + "name": "Ripple", + "statuses": [ + "primary" + ] + }, + { + "code": "RUR", + "name": "Ruble", + "statuses": [ + "secondary" + ] + }, + { + "code": "STEEM", + "name": "Steem", + "statuses": [ + "primary" + ] + }, + { + "code": "STRAT", + "name": "STRAT", + "statuses": [ + "primary" + ] + }, + { + "code": "UAH", + "name": "Ukrainian Hryvnia", + "statuses": [ + "secondary" + ] + }, + { + "code": "USD", + "name": "US Dollar", + "statuses": [ + "primary", + "secondary" + ] + }, + { + "code": "WAVES", + "name": "WAVES", + "statuses": [ + "primary" + ] + }, + { + "code": "ZEC", + "name": "Zcash", + "statuses": [ + "primary" + ] + } + ] +} diff --git a/ui/app/send.js b/ui/app/send.js index eb32d5e06..fd6994145 100644 --- a/ui/app/send.js +++ b/ui/app/send.js @@ -21,6 +21,8 @@ function mapStateToProps (state) { warning: state.appState.warning, network: state.metamask.network, addressBook: state.metamask.addressBook, + conversionRate: state.metamask.conversionRate, + currentCurrency: state.metamask.currentCurrency, } result.error = result.warning && result.warning.split('.')[0] @@ -40,13 +42,17 @@ function SendTransactionScreen () { SendTransactionScreen.prototype.render = function () { this.persistentFormParentId = 'send-tx-form' - var state = this.props - var address = state.address - var account = state.account - var identity = state.identity - var network = state.network - var identities = state.identities - var addressBook = state.addressBook + const props = this.props + const { + address, + account, + identity, + network, + identities, + addressBook, + conversionRate, + currentCurrency, + } = props return ( @@ -125,6 +131,8 @@ SendTransactionScreen.prototype.render = function () { h(EthBalance, { value: account && account.balance, + conversionRate, + currentCurrency, }), ]), @@ -147,7 +155,7 @@ SendTransactionScreen.prototype.render = function () { ]), // error message - state.error && h('span.error.flex-center', state.error), + props.error && h('span.error.flex-center', props.error), // 'to' field h('section.flex-row.flex-center', [