diff --git a/app/src/androidTest/kotlin/com/tangem/scenarios/OpenMainScreenScenario.kt b/app/src/androidTest/kotlin/com/tangem/scenarios/OpenMainScreenScenario.kt index 0c6b1790ea..cd966f6a0f 100644 --- a/app/src/androidTest/kotlin/com/tangem/scenarios/OpenMainScreenScenario.kt +++ b/app/src/androidTest/kotlin/com/tangem/scenarios/OpenMainScreenScenario.kt @@ -8,6 +8,7 @@ import com.tangem.domain.models.scan.ProductType import com.tangem.screens.DisclaimerTestScreen import com.tangem.screens.MainTestScreen import com.tangem.screens.StoriesTestScreen +import com.tangem.screens.TestTopBar import com.tangem.tap.domain.sdk.mocks.MockProvider import io.github.kakaocup.compose.node.element.ComposeScreen @@ -34,5 +35,10 @@ class OpenMainScreenScenario( assertIsDisplayed() } } + ComposeScreen.onComposeScreen(testRule) { + step("Close Markets tooltip"){ + performClick() + } + } } } \ No newline at end of file diff --git a/app/src/main/assets/features_dev.json b/app/src/main/assets/features_dev.json deleted file mode 100644 index b24d083053..0000000000 --- a/app/src/main/assets/features_dev.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "isTopUpEnabled": true, - "isCreatingTwinCardsAllowed": true -} \ No newline at end of file diff --git a/app/src/main/assets/features_prod.json b/app/src/main/assets/features_prod.json deleted file mode 100644 index b24d083053..0000000000 --- a/app/src/main/assets/features_prod.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "isTopUpEnabled": true, - "isCreatingTwinCardsAllowed": true -} \ No newline at end of file diff --git a/app/src/main/assets/fw_hashes.json b/app/src/main/assets/fw_hashes.json deleted file mode 100644 index 9c86b3a1db..0000000000 --- a/app/src/main/assets/fw_hashes.json +++ /dev/null @@ -1,138 +0,0 @@ -[ - { - "fw":"1.24r", - "challenge":"00000000000000000000000000000001", - "sha-256":[ - {"block":0,"count":1,"digest":"9B091DF443FE951D27AA8843517096DC421433F5603EBC566B11891F867E3D18"}, - {"block":1,"count":1,"digest":"B4F723EE79075C8C00FA17D037BF10528BB0C7CF421539EE15F4A397204C87AF"}, - {"block":2,"count":1,"digest":"1258585B438B6BC8F41FC22AFF383C86690E984E84E96AA752C9A54954DF731A"}, - {"block":3,"count":1,"digest":"14082C75D6AA533A06E9B764642F97B5783FED91BD1173EFADC3CF57D8769AAE"}, - {"block":4,"count":1,"digest":"A8F6CB02D56933361127072BB0D89999020CE196AE9718E9CF019DCCC9437E85"}, - {"block":5,"count":1,"digest":"491604BA2A2F6EE03A2B4812958F0356D745678FB0ABABF0109A9E8F59099D9D"}, - {"block":6,"count":1,"digest":"B2F057FF8B83343BC40058CA459F3C63B9670ABCD059730BE70223AEBDC88D77"}, - {"block":7,"count":1,"digest":"73F4391010345E27745A1AFEC93C02B2CA460D9EAB437605F82A18281DF17DCE"}, - {"block":8,"count":1,"digest":"74588EBB6704DD3DB9ECDFE6B85EC2872BD6A1F7C73E080E57697D3FF8DDD470"}, - {"block":9,"count":1,"digest":"3B382C35ADBBF206B0A6B216EE95AF2321EE34148E93BBFECCF275AB13ED08A2"}, - {"block":11500,"count":1,"digest":"21DDEC9788E3EA04663297AD0208F2714F139434E3540EBB7C96150EE1D320C9"}, - {"block":11501,"count":1,"digest":"C545C5D092D1EBC4BA266C139CE0F2A399E4D23E74EB4EBD0E53019AB58CB486"}, - {"block":0,"count":0,"digest":"C689C50352E9F6E41BF2E6EC852D8466814A51018F40BE32BAADEE9C2A9E6B6D"} - ], - "crc-16":[ - {"block":0,"count":1,"digest":"1BFC"}, - {"block":1,"count":1,"digest":"D58D"}, - {"block":2,"count":1,"digest":"7E3E"}, - {"block":3,"count":1,"digest":"14EA"}, - {"block":4,"count":1,"digest":"014F"}, - {"block":5,"count":1,"digest":"5FF0"}, - {"block":6,"count":1,"digest":"7D3A"}, - {"block":7,"count":1,"digest":"702C"}, - {"block":8,"count":1,"digest":"CC22"}, - {"block":9,"count":1,"digest":"392C"}, - {"block":11500,"count":1,"digest":"5FCB"}, - {"block":11501,"count":1,"digest":"FF77"}, - {"block":0,"count":0,"digest":"D07B"} - ] - }, - { - "fw":"1.24d SDK", - "challenge":"00000000000000000000000000000001", - "sha-256":[ - {"block":0,"count":1,"digest":"6B360B47FFB16641EF9CC778746FE6B1010AB60C69281CE431A46ECC29A72304"}, - {"block":1,"count":1,"digest":"648F50D44E9A31CB4C2682EAD7B8E2E570E5F252035849CD9B08BD4F9106B432"}, - {"block":2,"count":1,"digest":"BAA31588F599E2DBC8AC06CFBF4E710B9B0E3FEA0201AE67E5A9E605DB50D1ED"}, - {"block":3,"count":1,"digest":"48CFA13758F0B8018A97831C11BB1668A39CC76B141C90038551D950F83A43BA"}, - {"block":4,"count":1,"digest":"8932B8E9D93A28EEEAC8FD3477F38A8A384AC895B06E09B8396A7806C3DCFC09"}, - {"block":5,"count":1,"digest":"A3E7F2911AB380B366E47EB9E7DCC0C3D8667EEE3CF355FCCD5B113918873EFC"}, - {"block":6,"count":1,"digest":"32CFCDC12C3AAA6C8FE4935C76B795A81206141AE7C7AB941A4B5F74EB02D844"}, - {"block":7,"count":1,"digest":"1BA7B6ED5F28A0744E177843F2A960CB757B27FF6052C17F9E57B266AEC4F564"}, - {"block":8,"count":1,"digest":"7C1A2C88529DA038C3A124CC049B9A5CD73089C2CD9C66B15DF91020E981B94B"}, - {"block":9,"count":1,"digest":"5F14E10CBE14230EEF9B8896C84998197E56738952A1ECF22202801B9AE64340"}, - {"block":10,"count":1,"digest":"8FF4F496E7C68A654E574F13517EFA4F2058FDFC9E949421DA5ACC855C876F63"}, - {"block":11491,"count":1,"digest":"E45CFEA35B1C4C217A55B78B0D78C841978F1008C3C1917D228EECB0324A0942"}, - {"block":0,"count":0,"digest":"F4199A74F2D4BAF2E282A670989A50B9186665D8EC453D1CED02F4E4019E1C0F"} - ], - "crc-16":[ - {"block":0,"count":1,"digest":"22C3"}, - {"block":1,"count":1,"digest":"ECB2"}, - {"block":2,"count":1,"digest":"4701"}, - {"block":3,"count":1,"digest":"2DD5"}, - {"block":4,"count":1,"digest":"3870"}, - {"block":5,"count":1,"digest":"66CF"}, - {"block":6,"count":1,"digest":"4405"}, - {"block":7,"count":1,"digest":"4913"}, - {"block":8,"count":1,"digest":"F51D"}, - {"block":9,"count":1,"digest":"0013"}, - {"block":10,"count":1,"digest":"5E68"}, - {"block":11491,"count":1,"digest":"4078"}, - {"block":0,"count":0,"digest":"75C3"} - ] - }, - { - "fw":"1.28r", - "challenge":"00000000000000000000000000000001", - "sha-256":[ - {"block":0,"count":1,"digest":"A52D552A4CCA2979122300C7C8686031FBB216C187971C739305D493284DD262"}, - {"block":1,"count":1,"digest":"AF8D5DDC8FD0BA9B58707BC66940A50298AAB6FFE74D243874BAA25CCD53C7C3"}, - {"block":2,"count":1,"digest":"03612CB50531C2A2B7825B6A72C14528522A926A781391E8FE17027943543387"}, - {"block":3,"count":1,"digest":"88A984179C97654B7833824DF43A13133BC6E627C17C9A65BEEDFB671CD78D2A"}, - {"block":4,"count":1,"digest":"A3DB1DD3F876ED972287FEC903C2112F6B99A09BCF686E2B65A6E19EA9CD9ECB"}, - {"block":5,"count":1,"digest":"CA7685FCD6BE9D8310BBD58AA7DED1390925BADA47B6611DB010625CA6BA7542"}, - {"block":6,"count":1,"digest":"192E10BF1D4AA426676918AAC7312FF4914A4781A2E6372986356AC26917078B"}, - {"block":7,"count":1,"digest":"00B657206A8120DE159F3C16B4F036B7D2D292603067FCB6B33E3753421D9D15"}, - {"block":8,"count":1,"digest":"2F875EE18AD37A3A4666810E7E0942F7370CAD365C510B7952280EC43BE12ADE"}, - {"block":9,"count":1,"digest":"1CFAF013B43CAF9F6627DAC871335B09279375A9DE8644AEB2FBBA105C73C05A"}, - {"block":10,"count":1,"digest":"AD33E62400EFE078EB9256C3A6F9B9299A4B56F4A7E63E78C9BC34F7DCA2FE10"}, - {"block":11497,"count":1,"digest":"FBB56C858CF485012A08343B73C46CDA7423500D52FBE5E4F28326F2515C7150"}, - {"block":0,"count":0,"digest":"7582258B2AF9FDCD83BCDEA05FA0310216F7CFF4FB27C699461397EF4D189567"} - ], - "crc-16":[ - {"block":0,"count":1,"digest":"B42D"}, - {"block":1,"count":1,"digest":"7A5C"}, - {"block":2,"count":1,"digest":"D1EF"}, - {"block":3,"count":1,"digest":"BB3B"}, - {"block":4,"count":1,"digest":"AE9E"}, - {"block":5,"count":1,"digest":"F021"}, - {"block":6,"count":1,"digest":"D2EB"}, - {"block":7,"count":1,"digest":"DFFD"}, - {"block":8,"count":1,"digest":"63F3"}, - {"block":9,"count":1,"digest":"96FD"}, - {"block":10,"count":1,"digest":"C886"}, - {"block":11497,"count":1,"digest":"E4B0"}, - {"block":0,"count":0,"digest":"0143"} - ] - }, - { - "fw":"1.28d SDK", - "challenge":"00000000000000000000000000000001", - "sha-256":[ - {"block":0,"count":1,"digest":"2F9DB9B70A20E28A97A6A58919E71ABF757BA73E693D9DC9CEEE1B0BCA8DAB8E"}, - {"block":1,"count":1,"digest":"6B6F75ECF7E9CB76E570C290E7BEEAEF44E4B24C46BA4AA115D5BBAE3209869F"}, - {"block":2,"count":1,"digest":"4D584DDC73B940C7E508456BF0C52BC6BE018CD448A5886B54BEBF1D26D31AD5"}, - {"block":3,"count":1,"digest":"A9D5929A34793F5BCC623234AE34DEE246A95ED34D75D51508B9DC2694F28CD6"}, - {"block":4,"count":1,"digest":"094D5F3E03262B6D07E58F795E17FFF2D83D39ABCF86B3B04A856A37BB076AD0"}, - {"block":5,"count":1,"digest":"40F5586223406B2BD790629AB5D8D1AB97B6EA9151B69BF4D55C4A1EF5E2A1BB"}, - {"block":6,"count":1,"digest":"B56C71A3E6DFE98B1666825825844372EEE5811EEA743A40760FA7AE2D66CADD"}, - {"block":7,"count":1,"digest":"4331EB4B7415883536DDBA03D75F0408BE1F23F3DEE4459227755C12CBF98A8D"}, - {"block":8,"count":1,"digest":"7383EDD57D266591760CD74E50073D28973CB2DAFD1410E45030B33588768DEE"}, - {"block":9,"count":1,"digest":"893F5CF5E368E82CABE7F48D5DAA54AFAFA740B28496F303E845E680B7C1436C"}, - {"block":10,"count":1,"digest":"8DEEB29CD6C764FB7AB53A056BC3C860DBD8E121AB7C1E6E4DF3C273A503C405"}, - {"block":11497,"count":1,"digest":"6F6166E13672B12BD947CDFEC3158064A14C5A259AD0B3550738E30E90BC20C5"}, - {"block":0,"count":0,"digest":"E475661F4D0948ACBDF104EAD718260A73FB99448691F0EB68AED85D189B6F3C"} - ], - "crc-16":[ - {"block":0,"count":1,"digest":"3506"}, - {"block":1,"count":1,"digest":"FB77"}, - {"block":2,"count":1,"digest":"50C4"}, - {"block":3,"count":1,"digest":"3A10"}, - {"block":4,"count":1,"digest":"2FB5"}, - {"block":5,"count":1,"digest":"710A"}, - {"block":6,"count":1,"digest":"53C0"}, - {"block":7,"count":1,"digest":"5ED6"}, - {"block":8,"count":1,"digest":"E2D8"}, - {"block":9,"count":1,"digest":"17D6"}, - {"block":10,"count":1,"digest":"49AD"}, - {"block":11497,"count":1,"digest":"659B"}, - {"block":0,"count":0,"digest":"1893"} - ] - } -] \ No newline at end of file diff --git a/app/src/main/assets/testnet_tokens.json b/app/src/main/assets/testnet_tokens.json index cb960e3694..3badefc007 100644 --- a/app/src/main/assets/testnet_tokens.json +++ b/app/src/main/assets/testnet_tokens.json @@ -718,6 +718,36 @@ "networkId": "sei-network/test" } ] + }, + { + "id": "energy-web-chain", + "name": "Energy Web Chain", + "symbol": "EWT", + "networks": [ + { + "networkId": "energy-web-chain/test" + } + ] + }, + { + "id": "energy-web-x", + "name": "Energy Web X", + "symbol": "EWT", + "networks": [ + { + "networkId": "energy-web-x/test" + } + ] + }, + { + "id": "core", + "name": "Core", + "symbol": "CORE", + "networks": [ + { + "networkId": "core/test" + } + ] } ] } diff --git a/app/src/main/assets/tokens.json b/app/src/main/assets/tokens.json deleted file mode 100644 index 00457a63f6..0000000000 --- a/app/src/main/assets/tokens.json +++ /dev/null @@ -1 +0,0 @@ -{"imageHost":"https://s3.eu-central-1.amazonaws.com/tangem.api/coins/","ts":1652764975956,"coins":[{"id" : "arbitrum-one","symbol" : "ETH","name" : "Arbitrum", "active":true,"networks" : [{"networkId" : "arbitrum-one"}]},{"id" : "ethereum-classic","symbol" : "ETC","name" : "Ethereum Classic","networks" : [{"networkId" : "ethereum-classic"}]},{"id":"bitcoin","name":"Bitcoin","symbol":"BTC","active":true,"networks":[{"networkId":"bitcoin"}]},{"id":"ethereum","name":"Ethereum","symbol":"ETH","active":true,"networks":[{"networkId":"ethereum"}]},{"id":"tether","name":"Tether","symbol":"USDT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdac17f958d2ee523a2206206994597c13d831ec7","decimalCount":6},{"networkId":"binance-smart-chain","contractAddress":"0x55d398326f99059ff775485246999027b3197955","decimalCount":18},{"networkId":"solana","contractAddress":"Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB","decimalCount":6},{"networkId":"avalanche","contractAddress":"0xc7198437980c041c805a1edcba50c1ce5db95118","decimalCount":6},{"networkId":"polygon-pos","contractAddress":"0xc2132d05d31c914a87c6611c10748aeb04b58e8f","decimalCount":6},{"networkId":"fantom","contractAddress":"0x049d68029688eabf473097a2fc38ef61633a3c7a","decimalCount":6},{"networkId":"arbitrum-one","contractAddress":"0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9","decimalCount":6}]},{"id":"usd-coin","name":"USD Coin","symbol":"USDC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48","decimalCount":6},{"networkId":"binance-smart-chain","contractAddress":"0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d","decimalCount":18},{"networkId":"solana","contractAddress":"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v","decimalCount":6},{"networkId":"avalanche","contractAddress":"0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e","decimalCount":6},{"networkId":"polygon-pos","contractAddress":"0x2791bca1f2de4661ed88a30c99a7a9449aa84174","decimalCount":6},{"networkId":"fantom","contractAddress":"0x04068da6c83afcfa0e13ba15a6696662335d5b75","decimalCount":6},{"networkId":"arbitrum-one","contractAddress":"0xff970a61a04b1ca14834a43f5de4533ebddb5cc8","decimalCount":6}]},{"id":"binancecoin","name":"BNB","symbol":"BNB","active":true,"networks":[{"networkId":"binancecoin"},{"networkId":"binance-smart-chain"}]},{"id":"ripple","name":"XRP","symbol":"XRP","active":true,"networks":[{"networkId":"xrp"}]},{"id":"cardano","name":"Cardano","symbol":"ADA","active":true,"networks":[{"networkId":"cardano"}]},{"id":"solana","name":"Solana","symbol":"SOL","active":true,"networks":[{"networkId":"solana"}]},{"id":"binance-usd","name":"Binance USD","symbol":"BUSD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4fabb145d64652a948d72533023f6e7a623c7c53","decimalCount":18},{"networkId":"binancecoin","contractAddress":"BUSD-BD1","decimalCount":8},{"networkId":"binance-smart-chain","contractAddress":"0xe9e7cea3dedca5984780bafc599bd69add087d56","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x19860ccb0a68fd4213ab9d8266f7bbf05a8dde98","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xdab529f40e671a1d4bf91361c21bf9f0c9712ab7","decimalCount":18}]},{"id":"dogecoin","name":"Dogecoin","symbol":"DOGE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x4206931337dc273a630d328da6441786bfad668f","decimalCount":8},{"networkId":"dogecoin"}]},{"id":"avalanche-2","name":"Avalanche","symbol":"AVAX","active":true,"networks":[{"networkId":"avalanche"},{"networkId":"polygon-pos","contractAddress":"0x2c89bbc92bd86f8075d1decc58c7f4e0107f286b","decimalCount":18}]},{"id":"wrapped-bitcoin","name":"Wrapped Bitcoin","symbol":"WBTC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2260fac5e5542a773aa44fbcfedf7c193bc2c599","decimalCount":8},{"networkId":"avalanche","contractAddress":"0x50b7545627a5162f82a992c33b87adc75187b218","decimalCount":8},{"networkId":"polygon-pos","contractAddress":"0x1bfd67037b42cf73acf2047067bd4f2c47d9bfd6","decimalCount":8},{"networkId":"fantom","contractAddress":"0x321162cd933e2be498cd2267a90534a804051b11","decimalCount":8},{"networkId":"arbitrum-one","contractAddress":"0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f","decimalCount":8}]},{"id":"staked-ether","name":"Lido Staked Ether","symbol":"STETH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xae7ab96520de3a18e5e111b5eaab095312d7fe84","decimalCount":18}]},{"id":"tron","name":"TRON","symbol":"TRX","active":true,"networks":[{"networkId":"tron"}]},{"id":"shiba-inu","name":"Shiba Inu","symbol":"SHIB","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x95ad61b0a150d79219dcf64e1e6cc01f0b64c4ce","decimalCount":18}]},{"id":"dai","name":"Dai","symbol":"DAI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6b175474e89094c44da98b954eedeac495271d0f","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x1af3f329e8be154074d8769d1ffa4ee058b1dbc3","decimalCount":18},{"networkId":"avalanche","contractAddress":"0xd586e7f844cea2f87f50152665bcbc2c279d8d70","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x8f3cf7ad23cd3cadbd9735aff958023239c6a063","decimalCount":18},{"networkId":"fantom","contractAddress":"0x8d11ec38a3eb5e956b052f67da8bdc9bef8abf3e","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0xda10009cbd5d07dd0cecc66161fc93d7c9000da1","decimalCount":18}]},{"id":"crypto-com-chain","name":"Cronos","symbol":"CRO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa0b73e1ff0b80914ab6fe0444e65848c4c34450b","decimalCount":8}]},{"id":"litecoin","name":"Litecoin","symbol":"LTC","active":true,"networks":[{"networkId":"litecoin"}]},{"id":"matic-network","name":"Polygon","symbol":"MATIC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7d1afa7b718fb893db30a3abc0cfc608aacfebb0","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xcc42724c6683b7e57334c4e856f4c9965ed682bd","decimalCount":18},{"networkId":"polygon-pos"}]},{"id":"leo-token","name":"LEO Token","symbol":"LEO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2af5d2ad76741191d15dfe7bf6ac92d4bd912ca3","decimalCount":18}]},{"id":"ftx-token","name":"FTX Token","symbol":"FTT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x50d1c9771902476076ecfc8b2a83ad6b9355a4c9","decimalCount":18},{"networkId":"solana","contractAddress":"AGFEad2et2ZJif9jaGpdMixQqvW5i81aBdvKe7PHNfz3","decimalCount":6}]},{"id":"bitcoin-cash","name":"Bitcoin Cash","symbol":"BCH","active":true,"networks":[{"networkId":"bitcoin-cash"}]},{"id":"chainlink","name":"Chainlink","symbol":"LINK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x514910771af9ca656af840dff83e8264ecf986ca","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xf8a0bf9cf54bb92f17374d9e9a321e6a111a51bd","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x5947bb275c521040051d82396192181b413227a3","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x53e0bca35ec356bd5dddfebbd1fc0fd03fabad39","decimalCount":18},{"networkId":"fantom","contractAddress":"0xb3654dc3d10ea7645f8319668e8f54d2574fbdc8","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0xf97f4df75117a78c1a5a0dbb814af92458539fb4","decimalCount":18}]},{"id":"stellar","name":"Stellar","symbol":"XLM","active":true,"networks":[{"networkId":"stellar"}]},{"id":"cosmos","name":"Cosmos Hub","symbol":"ATOM","active":false,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x0eb3a705fc54725037cc9e008bdede697f62f335","decimalCount":18}]},{"id":"okb","name":"OKB","symbol":"OKB","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x75231f58b43240c9718dd58b4967c5114342a86c","decimalCount":18}]},{"id":"apecoin","name":"ApeCoin","symbol":"APE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4d224452801aced8b2f0aebe155379bb5d594381","decimalCount":18}]},{"id":"uniswap","name":"Uniswap","symbol":"UNI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1f9840a85d5af5bf1d1762f925bdaddc4201f984","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xbf5140a22578168fd562dccf235e5d43a02ce9b1","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x8ebaf22b6f053dffeaf46f4dd9efa95d89ba8580","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xb33eaad8d922b1083446dc23f610c2567fb5180f","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0xfa7f8980b0f1e64a2062791cc3b0871572f1f7f0","decimalCount":18}]},{"id":"magic-internet-money","name":"Magic Internet Money","symbol":"MIM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x130966628846bfd36ff31a822705796e8cb8c18d","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x49a0400587a7f65072c87c4910449fdcc5c47242","decimalCount":18},{"networkId":"fantom","contractAddress":"0x82f0b8b456c1a451378467398982d4834b6829c1","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0xfea7a6a0b346362bf88a9e4a88416b77a57d6c2a","decimalCount":18}]},{"id":"decentraland","name":"Decentraland","symbol":"MANA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0f5d2fb29fb7d3cfee444a200298f468908cc942","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xa1c57f48f0deb89f569dfbe6e2b7f46d33606fd4","decimalCount":18}]},{"id":"the-sandbox","name":"The Sandbox","symbol":"SAND","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3845badade8e6dff049820680d1f14bd3903a5d0","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xbbba073c31bf03b8acf7c28ef0738decf3695683","decimalCount":18}]},{"id":"compound-ether","name":"cETH","symbol":"CETH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4ddc2d193948926d02f9b1fe9e1daa0718270ed5","decimalCount":8}]},{"id":"chain-2","name":"Chain","symbol":"XCN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa2cd3d43c775978a96bdbf12d733d5a1ed94fb18","decimalCount":18}]},{"id":"tezos","name":"Tezos","symbol":"XTZ","active":true,"networks":[{"networkId":"tezos"}]},{"id":"axie-infinity","name":"Axie Infinity","symbol":"AXS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbb0e17ef65f82ab018d8edd776e8dd940327b28b","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x715d400f88c167884bbcc41c5fea407ed4d2f8a0","decimalCount":18}]},{"id":"maker","name":"Maker","symbol":"MKR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x88128fd4b259552a9a1d457f435a6527aab72d42","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x2e9a6df78e42a30712c10a9dc4b1c8656f8f2879","decimalCount":18}]},{"id":"frax","name":"Frax","symbol":"FRAX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x853d955acef822db058eb8505911ed77f175b99e","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x90c97f71e18723b0cf0dfa30ee176ab653e89f40","decimalCount":18},{"networkId":"solana","contractAddress":"FR87nWEUxVgerFGhZM8Y4AggKGLnaXswr1Pd8wZ4kZcp","decimalCount":8},{"networkId":"avalanche","contractAddress":"0xd24c2ad096400b6fbcd2ad8b24e7acbc21a1da64","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x45c32fa6df82ead1e2ef74d17b76547eddfaff89","decimalCount":18},{"networkId":"fantom","contractAddress":"0xdc301622e621166bd8e82f2ca0a26c13ad0be355","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x17fc002b466eec40dae837fc4be5c67993ddbd6f","decimalCount":18}]},{"id":"pancakeswap-token","name":"PancakeSwap","symbol":"CAKE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x0e09fabb73bd3ade0a17ecc321fd13a19e81ce82","decimalCount":18}]},{"id":"the-graph","name":"The Graph","symbol":"GRT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc944e90c64b2c07662a292be6244bdf05cda44a7","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x8a0cac13c7da965a312f08ea4229c37869e85cb9","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x5fe2b58c013d7601147dcdd68c143a77499f5531","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x23a941036ae778ac51ab04cea08ed6e2fe103614","decimalCount":18}]},{"id":"aave","name":"Aave","symbol":"AAVE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x63a72806098bd3d9520cc43356dd78afe5d386d9","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xd6df932a45c0f255f85145f286ea0b292b21c90b","decimalCount":18},{"networkId":"fantom","contractAddress":"0x6a07a792ab2965c72a5b8088d3a069a7ac3a993b","decimalCount":18}]},{"id":"true-usd","name":"TrueUSD","symbol":"TUSD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0000000000085d4780b73119b644ae5ecd22b376","decimalCount":18},{"networkId":"binancecoin","contractAddress":"TUSDB-888","decimalCount":8},{"networkId":"binance-smart-chain","contractAddress":"0x14016e85a25aeb13065688cafb43044c2ef86784","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x1c20e891bab6b1727d14da358fae2984ed9b59eb","decimalCount":18},{"networkId":"tron","contractAddress":"TUpMhErZL2fhh4sVNULAbNKLokS4GjC1F4","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x2e1ad108ff1d8c782fcbbb89aad783ac49586756","decimalCount":18},{"networkId":"fantom","contractAddress":"0x9879abdea01a879644185341f7af7d8343556b7a","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x4d15a3a2286d883af0aa1b3f21367843fac63e07","decimalCount":18}]},{"id":"huobi-btc","name":"Huobi BTC","symbol":"HBTC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0316eb71485b0ab14103307bf65a021042c6d380","decimalCount":18}]},{"id":"terra-luna","name":"Terra","symbol":"LUNA","active":true,"networks":[{"networkId":"fantom","contractAddress":"0x95dd59343a893637be1c3228060ee6afbf6f0730","decimalCount":6}]},{"id":"compound-usd-coin","name":"cUSDC","symbol":"CUSDC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x39aa39c021dfbae8fac545936693ac917d5e7563","decimalCount":8}]},{"id":"huobi-token","name":"Huobi Token","symbol":"HT","active":false,"networks":[{"networkId":"ethereum","contractAddress":"0x6f259637dcd74c767781e37bc6133cd6a68aa161","decimalCount":18}]},{"id":"bittorrent","name":"BitTorrent","symbol":"BTT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc669928185dbce49d2230cc9b0979be6dc797957","decimalCount":18},{"networkId":"tron","contractAddress":"TAFjULxiVgT4qWk6UZwjqwZXTSaGaqnVp4","decimalCount":18}]},{"id":"thorchain","name":"THORChain","symbol":"RUNE","active":false,"networks":[{"networkId":"binancecoin","contractAddress":"RUNE-B1A","decimalCount":8}]},{"id":"quant-network","name":"Quant","symbol":"QNT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4a220e6096b25eadb88358cb44068a3248254675","decimalCount":18}]},{"id":"paxos-standard","name":"Pax Dollar","symbol":"USDP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8e870d67f660d95d5be530380d0ec0bd388289e1","decimalCount":18}]},{"id":"fantom","name":"Fantom","symbol":"FTM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4e15361fd6b4bb609fa63c81a2be19d873717870","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xad29abb318791d579433d831ed122afeaf29dcfe","decimalCount":18},{"networkId":"fantom"}]},{"id":"stepn","name":"STEPN","symbol":"GMT","active":true,"networks":[{"networkId":"solana","contractAddress":"7i5KKsX2weiTkry7jA4ZwSuXGhs5eJBEjY8vVxR4pfRx","decimalCount":9}]},{"id":"neutrino","name":"Neutrino USD","symbol":"USDN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x674c6ad92fd080e4004b2312b45f796a192d27a0","decimalCount":18}]},{"id":"cdai","name":"cDAI","symbol":"CDAI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5d3a536e4d6dbd6114cc1ead35777bab948e3643","decimalCount":8}]},{"id":"gatechain-token","name":"GateToken","symbol":"GT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe66747a101bff2dba3697199dcce5b743b454759","decimalCount":18}]},{"id":"bitdao","name":"BitDAO","symbol":"BIT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1a4b46696b2bb4794eb3d4c26f1c55f9170fa4c5","decimalCount":18}]},{"id":"nexo","name":"NEXO","symbol":"NEXO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb62132e35a6c13ee1ee0f84dc5d40bad8d815206","decimalCount":18},{"networkId":"fantom","contractAddress":"0x7c598c96d02398d89fbcb9d41eab3df0c16f227d","decimalCount":18}]},{"id":"zilliqa","name":"Zilliqa","symbol":"ZIL","active":false,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xb86abcb37c3a4b64f74f59301aff131a1becc787","decimalCount":12}]},{"id":"convex-finance","name":"Convex Finance","symbol":"CVX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4e3fbd56cd56c3e72c1403e103b45db9da5b9d2b","decimalCount":18}]},{"id":"enjincoin","name":"Enjin Coin","symbol":"ENJ","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf629cbd94d3791c9250152bd8dfbdf380e2a3b9c","decimalCount":18}]},{"id":"gala","name":"Gala","symbol":"GALA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x15d4c048f83bd7e37d49ea4c83a07267ec4203da","decimalCount":8},{"networkId":"binance-smart-chain","contractAddress":"0x7ddee176f665cd201f93eede625770e2fd911990","decimalCount":18}]},{"id":"amp-token","name":"Amp","symbol":"AMP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xff20817765cb7f73d4bde2e66e067e58d11095c2","decimalCount":18}]},{"id":"waves","name":"Waves","symbol":"WAVES","active":false,"networks":[{"networkId":"ethereum","contractAddress":"0x1cf4592ebffd730c7dc92c1bdffdfc3b9efcf29a","decimalCount":18}]},{"id":"havven","name":"Synthetix Network Token","symbol":"SNX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f","decimalCount":18},{"networkId":"avalanche","contractAddress":"0xbec243c995409e6520d7c41e404da5deba4b209b","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x50b728d8d964fd00c2d0aad81718b71311fef68a","decimalCount":18},{"networkId":"fantom","contractAddress":"0x56ee926bd8c72b2d5fa1af4d9e4cbb515a1e3adc","decimalCount":18}]},{"id":"chiliz","name":"Chiliz","symbol":"CHZ","active":false,"networks":[{"networkId":"ethereum","contractAddress":"0x3506424f91fd33084466f402d5d97f05f8e3b4af","decimalCount":18}]},{"id":"basic-attention-token","name":"Basic Attention Token","symbol":"BAT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0d8775f648430679a709e98d2b0cb6250d2887ef","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x98443b96ea4b0858fdf3219cd13e98c7a4690588","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x3cef98bb43d732e2f285ee605a8158cde967d219","decimalCount":18}]},{"id":"loopring","name":"Loopring","symbol":"LRC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbbbbca6a901c926f240b89eacb641d8aec7aeafd","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x46d0ce7de6247b0a95f67b43b589b4041bae7fbe","decimalCount":18}]},{"id":"pax-gold","name":"PAX Gold","symbol":"PAXG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x45804880de22913dafe09f4980848ece6ecbaf78","decimalCount":18}]},{"id":"gnosis","name":"Gnosis","symbol":"GNO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6810e776880c02933d47db1b9fc05908e5386b96","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0xa0b862f60edef4452f25b4160f177db44deb6cf1","decimalCount":18}]},{"id":"compound-usdt","name":"cUSDT","symbol":"CUSDT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf650c3d88d12db855b8bf7d11be6c55a4e07dcc9","decimalCount":8}]},{"id":"curve-dao-token","name":"Curve DAO Token","symbol":"CRV","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd533a949740bb3306d119cc777fa900ba034cd52","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x172370d5cd63279efa6d502dab29171933a610af","decimalCount":18},{"networkId":"fantom","contractAddress":"0x1e4f97b9f9f913c46f1632781732927b9019c68b","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x11cdb42b0eb46d95f990bedd4695a6e3fa034978","decimalCount":18}]},{"id":"fei-usd","name":"Fei USD","symbol":"FEI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x956f47f50a910163d8bf957cf5846d573e7f87ca","decimalCount":18}]},{"id":"lido-dao","name":"Lido DAO","symbol":"LDO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5a98fcbea516cf06857215779fd812ca3bef1b32","decimalCount":18}]},{"id":"frax-share","name":"Frax Share","symbol":"FXS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3432b6a60d23ca0dfca7761b7ab56459d9c964d0","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xe48a3d7d0bc88d552f730b62c006bc925eadb9ee","decimalCount":18},{"networkId":"solana","contractAddress":"6LX8BhMQ4Sy2otmAWj7Y5sKd9YTVVUgfMsBzT6B9W7ct","decimalCount":8},{"networkId":"avalanche","contractAddress":"0x214db107654ff987ad859f34125307783fc8e387","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x1a3acf6d19267e2d3e7f898f42803e90c9219062","decimalCount":18},{"networkId":"fantom","contractAddress":"0x7d016eec9c25232b01f23ef992d98ca97fc2af5a","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x9d2f299715d94d8a7e6f5eaa8e654e8c74a988a7","decimalCount":18}]},{"id":"compound-governance-token","name":"Compound","symbol":"COMP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc00e94cb662c3520282e6f5717214004a7f26888","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x52ce071bd9b1c4b00a0b92d298c512478cad67e8","decimalCount":18},{"networkId":"avalanche","contractAddress":"0xc3048e19e76cb9a3aa9d77d8c03c29fc906e2437","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x8505b9d2254a7ae468c0e9dd10ccea3a837aef5c","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x354a6da3fcde098f8389cad84b0182725c6c91de","decimalCount":18}]},{"id":"nxm","name":"Nexus Mutual","symbol":"NXM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd7c49cee7e9188cca6ad8ff264c1da2e69d4cf3b","decimalCount":18}]},{"id":"holotoken","name":"Holo","symbol":"HOT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6c6ee5e31d828de241282b9606c8e98ea48526e2","decimalCount":18}]},{"id":"tether-gold","name":"Tether Gold","symbol":"XAUT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x68749665ff8d2d112fa859aa293f07a622782f38","decimalCount":6}]},{"id":"tokenize-xchange","name":"Tokenize Xchange","symbol":"TKX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x667102bd3413bfeaa3dffb48fa8288819e480a88","decimalCount":8}]},{"id":"ecomi","name":"ECOMI","symbol":"OMI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xed35af169af46a02ee13b9d79eb57d6d68c1749e","decimalCount":18}]},{"id":"bancor","name":"Bancor Network Token","symbol":"BNT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1f573d6fb3f13d689ff844b4ce37794d79a7ff1c","decimalCount":18}]},{"id":"1inch","name":"1inch","symbol":"1INCH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x111111111117dc0aa78b770fa6a738034120c302","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x111111111117dc0aa78b770fa6a738034120c302","decimalCount":18},{"networkId":"avalanche","contractAddress":"0xd501281565bf7789224523144fe5d98e8b28f267","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x9c2c5fd7b07e95ee044ddeba0e97a665f142394f","decimalCount":18}]},{"id":"serum","name":"Serum","symbol":"SRM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x476c5e26a75bd202a9683ffd34359c0cc15be0ff","decimalCount":6},{"networkId":"solana","contractAddress":"SRMuApVNdxXokk5GT7XD5cUUgXMBCoAz2LHeuAoKWRt","decimalCount":6}]},{"id":"livepeer","name":"Livepeer","symbol":"LPT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x58b6a8a3302369daec383334672404ee733ab239","decimalCount":18}]},{"id":"flex-coin","name":"FLEX Coin","symbol":"FLEX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfcf8eda095e37a41e002e266daad7efc1579bc0a","decimalCount":18}]},{"id":"yearn-finance","name":"yearn.finance","symbol":"YFI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0bc529c00c6401aef6d220be8c6ea1667f6ad93e","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x9eaac1b23d935365bd7b542fe22ceee2922f52dc","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xda537104d6a5edd53c6fbba9a898708e465260b6","decimalCount":18},{"networkId":"fantom","contractAddress":"0x29b0da86e484e1c0029b56e817912d778ac0ec69","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x82e3a8f066a6989666b031d916c43672085b1582","decimalCount":18}]},{"id":"msol","name":"Marinade staked SOL","symbol":"MSOL","active":true,"networks":[{"networkId":"solana","contractAddress":"mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So","decimalCount":9}]},{"id":"omisego","name":"OMG Network","symbol":"OMG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd26114cd6ee289accf82350c8d8487fedb8a0c07","decimalCount":18}]},{"id":"celsius-degree-token","name":"Celsius Network","symbol":"CEL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xaaaebe6fe48e54f431b0c390cfaf0b017d09d42d","decimalCount":4},{"networkId":"polygon-pos","contractAddress":"0xd85d1e945766fea5eda9103f918bd915fbca63e6","decimalCount":4},{"networkId":"fantom","contractAddress":"0x2c78f1b70ccf63cdee49f9233e9faa99d43aa07e","decimalCount":4}]},{"id":"0x","name":"0x","symbol":"ZRX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe41d2489571d322189246dafa5ebde1f4699f498","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x596fa47043f99a4e0f122243b841e55375cde0d2","decimalCount":18}]},{"id":"gemini-dollar","name":"Gemini Dollar","symbol":"GUSD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x056fd409e1d7a124bd7017459dfea2f387b6d5cd","decimalCount":2}]},{"id":"liquity-usd","name":"Liquity USD","symbol":"LUSD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5f98805a4e8be255a32880fdec7f6728c6568ba0","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x23001f892c0c82b79303edc9b9033cd190bb21c7","decimalCount":18}]},{"id":"rocket-pool","name":"Rocket Pool","symbol":"RPL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd33526068d116ce69f19a9ee46f0bd304f21a51f","decimalCount":18}]},{"id":"audius","name":"Audius","symbol":"AUDIO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x18aaa7115705e8be94bffebde57af9bfc265b998","decimalCount":18}]},{"id":"xido-finance","name":"Xido Finance","symbol":"XIDO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf6650117017ffd48b725b4ec5a00b414097108a7","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x3764bc0de9b6a68c67929130aaec16b6060cab8c","decimalCount":18}]},{"id":"ankr","name":"Ankr","symbol":"ANKR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8290333cef9e6d528dd5618fb97a76f268f3edd4","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xf307910a4c7bbc79691fd374889b36d8531b08e3","decimalCount":18}]},{"id":"olympus","name":"Olympus","symbol":"OHM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x64aa3364f17a4d01c6f1751fd97c2bd3d7e7f1d5","decimalCount":9}]},{"id":"convex-crv","name":"Convex CRV","symbol":"CVXCRV","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x62b9c7356a2dc64a1969e19c23e4f579f9810aa7","decimalCount":18}]},{"id":"skale","name":"SKALE","symbol":"SKL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x00c83aecc790e8a4453e5dd3b0b4b3680501a7a7","decimalCount":18}]},{"id":"everdome","name":"Everdome","symbol":"DOME","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x475bfaa1848591ae0e6ab69600f48d828f61a80e","decimalCount":18}]},{"id":"just","name":"JUST","symbol":"JST","active":true,"networks":[{"networkId":"tron","contractAddress":"TCFLL5dx5ZJdKnWuesXxi1VPwjLVmWZZy9","decimalCount":18}]},{"id":"husd","name":"HUSD","symbol":"HUSD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdf574c24545e5ffecb9a659c229253d4111d87e1","decimalCount":8}]},{"id":"swissborg","name":"SwissBorg","symbol":"CHSB","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xba9d4199fab4f26efe3551d490e3821486f135ba","decimalCount":8}]},{"id":"iotex","name":"IoTeX","symbol":"IOTX","active":false,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x9678e42cebeb63f23197d726b29b1cb20d0064e5","decimalCount":18}]},{"id":"everscale","name":"Everscale","symbol":"EVER","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x29d578cec46b50fa5c88a99c6a4b70184c062953","decimalCount":9}]},{"id":"dogelon-mars","name":"Dogelon Mars","symbol":"ELON","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x761d38e5ddf6ccf6cf7c55759d5210750b5d60f3","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xe0339c80ffde91f3e20494df88d4206d86024cdf","decimalCount":18}]},{"id":"ethereum-name-service","name":"Ethereum Name Service","symbol":"ENS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc18360217d8f7ab5e7c516566761ea12ce7f9d72","decimalCount":18}]},{"id":"titanswap","name":"TitanSwap","symbol":"TITAN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3a8cccb969a61532d1e6005e2ce12c200caece87","decimalCount":18}]},{"id":"safemoon","name":"SafeMoon [OLD]","symbol":"SAFEMOON","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x8076c74c5e3f5852037f31ff0093eeb8c8add8d3","decimalCount":9}]},{"id":"render-token","name":"Render Token","symbol":"RNDR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6de037ef9ad2725eb40118bb1702ebb27e4aeb24","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x61299774020da444af134c82fa83e3810b309991","decimalCount":18}]},{"id":"mimatic","name":"MAI","symbol":"MIMATIC","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0x3b55e45fd6bd7d4724f5c47e0d1bcaedd059263e","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xa3fa99a148fa48d14ed51d610c367c61876997f1","decimalCount":18},{"networkId":"fantom","contractAddress":"0xfb98b335551a418cd0737375a2ea0ded62ea213b","decimalCount":18}]},{"id":"synapse-2","name":"Synapse","symbol":"SYN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0f2d719407fdbeff09d87557abb7232601fd9f29","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xa4080f1778e69467e905b8d6f72f6e441f9e9484","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x1f1e7c893855525b303f99bdf5c3c05be09ca251","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xf8f9efc0db77d8881500bb06ff5d6abc3070e695","decimalCount":18},{"networkId":"fantom","contractAddress":"0xe55e19fb4f2d85af758950957714292dac1e25b2","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x080f6aed32fc474dd5717105dba5ea57268f46eb","decimalCount":18}]},{"id":"golem","name":"Golem","symbol":"GLM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7dd9c5cba05e151c895fde1cf355c9a1d5da6429","decimalCount":18}]},{"id":"sushi","name":"Sushi","symbol":"SUSHI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6b3595068778dd592e39a122f4f5a5cf09c90fe2","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x947950bcc74888a40ffa2593c5798f11fc9124c4","decimalCount":18},{"networkId":"solana","contractAddress":"ChVzxWRmrTeSgwd3Ui3UumcN8KX7VK3WaD4KGeSKpypj","decimalCount":8},{"networkId":"avalanche","contractAddress":"0x37b608519f91f70f2eeb0e5ed9af4061722e4f76","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x0b3f868e0be5597d5db7feb59e1cadbb0fdda50a","decimalCount":18},{"networkId":"fantom","contractAddress":"0xae75a438b2e0cb8bb01ec1e1e376de11d44477cc","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0xd4d42f0b6def4ce0383636770ef773390d85c61a","decimalCount":18}]},{"id":"safemoon-2","name":"SafeMoon","symbol":"SFM","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x42981d0bfbaf196529376ee702f2a9eb9092fcb5","decimalCount":9}]},{"id":"ethos","name":"Voyager Token","symbol":"VGX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3c4b6e6e1ea3d4863700d7f76b36b7f3d3f13e3d","decimalCount":8}]},{"id":"trust-wallet-token","name":"Trust Wallet Token","symbol":"TWT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x4b0f1812e5df2a09796481ff14017e6005508003","decimalCount":18}]},{"id":"swipe","name":"SXP","symbol":"SXP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8ce9137d39326ad0cd6491fb5cc0cba0e089b6a9","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x47bead2563dcbf3bf2c9407fea4dc236faba485a","decimalCount":18}]},{"id":"escoin-token","name":"Escoin Token","symbol":"ELG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa2085073878152ac3090ea13d1e41bd69e60dc99","decimalCount":18}]},{"id":"immutable-x","name":"Immutable X","symbol":"IMX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf57e7e7c23978c3caec3c3548e3d615c346e79ff","decimalCount":18}]},{"id":"woo-network","name":"WOO Network","symbol":"WOO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4691937a7508860f876c9c0a2a617e7d9e945d4b","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x4691937a7508860f876c9c0a2a617e7d9e945d4b","decimalCount":18},{"networkId":"solana","contractAddress":"E5rk3nmgLUuKUiS94gg4bpWwWwyjCMtddsAXkTFLtHEy","decimalCount":6},{"networkId":"avalanche","contractAddress":"0xabc9547b534519ff73921b1fba6e672b5f58d083","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x1b815d120b3ef02039ee11dc2d33de7aa4a8c603","decimalCount":18},{"networkId":"fantom","contractAddress":"0x6626c47c00f1d87902fc13eecfac3ed06d5e8d8a","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0xcafcd85d8ca7ad1e1c6f82f651fa15e33aefd07b","decimalCount":18}]},{"id":"tether-eurt","name":"Euro Tether","symbol":"EURT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc581b735a1688071a1746c968e0798d642ede491","decimalCount":6}]},{"id":"tenset","name":"Tenset","symbol":"10SET","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7ff4169a6b5122b664c51c95727d87750ec07c84","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x1f64fdad335ed784898effb5ce22d54d8f432523","decimalCount":18}]},{"id":"uma","name":"UMA","symbol":"UMA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x04fa0d235c4abf4bcf4787af4cf447de572ef828","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x3bd2b1c7ed8d396dbb98ded3aebb41350a5b2339","decimalCount":18}]},{"id":"playdapp","name":"PlayDapp","symbol":"PLA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3a4f40631a4f906c2bad353ed06de7a5d3fcb430","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x8765f05adce126d70bcdf1b0a48db573316662eb","decimalCount":18}]},{"id":"nucypher","name":"NuCypher","symbol":"NU","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4fe83213d56308330ec302a8bd641f1d0113a4cc","decimalCount":18}]},{"id":"apenft","name":"APENFT","symbol":"NFT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x198d14f2ad9ce69e76ea330b374de4957c3f850a","decimalCount":6},{"networkId":"binance-smart-chain","contractAddress":"0x20ee7b720f4e4c4ffcb00c4065cdae55271aecca","decimalCount":6},{"networkId":"tron","contractAddress":"TFczxzPhnThNSqr5by8tvxsdCFRRz6cPNq","decimalCount":6}]},{"id":"renbtc","name":"renBTC","symbol":"RENBTC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xeb4c2781e4eba804ce9a9803c67d0893436bb27d","decimalCount":8},{"networkId":"binance-smart-chain","contractAddress":"0xfce146bf3146100cfe5db4129cf6c82b0ef4ad8c","decimalCount":8},{"networkId":"polygon-pos","contractAddress":"0xdbf31df14b66535af65aac99c32e9ea844e14501","decimalCount":8}]},{"id":"illuvium","name":"Illuvium","symbol":"ILV","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x767fe9edc9e0df98e07454847909b5e959d7ca0e","decimalCount":18}]},{"id":"polymath","name":"Polymath","symbol":"POLY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9992ec3cf6a55b00978cddf2b27bc6882d88d1ec","decimalCount":18}]},{"id":"rally-2","name":"Rally","symbol":"RLY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf1f955016ecbcd7321c7266bccfb96c68ea5e49b","decimalCount":18}]},{"id":"dydx","name":"dYdX","symbol":"DYDX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x92d6c1e31e14520e676a687f0a93788b716beff5","decimalCount":18}]},{"id":"mxc","name":"MXC","symbol":"MXC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5ca381bbfb58f0092df149bd3d243b08b9a8386e","decimalCount":18}]},{"id":"velas","name":"Velas","symbol":"VLX","active":false,"networks":[{"networkId":"ethereum","contractAddress":"0x8c543aed163909142695f2d2acd0d55791a9edb9","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xe9c803f48dffe50180bd5b01dc04da939e3445fc","decimalCount":18}]},{"id":"dao-maker","name":"DAO Maker","symbol":"DAO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0f51bb10119727a7e5ea3538074fb341f56b09ad","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x22f3997a5df5a80e29871fed24fe3e85741f5e82","decimalCount":18}]},{"id":"radio-caca","name":"Radio Caca","symbol":"RACA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x12bb890508c125661e03b09ec06e404bc9289040","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x12bb890508c125661e03b09ec06e404bc9289040","decimalCount":18}]},{"id":"alchemix-usd","name":"Alchemix USD","symbol":"ALUSD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbc6da0fe9ad5f3b0d58160288917aa56653660e9","decimalCount":18}]},{"id":"kyber-network-crystal","name":"Kyber Network Crystal","symbol":"KNC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdefa4e8a7bcba345f687a2f1456f5edd9ce97202","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xfe56d5892bdffc7bf58f2e84be1b2c32d21c308b","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x39fc9e94caeacb435842fadedecb783589f50f5f","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x1c954e8fe737f99f68fa1ccda3e51ebdb291948c","decimalCount":18},{"networkId":"fantom","contractAddress":"0x1e1085efaa63edfe74aad7c05a28eae4ef917c3f","decimalCount":18}]},{"id":"cratos","name":"Cratos","symbol":"CRTS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x678e840c640f619e17848045d23072844224dd37","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x678e840c640f619e17848045d23072844224dd37","decimalCount":18}]},{"id":"e-radix","name":"e-Radix","symbol":"EXRD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6468e79a80c0eab0f9a2b574c8d5bc374af59414","decimalCount":18}]},{"id":"telcoin","name":"Telcoin","symbol":"TEL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x467bccd9d29f223bce8043b84e8c8b282827790f","decimalCount":2},{"networkId":"polygon-pos","contractAddress":"0xdf7837de1f2fa4631d716cf2502f8b230f1dcc32","decimalCount":2}]},{"id":"zipmex-token","name":"Zipmex Token","symbol":"ZMT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xaa602de53347579f86b996d2add74bb6f79462b2","decimalCount":18}]},{"id":"looksrare","name":"LooksRare","symbol":"LOOKS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf4d2888d29d722226fafa5d9b24f9164c092421e","decimalCount":18}]},{"id":"coinex-token","name":"CoinEx Token","symbol":"CET","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x081f67afa0ccf8c7b17540767bbe95df2ba8d97f","decimalCount":18}]},{"id":"gmx","name":"GMX","symbol":"GMX","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0x62edc0692bd897d2295872a9ffcac5425011c661","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0xfc5a1a6eb076a2c7ad06ed22c90d7e710e35ad0a","decimalCount":18}]},{"id":"mx-token","name":"MX Token","symbol":"MX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x11eef04c884e24d9b7b4760e7476d06ddf797f36","decimalCount":18}]},{"id":"lido-staked-sol","name":"Lido Staked SOL","symbol":"STSOL","active":true,"networks":[{"networkId":"solana","contractAddress":"7dHbWXmci3dT8UFYWYZweBLXgycu7Y3iL6trKn1Y7ARj","decimalCount":9}]},{"id":"republic-protocol","name":"REN","symbol":"REN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x408e41876cccdc0f92210600ef50372656052a38","decimalCount":18}]},{"id":"xsgd","name":"XSGD","symbol":"XSGD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x70e8de73ce538da2beed35d14187f6959a8eca96","decimalCount":6}]},{"id":"ceek","name":"CEEK Smart VR Token","symbol":"CEEK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb056c38f6b7dc4064367403e26424cd2c60655e1","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xe0f94ac5462997d2bc57287ac3a3ae4c31345d66","decimalCount":18}]},{"id":"baby-doge-coin","name":"Baby Doge Coin","symbol":"BABYDOGE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xac57de9c1a09fec648e93eb98875b212db0d460b","decimalCount":9},{"networkId":"binance-smart-chain","contractAddress":"0xc748673057861a797275cd8a068abb95a902e8de","decimalCount":9}]},{"id":"multichain","name":"Multichain","symbol":"MULTI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x65ef703f5594d2573eb71aaf55bc0cb548492df4","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x9fb9a33956351cf4fa040f65a13b835a3c8764e3","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x9fb9a33956351cf4fa040f65a13b835a3c8764e3","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x9fb9a33956351cf4fa040f65a13b835a3c8764e3","decimalCount":18},{"networkId":"fantom","contractAddress":"0x9fb9a33956351cf4fa040f65a13b835a3c8764e3","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x9fb9a33956351cf4fa040f65a13b835a3c8764e3","decimalCount":18}]},{"id":"biswap","name":"Biswap","symbol":"BSW","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x965f527d9159dce6288a2219db51fc6eef120dd1","decimalCount":18}]},{"id":"mobox","name":"Mobox","symbol":"MBOX","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x3203c9e46ca618c8c1ce5dc67e7e9d75f5da2377","decimalCount":18}]},{"id":"flex-usd","name":"flexUSD","symbol":"FLEXUSD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa774ffb4af6b0a91331c084e1aebae6ad535e6f3","decimalCount":18}]},{"id":"status","name":"Status","symbol":"SNT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x744d70fdbe2ba4cf95131626614a1763df805b9e","decimalCount":18}]},{"id":"maple","name":"Maple","symbol":"MPL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x33349b282065b0284d756f0577fb39c158f935e6","decimalCount":18}]},{"id":"raydium","name":"Raydium","symbol":"RAY","active":true,"networks":[{"networkId":"solana","contractAddress":"4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R","decimalCount":6}]},{"id":"orbs","name":"Orbs","symbol":"ORBS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xff56cc6b1e6ded347aa0b7676c85ab0b3d08b0fa","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xebd49b26169e1b52c04cfd19fcf289405df55f80","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x614389eaae0a6821dc49062d56bda3d9d45fa2ff","decimalCount":18}]},{"id":"wink","name":"WINkLink","symbol":"WIN","active":true,"networks":[{"networkId":"tron","contractAddress":"TLa2f6VPqDgRE67v1736s7bJ8Ray5wYjU7","decimalCount":6}]},{"id":"aurora-near","name":"Aurora","symbol":"AURORA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xaaaaaa20d9e0e2461697782ef11675f668207961","decimalCount":18}]},{"id":"pundi-x-2","name":"Pundi X","symbol":"PUNDIX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0fd10b9899882a6f2fcb5c371e17e70fdee00c38","decimalCount":18}]},{"id":"chromaway","name":"Chromia","symbol":"CHR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8a2279d4a90b6fe1c4b30fa660cc9f926797baa2","decimalCount":6},{"networkId":"binance-smart-chain","contractAddress":"0xf9cec8d50f6c8ad3fb6dccec577e05aa32b224fe","decimalCount":6}]},{"id":"xyo-network","name":"XYO Network","symbol":"XYO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x55296f69f40ea6d20e478533c15a6b08b654e758","decimalCount":18}]},{"id":"keep-network","name":"Keep Network","symbol":"KEEP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x85eee30c52b0b379b046fb0f85f4f3dc3009afec","decimalCount":18}]},{"id":"fetch-ai","name":"Fetch.ai","symbol":"FET","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xaea46a60368a7bd060eec7df8cba43b7ef41ad85","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x031b41e504677879370e9dbcf937283a8691fa7f","decimalCount":18}]},{"id":"btse-token","name":"BTSE Token","symbol":"BTSE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x666d875c600aa06ac1cf15641361dec3b00432ef","decimalCount":8}]},{"id":"stasis-eurs","name":"STASIS EURO","symbol":"EURS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdb25f211ab05b1c97d595516f45794528a807ad8","decimalCount":2},{"networkId":"polygon-pos","contractAddress":"0xe111178a87a3bff0c8d18decba5798827539ae99","decimalCount":2}]},{"id":"vulcan-forged","name":"Vulcan Forged","symbol":"PYR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x430ef9263e76dae63c84292c3409d61c598e9682","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x430ef9263e76dae63c84292c3409d61c598e9682","decimalCount":18}]},{"id":"benqi-liquid-staked-avax","name":"BENQI Liquid Staked AVAX","symbol":"SAVAX","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0x2b2c81e08f1af8835a78bb2a90ae924ace0ea4be","decimalCount":18}]},{"id":"spell-token","name":"Spell","symbol":"SPELL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x090185f2135308bad17527004364ebcc2d37e5f6","decimalCount":18},{"networkId":"avalanche","contractAddress":"0xce1bffbd5374dac86a2893119683f4911a2f7814","decimalCount":18},{"networkId":"fantom","contractAddress":"0x468003b688943977e6130f4f68f23aad939a1040","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x3e6648c5a70a150a88bce65f4ad4d506fe15d2af","decimalCount":18}]},{"id":"iron-bank-euro","name":"Iron Bank EURO","symbol":"IBEUR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x96e61422b6a9ba0e068b6c5add4ffabc6a4aae27","decimalCount":18}]},{"id":"seth2","name":"sETH2","symbol":"SETH2","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfe2e637202056d30016725477c5da089ab0a043a","decimalCount":18}]},{"id":"wazirx","name":"WazirX","symbol":"WRX","active":true,"networks":[{"networkId":"binancecoin","contractAddress":"WRX-ED1","decimalCount":8},{"networkId":"binance-smart-chain","contractAddress":"0x8e17ed70334c87ece574c9d537bc153d8609e2a3","decimalCount":8},{"networkId":"polygon-pos","contractAddress":"0x72d6066f486bd0052eefb9114b66ae40e0a6031a","decimalCount":8}]},{"id":"tribe-2","name":"Tribe","symbol":"TRIBE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc7283b66eb1eb5fb86327f08e1b5816b0720212b","decimalCount":18}]},{"id":"coti","name":"COTI","symbol":"COTI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xddb3422497e61e13543bea06989c0789117555c5","decimalCount":18}]},{"id":"liquity","name":"Liquity","symbol":"LQTY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6dea81c8171d0ba574754ef6f8b412f2ed88c54d","decimalCount":18}]},{"id":"insure","name":"inSure DeFi","symbol":"SURE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xcb86c6a22cb56b6cf40cafedb06ba0df188a416e","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x9b17baadf0f21f03e35249e0e59723f34994f806","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x5fc17416925789e0852fbfcd81c490ca4abc51f9","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xf88332547c680f755481bf489d890426248bb275","decimalCount":18}]},{"id":"fx-coin","name":"Function X","symbol":"FX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8c15ef5b4b21951d50e53e4fbda8298ffad25057","decimalCount":18}]},{"id":"injective-protocol","name":"Injective","symbol":"INJ","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe28b3b32b6c345a34ff64674606124dd5aceca30","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xa2b726b1145a4773f68593cf171187d8ebe4d495","decimalCount":18}]},{"id":"kirobo","name":"Kirobo","symbol":"KIRO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb1191f691a355b43542bea9b8847bc73e7abb137","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xf83c0f6d3a5665bd7cfdd5831a856d85942bc060","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xb382c1cfa622795a534e5bd56fac93d59bac8b0d","decimalCount":18}]},{"id":"civic","name":"Civic","symbol":"CVC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x41e5560054824ea6b0732e656e3ad64e20e94e45","decimalCount":8}]},{"id":"asd","name":"AscendEx Token","symbol":"ASD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xff742d05420b6aca4481f635ad8341f81a6300c2","decimalCount":18}]},{"id":"joe","name":"JOE","symbol":"JOE","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0x6e84a6216ea6dacc71ee8e6b0a5b7322eebc0fdd","decimalCount":18}]},{"id":"merit-circle","name":"Merit Circle","symbol":"MC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x949d48eca67b17269629c7194f4b727d4ef9e5d6","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x949d48eca67b17269629c7194f4b727d4ef9e5d6","decimalCount":18}]},{"id":"cartesi","name":"Cartesi","symbol":"CTSI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x491604c0fdf08347dd1fa4ee062a822a5dd06b5d","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x8da443f84fea710266c8eb6bc34b71702d033ef2","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x6b289cceaa8639e3831095d75a3e43520fabf552","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x2727ab1c2d22170abc9b595177b2d5c6e1ab7b7b","decimalCount":18}]},{"id":"origin-protocol","name":"Origin Protocol","symbol":"OGN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8207c1ffc5b6804f6024322ccf34f29c3541ae26","decimalCount":18}]},{"id":"origintrail","name":"OriginTrail","symbol":"TRAC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xaa7a9ca87d3694b5755f213b5d04094b8d0f0a6f","decimalCount":18}]},{"id":"power-ledger","name":"Power Ledger","symbol":"POWR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x595832f8fc6bf59c85c527fec3740a1b7a361269","decimalCount":6}]},{"id":"klever","name":"Klever","symbol":"KLV","active":true,"networks":[{"networkId":"tron","contractAddress":"TVj7RNVHy6thbM7BWdSe9G6gXwKhjhdNZS","decimalCount":6}]},{"id":"api3","name":"API3","symbol":"API3","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0b38210ea11411557c13457d4da7dc6ea731b88a","decimalCount":18}]},{"id":"hxro","name":"Hxro","symbol":"HXRO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4bd70556ae3f8a6ec6c4080a0c327b24325438f3","decimalCount":18}]},{"id":"dent","name":"Dent","symbol":"DENT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3597bfd533a99c9aa083587b074434e61eb0a258","decimalCount":8}]},{"id":"ankreth","name":"Ankr Reward-Bearing Staked ETH","symbol":"AETHC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe95a203b1a91a908f9b9ce46459d101078c2c3cb","decimalCount":18}]},{"id":"metis-token","name":"Metis Token","symbol":"METIS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9e32b13ce7f2e80a01932b42553652e053d6ed8e","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xe552fb52a4f19e44ef5a967632dbc320b0820639","decimalCount":18}]},{"id":"celer-network","name":"Celer Network","symbol":"CELR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4f9254c83eb525f9fcf346490bbb3ed28a81c667","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x3a8b787f78d775aecfeea15706d4221b40f345ab","decimalCount":18}]},{"id":"ultra","name":"Ultra","symbol":"UOS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd13c7342e1ef687c5ad21b27c2b65d772cab5c8c","decimalCount":4}]},{"id":"ellipsis","name":"Ellipsis [OLD]","symbol":"EPS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xa7f552078dcc247c2684336020c03648500c6d9f","decimalCount":18}]},{"id":"ocean-protocol","name":"Ocean Protocol","symbol":"OCEAN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x967da4048cd07ab37855c090aaf366e4ce1b9f48","decimalCount":18}]},{"id":"digitalbits","name":"DigitalBits","symbol":"XDB","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb9eefc4b0d472a44be93970254df4f4016569d27","decimalCount":7}]},{"id":"creditcoin-2","name":"Creditcoin","symbol":"CTC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa3ee21c306a700e682abcdfe9baa6a08f3820419","decimalCount":18}]},{"id":"balancer","name":"Balancer","symbol":"BAL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xba100000625a3754423978a60c9317c58a424e3d","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x9a71012b13ca4d3d0cdc72a177df3ef03b0e76a3","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x040d1edc9569d4bab2d15287dc5a4f10f56a56b8","decimalCount":18}]},{"id":"funfair","name":"FUNToken","symbol":"FUN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x419d0d8bdd9af5e606ae2232ed285aff190e711b","decimalCount":8}]},{"id":"tokamak-network","name":"Tokamak Network","symbol":"TON","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2be5e8c109e2197d077d13a82daead6a9b3433c5","decimalCount":18}]},{"id":"gpex","name":"GPEX","symbol":"GPX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3e7804c51a70ba26e904c2e0ab440c5623a8a83f","decimalCount":8}]},{"id":"coin98","name":"Coin98","symbol":"C98","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xae12c5930881c53715b369cec7606b70d8eb229f","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xaec945e04baf28b135fa7c640f624f8d90f1c3a6","decimalCount":18}]},{"id":"gensokishis-metaverse","name":"GensoKishi Metaverse","symbol":"MV","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0xa3c322ad15218fbfaed26ba7f616249f7705d945","decimalCount":18}]},{"id":"metal","name":"Metal","symbol":"MTL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf433089366899d83a9f26a773d59ec7ecf30355e","decimalCount":8}]},{"id":"sun-token","name":"Sun Token","symbol":"SUN","active":true,"networks":[{"networkId":"tron","contractAddress":"TSSMHYeV2uE9qYH95DqyoCuNCzEL1NvU3S","decimalCount":18}]},{"id":"storm","name":"StormX","symbol":"STMX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbe9375c6a420d2eeb258962efb95551a5b722803","decimalCount":18}]},{"id":"lukso-token","name":"LUKSO Token","symbol":"LYXE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa8b919680258d369114910511cc87595aec0be6d","decimalCount":18}]},{"id":"weway","name":"WeWay","symbol":"WWY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9ab70e92319f0b9127df78868fd3655fb9f1e322","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x9ab70e92319f0b9127df78868fd3655fb9f1e322","decimalCount":18}]},{"id":"nusd","name":"sUSD","symbol":"SUSD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x57ab1ec28d129707052df4df418d58a2d46d5f51","decimalCount":18},{"networkId":"fantom","contractAddress":"0x0e1694483ebb3b74d3054e383840c6cf011e518e","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0xa970af1a584579b618be4d69ad6f73459d112f95","decimalCount":18}]},{"id":"railgun","name":"Railgun","symbol":"RAIL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe76c6c83af64e4c60245d8c7de953df673a7a33d","decimalCount":18}]},{"id":"rari-governance-token","name":"Rari Governance Token","symbol":"RGT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd291e7a03283640fdc51b121ac401383a46cc623","decimalCount":18},{"networkId":"fantom","contractAddress":"0xcf726a06f3dcec8ef2b033336d138caa0eae5af2","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0xef888bca6ab6b1d26dbec977c455388ecd794794","decimalCount":18}]},{"id":"reef-finance","name":"Reef Finance","symbol":"REEF","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfe3e6a25e6b192a42a44ecddcd13796471735acf","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xf21768ccbc73ea5b6fd3c687208a7c2def2d966e","decimalCount":18}]},{"id":"mdex","name":"Mdex","symbol":"MDX","active":false,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x9c65ab58d8d978db963e63f2bfb7121627e3a739","decimalCount":18}]},{"id":"tokemak","name":"Tokemak","symbol":"TOKE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2e9d63788249371f1dfc918a52f8d799f4a38c94","decimalCount":18}]},{"id":"hoo-token","name":"Hoo Token","symbol":"HOO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd241d7b5cb0ef9fc79d9e4eb9e21f5e209f52f7d","decimalCount":8}]},{"id":"request-network","name":"Request","symbol":"REQ","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8f8221afbb33998d8584a2b05749ba73c37a938a","decimalCount":18}]},{"id":"poollotto-finance","name":"Poollotto.finance","symbol":"PLT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x631c2f0edabac799f07550aee4ff0bf7fd35212b","decimalCount":18}]},{"id":"perpetual-protocol","name":"Perpetual Protocol","symbol":"PERP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbc396689893d065f41bc2c6ecbee5e0085233447","decimalCount":18}]},{"id":"xsushi","name":"xSUSHI","symbol":"XSUSHI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8798249c2e607446efb7ad49ec89dd1865ff4272","decimalCount":18}]},{"id":"compound-basic-attention-token","name":"cBAT","symbol":"CBAT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6c8c6b02e7b2be14d4fa6022dfd6d75921d90e4e","decimalCount":8}]},{"id":"kyber-network","name":"Kyber Network Crystal Legacy","symbol":"KNCL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdd974d5c2e2928dea5f71b9825b8b646686bd200","decimalCount":18},{"networkId":"fantom","contractAddress":"0x765277eebeca2e31912c9946eae1021199b39c61","decimalCount":18}]},{"id":"metadium","name":"Metadium","symbol":"META","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xde2f7766c8bf14ca67193128535e5c7454f8387c","decimalCount":18}]},{"id":"mask-network","name":"Mask Network","symbol":"MASK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x69af81e73a73b40adf4f3d4223cd9b1ece623074","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x2ed9a5c8c13b93955103b9a7c167b67ef4d568a3","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x2b9e7ccdf0f4e5b24757c1e1a80e311e34cb10c7","decimalCount":18}]},{"id":"orchid-protocol","name":"Orchid Protocol","symbol":"OXT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4575f41308ec1483f3d399aa9a2826d74da13deb","decimalCount":18}]},{"id":"aavegotchi","name":"Aavegotchi","symbol":"GHST","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3f382dbd960e3a9bbceae22651e88158d2791550","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x385eeac5cb85a38a9a07a70c73e0a3271cfb54a7","decimalCount":18}]},{"id":"reserve-rights-token","name":"Reserve Rights Token","symbol":"RSR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x320623b8e4ff03373931769a31fc52a4e78b5d70","decimalCount":18}]},{"id":"radicle","name":"Radicle","symbol":"RAD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x31c8eacbffdd875c74b94b077895bd78cf1e64a3","decimalCount":18}]},{"id":"metahero","name":"Metahero","symbol":"HERO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xd40bedb44c081d2935eeba6ef5a3c8a31a1bbe13","decimalCount":18}]},{"id":"constitutiondao","name":"ConstitutionDAO","symbol":"PEOPLE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7a58c0be72be218b41c608b7fe7c5bb630736c71","decimalCount":18}]},{"id":"quark-chain","name":"QuarkChain","symbol":"QKC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xea26c4ac16d4a5a106820bc8aee85fd0b7b2b664","decimalCount":18}]},{"id":"nest","name":"Nest Protocol","symbol":"NEST","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x04abeda201850ac0124161f037efd70c74ddc74c","decimalCount":18}]},{"id":"biconomy","name":"Biconomy","symbol":"BICO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf17e65822b568b3903685a7c9f496cf7656cc6c2","decimalCount":18}]},{"id":"dopex","name":"Dopex","symbol":"DPX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xeec2be5c91ae7f8a338e1e5f3b5de49d07afdc81","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x6c2c06790b3e3e3c38e12ee22f8183b37a13ee55","decimalCount":18}]},{"id":"prometeus","name":"Prometeus","symbol":"PROM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfc82bb4ba86045af6f327323a46e80412b91b27d","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xaf53d56ff99f1322515e54fdde93ff8b3b7dafd5","decimalCount":18}]},{"id":"stratis","name":"Stratis","symbol":"STRAX","active":false,"networks":[{"networkId":"ethereum","contractAddress":"0xa3c22370de5f9544f0c4de126b1e46ceadf0a51b","decimalCount":18}]},{"id":"numeraire","name":"Numeraire","symbol":"NMR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1776e1f26f98b1a5df9cd347953a26dd3cb46671","decimalCount":18}]},{"id":"storj","name":"Storj","symbol":"STORJ","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb64ef51c888972c908cfacf59b47c1afbc0ab8ac","decimalCount":8}]},{"id":"strike","name":"Strike","symbol":"STRK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x74232704659ef37c08995e386a2e26cc27a8d7b1","decimalCount":18}]},{"id":"adshares","name":"Adshares","symbol":"ADS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xcfcecfe2bd2fed07a9145222e8a7ad9cf1ccd22a","decimalCount":11},{"networkId":"binance-smart-chain","contractAddress":"0xcfcecfe2bd2fed07a9145222e8a7ad9cf1ccd22a","decimalCount":11},{"networkId":"polygon-pos","contractAddress":"0x598e49f01befeb1753737934a5b11fea9119c796","decimalCount":11}]},{"id":"dawn-protocol","name":"Dawn Protocol","symbol":"DAWN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x580c8520deda0a441522aeae0f9f7a5f29629afa","decimalCount":18}]},{"id":"nerve-finance","name":"Nerve Finance","symbol":"NRV","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x42f6f551ae042cbe50c739158b4f0cac0edb9096","decimalCount":18}]},{"id":"bifrost","name":"Bifrost","symbol":"BFC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0c7d5ae016f806603cb1782bea29ac69471cab9c","decimalCount":18},{"networkId":"fantom","contractAddress":"0x84c882a4d8eb448ce086ea19418ca0f32f106117","decimalCount":18}]},{"id":"floki-inu","name":"Floki Inu","symbol":"FLOKI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xcf0c122c6b73ff809c693db761e7baebe62b6a2e","decimalCount":9},{"networkId":"binance-smart-chain","contractAddress":"0xfb5b838b6cfeedc2873ab27866079ac55363d37e","decimalCount":9}]},{"id":"stp-network","name":"STP Network","symbol":"STPT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xde7d85157d9714eadf595045cc12ca4a5f3e2adb","decimalCount":18}]},{"id":"hermez-network-token","name":"Hermez Network","symbol":"HEZ","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xeef9f339514298c6a857efcfc1a762af84438dee","decimalCount":18}]},{"id":"mango-markets","name":"Mango","symbol":"MNGO","active":true,"networks":[{"networkId":"solana","contractAddress":"MangoCzJ36AjZyKwVj3VnYU4GTonjfVEnJmvvWaxLac","decimalCount":6}]},{"id":"aelf","name":"aelf","symbol":"ELF","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbf2179859fc6d5bee9bf9158632dc51678a4100e","decimalCount":18}]},{"id":"uquid-coin","name":"Uquid Coin","symbol":"UQC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8806926ab68eb5a7b909dcaf6fdbe5d93271d6e2","decimalCount":18}]},{"id":"boba-network","name":"Boba Network","symbol":"BOBA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x42bbfa2e77757c645eeaad1655e0911a7553efbc","decimalCount":18}]},{"id":"efinity","name":"Efinity","symbol":"EFI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x656c00e1bcd96f256f224ad9112ff426ef053733","decimalCount":18}]},{"id":"veritaseum","name":"Veritaseum","symbol":"VERI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8f3470a7388c05ee4e7af3d01d8c722b0ff52374","decimalCount":18}]},{"id":"coinmetro","name":"Coinmetro","symbol":"XCM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x36ac219f90f5a6a3c77f2a7b660e3cc701f68e25","decimalCount":18}]},{"id":"sifchain","name":"Sifchain","symbol":"EROWAN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x07bac35846e5ed502aa91adf6a9e7aa210f2dcbe","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xa7051c5a22d963b81d71c2ba64d46a877fbc1821","decimalCount":18}]},{"id":"bezoge-earth","name":"Bezoge Earth","symbol":"BEZOGE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdc349913d53b446485e98b76800b6254f43df695","decimalCount":9}]},{"id":"sai","name":"Sai","symbol":"SAI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359","decimalCount":18}]},{"id":"ampleforth","name":"Ampleforth","symbol":"AMPL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd46ba6d942050d489dbd938a2c909a5d5039a161","decimalCount":9},{"networkId":"binance-smart-chain","contractAddress":"0xdb021b1b247fe2f1fa57e0a87c748cc1e321f07f","decimalCount":9},{"networkId":"avalanche","contractAddress":"0x027dbca046ca156de9622cd1e2d907d375e53aa7","decimalCount":9}]},{"id":"alpha-finance","name":"Alpha Venture DAO","symbol":"ALPHA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa1faa113cbe53436df28ff0aee54275c13b40975","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xa1faa113cbe53436df28ff0aee54275c13b40975","decimalCount":18}]},{"id":"band-protocol","name":"Band Protocol","symbol":"BAND","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xba11d00c5f74255f56a5e366f4f77f5a186d7f55","decimalCount":18},{"networkId":"fantom","contractAddress":"0x46e7628e8b4350b2716ab470ee0ba1fa9e76c6c5","decimalCount":18}]},{"id":"alchemy-pay","name":"Alchemy Pay","symbol":"ACH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xed04915c23f00a313a544955524eb7dbd823143d","decimalCount":8},{"networkId":"binance-smart-chain","contractAddress":"0xbc7d6b50616989655afd682fb42743507003056d","decimalCount":8}]},{"id":"sharering","name":"ShareToken","symbol":"SHR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd98f75b1a3261dab9eed4956c93f33749027a964","decimalCount":2}]},{"id":"jasmycoin","name":"JasmyCoin","symbol":"JASMY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7420b4b9a0110cdc71fb720908340c03f9bc03ec","decimalCount":18}]},{"id":"ufo-gaming","name":"UFO Gaming","symbol":"UFO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x249e38ea4102d0cf8264d3701f1a0e39c4f2dc3b","decimalCount":18}]},{"id":"wrapped-centrifuge","name":"Wrapped Centrifuge","symbol":"WCFG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc221b7e65ffc80de234bbb6667abdd46593d34f0","decimalCount":18}]},{"id":"singularitynet","name":"SingularityNET","symbol":"AGIX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5b7533812759b45c2b44c19e320ba2cd2681b542","decimalCount":8}]},{"id":"propy","name":"Propy","symbol":"PRO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x226bb599a12c826476e3a771454697ea52e9e220","decimalCount":8}]},{"id":"platoncoin","name":"PlatonCoin","symbol":"PLTC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x429d83bb0dcb8cdd5311e34680adc8b12070a07f","decimalCount":18}]},{"id":"utrust","name":"Utrust","symbol":"UTK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdc9ac3c20d1ed0b540df9b1fedc10039df13f99c","decimalCount":18}]},{"id":"ageur","name":"agEUR","symbol":"AGEUR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1a7e4e63778b4f12a199c062f3efdd288afcbce8","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xe0b52e49357fd4daf2c15e02058dce6bc0057db4","decimalCount":18}]},{"id":"dola-usd","name":"Dola","symbol":"DOLA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x865377367054516e17014ccded1e7d814edc9ce4","decimalCount":18}]},{"id":"truefi","name":"TrueFi","symbol":"TRU","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4c19596f5aaff459fa38b0f7ed92f11ae6543784","decimalCount":8}]},{"id":"temple","name":"TempleDAO","symbol":"TEMPLE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x470ebf5f030ed85fc1ed4c2d36b9dd02e77cf1b7","decimalCount":18}]},{"id":"tomb","name":"Tomb","symbol":"TOMB","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0xb84527d59b6ecb96f433029ecc890d4492c5dce1","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x0e98c977b943f06075b2d795794238fbfb9b9a34","decimalCount":18},{"networkId":"fantom","contractAddress":"0x6c021ae822bea943b2e66552bde1d2696a53fbb7","decimalCount":18}]},{"id":"shapeshift-fox-token","name":"ShapeShift FOX Token","symbol":"FOX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc770eefad204b5180df6a14ee197d99d808ee52d","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x65a05db8322701724c197af82c9cae41195b0aa8","decimalCount":18}]},{"id":"victoria-vr","name":"Victoria VR","symbol":"VR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7d5121505149065b562c789a0145ed750e6e8cdd","decimalCount":18}]},{"id":"origin-dollar","name":"Origin Dollar","symbol":"OUSD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2a8e1e676ec238d8a992307b495b45b3feaa5e86","decimalCount":18}]},{"id":"cvault-finance","name":"cVault.finance","symbol":"CORE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x62359ed7505efc61ff1d56fef82158ccaffa23d7","decimalCount":18}]},{"id":"iexec-rlc","name":"iExec RLC","symbol":"RLC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x607f4c5bb672230e8672085532f7e901544a7375","decimalCount":9}]},{"id":"aragon","name":"Aragon","symbol":"ANT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa117000000f279d81a1d3cc75430faa017fa5a2e","decimalCount":18}]},{"id":"everipedia","name":"Everipedia","symbol":"IQ","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x579cea1889991f68acc35ff5c3dd0621ff29b0c9","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x0e37d70b51ffa2b98b4d34a5712c5291115464e3","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xb9638272ad6998708de56bbc0a290a1de534a578","decimalCount":18}]},{"id":"nkn","name":"NKN","symbol":"NKN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5cf04716ba20127f1e2297addcf4b5035000c9eb","decimalCount":18}]},{"id":"proton","name":"Proton","symbol":"XPR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd7efb00d12c2c13131fd319336fdf952525da2af","decimalCount":4},{"networkId":"binance-smart-chain","contractAddress":"0x5de3939b2f811a61d830e6f52d13b066881412ab","decimalCount":4}]},{"id":"venus","name":"Venus","symbol":"XVS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xcf6bb5389c92bdda8a3747ddb454cb7a64626c63","decimalCount":18}]},{"id":"yoshi-exchange","name":"Yoshi.exchange","symbol":"YOSHI","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x4374f26f0148a6331905edf4cd33b89d8eed78d1","decimalCount":18},{"networkId":"fantom","contractAddress":"0x3dc57b391262e3aae37a08d91241f9ba9d58b570","decimalCount":18}]},{"id":"dusk-network","name":"DUSK Network","symbol":"DUSK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x940a2db1b7008b6c776d4faaca729d6d4a4aa551","decimalCount":18}]},{"id":"beefy-finance","name":"Beefy.Finance","symbol":"BIFI","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xca3f508b8e4dd382ee878a314789373d80a5190a","decimalCount":18},{"networkId":"avalanche","contractAddress":"0xd6070ae98b8069de6b494332d1a1a81b6179d960","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xfbdd194376de19a88118e84e279b977f165d01b8","decimalCount":18},{"networkId":"fantom","contractAddress":"0xd6070ae98b8069de6b494332d1a1a81b6179d960","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x99c409e5f62e4bd2ac142f17cafb6810b8f0baae","decimalCount":18}]},{"id":"polkastarter","name":"Polkastarter","symbol":"POLS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x83e6f1e41cdd28eaceb20cb649155049fac3d5aa","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x7e624fa0e1c4abfd309cc15719b7e2580887f570","decimalCount":18}]},{"id":"neutrino-system-base-token","name":"Neutrino System Base Token","symbol":"NSBT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9d79d5b61de59d882ce90125b18f74af650acb93","decimalCount":6}]},{"id":"sperax","name":"Sperax","symbol":"SPA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb4a3b0faf0ab53df58001804dda5bfc6a3d59008","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x5575552988a3a80504bbaeb1311674fcfd40ad4b","decimalCount":18}]},{"id":"kishu-inu","name":"Kishu Inu","symbol":"KISHU","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa2b4c0af19cc16a6cfacce81f192b024d625817d","decimalCount":9}]},{"id":"superfarm","name":"SuperFarm","symbol":"SUPER","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe53ec727dbdeb9e2d5456c3be40cff031ab40a55","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x51ba0b044d96c3abfca52b64d733603ccc4f0d4d","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xa1428174f516f527fafdd146b883bb4428682737","decimalCount":18}]},{"id":"unibright","name":"Unibright","symbol":"UBT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8400d94a5cb0fa0d041a3788e395285d61c9ee5e","decimalCount":8},{"networkId":"polygon-pos","contractAddress":"0x7fbc10850cae055b27039af31bd258430e714c62","decimalCount":8}]},{"id":"deapcoin","name":"DEAPCOIN","symbol":"DEP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1a3496c18d558bd9c6c8f609e1b129f67ab08163","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xcaf5191fc480f43e4df80106c7695eca56e48b18","decimalCount":18},{"networkId":"avalanche","contractAddress":"0xd4d026322c88c2d49942a75dff920fcfbc5614c1","decimalCount":18}]},{"id":"blox","name":"Blox","symbol":"CDT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x177d39ac676ed1c67a2b268ad7f1e58826e5b0af","decimalCount":18}]},{"id":"wonderland","name":"Wonderland","symbol":"TIME","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0xb54f16fb19478766a268f172c9480f8da1a7c9c3","decimalCount":9}]},{"id":"tornado-cash","name":"Tornado Cash","symbol":"TORN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x77777feddddffc19ff86db637967013e6c6a116c","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x1ba8d3c4c219b124d351f603060663bd1bcd9bbf","decimalCount":18}]},{"id":"yield-guild-games","name":"Yield Guild Games","symbol":"YGG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x25f8087ead173b73d6e8b84329989a8eea16cf73","decimalCount":18}]},{"id":"carry","name":"Carry","symbol":"CRE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x115ec79f1de567ec68b7ae7eda501b406626478e","decimalCount":18}]},{"id":"reflexer-ungovernance-token","name":"Reflexer Ungovernance Token","symbol":"FLX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6243d8cea23066d098a15582d81a598b4e8391f4","decimalCount":18}]},{"id":"bakerytoken","name":"BakerySwap","symbol":"BAKE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xe02df9e3e622debdd69fb838bb799e3f168902c5","decimalCount":18}]},{"id":"kardiachain","name":"KardiaChain","symbol":"KAI","active":false,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x39ae8eefb05138f418bb27659c21632dc1ddab10","decimalCount":18}]},{"id":"dei-token","name":"DEI","symbol":"DEI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xde12c7959e1a72bbe8a5f7a1dc8f8eef9ab011b3","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xde12c7959e1a72bbe8a5f7a1dc8f8eef9ab011b3","decimalCount":18},{"networkId":"fantom","contractAddress":"0xde12c7959e1a72bbe8a5f7a1dc8f8eef9ab011b3","decimalCount":18}]},{"id":"btc-standard-hashrate-token","name":"BTC Standard Hashrate Token","symbol":"BTCST","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x78650b139471520656b9e7aa7a5e9276814a38e9","decimalCount":17}]},{"id":"boringdao-[old]","name":"BoringDAO [OLD]","symbol":"BOR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3c9d6c1c73b31c837832c72e04d3152f051fc1a9","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x92d7756c60dcfd4c689290e8a9f4d263b3b32241","decimalCount":18}]},{"id":"aergo","name":"Aergo","symbol":"AERGO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x91af0fbb28aba7e31403cb457106ce79397fd4e6","decimalCount":18}]},{"id":"wozx","name":"Efforce","symbol":"WOZX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x34950ff2b487d9e5282c5ab342d08a2f712eb79f","decimalCount":18}]},{"id":"wrapped-nxm","name":"Wrapped NXM","symbol":"WNXM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0d438f3b5175bebc262bf23753c1e53d03432bde","decimalCount":18}]},{"id":"hunt-token","name":"HUNT","symbol":"HUNT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9aab071b4129b083b01cb5a0cb513ce7eca26fa5","decimalCount":18}]},{"id":"luffy-inu","name":"Luffy","symbol":"LUFFY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7121d00b4fa18f13da6c2e30d19c04844e6afdc8","decimalCount":9}]},{"id":"augur","name":"Augur","symbol":"REP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x221657776846890989a759ba2973e427dff5c9bb","decimalCount":18}]},{"id":"xcad-network","name":"XCAD Network","symbol":"XCAD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7659ce147d0e714454073a5dd7003544234b6aa0","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x431e0cd023a32532bf3969cddfc002c00e98429d","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xa55870278d6389ec5b524553d03c04f5677c061e","decimalCount":18}]},{"id":"musd","name":"mStable USD","symbol":"MUSD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe2f2a5c287993345a840db3b0845fbc70f5935a5","decimalCount":18}]},{"id":"aleph","name":"Aleph.im","symbol":"ALEPH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x27702a26126e0b3702af63ee09ac4d1a084ef628","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x82d2f8e02afb160dd5a480a617692e62de9038c4","decimalCount":18}]},{"id":"e-money","name":"e-Money","symbol":"NGM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xed0d5747a9ab03a75fbfec3228cd55848245b75d","decimalCount":6}]},{"id":"avinoc","name":"AVINOC","symbol":"AVINOC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf1ca9cb74685755965c7458528a36934df52a3ef","decimalCount":18}]},{"id":"orion-protocol","name":"Orion Protocol","symbol":"ORN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0258f474786ddfd37abce6df6bbb1dd5dfc4434a","decimalCount":8}]},{"id":"unifty","name":"Unifty","symbol":"NIF","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7e291890b01e5181f7ecc98d79ffbe12ad23df9e","decimalCount":18}]},{"id":"green-satoshi-token","name":"Green Satoshi Token","symbol":"GST","active":true,"networks":[{"networkId":"solana","contractAddress":"AFbX8oGjGpmVFywbVouvhQSRmiW2aR1mohfahi4Y2AdB","decimalCount":9}]},{"id":"rainbow-token-2","name":"Crypto Unicorns Rainbow","symbol":"RBW","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0x431cd3c9ac9fc73644bf68bf5691f4b83f9e104f","decimalCount":18}]},{"id":"cocos-bcx","name":"COCOS BCX","symbol":"COCOS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc4c7ea4fab34bd9fb9a5e1b1a98df76e26e6407c","decimalCount":18}]},{"id":"cult-dao","name":"Cult DAO","symbol":"CULT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf0f9d895aca5c8678f706fb8216fa22957685a13","decimalCount":18}]},{"id":"badger-dao","name":"Badger DAO","symbol":"BADGER","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3472a5a71965499acd81997a54bba8d852c6e53d","decimalCount":18},{"networkId":"fantom","contractAddress":"0x753fbc5800a8c8e3fb6dc6415810d627a387dfc9","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0xbfa641051ba0a0ad1b0acf549a89536a0d76472e","decimalCount":18}]},{"id":"dodo","name":"DODO","symbol":"DODO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x43dfc4159d86f3a37a5a4b3d4580b888ad7d4ddd","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x67ee3cb086f8a16f34bee3ca72fad36f7db929e2","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xe4bf2864ebec7b7fdf6eeca9bacae7cdfdaffe78","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x69eb4fa4a2fbd498c257c57ea8b7655a2559a581","decimalCount":18}]},{"id":"seth","name":"sETH","symbol":"SETH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5e74c9036fb86bd7ecdcb084a0673efc32ea31cb","decimalCount":18}]},{"id":"my-neighbor-alice","name":"My Neighbor Alice","symbol":"ALICE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xac51066d7bec65dc4589368da368b212745d63e8","decimalCount":6},{"networkId":"binance-smart-chain","contractAddress":"0xac51066d7bec65dc4589368da368b212745d63e8","decimalCount":6}]},{"id":"covalent","name":"Covalent","symbol":"CQT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd417144312dbf50465b1c641d016962017ef6240","decimalCount":18}]},{"id":"bitrue-token","name":"Bitrue Coin","symbol":"BTR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd433138d12beb9929ff6fd583dc83663eea6aaa5","decimalCount":18}]},{"id":"toucan-protocol-base-carbon-tonne","name":"Toucan Protocol: Base Carbon Tonne","symbol":"BCT","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0x2f800db0fdb5223b3c3f354886d907a671414a7f","decimalCount":18}]},{"id":"koda-finance","name":"Koda Cryptocurrency","symbol":"KODA","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x8094e772fa4a60bdeb1dfec56ab040e17dd608d5","decimalCount":9}]},{"id":"seedify-fund","name":"Seedify.fund","symbol":"SFUND","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x477bc8d23c634c154061869478bce96be6045d12","decimalCount":18}]},{"id":"nominex","name":"Nominex","symbol":"NMX","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xd32d01a43c869edcd1117c640fbdcfcfd97d9d65","decimalCount":18}]},{"id":"yfii-finance","name":"DFI.money","symbol":"YFII","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa1d0e215a23d7030842fc67ce582a6afa3ccab83","decimalCount":18}]},{"id":"rook","name":"Rook","symbol":"ROOK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfa5047c9c78b8877af97bdcb85db743fd7313d4a","decimalCount":18}]},{"id":"defipulse-index","name":"DeFi Pulse Index","symbol":"DPI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1494ca1f11d487c2bbe4543e90080aeba4ba3c2b","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x85955046df4668e1dd369d2de9f3aeb98dd2a369","decimalCount":18}]},{"id":"alpaca-finance","name":"Alpaca Finance","symbol":"ALPACA","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x8f0528ce5ef7b51152a59745befdd91d97091d2f","decimalCount":18},{"networkId":"fantom","contractAddress":"0xad996a45fd2373ed0b10efa4a8ecb9de445a4302","decimalCount":18}]},{"id":"beta-finance","name":"Beta Finance","symbol":"BETA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbe1a001fe942f96eea22ba08783140b9dcc09d28","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xbe1a001fe942f96eea22ba08783140b9dcc09d28","decimalCount":18}]},{"id":"mainframe","name":"Hifi Finance","symbol":"MFT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdf2c7238198ad8b389666574f2d8bc411a4b7428","decimalCount":18}]},{"id":"dopex-rebate-token","name":"Dopex Rebate","symbol":"RDPX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0ff5a8451a839f5f0bb3562689d9a44089738d11","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x32eb7902d4134bf98a28b963d26de779af92a212","decimalCount":18}]},{"id":"aurory","name":"Aurory","symbol":"AURY","active":true,"networks":[{"networkId":"solana","contractAddress":"AURYydfxJib1ZkTir1Jn1J9ECYUtjb6rKQVmtYaixWPP","decimalCount":9}]},{"id":"keep3rv1","name":"Keep3rV1","symbol":"KP3R","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1ceb5cb57c4d4e2b2433641b95dd330a33185a44","decimalCount":18},{"networkId":"fantom","contractAddress":"0x2a5062d22adcfaafbd5c541d4da82e4b450d4212","decimalCount":18}]},{"id":"auction","name":"Bounce","symbol":"AUCTION","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa9b1eb5908cfc3cdf91f9b8b3a74108598009096","decimalCount":18}]},{"id":"alien-worlds","name":"Alien Worlds","symbol":"TLM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x888888848b652b3e3a0f34c96e00eec0f3a23f72","decimalCount":4}]},{"id":"anchor-protocol","name":"Anchor Protocol","symbol":"ANC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0f3adc247e91c3c50bc08721355a41037e89bc20","decimalCount":18}]},{"id":"spookyswap","name":"Spookyswap","symbol":"BOO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x55af5865807b196bd0197e0902746f31fbccfa58","decimalCount":18},{"networkId":"avalanche","contractAddress":"0xbd83010eb60f12112908774998f65761cf9f6f9a","decimalCount":18},{"networkId":"fantom","contractAddress":"0x841fad6eae12c286d1fd18d1d525dffa75c7effe","decimalCount":18}]},{"id":"ethlend","name":"Aave [OLD]","symbol":"LEND","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x80fb784b7ed66730e8b1dbd9820afd29931aab03","decimalCount":18}]},{"id":"compound-0x","name":"c0x","symbol":"CZRX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb3319f5d18bc0d84dd1b4825dcde5d5f7266d407","decimalCount":8}]},{"id":"melon","name":"Enzyme","symbol":"MLN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xec67005c4e498ec7f55e092bd1d35cbc47c91892","decimalCount":18}]},{"id":"compound-uniswap","name":"cUNI","symbol":"CUNI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x35a18000230da775cac24873d00ff85bccded550","decimalCount":8}]},{"id":"alchemix","name":"Alchemix","symbol":"ALCX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdbdb4d16eda451d0503b854cf79d55697f90c8df","decimalCount":18}]},{"id":"presearch","name":"Presearch","symbol":"PRE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xec213f83defb583af3a000b1c0ada660b1902a0f","decimalCount":18}]},{"id":"phantasma","name":"Phantasma","symbol":"SOUL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x75858677e27c930fb622759feaffee2b754af07f","decimalCount":8},{"networkId":"binance-smart-chain","contractAddress":"0x298eff8af1ecebbb2c034eaa3b9a5d0cc56c59cd","decimalCount":8}]},{"id":"umee","name":"Umee","symbol":"UMEE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc0a4df35568f116c370e6a6a6022ceb908eeddac","decimalCount":6}]},{"id":"clover-finance","name":"Clover Finance","symbol":"CLV","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x80c62fe4487e1351b47ba49809ebd60ed085bf52","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x09e889bb4d5b474f561db0491c38702f367a4e4d","decimalCount":18}]},{"id":"everrise","name":"EverRise","symbol":"RISE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc17c30e98541188614df99239cabd40280810ca3","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xc17c30e98541188614df99239cabd40280810ca3","decimalCount":18},{"networkId":"avalanche","contractAddress":"0xc17c30e98541188614df99239cabd40280810ca3","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xc17c30e98541188614df99239cabd40280810ca3","decimalCount":18},{"networkId":"fantom","contractAddress":"0xc17c30e98541188614df99239cabd40280810ca3","decimalCount":18}]},{"id":"klima-dao","name":"Klima DAO","symbol":"KLIMA","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0x4e78011ce80ee02d2c3e649fb657e45898257815","decimalCount":9}]},{"id":"decentral-games","name":"Decentral Games","symbol":"DG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4b520c812e8430659fc9f12f6d0c39026c83588d","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xef938b6da8576a896f6e0321ef80996f4890f9c4","decimalCount":18}]},{"id":"axion","name":"Axion","symbol":"AXN","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0x839f1a22a59eaaf26c85958712ab32f80fea23d9","decimalCount":18}]},{"id":"dvision-network","name":"Dvision Network","symbol":"DVI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x10633216e7e8281e33c86f02bf8e565a635d9770","decimalCount":18}]},{"id":"splinterlands","name":"Splinterlands","symbol":"SPS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x1633b7157e7638c4d6593436111bf125ee74703f","decimalCount":18}]},{"id":"elastos","name":"Elastos","symbol":"ELA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe6fd75ff38adca4b97fbcd938c86b98772431867","decimalCount":18}]},{"id":"mirror-protocol","name":"Mirror Protocol","symbol":"MIR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x09a3ecafa817268f77be1283176b946c4ff2e608","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x5b6dcf557e2abe2323c48445e8cc948910d8c2c9","decimalCount":18}]},{"id":"usdk","name":"USDK","symbol":"USDK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1c48f86ae57291f7686349f12601910bd8d470bb","decimalCount":18}]},{"id":"aioz-network","name":"AIOZ Network","symbol":"AIOZ","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x626e8036deb333b408be468f951bdb42433cbf18","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x33d08d8c7a168333a85285a68c0042b39fc3741d","decimalCount":18}]},{"id":"loom-network","name":"Loom Network (OLD)","symbol":"LOOMOLD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa4e8c3ec456107ea67d3075bf9e3df3a75823db0","decimalCount":18}]},{"id":"zignaly","name":"Zignaly","symbol":"ZIG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb2617246d0c6c0087f18703d576831899ca94f01","decimalCount":18}]},{"id":"district0x","name":"district0x","symbol":"DNT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0abdace70d3790235af448c88547603b945604ea","decimalCount":18}]},{"id":"starlink","name":"StarLink","symbol":"STARL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8e6cd950ad6ba651f6dd608dc70e5886b1aa6b24","decimalCount":18}]},{"id":"gyen","name":"GYEN","symbol":"GYEN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc08512927d12348f6620a698105e1baac6ecd911","decimalCount":6}]},{"id":"lto-network","name":"LTO Network","symbol":"LTO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd01409314acb3b245cea9500ece3f6fd4d70ea30","decimalCount":8},{"networkId":"binance-smart-chain","contractAddress":"0x857b222fc79e1cbbf8ca5f78cb133d1b7cf34bbd","decimalCount":18}]},{"id":"handshake","name":"Handshake","symbol":"HNS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa771b49064da011df051052848477f18dba1d2ac","decimalCount":6}]},{"id":"doge-army-token","name":"Doge Army","symbol":"DGAT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x96e3bd1915483ed6e6569e908a0f6f49434557ed","decimalCount":18}]},{"id":"qanplatform","name":"QANplatform","symbol":"QANX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xaaa7a10a8ee237ea61e8ac46c50a8db8bcc1baaa","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xaaa7a10a8ee237ea61e8ac46c50a8db8bcc1baaa","decimalCount":18}]},{"id":"qredo","name":"Qredo","symbol":"QRDO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4123a133ae3c521fd134d7b13a2dec35b56c2463","decimalCount":8}]},{"id":"qash","name":"QASH","symbol":"QASH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x618e75ac90b12c6049ba3b27f5d5f8651b0037f6","decimalCount":6}]},{"id":"verasity","name":"Verasity","symbol":"VRA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf411903cbc70a74d22900a5de66a2dda66507255","decimalCount":18}]},{"id":"xmon","name":"XMON","symbol":"XMON","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3aada3e213abf8529606924d8d1c55cbdc70bf74","decimalCount":18}]},{"id":"vectorspace","name":"Vectorspace AI","symbol":"VXV","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7d29a64504629172a429e64183d6673b9dacbfce","decimalCount":18}]},{"id":"butterflydao","name":"Redacted Cartel","symbol":"BTRFLY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc0d4ceb216b3ba9c3701b291766fdcba977cec3a","decimalCount":9}]},{"id":"alpha-quark-token","name":"Alpha Quark Token","symbol":"AQT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2a9bdcff37ab68b95a53435adfd8892e86084f93","decimalCount":18}]},{"id":"cudos","name":"Cudos","symbol":"CUDOS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x817bbdbc3e8a1204f3691d14bb44992841e3db35","decimalCount":18}]},{"id":"adventure-gold","name":"Adventure Gold","symbol":"AGLD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x32353a6c91143bfd6c7d363b546e62a9a2489a20","decimalCount":18}]},{"id":"allianceblock","name":"AllianceBlock","symbol":"ALBT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x00a8b738e453ffd858a7edf03bccfe20412f0eb0","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x9e037de681cafa6e661e6108ed9c2bd1aa567ecd","decimalCount":18}]},{"id":"aurora-dao","name":"IDEX","symbol":"IDEX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb705268213d593b8fd88d3fdeff93aff5cbdcfae","decimalCount":18}]},{"id":"bzx-protocol","name":"bZx Protocol","symbol":"BZRX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x56d811088235f11c8920698a204a5010a788f4b3","decimalCount":18}]},{"id":"superrare","name":"SuperRare","symbol":"RARE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xba5bde662c17e2adff1075610382b9b691296350","decimalCount":18}]},{"id":"lcx","name":"LCX","symbol":"LCX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x037a54aab062628c9bbae1fdb1583c195585fe41","decimalCount":18}]},{"id":"safepal","name":"SafePal","symbol":"SFP","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xd41fdb03ba84762dd66a0af1a6c8540ff1ba5dfb","decimalCount":18}]},{"id":"concierge-io","name":"Travala.com","symbol":"AVA","active":true,"networks":[{"networkId":"binancecoin","contractAddress":"AVA-645","decimalCount":8}]},{"id":"gains-farm","name":"Gains Farm","symbol":"GFARM2","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x831091da075665168e01898c6dac004a867f1e1b","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x7075cab6bcca06613e2d071bd918d1a0241379e2","decimalCount":18}]},{"id":"quick","name":"Quickswap [OLD]","symbol":"QUICK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6c28aef8977c9b773996d0e8376d2ee379446f2f","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x831753dd7087cac61ab5644b308642cc1c33dc13","decimalCount":18}]},{"id":"sbtc","name":"sBTC","symbol":"SBTC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfe18be6b3bd88a2d2a7f928d00292e7a9963cfc6","decimalCount":18}]},{"id":"singularitydao","name":"SingularityDAO","symbol":"SDAO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x993864e43caa7f7f12953ad6feb1d1ca635b875f","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x90ed8f1dc86388f14b64ba8fb4bbd23099f18240","decimalCount":18}]},{"id":"shiba-predator","name":"Shiba Predator","symbol":"QOM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa71d0588eaf47f12b13cf8ec750430d21df04974","decimalCount":18}]},{"id":"jet","name":"JET","symbol":"JET","active":true,"networks":[{"networkId":"solana","contractAddress":"JET6zMJWkCN9tpRT2v2jfAmm5VnQFDpUBCyaKojmGtz","decimalCount":9}]},{"id":"automata","name":"Automata","symbol":"ATA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa2120b9e674d3fc3875f415a7df52e382f141225","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xa2120b9e674d3fc3875f415a7df52e382f141225","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x0df0f72ee0e5c9b7ca761ecec42754992b2da5bf","decimalCount":18}]},{"id":"marketpeak","name":"PEAKDEFI","symbol":"PEAK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x630d98424efe0ea27fb1b3ab7741907dffeaad78","decimalCount":8}]},{"id":"boson-protocol","name":"Boson Protocol","symbol":"BOSON","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc477d038d5420c6a9e0b031712f61c5120090de9","decimalCount":18}]},{"id":"market-making-pro","name":"Market Making Pro","symbol":"MMPRO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x6067490d05f3cf2fdffc0e353b1f5fd6e5ccdf70","decimalCount":18}]},{"id":"bonfida","name":"Bonfida","symbol":"FIDA","active":true,"networks":[{"networkId":"solana","contractAddress":"EchesyfXePKdLtoiZSL8pBe8Myagyy8ZRqsACNCFGnvp","decimalCount":6}]},{"id":"interest-bearing-bitcoin","name":"Interest Bearing Bitcoin","symbol":"IBBTC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc4e15973e6ff2a35cc804c2cf9d2a1b817a8b40f","decimalCount":18}]},{"id":"maps","name":"MAPS","symbol":"MAPS","active":true,"networks":[{"networkId":"solana","contractAddress":"MAPS41MDahZ9QdKXhVa4dWB9RuyfV4XqhyAZ8XcYepb","decimalCount":6}]},{"id":"snowbank","name":"Snowbank","symbol":"SB","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0x7d1232b90d3f809a54eeaeebc639c62df8a8942f","decimalCount":9}]},{"id":"feg-token-bsc","name":"FEG Token BSC","symbol":"FEG","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xacfc95585d80ab62f67a14c566c1b7a49fe91167","decimalCount":9}]},{"id":"jpeg-d","name":"JPEG'd","symbol":"JPEG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe80c0cd204d654cebe8dd64a4857cab6be8345a3","decimalCount":18}]},{"id":"refereum","name":"Refereum","symbol":"RFR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd0929d411954c47438dc1d871dd6081f5c5e149c","decimalCount":4}]},{"id":"gitcoin","name":"Gitcoin","symbol":"GTC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xde30da39c46104798bb5aa3fe8b9e0e1f348163f","decimalCount":18}]},{"id":"noia-network","name":"Syntropy","symbol":"NOIA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa8c8cfb141a3bb59fea1e2ea6b79b5ecbcd7b6ca","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x957d1ad5214468332c5e6c00305a25116f9a46bb","decimalCount":18}]},{"id":"arpa-chain","name":"ARPA Chain","symbol":"ARPA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xba50933c268f567bdc86e1ac131be072c6b0b71a","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xee800b277a96b0f490a1a732e1d6395fad960a26","decimalCount":18}]},{"id":"ribbon-finance","name":"Ribbon Finance","symbol":"RBN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6123b0049f904d730db3c36a31167d9d4121fa6b","decimalCount":18}]},{"id":"genopets","name":"Genopets","symbol":"GENE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x9df465460938f9ebdf51c38cc87d72184471f8f0","decimalCount":18},{"networkId":"solana","contractAddress":"GENEtH5amGSi8kHAtQoezp1XEXwZJ8vcuePYnXdKrMYz","decimalCount":9}]},{"id":"marlin","name":"Marlin","symbol":"POND","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x57b946008913b82e4df85f501cbaed910e58d26c","decimalCount":18}]},{"id":"bitmart-token","name":"BitMart Token","symbol":"BMX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x986ee2b944c42d017f52af21c4c69b84dbea35d8","decimalCount":18}]},{"id":"harvest-finance","name":"Harvest Finance","symbol":"FARM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa0246c9032bc3a600820415ae600c6388619a14d","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x4b5c23cac08a567ecf0c1ffca8372a45a5d33743","decimalCount":18}]},{"id":"rootkit","name":"Rootkit","symbol":"ROOT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xcb5f72d37685c3d5ad0bb5f982443bc8fcdf570e","decimalCount":18}]},{"id":"eth-2x-flexible-leverage-index","name":"Index Coop - ETH 2x Flexible Leverage Index","symbol":"ETH2X-FLI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xaa6e8127831c9de45ae56bb1b0d4d4da6e5665bd","decimalCount":18}]},{"id":"derivadao","name":"DerivaDAO","symbol":"DDX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3a880652f47bfaa771908c07dd8673a787daed3a","decimalCount":18}]},{"id":"refinable","name":"Refinable","symbol":"FINE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x4e6415a5727ea08aae4580057187923aec331227","decimalCount":18}]},{"id":"rai","name":"Rai Reflex Index","symbol":"RAI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x03ab458634910aad20ef5f1c8ee96f1d6ac54919","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x97cd1cfe2ed5712660bb6c14053c0ecb031bff7d","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x00e5646f60ac6fb446f621d146b6e1886f002905","decimalCount":18}]},{"id":"adex","name":"Ambire AdEx","symbol":"ADX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xade00c28244d5ce17d72e40330b1c318cd12b7c3","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x6bff4fb161347ad7de4a625ae5aa3a1ca7077819","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xc8e36f0a44fbeca89fdd5970439cbe62eb4b5d03","decimalCount":18}]},{"id":"magic","name":"Magic","symbol":"MAGIC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb0c7a3ba49c7a6eaba6cd4a96c55a1391070ac9a","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x539bde0d7dbd336b79148aa742883198bbf60342","decimalCount":18}]},{"id":"sovryn","name":"Sovryn","symbol":"SOV","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbdab72602e9ad40fc6a6852caf43258113b8f7a5","decimalCount":18}]},{"id":"token-pocket","name":"Token Pocket","symbol":"TPT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4161725d019690a3e0de50f6be67b07a86a9fae1","decimalCount":4},{"networkId":"binance-smart-chain","contractAddress":"0xeca41281c24451168a37211f0bc2b8645af45092","decimalCount":4}]},{"id":"koinos","name":"Koinos","symbol":"KOIN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x66d28cb58487a7609877550e1a34691810a6b9fc","decimalCount":8}]},{"id":"linear","name":"Linear","symbol":"LINA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3e9bc21c9b189c09df3ef1b824798658d5011937","decimalCount":18}]},{"id":"feg-token","name":"FEG Token","symbol":"FEG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x389999216860ab8e0175387a0c90e5c52522c945","decimalCount":9}]},{"id":"circuits-of-value","name":"Circuits of Value","symbol":"COVAL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3d658390460295fb963f54dc0899cfb1c30776df","decimalCount":8},{"networkId":"binance-smart-chain","contractAddress":"0xd15cee1deafbad6c0b3fd7489677cc102b141464","decimalCount":8},{"networkId":"polygon-pos","contractAddress":"0x4597c8a59ab28b36840b82b3a674994a279593d0","decimalCount":8},{"networkId":"fantom","contractAddress":"0x8b8407c6184f1f0fd1082e83d6a3b8349caced12","decimalCount":8}]},{"id":"box-token","name":"BOX Token","symbol":"BOX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe1a178b681bd05964d3e3ed33ae731577d9d96dd","decimalCount":18}]},{"id":"x2y2","name":"X2Y2","symbol":"X2Y2","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1e4ede388cbc9f4b5c79681b7f94d36a11abebc9","decimalCount":18}]},{"id":"swarm-bzz","name":"Swarm","symbol":"BZZ","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x19062190b1925b5b6689d7073fdfc8c2976ef8cb","decimalCount":16}]},{"id":"bnb48-club-token","name":"BNB48 Club Token","symbol":"KOGE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xe6df05ce8c8301223373cf5b969afcb1498c5528","decimalCount":18}]},{"id":"kin","name":"Kin","symbol":"KIN","active":false,"networks":[{"networkId":"solana","contractAddress":"kinXdEcpDQeHPEuQnqmUgtYykqKGVFq6CeVX5iAHJq6","decimalCount":5}]},{"id":"ampleforth-governance-token","name":"Ampleforth Governance Token","symbol":"FORTH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x77fba179c79de5b7653f68b5039af940ada60ce0","decimalCount":18}]},{"id":"woonkly-power","name":"Woonkly Power","symbol":"WOOP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xaad483f97f13c6a20b9d05d07c397ce85c42c393","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x8b303d5bbfbbf46f1a4d9741e491e06986894e18","decimalCount":18}]},{"id":"alpine-f1-team-fan-token","name":"Alpine F1 Team Fan Token","symbol":"ALPINE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x287880ea252b52b63cc5f40a2d3e5a44aa665a76","decimalCount":8}]},{"id":"velo","name":"Velo","symbol":"VELO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xf486ad071f3bee968384d2e39e2d8af0fcf6fd46","decimalCount":18}]},{"id":"dvf","name":"DeversiFi","symbol":"DVF","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdddddd4301a082e62e84e43f474f044423921918","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0xa7aa2921618e3d63da433829d448b58c9445a4c3","decimalCount":18}]},{"id":"redfox-labs-2","name":"RFOX","symbol":"RFOX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa1d6df714f91debf4e0802a542e13067f31b8262","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x0a3a21356793b49154fd3bbe91cbc2a16c0457f5","decimalCount":18}]},{"id":"wilder-world","name":"Wilder World","symbol":"WILD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2a3bff78b79a009976eea096a51a948a3dc00e34","decimalCount":18}]},{"id":"saito","name":"Saito","symbol":"SAITO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfa14fa6958401314851a17d6c5360ca29f74b57b","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x3c6dad0475d3a1696b359dc04c99fd401be134da","decimalCount":18}]},{"id":"marcopolo","name":"MAP Protocol","symbol":"MAP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9e976f211daea0d652912ab99b0dc21a7fd728e4","decimalCount":18}]},{"id":"ethernity-chain","name":"Ethernity Chain","symbol":"ERN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbbc2ae13b23d715c30720f079fcd9b4a74093505","decimalCount":18}]},{"id":"ovr","name":"Ovr","symbol":"OVR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x21bfbda47a0b4b5b1248c767ee49f7caa9b23697","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x7e35d0e9180bf3a1fc47b0d110be7a21a10b41fe","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x1631244689ec1fecbdd22fb5916e920dfc9b8d30","decimalCount":18}]},{"id":"mossland","name":"Mossland","symbol":"MOC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x865ec58b06bf6305b886793aa20a2da31d034e68","decimalCount":18}]},{"id":"tomb-shares","name":"Tomb Shares","symbol":"TSHARE","active":true,"networks":[{"networkId":"fantom","contractAddress":"0x4cdf39285d7ca8eb3f090fda0c069ba5f4145b37","decimalCount":18}]},{"id":"aeternity","name":"Aeternity","symbol":"AE","active":false,"networks":[{"networkId":"ethereum","contractAddress":"0x5ca9a71b1d01849c0a95490cc00559717fcf0d1d","decimalCount":18}]},{"id":"pundi-x","name":"Pundi X [OLD]","symbol":"NPXS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa15c7ebe1f07caf6bff097d8a589fb8ac49ae5b3","decimalCount":18}]},{"id":"rupiah-token","name":"Rupiah Token","symbol":"IDRT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x998ffe1e43facffb941dc337dd0468d52ba5b48a","decimalCount":2}]},{"id":"trustswap","name":"Trustswap","symbol":"SWAP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xcc4304a31d09258b0029ea7fe63d032f52e44efe","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x82443a77684a7da92fdcb639c8d2bd068a596245","decimalCount":18},{"networkId":"avalanche","contractAddress":"0xc7b5d72c836e718cda8888eaf03707faef675079","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x3809dcdd5dde24b37abe64a5a339784c3323c44f","decimalCount":18}]},{"id":"hi-dollar","name":"hi Dollar","symbol":"HI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc4f6e93aeddc11dc22268488465babcaf09399ac","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x77087ab5df23cfb52449a188e80e9096201c2097","decimalCount":18}]},{"id":"rai-finance","name":"RAI Finance","symbol":"SOFI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb49fa25978abf9a248b8212ab4b87277682301c0","decimalCount":18}]},{"id":"decentral-games-governance","name":"Decentral Games Governance","symbol":"XDG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4f81c790581b240a5c948afd173620ecc8c71c8d","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xc6480da81151b2277761024599e8db2ad4c388c8","decimalCount":18}]},{"id":"richquack","name":"Rich Quack","symbol":"QUACK","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xd74b782e05aa25c50e7330af541d46e18f36661c","decimalCount":9}]},{"id":"alethea-artificial-liquid-intelligence-token","name":"Alethea Artificial Liquid Intelligence","symbol":"ALI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6b0b3a982b4634ac68dd83a4dbf02311ce324181","decimalCount":18}]},{"id":"pha","name":"Phala Network","symbol":"PHA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6c5ba91642f10282b576d91922ae6448c9d52f4e","decimalCount":18}]},{"id":"reserve","name":"Reserve","symbol":"RSV","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x196f4727526ea7fb1e17b2071b3d8eaa38486988","decimalCount":18}]},{"id":"hopr","name":"HOPR","symbol":"HOPR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf5581dfefd8fb0e4aec526be659cfab1f8c781da","decimalCount":18}]},{"id":"dia-data","name":"DIA","symbol":"DIA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x84ca8bc7997272c7cfb4d0cd3d55cd942b3c9419","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x99956d38059cf7beda96ec91aa7bb2477e0901dd","decimalCount":18}]},{"id":"polyswarm","name":"PolySwarm","symbol":"NCT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9e46a38f5daabe8683e10793b06749eef7d733d1","decimalCount":18}]},{"id":"morpheus-network","name":"Morpheus Network","symbol":"MNW","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd3e4ba569045546d09cf021ecc5dfe42b1d7f6e4","decimalCount":18}]},{"id":"zenon","name":"Zenon","symbol":"ZNN","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x84b174628911896a3b87fa6980d05dbc2ee74836","decimalCount":8}]},{"id":"civilization","name":"Civilization","symbol":"CIV","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x37fe0f067fa808ffbdd12891c0858532cfe7361d","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x42f6bdcfd82547e89f1069bf375aa60e6c6c063d","decimalCount":18}]},{"id":"apollox-2","name":"ApolloX","symbol":"APX","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x78f5d389f5cdccfc41594abab4b0ed02f31398b3","decimalCount":18}]},{"id":"hedpay","name":"HEdpAY","symbol":"HDP.Ф","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc4d5545392f5fc57eba3af8981815669bb7e2a48","decimalCount":4}]},{"id":"pstake-finance","name":"pSTAKE Finance","symbol":"PSTAKE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfb5c6815ca3ac72ce9f5006869ae67f18bf77006","decimalCount":18}]},{"id":"somnium-space-cubes","name":"Somnium Space CUBEs","symbol":"CUBE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdf801468a808a32656d2ed2d2d80b72a129739f4","decimalCount":8}]},{"id":"coin-of-the-champions","name":"Coin of the champions","symbol":"COC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc4bb7277a74678f053259cb1f96140347efbfd46","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xbdc3b3639f7aa19e623a4d603a3fb7ab20115a91","decimalCount":18}]},{"id":"yield-app","name":"YIELD App","symbol":"YLD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf94b5c5651c888d928439ab6514b93944eee6f48","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x4cebdbcb286101a17d3ea1f7fe7bbded2b2053dd","decimalCount":18}]},{"id":"meter","name":"Meter Governance","symbol":"MTRG","active":false,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xbd2949f67dcdc549c6ebe98696449fa79d988a9f","decimalCount":18}]},{"id":"sentinel-protocol","name":"Sentinel Protocol","symbol":"UPP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc86d054809623432210c107af2e3f619dcfbf652","decimalCount":18}]},{"id":"gains-network","name":"Gains Network","symbol":"GNS","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0xe5417af564e4bfda1c483642db72007871397896","decimalCount":18}]},{"id":"popcorn","name":"Popcorn","symbol":"POP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd0cd466b34a24fcb2f87676278af2005ca8a78c4","decimalCount":18}]},{"id":"mixmarvel","name":"MixMarvel","symbol":"MIX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5d285f735998f36631f678ff41fb56a10a4d0429","decimalCount":18}]},{"id":"contentos","name":"Contentos","symbol":"COS","active":true,"networks":[{"networkId":"binancecoin","contractAddress":"COS-2E4","decimalCount":8}]},{"id":"quantstamp","name":"Quantstamp","symbol":"QSP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x99ea4db9ee77acd40b119bd1dc4e33e1c070b80d","decimalCount":18}]},{"id":"tranchess","name":"Tranchess","symbol":"CHESS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x20de22029ab63cf9a7cf5feb2b737ca1ee4c82a6","decimalCount":18}]},{"id":"vega-protocol","name":"Vega Protocol","symbol":"VEGA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xcb84d72e61e383767c4dfeb2d8ff7f4fb89abc6e","decimalCount":18}]},{"id":"benqi","name":"BENQI","symbol":"QI","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0x8729438eb15e2c8b576fcc6aecda6a148776c0f5","decimalCount":18}]},{"id":"cargox","name":"CargoX","symbol":"CXO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb6ee9668771a79be7967ee29a63d4184f8097143","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xf2ae0038696774d65e67892c9d301c5f2cbbda58","decimalCount":18}]},{"id":"shibadoge","name":"ShibaDoge","symbol":"SHIBDOGE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6adb2e268de2aa1abf6578e4a8119b960e02928f","decimalCount":9}]},{"id":"tokocrypto","name":"Tokocrypto","symbol":"TKO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x9f589e3eabe42ebc94a44727b3f3531c0c877809","decimalCount":18}]},{"id":"panther","name":"Panther Protocol","symbol":"ZKP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x909e34d3f6124c324ac83dcca84b74398a6fa173","decimalCount":18}]},{"id":"bone-shibaswap","name":"Bone ShibaSwap","symbol":"BONE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9813037ee2218799597d83d4a5b6f3b6778218d9","decimalCount":18}]},{"id":"dxdao","name":"DXdao","symbol":"DXD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa1d65e8fb6e87b60feccbc582f7f97804b725521","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0xc3ae0333f0f34aa734d5493276223d95b8f9cb37","decimalCount":18}]},{"id":"whale","name":"WHALE","symbol":"WHALE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9355372396e3f6daf13359b7b607a3374cc638e0","decimalCount":4}]},{"id":"sipher","name":"Sipher","symbol":"SIPHER","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9f52c8ecbee10e00d9faaac5ee9ba0ff6550f511","decimalCount":18}]},{"id":"mcontent","name":"MContent","symbol":"MCONTENT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd3c51de3e6dd9b53d7f37699afb3ee3bf9b9b3f4","decimalCount":6},{"networkId":"binance-smart-chain","contractAddress":"0x799e1cf88a236e42b4a87c544a22a94ae95a6910","decimalCount":6}]},{"id":"rarible","name":"Rarible","symbol":"RARI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfca59cd816ab1ead66534d82bc21e7515ce441cf","decimalCount":18}]},{"id":"wirex","name":"Wirex","symbol":"WXT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa02120696c7b8fe16c09c749e4598819b2b0e915","decimalCount":18}]},{"id":"naga","name":"NAGA","symbol":"NGC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x72dd4b6bd852a3aa172be4d6c5a6dbec588cf131","decimalCount":18}]},{"id":"gamezone","name":"GameZone","symbol":"GZONE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xb6adb74efb5801160ff749b1985fd3bd5000e938","decimalCount":18}]},{"id":"content-value-network","name":"Conscious Value Network","symbol":"CVNT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6400b5522f8d448c0803e6245436dd1c81df09ce","decimalCount":8}]},{"id":"thorchain-erc20","name":"THORChain (ERC20)","symbol":"RUNE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3155ba85d5f96b2d030a4966af206230e46849cb","decimalCount":18}]},{"id":"lattice-token","name":"Lattice Token","symbol":"LTX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa393473d64d2f9f026b60b6df7859a689715d092","decimalCount":8}]},{"id":"vai","name":"Vai","symbol":"VAI","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x4bd17003473389a42daf6a0a729f6fdb328bbbd7","decimalCount":18}]},{"id":"bluzelle","name":"Bluzelle","symbol":"BLZ","active":false,"networks":[{"networkId":"ethereum","contractAddress":"0x5732046a883704404f284ce41ffadd5b007fd668","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x935a544bf5816e3a7c13db2efe3009ffda0acda2","decimalCount":18}]},{"id":"barnbridge","name":"BarnBridge","symbol":"BOND","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0391d2021f89dc339f60fff84546ea23e337750f","decimalCount":18}]},{"id":"idia","name":"Impossible Finance Launchpad","symbol":"IDIA","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x0b15ddf19d47e6a86a56148fb4afffc6929bcb89","decimalCount":18}]},{"id":"get-token","name":"GET Protocol","symbol":"GET","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8a854288a5976036a725879164ca3e91d30c6a1b","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xdb725f82818de83e99f1dac22a9b5b51d3d04dd4","decimalCount":18}]},{"id":"qi-dao","name":"Qi Dao","symbol":"QI","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0xa56f9a54880afbc30cf29bb66d2d9adcdcaeadd6","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x580a84c73811e1839f75d86d75d88cca0c241ff4","decimalCount":18}]},{"id":"yieldly","name":"Yieldly","symbol":"YLDY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x88cb253d4c8cab8cdf7948a9251db85a13669e23","decimalCount":18}]},{"id":"fuse-network-token","name":"Fuse","symbol":"FUSE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x970b9bb2c0444f5e81e9d0efb84c8ccdcdcaf84d","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x5857c96dae9cf8511b08cb07f85753c472d36ea3","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xf915fdda4c882731c0456a4214548cd13a822886","decimalCount":18}]},{"id":"tellor","name":"Tellor","symbol":"TRB","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x88df592f8eb5d7bd38bfef7deb0fbc02cf3778a0","decimalCount":18}]},{"id":"tbtc","name":"tBTC","symbol":"TBTC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8daebade922df735c38c80c7ebd708af50815faa","decimalCount":18}]},{"id":"tokenlon","name":"Tokenlon","symbol":"LON","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0000000000095413afc295d19edeb1ad7b71c952","decimalCount":18}]},{"id":"nftx","name":"NFTX","symbol":"NFTX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x87d73e916d7057945c9bcd8cdd94e42a6f47f776","decimalCount":18}]},{"id":"sx-network","name":"SX Network","symbol":"SX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x99fe3b1391503a1bc1788051347a1324bff41452","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x840195888db4d6a99ed9f73fcd3b225bb3cb1a79","decimalCount":18}]},{"id":"fodl-finance","name":"Fodl Finance","symbol":"FODL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4c2e59d098df7b6cbae0848d66de2f8a4889b9c3","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x5314ba045a459f63906aa7c76d9f337dcb7d6995","decimalCount":18}]},{"id":"bscpad","name":"BSCPAD","symbol":"BSCPAD","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x5a3010d4d8d3b5fb49f8b6e57fb9e48063f16700","decimalCount":18}]},{"id":"phonon-dao","name":"Phonon DAO","symbol":"PHONON","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x758b4684be769e92eefea93f60dda0181ea303ec","decimalCount":18}]},{"id":"boringdao","name":"BoringDAO","symbol":"BORING","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbc19712feb3a26080ebf6f2f7849b417fdd792ca","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xffeecbf8d7267757c2dc3d13d730e97e15bfdf7f","decimalCount":18}]},{"id":"pinksale","name":"PinkSale","symbol":"PINKSALE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x602ba546a7b06e0fc7f58fd27eb6996ecc824689","decimalCount":18}]},{"id":"lockchain","name":"LockTrip","symbol":"LOC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5e3346444010135322268a4630d2ed5f8d09446c","decimalCount":18}]},{"id":"avalaunch","name":"Avalaunch","symbol":"XAVA","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0xd1c3f94de7e5b45fa4edbba472491a9f4b166fc4","decimalCount":18}]},{"id":"streamr-xdata","name":"Streamr XDATA","symbol":"XDATA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0cf0ee63788a0849fe5297f3407f701e122cc023","decimalCount":18}]},{"id":"hotbit-token","name":"Hotbit Token","symbol":"HTB","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6be61833fc4381990e82d7d4a9f4c9b3f67ea941","decimalCount":18}]},{"id":"mantra-dao","name":"MANTRA DAO","symbol":"OM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3593d125a4f7849a1b059e64f4517a86dd60c95d","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xf78d2e7936f5fe18308a3b2951a93b6c4a41f5e2","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xc3ec80343d2bae2f8e680fdadde7c17e71e114ea","decimalCount":18}]},{"id":"kleros","name":"Kleros","symbol":"PNK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x93ed3fbe21207ec2e8f2d3c3de6e058cb73bc04d","decimalCount":18}]},{"id":"chronobank","name":"chrono.tech","symbol":"TIME","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x485d17a6f1b8780392d53d64751824253011a260","decimalCount":8},{"networkId":"binance-smart-chain","contractAddress":"0x3b198e26e473b8fab2085b37978e36c9de5d7f68","decimalCount":8}]},{"id":"guildfi","name":"GuildFi","symbol":"GF","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xaaef88cea01475125522e117bfe45cf32044e238","decimalCount":18}]},{"id":"mimo-parallel-governance-token","name":"Mimo Governance","symbol":"MIMO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x90b831fa3bebf58e9744a14d638e25b4ee06f9bc","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xadac33f543267c4d59a8c299cf804c303bc3e4ac","decimalCount":18},{"networkId":"fantom","contractAddress":"0x1d1764f04de29da6b90ffbef372d1a45596c4855","decimalCount":18}]},{"id":"vitadao","name":"VitaDAO","symbol":"VITA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x81f8f0bb1cb2a06649e51913a151f0e7ef6fa321","decimalCount":18}]},{"id":"grid","name":"GridPlus [OLD]","symbol":"GRID","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x12b19d3e2ccc14da04fae33e63652ce469b3f2fd","decimalCount":12}]},{"id":"revolution-populi","name":"Revolution Populi","symbol":"RVP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x17ef75aa22dd5f6c2763b8304ab24f40ee54d48a","decimalCount":18}]},{"id":"hector-dao","name":"Hector Finance","symbol":"HEC","active":true,"networks":[{"networkId":"fantom","contractAddress":"0x5c4fdfc5233f935f20d2adba572f770c2e377ab0","decimalCount":9}]},{"id":"peculium-2","name":"Peculium","symbol":"PCL","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x1dbdf52915875f749cbaeaaf515252455b623f6e","decimalCount":10}]},{"id":"frontier-token","name":"Frontier","symbol":"FRONT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf8c3527cc04340b208c854e985240c02f7b7793f","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x928e55dab735aa8260af3cedada18b5f70c72f1b","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xa3ed22eee92a3872709823a6970069e12a4540eb","decimalCount":18}]},{"id":"blockport","name":"BUX Token","symbol":"BUX","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x211ffbe424b90e25a15531ca322adf1559779e45","decimalCount":18}]},{"id":"treeb","name":"Retreeb","symbol":"TREEB","active":true,"networks":[{"networkId":"fantom","contractAddress":"0xc60d7067dfbc6f2caf30523a064f416a5af52963","decimalCount":18}]},{"id":"spartacus","name":"Spartacus","symbol":"SPA","active":true,"networks":[{"networkId":"fantom","contractAddress":"0x5602df4a94eb6c680190accfa2a475621e0ddbdc","decimalCount":9}]},{"id":"star-atlas","name":"Star Atlas","symbol":"ATLAS","active":true,"networks":[{"networkId":"solana","contractAddress":"ATLASXmbPQxBUYbxPsV97usA3fPQYEqzQBUHgiFCUsXx","decimalCount":8}]},{"id":"paraswap","name":"ParaSwap","symbol":"PSP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xcafe001067cdef266afb7eb5a286dcfd277f3de5","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xcafe001067cdef266afb7eb5a286dcfd277f3de5","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x42d61d766b85431666b39b89c43011f24451bff6","decimalCount":18}]},{"id":"bilira","name":"BiLira","symbol":"TRYB","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2c537e5624e4af88a7ae4060c022609376c8d0eb","decimalCount":6},{"networkId":"binance-smart-chain","contractAddress":"0xc1fdbed7dac39cae2ccc0748f7a80dc446f6a594","decimalCount":6},{"networkId":"avalanche","contractAddress":"0x564a341df6c126f90cf3ecb92120fd7190acb401","decimalCount":6}]},{"id":"metronome","name":"Metronome","symbol":"MET","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa3d58c4e56fedcae3a7c43a725aee9a71f0ece4e","decimalCount":18}]},{"id":"unizen","name":"Unizen","symbol":"ZCX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc52c326331e9ce41f04484d3b5e5648158028804","decimalCount":18}]},{"id":"voxies","name":"Voxies","symbol":"VOXEL","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0xd0258a3fd00f38aa8090dfee343f10a9d4d30d3f","decimalCount":18}]},{"id":"fsn","name":"FUSION","symbol":"FSN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x979aca85ba37c675e78322ed5d97fa980b9bdf00","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xfa4fa764f15d0f6e20aaec8e0d696870e5b77c6e","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x2bf9b864cdc97b08b6d79ad4663e71b8ab65c45c","decimalCount":18},{"networkId":"fantom","contractAddress":"0x50eb82cc284e3d35936827023b048106aaecfc5f","decimalCount":18}]},{"id":"freeway-token","name":"Freeway Token","symbol":"FWT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4a7397b0b86bb0f9482a3f4f16de942f04e88702","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x893169619461d3aba810a40b5403c62f27e703f9","decimalCount":18}]},{"id":"ultiledger","name":"Ultiledger","symbol":"ULT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe884cc2795b9c45beeac0607da9539fd571ccf85","decimalCount":18}]},{"id":"selfkey","name":"SelfKey","symbol":"KEY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4cc19356f2d37338b9802aa8e8fc58b0373296e7","decimalCount":18}]},{"id":"litentry","name":"Litentry","symbol":"LIT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb59490ab09a0f526cc7305822ac65f2ab12f9723","decimalCount":18}]},{"id":"dexe","name":"DeXe","symbol":"DEXE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xde4ee8057785a7e8e800db58f9784845a5c2cbd6","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x039cb485212f996a9dbb85a9a75d898f94d38da6","decimalCount":18}]},{"id":"oxygen","name":"Oxygen","symbol":"OXY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x965697b4ef02f0de01384d0d4f9f782b1670c163","decimalCount":6},{"networkId":"solana","contractAddress":"z3dn17yLaGMKffVogeFHQ9zWVcXgqgf3PQnDsNs2g6M","decimalCount":6}]},{"id":"tracer-dao","name":"Tracer DAO","symbol":"TCR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9c4a4204b79dd291d6b6571c5be8bbcd0622f050","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0xa72159fc390f0e3c6d415e658264c7c4051e9b87","decimalCount":18}]},{"id":"kryll","name":"KRYLL","symbol":"KRL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x464ebe77c293e473b48cfe96ddcf88fcf7bfdac0","decimalCount":18}]},{"id":"ooki","name":"Ooki","symbol":"OOKI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0de05f6447ab4d22c8827449ee4ba2d5c288379b","decimalCount":18}]},{"id":"math","name":"MATH","symbol":"MATH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x08d967bb0134f2d07f7cfb6e246680c53927dd30","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xf218184af829cf2b0019f8e6f0b2423498a36983","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x99f40b01ba9c469193b360f72740e416b17ac332","decimalCount":18}]},{"id":"measurable-data-token","name":"Measurable Data Token","symbol":"MDT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x814e0908b12a99fecf5bc101bb5d0b8b5cdf7d26","decimalCount":18}]},{"id":"apeswap-finance","name":"ApeSwap","symbol":"BANANA","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x603c7f932ed1fc6575303d8fb018fdcbb0f39a95","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x5d47baba0d66083c52009271faf3f50dcc01023c","decimalCount":18}]},{"id":"position-token","name":"Position","symbol":"POSI","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x5ca42204cdaa70d5c773946e69de942b85ca6706","decimalCount":18}]},{"id":"stafi","name":"Stafi","symbol":"FIS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xef3a930e1ffffacd2fc13434ac81bd278b0ecc8d","decimalCount":18}]},{"id":"moviebloc","name":"MovieBloc","symbol":"MBL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb879da8b24c9b8685de8526cf492e954f165d74b","decimalCount":18}]},{"id":"jade-protocol","name":"Jade Protocol","symbol":"JADE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x7ad7242a99f21aa543f9650a56d141c57e4f6081","decimalCount":9}]},{"id":"parsiq","name":"PARSIQ","symbol":"PRQ","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x362bc847a3a9637d3af6624eec853618a43ed7d2","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xd21d29b38374528675c34936bf7d5dd693d2a577","decimalCount":18}]},{"id":"vite","name":"Vite","symbol":"VITE","active":false,"networks":[{"networkId":"ethereum","contractAddress":"0xadd5e881984783dd432f80381fb52f45b53f3e70","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x2794dad4077602ed25a88d03781528d1637898b4","decimalCount":18}]},{"id":"deus-finance-2","name":"DEUS Finance","symbol":"DEUS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xde5ed76e7c05ec5e4572cfc88d1acea165109e44","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xde5ed76e7c05ec5e4572cfc88d1acea165109e44","decimalCount":18},{"networkId":"fantom","contractAddress":"0xde5ed76e7c05ec5e4572cfc88d1acea165109e44","decimalCount":18}]},{"id":"bella-protocol","name":"Bella Protocol","symbol":"BEL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa91ac63d040deb1b7a5e4d4134ad23eb0ba07e14","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x8443f091997f06a61670b735ed92734f5628692f","decimalCount":18}]},{"id":"cow-protocol","name":"CoW Protocol","symbol":"COW","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdef1ca1fb7fbcdc777520aa7f396b4e015f497ab","decimalCount":18}]},{"id":"orca","name":"Orca","symbol":"ORCA","active":true,"networks":[{"networkId":"solana","contractAddress":"orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE","decimalCount":6}]},{"id":"vader-protocol","name":"Vader Protocol","symbol":"VADER","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2602278ee1882889b946eb11dc0e810075650983","decimalCount":18}]},{"id":"solve-care","name":"SOLVE","symbol":"SOLVE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x446c9033e7516d820cc9a2ce2d0b7328b579406f","decimalCount":8}]},{"id":"anj","name":"Aragon Court","symbol":"ANJ","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xcd62b1c403fa761baadfc74c525ce2b51780b184","decimalCount":18}]},{"id":"global-coin-research","name":"Global Coin Research","symbol":"GCR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6307b25a665efc992ec1c1bc403c38f3ddd7c661","decimalCount":4},{"networkId":"polygon-pos","contractAddress":"0xa69d14d6369e414a32a5c7e729b7afbafd285965","decimalCount":4}]},{"id":"annex","name":"Annex Finance","symbol":"ANN","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x98936bde1cf1bff1e7a8012cee5e2583851f2067","decimalCount":18}]},{"id":"bigshortbets","name":"BigShortBets","symbol":"BIGSB","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x131157c6760f78f7ddf877c0019eba175ba4b6f6","decimalCount":18}]},{"id":"silo-finance","name":"Silo Finance","symbol":"SILO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6f80310ca7f2c654691d1383149fa1a57d8ab1f8","decimalCount":18}]},{"id":"crabada","name":"Crabada","symbol":"CRA","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0xa32608e873f9ddef944b24798db69d80bbb4d1ed","decimalCount":18}]},{"id":"talken","name":"Talken","symbol":"TALK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xcaabcaa4ca42e1d86de1a201c818639def0ba7a7","decimalCount":18}]},{"id":"dextools","name":"DexTools","symbol":"DEXT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfb7b4564402e5500db5bb6d63ae671302777c75a","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xe91a8d2c584ca93c7405f15c22cdfe53c29896e3","decimalCount":18}]},{"id":"catecoin","name":"CateCoin","symbol":"CATE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xe4fae3faa8300810c835970b9187c268f55d998f","decimalCount":9}]},{"id":"yuan-chain-coin","name":"Yuan Chain Coin","symbol":"YCC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x37e1160184f7dd29f00b78c050bf13224780b0b0","decimalCount":8}]},{"id":"netvrk","name":"Netvrk","symbol":"NTVRK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfc0d6cf33e38bce7ca7d89c0e292274031b7157a","decimalCount":18}]},{"id":"btu-protocol","name":"BTU Protocol","symbol":"BTU","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb683d83a532e2cb7dfa5275eed3698436371cc9f","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xfdc26cda2d2440d0e83cd1dee8e8be48405806dc","decimalCount":18}]},{"id":"tor","name":"TOR","symbol":"TOR","active":true,"networks":[{"networkId":"fantom","contractAddress":"0x74e23df9110aa9ea0b6ff2faee01e740ca1c642e","decimalCount":18}]},{"id":"gemma-extending-tech","name":"Gemma Extending Tech","symbol":"GXT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4674672bcddda2ea5300f5207e1158185c944bc0","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x3107c0a1126268ca303f8d99c712392fa596e6d7","decimalCount":18}]},{"id":"seur","name":"sEUR","symbol":"SEUR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd71ecff9342a5ced620049e616c5035f1db98620","decimalCount":18}]},{"id":"polkadex","name":"Polkadex","symbol":"PDEX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf59ae934f6fe444afc309586cc60a84a0f89aaea","decimalCount":18}]},{"id":"terra-virtua-kolect","name":"Terra Virtua Kolect","symbol":"TVK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd084b83c305dafd76ae3e1b4e1f1fe2ecccb3988","decimalCount":18}]},{"id":"xdefi","name":"XDEFI","symbol":"XDEFI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x72b886d09c117654ab7da13a14d603001de0b777","decimalCount":18}]},{"id":"compound-chainlink-token","name":"cLINK","symbol":"CLINK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xface851a4921ce59e912d19329929ce6da6eb0c7","decimalCount":8}]},{"id":"pluton","name":"Pluton","symbol":"PLU","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd8912c10681d8b21fd3742244f44658dba12264e","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x7dc0cb65ec6019330a6841e9c274f2ee57a6ca6c","decimalCount":18}]},{"id":"sperax-usd","name":"Sperax USD","symbol":"USDS","active":true,"networks":[{"networkId":"arbitrum-one","contractAddress":"0xd74f5255d557944cf7dd0e45ff521520002d5748","decimalCount":18}]},{"id":"chain-games","name":"Chain Games","symbol":"CHAIN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc4c2614e694cf534d407ee49f8e44d125e4681c4","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x35de111558f691f77f791fb0c08b2d6b931a9d47","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xd55fce7cdab84d84f2ef3f99816d765a2a94a509","decimalCount":18}]},{"id":"derace","name":"DeRace","symbol":"DERC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9fa69536d1cda4a04cfb50688294de75b505a9ae","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x373e768f79c820aa441540d254dca6d045c6d25b","decimalCount":18}]},{"id":"crypterium","name":"Crypterium","symbol":"CRPT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x08389495d7456e1951ddf7c3a1314a4bfb646d8b","decimalCount":18}]},{"id":"banana","name":"Banana","symbol":"BANANA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x94e496474f1725f1c1824cb5bdb92d7691a4f03a","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xbc91347e80886453f3f8bbd6d7ac07c122d87735","decimalCount":18}]},{"id":"revv","name":"REVV","symbol":"REVV","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x557b933a7c2c45672b610f8954a3deb39a51a8ca","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x833f307ac507d47309fd8cdd1f835bef8d702a93","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x70c006878a5a50ed185ac4c87d837633923de296","decimalCount":18}]},{"id":"bosagora","name":"BOSAGORA","symbol":"BOA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x746dda2ea243400d5a63e0700f190ab79f06489e","decimalCount":7}]},{"id":"eden","name":"EDEN","symbol":"EDEN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1559fa1b8f28238fd5d76d9f434ad86fd20d1559","decimalCount":18}]},{"id":"airswap","name":"AirSwap","symbol":"AST","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x27054b13b1b798b345b591a4d22e6562d47ea75a","decimalCount":4}]},{"id":"insurace","name":"InsurAce","symbol":"INSUR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x544c42fbb96b39b21df61cf322b5edc285ee7429","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x3192ccddf1cdce4ff055ebc80f3f0231b86a7e30","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x544c42fbb96b39b21df61cf322b5edc285ee7429","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x8a0e8b4b0903929f47c3ea30973940d4a9702067","decimalCount":18}]},{"id":"givingtoservices-svs","name":"GivingToServices SVS","symbol":"SVS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7ca62545a380e7d71f8f5cfa14b9211002075930","decimalCount":18}]},{"id":"alkimi","name":"Alkimi","symbol":"$ADS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3106a0a076bedae847652f42ef07fd58589e001f","decimalCount":18}]},{"id":"platypus-finance","name":"Platypus Finance","symbol":"PTP","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0x22d4002028f537599be9f666d1c4fa138522f9c8","decimalCount":18}]},{"id":"cream-2","name":"Cream","symbol":"CREAM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2ba592f78db6436527729929aaf6c908497cb200","decimalCount":18},{"networkId":"fantom","contractAddress":"0x657a1861c15a3ded9af0b6799a195a249ebdcbc6","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0xf4d48ce3ee1ac3651998971541badbb9a14d7234","decimalCount":18}]},{"id":"newscrypto-coin","name":"Newscrypto Coin","symbol":"NWC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x968f6f898a6df937fc1859b323ac2f14643e3fed","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x968f6f898a6df937fc1859b323ac2f14643e3fed","decimalCount":18}]},{"id":"step-finance","name":"Step Finance","symbol":"STEP","active":true,"networks":[{"networkId":"solana","contractAddress":"StepAscQoEioFxxWGnh2sLBDFp9d8rvKz2Yp39iDpyT","decimalCount":9}]},{"id":"manifold-finance","name":"Manifold Finance","symbol":"FOLD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd084944d3c05cd115c09d072b9f44ba3e0e45921","decimalCount":18}]},{"id":"bepro-network","name":"BEPRO Network","symbol":"BEPRO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xcf3c8be2e2c42331da80ef210e9b1b307c03d36a","decimalCount":18}]},{"id":"star-atlas-dao","name":"Star Atlas DAO","symbol":"POLIS","active":true,"networks":[{"networkId":"solana","contractAddress":"poLisWXnNRwC6oBu1vHiuKQzFjGL4XDSu4g9qjz9qVk","decimalCount":8}]},{"id":"stake-dao","name":"Stake DAO","symbol":"SDT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x73968b9a57c6e53d41345fd57a6e6ae27d6cdb2f","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x361a5a4993493ce00f61c32d4ecca5512b82ce90","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x7ba4a00d54a07461d9db2aef539e91409943adc9","decimalCount":18}]},{"id":"dfx-finance","name":"DFX Finance","symbol":"DFX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x888888435fde8e7d4c54cab67f206e4199454c60","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xe7804d91dfcde7f776c90043e03eaa6df87e6395","decimalCount":18}]},{"id":"the-doge-nft","name":"The Doge NFT","symbol":"DOG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbaac2b4491727d78d2b78815144570b9f2fe8899","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xaa88c603d142c371ea0eac8756123c5805edee03","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xeee3371b89fc43ea970e908536fcddd975135d8a","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x4425742f1ec8d98779690b5a3a6276db85ddc01a","decimalCount":18}]},{"id":"route","name":"Router Protocol","symbol":"ROUTE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x16eccfdbb4ee1a85a33f3a9b21175cd7ae753db4","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x16eccfdbb4ee1a85a33f3a9b21175cd7ae753db4","decimalCount":18}]},{"id":"index-cooperative","name":"Index Cooperative","symbol":"INDEX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0954906da0bf32d5479e25f46056d22f08464cab","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xfbd8a3b908e764dbcd51e27992464b4432a1132b","decimalCount":18}]},{"id":"adappter-token","name":"Adappter Token","symbol":"ADP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc314b0e758d5ff74f63e307a86ebfe183c95767b","decimalCount":18}]},{"id":"ariva","name":"Ariva","symbol":"ARV","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x6679eb24f59dfe111864aec72b443d1da666b360","decimalCount":8}]},{"id":"ramp","name":"RAMP","symbol":"RAMP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x33d0568941c0c64ff7e0fb4fba0b11bd37deed9f","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x8519ea49c997f50ceffa444d240fb655e89248aa","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xaecebfcf604ad245eaf0d5bd68459c3a7a6399c2","decimalCount":18}]},{"id":"dforce-token","name":"dForce Token","symbol":"DF","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x431ad2ff6a9c365805ebad47ee021148d6f7dbe0","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0xae6aab43c4f3e0cea4ab83752c278f8debaba689","decimalCount":18}]},{"id":"interest-compounding-eth-index","name":"Interest Compounding ETH Index","symbol":"ICETH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7c07f7abe10ce8e33dc6c5ad68fe033085256a84","decimalCount":18}]},{"id":"opendao","name":"OpenDAO","symbol":"SOS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3b484b82567a09e2588a13d54d032153f0c0aee0","decimalCount":18}]},{"id":"urus-token","name":"Aurox Token","symbol":"URUS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc6dddb5bc6e61e0841c54f3e723ae1f3a807260b","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xc6dddb5bc6e61e0841c54f3e723ae1f3a807260b","decimalCount":18}]},{"id":"santiment-network-token","name":"Santiment Network Token","symbol":"SAN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7c5a0ce9267ed19b22f8cae653f198e3e8daf098","decimalCount":18}]},{"id":"marinade","name":"Marinade","symbol":"MNDE","active":true,"networks":[{"networkId":"solana","contractAddress":"MNDEFzGvMt87ueuHvVU9VcTqsAP5b3fTGPsHuuPA5ey","decimalCount":9}]},{"id":"suku","name":"SUKU","symbol":"SUKU","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0763fdccf1ae541a5961815c0872a8c5bc6de4d7","decimalCount":18}]},{"id":"ichi-farm","name":"ICHI","symbol":"ICHI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x903bef1736cddf2a537176cf3c64579c3867a881","decimalCount":9}]},{"id":"0chain","name":"0chain","symbol":"ZCN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb9ef770b6a5e12e45983c5d80545258aa38f3b78","decimalCount":10},{"networkId":"polygon-pos","contractAddress":"0x8bb30e0e67b11b978a5040144c410e1ccddcba30","decimalCount":10}]},{"id":"solanium","name":"Solanium","symbol":"SLIM","active":true,"networks":[{"networkId":"solana","contractAddress":"xxxxa1sKNGwFtw2kFn8XauW9xq8hBZ5kVtcSesTT9fW","decimalCount":6}]},{"id":"numbers-protocol","name":"Numbers Protocol","symbol":"NUM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3496b523e5c00a4b4150d6721320cddb234c3079","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xeceb87cf00dcbf2d4e2880223743ff087a995ad9","decimalCount":18}]},{"id":"delta-exchange-token","name":"Delta Exchange Token","symbol":"DETO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xab93df617f51e1e415b5b4f8111f122d6b48e55c","decimalCount":18}]},{"id":"cryptex-finance","name":"Cryptex Finance","symbol":"CTX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x321c2fe4446c7c963dc41dd58879af648838f98d","decimalCount":18}]},{"id":"lunr-token","name":"Lunr","symbol":"LUNR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa87135285ae208e22068acdbff64b11ec73eaa5a","decimalCount":4},{"networkId":"binance-smart-chain","contractAddress":"0x37807d4fbeb84124347b8899dd99616090d3e304","decimalCount":4}]},{"id":"loot","name":"Lootex","symbol":"LOOT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x721a1b990699ee9d90b6327faad0a3e840ae8335","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x14a9a94e555fdd54c21d7f7e328e61d7ebece54b","decimalCount":18}]},{"id":"xels","name":"XELS","symbol":"XELS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x397deb686c72384fad502a81f4d7fdb89e1f1280","decimalCount":8}]},{"id":"xdai-stake","name":"STAKE","symbol":"STAKE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0ae055097c6d159879521c384f1d2123d1f195e6","decimalCount":18}]},{"id":"angle-protocol","name":"ANGLE","symbol":"ANGLE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x31429d1856ad1377a8a0079410b297e1a9e214c2","decimalCount":18}]},{"id":"stratos","name":"Stratos","symbol":"STOS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x08c32b0726c5684024ea6e141c50ade9690bbdcc","decimalCount":18}]},{"id":"vecrv-dao-yvault","name":"veCRV-DAO yVault","symbol":"YVE-CRVDAO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc5bddf9843308380375a611c18b50fb9341f502a","decimalCount":18}]},{"id":"stackos","name":"StackOS","symbol":"STACK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x56a86d648c435dc707c8405b78e2ae8eb4e60ba4","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x6855f7bb6287f94ddcc8915e37e73a3c9fee5cf3","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x980111ae1b84e50222c8843e3a7a038f36fecd2b","decimalCount":18}]},{"id":"elysia","name":"ELYSIA","symbol":"EL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2781246fe707bb15cee3e5ea354e2154a2877b16","decimalCount":18}]},{"id":"nectar-token","name":"Nectar","symbol":"NEC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xcc80c051057b774cd75067dc48f8987c4eb97a5e","decimalCount":18}]},{"id":"gods-unchained","name":"Gods Unchained","symbol":"GODS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xccc8cb5229b0ac8069c51fd58367fd1e622afd97","decimalCount":18}]},{"id":"sportium","name":"Sportium","symbol":"SPRT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x56156fb7860d7eb0b4b1a5356c5354b295194a45","decimalCount":18}]},{"id":"pnetwork","name":"pNetwork","symbol":"PNT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x89ab32156e46f46d02ade3fecbe5fc4243b9aaed","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xdaacb0ab6fb34d24e8a67bfa14bf4d95d4c7af92","decimalCount":18}]},{"id":"vvsp","name":"vVSP","symbol":"VVSP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xba4cfe5741b357fa371b506e5db0774abfecf8fc","decimalCount":18}]},{"id":"altura","name":"Altura","symbol":"ALU","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x8263cd1601fe73c066bf49cc09841f35348e3be0","decimalCount":18}]},{"id":"coin-capsule","name":"Ternoa","symbol":"CAPS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x03be5c903c727ee2c8c4e9bc0acc860cca4715e2","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xffba7529ac181c2ee1844548e6d7061c9a597df4","decimalCount":18}]},{"id":"time-new-bank","name":"Time New Bank","symbol":"TNB","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf7920b0768ecb20a123fac32311d07d193381d6f","decimalCount":18}]},{"id":"3x-long-ethereum-token","name":"3X Long Ethereum Token","symbol":"ETHBULL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x871baed4088b863fd6407159f3672d70cd34837d","decimalCount":18}]},{"id":"nfty-token","name":"NFTY Labs","symbol":"NFTY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe1d7c7a4596b038ced2a84bf65b8647271c53208","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x5774b2fc3e91af89f89141eacf76545e74265982","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xcc081220542a60a8ea7963c4f53d522b503272c1","decimalCount":18}]},{"id":"lyra-finance","name":"Lyra Finance","symbol":"LYRA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x01ba67aac7f75f647d94220cc98fb30fcc5105bf","decimalCount":18}]},{"id":"dotmoovs","name":"dotmoovs","symbol":"MOOV","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x24ec2ca132abf8f6f8a6e24a1b97943e31f256a7","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x0ebd9537a25f56713e34c45b38f421a1e7191469","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xe46f5128b933e5a6f907fe73ece80059c222db0a","decimalCount":18}]},{"id":"velaspad","name":"VelasPad","symbol":"VLXPAD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb8e3bb633f7276cc17735d86154e0ad5ec9928c0","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xb8e3bb633f7276cc17735d86154e0ad5ec9928c0","decimalCount":18}]},{"id":"unicrypt-2","name":"UniCrypt","symbol":"UNCX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xadb2437e6f65682b85f814fbc12fec0508a7b1d0","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x09a6c44c3947b69e2b45f4d51b67e6a39acfb506","decimalCount":18}]},{"id":"era-swap-token","name":"Era Swap Token","symbol":"ES","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x72108a8cc3254813c6be2f1b77be53e185abfdd9","decimalCount":18}]},{"id":"arianee","name":"Arianee","symbol":"ARIA20","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xedf6568618a00c6f0908bf7758a16f76b6e04af9","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x46f48fbdedaa6f5500993bede9539ef85f4bee8e","decimalCount":18}]},{"id":"everid","name":"Everest","symbol":"ID","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xebd9d99a3982d547c5bb4db7e3b1f9f14b67eb83","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x8ea2526c2373ba3fe1d0987f5db8ac770a42dd51","decimalCount":18}]},{"id":"shabu-shabu","name":"Shabu Shabu","symbol":"KOBE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xcb4e8cafeda995da5cedfda5205bd5664a12b848","decimalCount":18}]},{"id":"bridge","name":"Bridge$","symbol":"BRG.X","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x0e2114955023b736fa97d9e2fcde2836d10b7a5c","decimalCount":18}]},{"id":"futureswap","name":"Futureswap","symbol":"FST","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0e192d382a36de7011f795acc4391cd302003606","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x488cc08935458403a0458e45e20c0159c8ab2c92","decimalCount":18}]},{"id":"rss3","name":"RSS3","symbol":"RSS3","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc98d64da73a6616c42117b582e832812e7b8d57f","decimalCount":18}]},{"id":"thorswap","name":"THORSwap","symbol":"THOR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa5f2211b9b8170f694421f2046281775e8468044","decimalCount":18}]},{"id":"neos-credits","name":"Neos Credits","symbol":"NCR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdb5c3c46e28b53a39c255aa39a411dd64e5fed9c","decimalCount":18}]},{"id":"lunar","name":"Lunar","symbol":"LNR","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x9d4451151a8de5b545a1bc6c8fdeb9d94a2868e1","decimalCount":9}]},{"id":"erc20","name":"ERC20","symbol":"ERC20","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc3761eb917cd790b30dad99f6cc5b4ff93c4f9ea","decimalCount":18}]},{"id":"qmall","name":"Qmall","symbol":"QMALL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2217e5921b7edfb4bb193a6228459974010d2198","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x07e551e31a793e20dc18494ff6b03095a8f8ee36","decimalCount":18}]},{"id":"unlend-finance","name":"UniLend Finance","symbol":"UFT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0202be363b8a4820f3f4de7faf5224ff05943ab1","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x2645d5f59d952ef2317c8e0aaa5a61c392ccd44d","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x5b4cf2c120a9702225814e18543ee658c5f8631e","decimalCount":18}]},{"id":"unifi-protocol-dao","name":"Unifi Protocol DAO","symbol":"UNFI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x441761326490cacf7af299725b6292597ee822c2","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x728c5bac3c3e370e372fc4671f9ef6916b814d8b","decimalCount":18}]},{"id":"rainicorn","name":"Rainicorn","symbol":"RAINI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xeb953eda0dc65e3246f43dc8fa13f35623bdd5ed","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xeb953eda0dc65e3246f43dc8fa13f35623bdd5ed","decimalCount":18},{"networkId":"fantom","contractAddress":"0xe83dfaaafd3310474d917583ae9633b4f68fb036","decimalCount":18}]},{"id":"paragonsdao","name":"ParagonsDAO","symbol":"PDT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x375abb85c329753b1ba849a601438ae77eec9893","decimalCount":18}]},{"id":"occamfi","name":"OccamFi","symbol":"OCC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2f109021afe75b949429fe30523ee7c0d5b27207","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x2a4dffa1fa0f86ce7f0982f88aecc199fb3476bc","decimalCount":18}]},{"id":"defi-land","name":"DeFi Land","symbol":"DFL","active":true,"networks":[{"networkId":"solana","contractAddress":"DFL1zNkaGPWm1BqAVqRjCZvHmwTFrEaJtbzJWgseoNJh","decimalCount":9}]},{"id":"hackenai","name":"Hacken Token","symbol":"HAI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x05fb86775fd5c16290f1e838f5caaa7342bd9a63","decimalCount":8},{"networkId":"binance-smart-chain","contractAddress":"0xaa9e582e5751d703f85912903bacaddfed26484c","decimalCount":8}]},{"id":"peardao","name":"PearDAO","symbol":"PEX","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x6a0b66710567b6beb81a71f7e9466450a91a384b","decimalCount":18}]},{"id":"inverse-finance","name":"Inverse Finance","symbol":"INV","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x41d5d79431a913c4ae7d69a668ecdfe5ff9dfb68","decimalCount":18}]},{"id":"zkspace","name":"ZKSpace","symbol":"ZKS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe4815ae53b124e7263f08dcdbbb757d41ed658c6","decimalCount":18}]},{"id":"trustpad","name":"TrustPad","symbol":"TPAD","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xadcfc6bf853a0a8ad7f9ff4244140d10cf01363c","decimalCount":9}]},{"id":"gifto","name":"Gifto","symbol":"GTO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc5bbae50781be1669306b9e001eff57a2957b09d","decimalCount":5}]},{"id":"hoge-finance","name":"Hoge Finance","symbol":"HOGE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfad45e47083e4607302aa43c65fb3106f1cd7607","decimalCount":9},{"networkId":"binance-smart-chain","contractAddress":"0xa4fffc757e8c4f24e7b209c033c123d20983ad40","decimalCount":9}]},{"id":"trias-token","name":"Trias Token","symbol":"TRIAS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3a856d4effa670c54585a5d523e96513e148e95d","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xa4838122c683f732289805fc3c207febd55babdd","decimalCount":18}]},{"id":"dora-factory","name":"Dora Factory","symbol":"DORA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbc4171f45ef0ef66e76f979df021a34b46dcc81d","decimalCount":18}]},{"id":"tower","name":"Tower","symbol":"TOWER","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1c9922314ed1415c95b9fd453c3818fd41867d0b","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xe7c9c6bc87b86f9e5b57072f907ee6460b593924","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x2bc07124d8dac638e290f401046ad584546bc47b","decimalCount":18}]},{"id":"banano","name":"Banano","symbol":"BAN","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xe20b9e246db5a0d21bf9209e4858bc9a3ff7a034","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xe20b9e246db5a0d21bf9209e4858bc9a3ff7a034","decimalCount":18},{"networkId":"fantom","contractAddress":"0xe20b9e246db5a0d21bf9209e4858bc9a3ff7a034","decimalCount":18}]},{"id":"instadapp","name":"Instadapp","symbol":"INST","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6f40d4a6237c257fff2db00fa0510deeecd303eb","decimalCount":18}]},{"id":"veraone","name":"VeraOne","symbol":"VRO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x10bc518c32fbae5e38ecb50a612160571bd81e44","decimalCount":8}]},{"id":"mcdex","name":"MCDEX","symbol":"MCB","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4e352cf164e64adcbad318c3a1e222e9eba4ce42","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x5fe80d2cd054645b9419657d3d10d26391780a7b","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x4e352cf164e64adcbad318c3a1e222e9eba4ce42","decimalCount":18}]},{"id":"videocoin","name":"Vivid Labs","symbol":"VID","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2c9023bbc572ff8dc1228c7858a280046ea8c9e5","decimalCount":18},{"networkId":"fantom","contractAddress":"0x922d641a426dcffaef11680e5358f34d97d112e1","decimalCount":18}]},{"id":"town-star","name":"Town Star","symbol":"TOWN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3dd98c8a089dbcff7e8fc8d4f532bd493501ab7f","decimalCount":8}]},{"id":"paid-network","name":"PAID Network","symbol":"PAID","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1614f18fc94f47967a3fbe5ffcd46d4e7da3d787","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xad86d0e9764ba90ddd68747d64bffbd79879a238","decimalCount":18}]},{"id":"gamercoin","name":"GamerCoin","symbol":"GHX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x728f30fa2f100742c7949d1961804fa8e0b1387d","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xbd7b8e4de08d9b01938f7ff2058f110ee1e0e8d4","decimalCount":18}]},{"id":"stakewise","name":"StakeWise","symbol":"SWISE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x48c3399719b582dd63eb5aadf12a40b4c3f52fa2","decimalCount":18}]},{"id":"friends-with-benefits-pro","name":"Friends With Benefits Pro","symbol":"FWB","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x35bd01fc9d6d5d81ca9e055db88dc49aa2c699a8","decimalCount":18}]},{"id":"block-ape-scissors","name":"Block Ape Scissors","symbol":"BAS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x8ddeec6b677c7c552c9f3563b99e4ff90b862ebc","decimalCount":18}]},{"id":"switcheo","name":"Carbon Protocol","symbol":"SWTH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb4371da53140417cbb3362055374b10d97e420bb","decimalCount":8},{"networkId":"binance-smart-chain","contractAddress":"0xc0ecb8499d8da2771abcbf4091db7f65158f1468","decimalCount":8}]},{"id":"spool-dao-token","name":"Spool DAO","symbol":"SPOOL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x40803cea2b2a32bda1be61d3604af6a814e70976","decimalCount":18}]},{"id":"beethoven-x","name":"Beethoven X","symbol":"BEETS","active":true,"networks":[{"networkId":"fantom","contractAddress":"0xf24bcf4d1e507740041c9cfd2dddb29585adce1e","decimalCount":18}]},{"id":"refi","name":"Reimagined Finance","symbol":"REFI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa808b22ffd2c472ad1278088f16d4010e6a54d5f","decimalCount":18}]},{"id":"swapxi-token","name":"SwapXI","symbol":"SWAPXI","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0x312ee43df66d1fd1ea28e5b28f355da84dca13c2","decimalCount":12}]},{"id":"scrooge","name":"Scrooge","symbol":"SCROOGE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xfa1ba18067ac6884fb26e329e60273488a247fc3","decimalCount":18}]},{"id":"one-ledger","name":"OneLedger","symbol":"OLT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x64a60493d888728cf42616e034a0dfeae38efcf0","decimalCount":18}]},{"id":"label-foundation","name":"LABEL Foundation","symbol":"LBL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2162f572b25f7358db9376ab58a947a4e45cede1","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x77edfae59a7948d66e9911a30cc787d2172343d4","decimalCount":18}]},{"id":"shyft-network-2","name":"Shyft Network","symbol":"SHFT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb17c88bda07d28b3838e0c1de6a30eafbcf52d85","decimalCount":18}]},{"id":"goldfinch","name":"Goldfinch","symbol":"GFI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdab396ccf3d84cf2d07c4454e10c8a6f5b008d2b","decimalCount":18}]},{"id":"concentrated-voting-power","name":"PowerPool Concentrated Voting Power","symbol":"CVP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x38e4adb44ef08f22f5b5b76a8f0c2d0dcbe7dca1","decimalCount":18}]},{"id":"pbtc35a","name":"pBTC35A","symbol":"PBTC35A","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa8b12cc90abf65191532a12bb5394a714a46d358","decimalCount":18}]},{"id":"coinweb","name":"Coinweb","symbol":"CWEB","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x505b5eda5e25a67e1c24a2bf1a527ed9eb88bf04","decimalCount":18}]},{"id":"cellframe","name":"Cellframe","symbol":"CELL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x26c8afbbfe1ebaca03c2bb082e69d0476bffe099","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xf3e1449ddb6b218da2c9463d4594ceccc8934346","decimalCount":18}]},{"id":"wasder","name":"Wasder","symbol":"WAS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0c572544a4ee47904d54aaa6a970af96b6f00e1b","decimalCount":18}]},{"id":"byteball","name":"Obyte","symbol":"GBYTE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x31f69de127c8a0ff10819c0955490a4ae46fcc2a","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xeb34de0c4b2955ce0ff1526cdf735c9e6d249d09","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xab5f7a0e20b0d056aed4aa4528c78da45be7308b","decimalCount":18}]},{"id":"enreachdao","name":"EnreachDAO","symbol":"NRCH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x69fa8e7f6bf1ca1fb0de61e1366f7412b827cc51","decimalCount":9},{"networkId":"binance-smart-chain","contractAddress":"0x69fa8e7f6bf1ca1fb0de61e1366f7412b827cc51","decimalCount":9}]},{"id":"lossless","name":"Lossless","symbol":"LSS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3b9be07d622accaed78f479bc0edabfd6397e320","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xf7686f43591302cd9b4b9c4fe1291473fae7d9c9","decimalCount":18}]},{"id":"affyn","name":"Affyn","symbol":"FYN","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0x3b56a704c01d650147ade2b8cee594066b3f9421","decimalCount":18}]},{"id":"blockchainspace","name":"BlockchainSpace","symbol":"GUILD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x83e9f223e1edb3486f876ee888d76bfba26c475a","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x0565805ca3a4105faee51983b0bd8ffb5ce1455c","decimalCount":18}]},{"id":"metaverse-index","name":"Metaverse Index","symbol":"MVI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x72e364f2abdc788b7e918bc238b21f109cd634d7","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xfe712251173a2cd5f5be2b46bb528328ea3565e1","decimalCount":18}]},{"id":"opulous","name":"Opulous","symbol":"OPUL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x80d55c03180349fff4a229102f62328220a96444","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x686318000d982bc8dcc1cdcf8ffd22322f0960ed","decimalCount":18}]},{"id":"aag-ventures","name":"AAG Ventures","symbol":"AAG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5ba19d656b65f1684cfea4af428c23b9f3628f97","decimalCount":18}]},{"id":"force-protocol","name":"ForTube","symbol":"FOR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1fcdce58959f536621d76f5b7ffb955baa5a672f","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x658a109c5900bc6d2357c87549b651670e5b0539","decimalCount":18}]},{"id":"lazio-fan-token","name":"Lazio Fan Token","symbol":"LAZIO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x77d547256a2cd95f32f67ae0313e450ac200648d","decimalCount":8}]},{"id":"lgcy-network","name":"LGCY Network","symbol":"LGCY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xae697f994fc5ebc000f8e22ebffee04612f98a0d","decimalCount":18}]},{"id":"rich","name":"Rich","symbol":"RCH","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x041e714aa0dce7d4189441896486d361e98bad5f","decimalCount":9}]},{"id":"glitch-protocol","name":"Glitch Protocol","symbol":"GLCH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x038a68ff68c393373ec894015816e33ad41bd564","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xf0902eb0049a4003793bab33f3566a22d2834442","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xbe5cf150e1ff59ca7f2499eaa13bfc40aae70e78","decimalCount":18}]},{"id":"bao-finance","name":"Bao Finance","symbol":"BAO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x374cb8c27130e2c9e04f44303f3c8351b9de61c1","decimalCount":18}]},{"id":"sylo","name":"Sylo","symbol":"SYLO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf293d23bf2cdc05411ca0eddd588eb1977e8dcd4","decimalCount":18}]},{"id":"taboo-token","name":"Taboo Token","symbol":"TABOO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x9abdba20edfba06b782126b4d8d72a5853918fd0","decimalCount":9}]},{"id":"foam-protocol","name":"FOAM","symbol":"FOAM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4946fcea7c692606e8908002e55a582af44ac121","decimalCount":18}]},{"id":"outer-ring","name":"Outer Ring","symbol":"GQ","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xf700d4c708c2be1463e355f337603183d20e0808","decimalCount":18}]},{"id":"akropolis","name":"Akropolis","symbol":"AKRO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8ab7404063ec4dbcfd4598215992dc3f8ec853d7","decimalCount":18}]},{"id":"sentivate","name":"Sentivate","symbol":"SNTVT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7865af71cf0b288b4e7f654f4f7851eb46a2b7f8","decimalCount":18}]},{"id":"mithril","name":"Mithril","symbol":"MITH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3893b9422cd5d70a81edeffe3d5a1c6a978310bb","decimalCount":18}]},{"id":"gamestarter","name":"Gamestarter","symbol":"GAME","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd567b5f02b9073ad3a982a099a23bf019ff11d1c","decimalCount":5},{"networkId":"binance-smart-chain","contractAddress":"0x66109633715d2110dda791e64a7b2afadb517abb","decimalCount":5}]},{"id":"sandclock","name":"Sandclock","symbol":"QUARTZ","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xba8a621b4a54e61c442f5ec623687e2a942225ef","decimalCount":18}]},{"id":"marketmove","name":"MarketMove","symbol":"MOVE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x231cf6f78620e42fe00d0c5c3088b427f355d01c","decimalCount":9}]},{"id":"aventus","name":"Aventus","symbol":"AVT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0d88ed6e74bbfd96b831231638b66c05571e824f","decimalCount":18}]},{"id":"pallapay","name":"Pallapay","symbol":"PALLA","active":true,"networks":[{"networkId":"tron","contractAddress":"TCfLxS9xHxH8auBL3T8pf3NFTZhsxy4Ncg","decimalCount":8}]},{"id":"sideshift-token","name":"SideShift Token","symbol":"XAI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x35e78b3982e87ecfd5b3f3265b601c046cdbe232","decimalCount":18}]},{"id":"unisocks","name":"Unisocks","symbol":"SOCKS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x23b608675a2b2fb1890d3abbd85c5775c51691d5","decimalCount":18}]},{"id":"alchemist","name":"Alchemist","symbol":"MIST","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x88acdd2a6425c3faae4bc9650fd7e27e0bebb7ab","decimalCount":18}]},{"id":"dragonchain","name":"Dragonchain","symbol":"DRGN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x419c4db4b9e25d6db2ad9691ccb832c8d9fda05e","decimalCount":18}]},{"id":"antimatter","name":"AntiMatter","symbol":"MATTER","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9b99cca871be05119b2012fd4474731dd653febe","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0xaaa62d9584cbe8e4d68a43ec91bff4ff1fadb202","decimalCount":18}]},{"id":"bitnautic","name":"BitNautic","symbol":"BTNT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc45dbdf28844fdb1482c502897d433ac08d6ccd0","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xb9c7099d2fbbf82314de08045745daf951cdda85","decimalCount":18}]},{"id":"advertise-coin","name":"Advertise Coin","symbol":"ADCO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb6c3dc857845a713d3531cea5ac546f6767992f4","decimalCount":6}]},{"id":"stader","name":"Stader","symbol":"SD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x30d20208d987713f46dfd34ef128bb16c404d10f","decimalCount":18}]},{"id":"scallop","name":"Scallop","symbol":"SCLP","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xf2c96e402c9199682d5ded26d3771c6b192c01af","decimalCount":18}]},{"id":"paribus","name":"Paribus","symbol":"PBX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd528cf2e081f72908e086f8800977df826b5a483","decimalCount":18}]},{"id":"wliti","name":"wLITI","symbol":"WLITI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0b63128c40737b13647552e0c926bcfeccc35f93","decimalCount":18}]},{"id":"adapad","name":"ADAPad","symbol":"ADAPAD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdb0170e2d0c1cc1b2e7a90313d9b9afa4f250289","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xdb0170e2d0c1cc1b2e7a90313d9b9afa4f250289","decimalCount":18}]},{"id":"ekta-2","name":"Ekta","symbol":"EKTA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2f75113b13d136f861d212fa9b572f2c79ac81c4","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x45808ce43eb2d7685ff0242631f0feb6f3d8701a","decimalCount":18}]},{"id":"rubic","name":"Rubic","symbol":"RBC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa4eed63db85311e22df4473f87ccfc3dadcfa3e3","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x8e3bcc334657560253b83f08331d85267316e08a","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xc3cffdaf8f3fdf07da6d5e3a89b8723d5e385ff8","decimalCount":18}]},{"id":"lit","name":"LIT","symbol":"LIT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc5b3d3231001a776123194cf1290068e8b0c783b","decimalCount":18}]},{"id":"flux-token","name":"FluxProtocol","symbol":"FLX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3ea8ea4237344c9931214796d9417af1a1180770","decimalCount":18}]},{"id":"premia","name":"Premia","symbol":"PREMIA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6399c842dd2be3de30bf99bc7d1bbf6fa3650e70","decimalCount":18},{"networkId":"fantom","contractAddress":"0x3028b4395f98777123c7da327010c40f3c7cc4ef","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x51fc0f6660482ea73330e414efd7808811a57fa2","decimalCount":18}]},{"id":"pawtocol","name":"Pawtocol","symbol":"UPI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x70d2b7c19352bb76e4409858ff5746e500f2b67c","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x0d35a2b85c5a63188d566d104bebf7c694334ee4","decimalCount":18}]},{"id":"v-id-blockchain","name":"VIDT Datalink","symbol":"VIDT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfef4185594457050cc9c23980d301908fe057bb1","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x3f515f0a8e93f2e2f891ceeb3db4e62e202d7110","decimalCount":18}]},{"id":"wpp-token","name":"WPP Token","symbol":"WPP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1955d744f9435522be508d1ba60e3c12d0690b6a","decimalCount":18}]},{"id":"notional-finance","name":"Notional Finance","symbol":"NOTE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xcfeaead4947f0705a14ec42ac3d44129e1ef3ed5","decimalCount":8}]},{"id":"electra-protocol","name":"Electra Protocol","symbol":"XEP","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xb897d0a0f68800f8be7d69ffdd1c24b69f57bf3e","decimalCount":8}]},{"id":"gelato","name":"Gelato","symbol":"GEL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x15b7c0c907e4c6b9adaaaabc300c08991d6cea05","decimalCount":18}]},{"id":"oraichain-token","name":"Oraichain Token","symbol":"ORAI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4c11249814f11b9346808179cf06e71ac328c1b5","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xa325ad6d9c92b55a3fc5ad7e412b1518f96441c0","decimalCount":18}]},{"id":"mute","name":"Mute","symbol":"MUTE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa49d7499271ae71cd8ab9ac515e6694c755d400c","decimalCount":18}]},{"id":"kylin-network","name":"Kylin Network","symbol":"KYL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x67b6d479c7bb412c54e03dca8e1bc6740ce6b99c","decimalCount":18}]},{"id":"cake-monster","name":"Cake Monster","symbol":"MONSTA","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x8a5d7fcd4c90421d21d30fcc4435948ac3618b2f","decimalCount":18}]},{"id":"opacity","name":"Opacity","symbol":"OPCT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdb05ea0877a2622883941b939f0bb11d1ac7c400","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xce6bf09e5c7a3e65b84f88dcc6475c88d38ba5ef","decimalCount":18}]},{"id":"pangolin","name":"Pangolin","symbol":"PNG","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0x60781c2586d68229fde47564546784ab3faca982","decimalCount":18}]},{"id":"proximax","name":"ProximaX","symbol":"XPX","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x6f3aaf802f57d045efdd2ac9c06d8879305542af","decimalCount":6}]},{"id":"mogul-productions","name":"Mogul Productions","symbol":"STARS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc55c2175e90a46602fd42e931f62b3acc1a013ca","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xbd83010eb60f12112908774998f65761cf9f6f9a","decimalCount":18}]},{"id":"magnet-dao","name":"Magnet DAO","symbol":"MAG","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0x1d60109178c48e4a937d8ab71699d8ebb6f7c5de","decimalCount":9}]},{"id":"dollars","name":"Dollars","symbol":"USDX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2f6081e3552b1c86ce4479b80062a1dda8ef23e3","decimalCount":9}]},{"id":"straitsx-indonesia-rupiah","name":"XIDR","symbol":"XIDR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xebf2096e01455108badcbaf86ce30b6e5a72aa52","decimalCount":6}]},{"id":"bytz","name":"BYTZ","symbol":"BYTZ","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2aad9dbc82611485a52325923e1187734e951b78","decimalCount":8},{"networkId":"binance-smart-chain","contractAddress":"0x586fc153cf7e9c029d8c30842c4cb6a86f03b816","decimalCount":8}]},{"id":"arc","name":"Arc","symbol":"ARC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc82e3db60a52cf7529253b4ec688f631aad9e7c2","decimalCount":18}]},{"id":"compound-wrapped-btc","name":"cWBTC","symbol":"CWBTC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xccf4429db6322d5c611ee964527d42e5d685dd6a","decimalCount":8}]},{"id":"babylon-finance","name":"Babylon Finance","symbol":"BABL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf4dc48d260c93ad6a96c5ce563e70ca578987c74","decimalCount":18}]},{"id":"mint-club","name":"Mint Club","symbol":"MINT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x1f3af095cda17d63cad238358837321e95fc5915","decimalCount":18}]},{"id":"universe-xyz","name":"Universe.XYZ","symbol":"XYZ","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x618679df9efcd19694bb1daa8d00718eacfa2883","decimalCount":18}]},{"id":"ethereum-push-notification-service","name":"Ethereum Push Notification Service - EPNS","symbol":"PUSH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf418588522d5dd018b425e472991e52ebbeeeeee","decimalCount":18}]},{"id":"dacxi","name":"Dacxi","symbol":"DACXI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xefab7248d36585e2340e5d25f8a8d243e6e3193f","decimalCount":18}]},{"id":"arcblock","name":"Arcblock","symbol":"ABT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb98d4c97425d9908e66e53a6fdf673acca0be986","decimalCount":18}]},{"id":"apm-coin","name":"apM Coin","symbol":"APM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc8c424b91d8ce0137bab4b832b7f7d154156ba6c","decimalCount":18}]},{"id":"gamium","name":"Gamium","symbol":"GMM","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x5b6bf0c7f989de824677cfbd507d9635965e9cd3","decimalCount":18}]},{"id":"buying","name":"Buying.com","symbol":"BUY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x396ec402b42066864c406d1ac3bc86b575003ed8","decimalCount":2},{"networkId":"binance-smart-chain","contractAddress":"0x40225c6277b29bf9056b4acb7ee1512cbff11671","decimalCount":18}]},{"id":"unicly-cryptopunks-collection","name":"Unicly CryptoPunks Collection","symbol":"UPUNK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8d2bffcbb19ff14a698c424fbcdcfd17aab9b905","decimalCount":18}]},{"id":"sora","name":"Sora","symbol":"XOR","active":false,"networks":[{"networkId":"ethereum","contractAddress":"0x40fd72257597aa14c7231a7b1aaa29fce868f677","decimalCount":18}]},{"id":"88mph","name":"88mph","symbol":"MPH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8888801af4d980682e47f1a9036e589479e835c5","decimalCount":18}]},{"id":"rae-token","name":"Receive Access Ecosystem","symbol":"RAE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe5a3229ccb22b6484594973a03a3851dcd948756","decimalCount":18}]},{"id":"polkafoundry","name":"PolkaFoundry","symbol":"PKF","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8b39b70e39aa811b69365398e0aace9bee238aeb","decimalCount":18}]},{"id":"zb-token","name":"ZB Token","symbol":"ZB","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbd0793332e9fb844a52a205a233ef27a5b34b927","decimalCount":18}]},{"id":"media-network","name":"Media Network","symbol":"MEDIA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdb726152680ece3c9291f1016f1d36f3995f6941","decimalCount":6},{"networkId":"solana","contractAddress":"ETAtLmCmsoiEEKfNrHKJ2kYy3MoABhU6NQvpSfij5tDs","decimalCount":6}]},{"id":"hollaex-token","name":"HollaEx","symbol":"XHT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd3c625f54dec647db8780dbbe0e880ef21ba4329","decimalCount":18}]},{"id":"o3-swap","name":"O3 Swap","symbol":"O3","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xee9801669c6138e84bd50deb500827b776777d28","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xee9801669c6138e84bd50deb500827b776777d28","decimalCount":18},{"networkId":"avalanche","contractAddress":"0xee9801669c6138e84bd50deb500827b776777d28","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xee9801669c6138e84bd50deb500827b776777d28","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0xee9801669c6138e84bd50deb500827b776777d28","decimalCount":18}]},{"id":"tronpad","name":"TRONPAD","symbol":"TRONPAD","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x1bf7aedec439d6bfe38f8f9b20cf3dc99e3571c4","decimalCount":18}]},{"id":"zombie-inu","name":"Zombie Inu","symbol":"ZINU","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc50ef449171a51fbeafd7c562b064b6471c36caa","decimalCount":9},{"networkId":"binance-smart-chain","contractAddress":"0x21f9b5b2626603e3f40bfc13d01afb8c431d382f","decimalCount":9}]},{"id":"signum","name":"Signum","symbol":"SIGNA","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x7b0e7e40ee4672599f7095d1ddd730b0805195ba","decimalCount":8}]},{"id":"jupiter","name":"Jupiter","symbol":"JUP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4b1e80cac91e2216eeb63e29b957eb91ae9c2be8","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x0231f91e02debd20345ae8ab7d71a41f8e140ce7","decimalCount":18}]},{"id":"nunet","name":"NuNet","symbol":"NTX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf0d33beda4d734c72684b5f9abbebf715d0a7935","decimalCount":6}]},{"id":"exeedme","name":"Exeedme","symbol":"XED","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xee573a945b01b788b9287ce062a0cfc15be9fd86","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x5621b5a3f4a8008c4ccdd1b942b121c8b1944f1f","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x2fe8733dcb25bfbba79292294347415417510067","decimalCount":18}]},{"id":"pibble","name":"Pibble","symbol":"PIB","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1864ce27e9f7517047933caae530674e8c70b8a7","decimalCount":18}]},{"id":"april","name":"April","symbol":"APRIL","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xbfea674ce7d16e26e39e3c088810367a708ef94c","decimalCount":18}]},{"id":"neon-exchange","name":"Nash","symbol":"NEX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe2dc070524a6e305ddb64d8513dc444b6a1ec845","decimalCount":8}]},{"id":"ice-token","name":"Popsicle Finance","symbol":"ICE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf16e81dce15b08f326220742020379b855b87df9","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xf16e81dce15b08f326220742020379b855b87df9","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x4e1581f01046efdd7a1a2cdb0f82cdd7f71f2e59","decimalCount":18},{"networkId":"fantom","contractAddress":"0xf16e81dce15b08f326220742020379b855b87df9","decimalCount":18}]},{"id":"jones-dao","name":"Jones DAO","symbol":"JONES","active":true,"networks":[{"networkId":"arbitrum-one","contractAddress":"0x10393c20975cf177a3513071bc110f7962cd67da","decimalCount":18}]},{"id":"doge-dash","name":"Doge Dash","symbol":"DOGEDASH","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x7ae5709c585ccfb3e61ff312ec632c21a5f03f70","decimalCount":18}]},{"id":"epik-prime","name":"Epik Prime","symbol":"EPIK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4da0c48376c277cdbd7fc6fdc6936dee3e4adf75","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x368ce786ea190f32439074e8d22e12ecb718b44c","decimalCount":18}]},{"id":"shardus","name":"Shardus","symbol":"ULT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x09617f6fd6cf8a71278ec86e23bbab29c04353a7","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xf0059cc2b3e980065a906940fbce5f9db7ae40a7","decimalCount":18}]},{"id":"werewolf-coin","name":"Werewolf Coin","symbol":"WWC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x38118bdb3b480f570837a4c2e88fac6e83be6689","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x7f13dbb949c48f2a377fa4db4f2d5221ecbf3df9","decimalCount":18}]},{"id":"vector-finance","name":"Vector Finance","symbol":"VTX","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0x5817d4f0b62a59b17f75207da1848c2ce75e7af4","decimalCount":18}]},{"id":"blackpool-token","name":"BlackPool","symbol":"BPT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0ec9f76202a7061eb9b3a7d6b59d36215a7e37da","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x6863bd30c9e313b264657b107352ba246f8af8e0","decimalCount":18}]},{"id":"dope-wars-paper","name":"Dope Wars Paper","symbol":"PAPER","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7ae1d57b58fa6411f32948314badd83583ee0e8c","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xc28ea768221f67b6a1fd33e6aa903d4e42f6b177","decimalCount":18}]},{"id":"steam-exchange","name":"Steam Exchange","symbol":"STEAMX","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xc0924edefb2c0c303de2d0c21bff07ab763163b5","decimalCount":9}]},{"id":"stakeborg-dao","name":"Stakeborg DAO","symbol":"STANDARD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xda0c94c73d127ee191955fb46bacd7ff999b2bcd","decimalCount":18}]},{"id":"swftcoin","name":"SWFTCOIN","symbol":"SWFTC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0bb217e40f8a5cb79adf04e1aab60e5abd0dfc1e","decimalCount":8}]},{"id":"kan","name":"BitKan","symbol":"KAN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1410434b0346f5be678d0fb554e5c7ab620f8f4a","decimalCount":18}]},{"id":"kunci-coin","name":"Kunci Coin","symbol":"KUNCI","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x6cf271270662be1c4fc1b7bb7d7d7fc60cc19125","decimalCount":6}]},{"id":"ston","name":"Ston","symbol":"STON","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdc47f2ba852669b178699449e50682d6ceaf8c07","decimalCount":18}]},{"id":"vesper-finance","name":"Vesper Finance","symbol":"VSP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1b40183efb4dd766f11bda7a7c3ad8982e998421","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x09c5a4bca808bd1ba2b8e6b3aaf7442046b4ca5b","decimalCount":18},{"networkId":"fantom","contractAddress":"0x461d52769884ca6235b685ef2040f47d30c94eb5","decimalCount":18}]},{"id":"dego-finance","name":"Dego Finance","symbol":"DEGO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x88ef27e69108b2633f8e1c184cc37940a075cc02","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x3fda9383a84c05ec8f7630fe10adf1fac13241cc","decimalCount":18}]},{"id":"floordao","name":"FloorDAO","symbol":"FLOOR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf59257e961883636290411c11ec5ae622d19455e","decimalCount":9}]},{"id":"yearn-lazy-ape","name":"Yearn Lazy Ape","symbol":"YLA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9ba60ba98413a60db4c651d4afe5c937bbd8044b","decimalCount":18}]},{"id":"auto","name":"Auto","symbol":"AUTO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xa184088a740c695e156f91f5cc086a06bb78b827","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x7f426f6dc648e50464a0392e60e1bb465a67e9cf","decimalCount":18}]},{"id":"dose-token","name":"DOSE","symbol":"DOSE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb31ef9e52d94d4120eb44fe1ddfde5b4654a6515","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x7837fd820ba38f95c54d6dac4ca3751b81511357","decimalCount":18}]},{"id":"evolution-finance","name":"Evolution Finance","symbol":"EVN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9af15d7b8776fa296019979e70a5be53c714a7ec","decimalCount":18}]},{"id":"hot-cross","name":"Hot Cross","symbol":"HOTCROSS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4297394c20800e8a38a619a243e9bbe7681ff24e","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x4fa7163e153419e0e1064e418dd7a99314ed27b6","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x2f86508f41310d8d974b76deb3d246c0caa71cf5","decimalCount":18}]},{"id":"lords","name":"LORDS","symbol":"LORDS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x686f2404e77ab0d9070a46cdfb0b7fecdd2318b0","decimalCount":18}]},{"id":"chain-guardians","name":"Chain Guardians","symbol":"CGG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1fe24f25b1cf609b9c4e7e12d802e3640dfa5e43","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x1613957159e9b0ac6c80e824f7eea748a32a0ae2","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x2ab4f9ac80f33071211729e45cfc346c1f8446d5","decimalCount":18}]},{"id":"polkamarkets","name":"Polkamarkets","symbol":"POLK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd478161c952357f05f0292b56012cd8457f1cfbf","decimalCount":18}]},{"id":"splyt","name":"SHOPX","symbol":"SHOPX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7bef710a5759d197ec0bf621c3df802c2d60d848","decimalCount":18}]},{"id":"mork","name":"MORK","symbol":"MORK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf552b656022c218c26dad43ad88881fc04116f76","decimalCount":4}]},{"id":"metasoccer","name":"MetaSoccer","symbol":"MSU","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0xe8377a076adabb3f9838afb77bee96eac101ffb1","decimalCount":18}]},{"id":"vempire-ddao","name":"vEmpire DDAO","symbol":"VEMP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xcfeb09c3c5f0f78ad72166d55f9e6e9a60e96eec","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xedf3ce4dd6725650a8e9398e5c6398d061fa7955","decimalCount":18}]},{"id":"media-licensing-token","name":"Media Licensing Token","symbol":"MLT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9506d37f70eb4c3d79c398d326c871abbf10521d","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x4518231a8fdf6ac553b9bbd51bbb86825b583263","decimalCount":18}]},{"id":"openocean","name":"OpenOcean","symbol":"OOE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7778360f035c589fce2f4ea5786cbd8b36e5396b","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x9029fdfae9a03135846381c7ce16595c3554e10a","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x0ebd9537a25f56713e34c45b38f421a1e7191469","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x9d5565da88e596730522cbc5a918d2a89dbc16d9","decimalCount":18},{"networkId":"fantom","contractAddress":"0x9d8f97a3c2f9f397b6d46cbe2d39cc1d8cf19010","decimalCount":18}]},{"id":"blockbank","name":"BlockBank","symbol":"BBANK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf4b5470523ccd314c6b9da041076e7d79e0df267","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xf4b5470523ccd314c6b9da041076e7d79e0df267","decimalCount":18}]},{"id":"aladdin-dao","name":"Aladdin DAO","symbol":"ALD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb26c4b3ca601136daf98593feaeff9e0ca702a8d","decimalCount":18}]},{"id":"bomb-money","name":"Bomb Money","symbol":"BOMB","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x522348779dcb2911539e76a1042aa922f9c47ee3","decimalCount":18}]},{"id":"chimaera","name":"XAYA","symbol":"CHI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6dc02164d75651758ac74435806093e421b64605","decimalCount":8},{"networkId":"binance-smart-chain","contractAddress":"0x22648c12acd87912ea1710357b1302c6a4154ebc","decimalCount":8},{"networkId":"polygon-pos","contractAddress":"0xe79feaaa457ad7899357e8e2065a3267ac9ee601","decimalCount":8}]},{"id":"troy","name":"Troy","symbol":"TROY","active":true,"networks":[{"networkId":"binancecoin","contractAddress":"TROY-9B8","decimalCount":8}]},{"id":"saffron-finance","name":"saffron.finance","symbol":"SFI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb753428af26e81097e7fd17f40c88aaa3e04902c","decimalCount":18}]},{"id":"blockchain-monster-hunt","name":"Blockchain Monster Hunt","symbol":"BCMC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2ba8349123de45e931a8c8264c332e6e9cf593f9","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xc10358f062663448a3489fc258139944534592ac","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xc10358f062663448a3489fc258139944534592ac","decimalCount":18}]},{"id":"smart-valor","name":"Smart Valor","symbol":"VALOR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x297e4e5e59ad72b1b0a2fd446929e76117be0e0a","decimalCount":18}]},{"id":"radar","name":"Radar","symbol":"RADAR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf9fbe825bfb2bf3e387af0dc18cac8d87f29dea8","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xf03a2dc374d494fbe894563fe22ee544d826aa50","decimalCount":18}]},{"id":"blockv","name":"BLOCKv","symbol":"VEE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x340d2bde5eb28c1eed91b2f790723e3b160613b7","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xf1c1a3c2481a3a8a3f173a9ab5ade275292a6fa3","decimalCount":18}]},{"id":"santos-fc-fan-token","name":"Santos FC Fan Token","symbol":"SANTOS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xa64455a4553c9034236734faddaddbb64ace4cc7","decimalCount":8}]},{"id":"poolz-finance","name":"Poolz Finance","symbol":"POOLZ","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x69a95185ee2a045cdc4bcd1b1df10710395e4e23","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x77018282fd033daf370337a5367e62d8811bc885","decimalCount":18}]},{"id":"te-food","name":"TE-FOOD","symbol":"TONE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2ab6bb8408ca3199b8fa6c92d5b455f820af03c4","decimalCount":18}]},{"id":"zano","name":"Zano","symbol":"ZANO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdb85f6685950e285b1e611037bebe5b34e2b7d78","decimalCount":18}]},{"id":"hegic","name":"Hegic","symbol":"HEGIC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x584bc13c7d411c00c01a62e8019472de68768430","decimalCount":18},{"networkId":"fantom","contractAddress":"0x44b26e839eb3572c5e959f994804a5de66600349","decimalCount":18}]},{"id":"calo-app","name":"Calo","symbol":"CALO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xb6b91269413b6b99242b1c0bc611031529999999","decimalCount":18}]},{"id":"empire-capital-token","name":"Empire Capital","symbol":"ECC","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xc84d8d03aa41ef941721a4d77b24bb44d7c7ac55","decimalCount":9}]},{"id":"ridotto","name":"Ridotto","symbol":"RDT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4740735aa98dc8aa232bd049f8f0210458e7fca3","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xe9c64384deb0c2bf06d991a8d708c77eb545e3d5","decimalCount":18}]},{"id":"polar-sync","name":"Polar Sync","symbol":"POLAR","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xc64c9b30c981fc2ee4e13d0ca3f08258e725fd24","decimalCount":18}]},{"id":"guild-of-guardians","name":"Guild of Guardians","symbol":"GOG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9ab7bb7fdc60f4357ecfef43986818a2a3569c62","decimalCount":18}]},{"id":"vedao","name":"veDAO","symbol":"WEVE","active":true,"networks":[{"networkId":"fantom","contractAddress":"0x911da02c1232a3c3e1418b834a311921143b04d7","decimalCount":18}]},{"id":"bogged-finance","name":"Bogged Finance","symbol":"BOG","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xb09fe1613fe03e7361319d2a43edc17422f36b09","decimalCount":18},{"networkId":"avalanche","contractAddress":"0xb09fe1613fe03e7361319d2a43edc17422f36b09","decimalCount":18}]},{"id":"raiden-network","name":"Raiden Network Token","symbol":"RDN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x255aa6df07540cb5d3d297f0d0d4d84cb52bc8e6","decimalCount":18}]},{"id":"k21","name":"K21","symbol":"K21","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb9d99c33ea2d86ec5ec6b8a4dd816ebba64404af","decimalCount":18}]},{"id":"strikecoin","name":"StrikeX","symbol":"STRX","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xd6fdde76b8c1c45b33790cc8751d5b88984c44ec","decimalCount":18}]},{"id":"fantohm","name":"Fantohm","symbol":"FHM","active":true,"networks":[{"networkId":"fantom","contractAddress":"0xfa1fbb8ef55a4855e5688c0ee13ac3f202486286","decimalCount":9}]},{"id":"pendle","name":"Pendle","symbol":"PENDLE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x808507121b80c02388fad14726482e061b8da827","decimalCount":18},{"networkId":"avalanche","contractAddress":"0xfb98b335551a418cd0737375a2ea0ded62ea213b","decimalCount":18}]},{"id":"polkaswap","name":"Polkaswap","symbol":"PSWAP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x519c1001d550c0a1dae7d1fc220f7d14c2a521bb","decimalCount":18}]},{"id":"mysterium","name":"Mysterium","symbol":"MYST","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4cf89ca06ad997bc732dc876ed2a7f26a9e7f361","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x2ff0b946a6782190c4fe5d4971cfe79f0b6e4df2","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x1379e8886a944d2d9d440b3d88df536aea08d9f3","decimalCount":18}]},{"id":"bread","name":"Bread","symbol":"BRD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x558ec3152e2eb2174905cd19aea4e34a23de9ad6","decimalCount":18}]},{"id":"multivac","name":"MultiVAC","symbol":"MTV","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6226e00bcac68b0fe55583b90a1d727c14fab77f","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x8aa688ab789d1848d131c65d98ceaa8875d97ef1","decimalCount":18}]},{"id":"daohaus","name":"DAOhaus","symbol":"HAUS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf2051511b9b121394fa75b8f7d4e7424337af687","decimalCount":18}]},{"id":"usdp","name":"USDP Stablecoin","symbol":"USDP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1456688345527be1f37e9e627da0837d6f08c925","decimalCount":18}]},{"id":"cirus","name":"Cirus","symbol":"CIRUS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa01199c61841fce3b3dafb83fefc1899715c8756","decimalCount":18}]},{"id":"govi","name":"CVI","symbol":"GOVI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xeeaa40b28a2d1b0b08f6f97bb1dd4b75316c6107","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x43df9c0a1156c96cea98737b511ac89d0e2a1f46","decimalCount":18}]},{"id":"moon-nation-game","name":"Moon Nation Game","symbol":"MNG","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x5941f87eb62737ec5ebbecab3e373c40fe40566b","decimalCount":9}]},{"id":"probit-exchange","name":"Probit Token","symbol":"PROB","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfb559ce67ff522ec0b9ba7f5dc9dc7ef6c139803","decimalCount":18}]},{"id":"bankless-dao","name":"Bankless DAO","symbol":"BANK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2d94aa3e47d9d5024503ca8491fce9a2fb4da198","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xdb7cb471dd0b49b29cab4a1c14d070f27216a0ab","decimalCount":18}]},{"id":"nftrade","name":"NFTrade","symbol":"NFTD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8e0fe2947752be0d5acf73aae77362daf79cb379","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xac83271abb4ec95386f08ad2b904a46c61777cef","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x9e3ca00f2d4a9e5d4f0add0900de5f15050812cf","decimalCount":18}]},{"id":"cardstack","name":"Cardstack","symbol":"CARD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x954b890704693af242613edef1b603825afcd708","decimalCount":18}]},{"id":"fractal","name":"Fractal","symbol":"FCL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf4d861575ecc9493420a3f5a14f85b13f0b50eb3","decimalCount":18}]},{"id":"polychain-monsters","name":"Polychain Monsters","symbol":"PMON","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1796ae0b0fa4862485106a0de9b654efe301d0b2","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x1796ae0b0fa4862485106a0de9b654efe301d0b2","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x1796ae0b0fa4862485106a0de9b654efe301d0b2","decimalCount":18}]},{"id":"kalmar","name":"Kalmar","symbol":"KALM","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x4ba0057f784858a48fe351445c672ff2a3d43515","decimalCount":18}]},{"id":"zmine","name":"ZMINE","symbol":"ZMN","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xfcb8a4b1a0b645e08064e05b98e9cc6f48d2aa57","decimalCount":18}]},{"id":"polka-city","name":"Polkacity","symbol":"POLC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xaa8330fb2b4d5d07abfe7a72262752a8505c6b37","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x6ae9701b9c423f40d54556c9a443409d79ce170a","decimalCount":18}]},{"id":"vent-finance","name":"Vent Finance","symbol":"VENT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5f0bc16d50f72d10b719dbf6845de2e599eb5624","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x872d068c25511be88c1f5990c53eeffcdf46c9b4","decimalCount":18}]},{"id":"thales","name":"Thales","symbol":"THALES","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8947da500eb47f82df21143d0c01a29862a8c3c5","decimalCount":18}]},{"id":"umbrella-network","name":"Umbrella Network","symbol":"UMB","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6fc13eace26590b80cccab1ba5d51890577d83b2","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x846f52020749715f02aef25b5d1d65e48945649d","decimalCount":18}]},{"id":"liquiddriver","name":"LiquidDriver","symbol":"LQDR","active":true,"networks":[{"networkId":"fantom","contractAddress":"0x10b620b2dbac4faa7d7ffd71da486f5d44cd86f9","decimalCount":18}]},{"id":"friesdao","name":"friesDAO","symbol":"FRIES","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfa57f00d948bb6a28072f5416fcbf7836c3d62dd","decimalCount":18}]},{"id":"gold-fever-native-gold","name":"Gold Fever Native Gold","symbol":"NGL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2653891204f463fb2a2f4f412564b19e955166ae","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x0f5d8cd195a4539bcf2ec6118c6da50287c6d5f5","decimalCount":18}]},{"id":"satt","name":"SaTT","symbol":"SATT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdf49c9f599a0a9049d97cff34d0c30e468987389","decimalCount":18}]},{"id":"mobiecoin","name":"MobieCoin","symbol":"MBX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x71ba91dc68c6a206db0a6a92b4b1de3f9271432d","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x064c8e55aa484adbd58ca2d43343ef50137473b7","decimalCount":18}]},{"id":"stacktical","name":"DSLA Protocol","symbol":"DSLA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3affcca64c2a6f4e3b6bd9c64cd2c969efd1ecbe","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x1861c9058577c3b48e73d91d6f25c18b17fbffe0","decimalCount":18},{"networkId":"avalanche","contractAddress":"0xd7c295e399ca928a3a14b01d760e794f1adf8990","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xa0e390e9cea0d0e8cd40048ced9fa9ea10d71639","decimalCount":18},{"networkId":"fantom","contractAddress":"0x25a528af62e56512a19ce8c3cab427807c28cc19","decimalCount":18}]},{"id":"wegro","name":"WeGro","symbol":"WEGRO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xd7c5d2a3b7868e6dd539e145c98a565f29ef3fa4","decimalCount":18}]},{"id":"babb","name":"BABB","symbol":"BAX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9a0242b7a33dacbe40edb927834f96eb39f8fbcb","decimalCount":18}]},{"id":"infinity-pad","name":"Infinity Pad","symbol":"IPAD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x36ed7baad9a571b5dad55d096c0ed902188d6d3c","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xf07dfc2ad28ab5b09e8602418d2873fcb95e1744","decimalCount":18}]},{"id":"mahadao","name":"MahaDAO","symbol":"MAHA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb4d930279552397bba2ee473229f89ec245bc365","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xedd6ca8a4202d4a36611e2fff109648c4863ae19","decimalCount":18}]},{"id":"anchorswap","name":"AnchorSwap","symbol":"ANCHOR","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x4aac18de824ec1b553dbf342829834e4ff3f7a9f","decimalCount":18}]},{"id":"gamee","name":"GAMEE","symbol":"GMEE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd9016a907dc0ecfa3ca425ab20b6b785b42f2373","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x84e9a6f9d240fdd33801f7135908bfa16866939a","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xcf32822ff397ef82425153a9dcb726e5ff61dca7","decimalCount":18}]},{"id":"wom-token","name":"WOM Protocol","symbol":"WOM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbd356a39bff2cada8e9248532dd879147221cf76","decimalCount":18}]},{"id":"ambire-wallet","name":"Ambire Wallet","symbol":"WALLET","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x88800092ff476844f74dc2fc427974bbee2794ae","decimalCount":18}]},{"id":"morpheus-labs","name":"Morpheus Labs","symbol":"MITX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4a527d8fc13c5203ab24ba0944f4cb14658d1db6","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x31042a4e66eda0d12143ffc8cc1552d611da4cba","decimalCount":18}]},{"id":"aldrin","name":"Aldrin","symbol":"RIN","active":true,"networks":[{"networkId":"solana","contractAddress":"E5ndSkaB17Dm7CsD22dvcjfrYSDLCxFcMd6z8ddCk5wp","decimalCount":9}]},{"id":"betu","name":"Betu","symbol":"BETU","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x0df1b3f30865c5b324797f8db9d339514cac4e94","decimalCount":18}]},{"id":"hapi","name":"HAPI","symbol":"HAPI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd9c2d319cd7e6177336b0a9c93c21cb48d84fb54","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xd9c2d319cd7e6177336b0a9c93c21cb48d84fb54","decimalCount":18}]},{"id":"bitcoin-pro","name":"Bitcoin Pro","symbol":"BTCP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x723cbfc05e2cfcc71d3d89e770d32801a5eef5ab","decimalCount":8}]},{"id":"populous","name":"Populous","symbol":"PPT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd4fa1460f537bb9085d22c7bccb5dd450ef28e3a","decimalCount":8}]},{"id":"vfox","name":"VFOX","symbol":"VFOX","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x4d61577d8fd2208a0afb814ea089fdeae19ed202","decimalCount":18}]},{"id":"filecoin-standard-full-hashrate","name":"Filecoin Standard Full Hashrate","symbol":"SFIL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x965b85d4674f64422c4898c8f8083187f02b32c0","decimalCount":8},{"networkId":"binance-smart-chain","contractAddress":"0x965b85d4674f64422c4898c8f8083187f02b32c0","decimalCount":8}]},{"id":"credmark","name":"Credmark","symbol":"CMK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x68cfb82eacb9f198d508b514d898a403c449533e","decimalCount":18}]},{"id":"symbiosis-finance","name":"Symbiosis Finance","symbol":"SIS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd38bb40815d2b0c2d2c866e0c72c5728ffc76dd9","decimalCount":18}]},{"id":"ptokens-btc","name":"pTokens BTC","symbol":"PBTC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5228a22e72ccc52d415ecfd199f99d0665e7733b","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xed28a457a5a76596ac48d87c0f577020f6ea1c4c","decimalCount":18}]},{"id":"usd-balance","name":"USD Balance","symbol":"USDB","active":true,"networks":[{"networkId":"fantom","contractAddress":"0x6fc9383486c163fa48becdec79d6058f984f62ca","decimalCount":18}]},{"id":"safemars","name":"Safemars","symbol":"SAFEMARS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x3ad9594151886ce8538c1ff615efa2385a8c3a88","decimalCount":9}]},{"id":"babydoge-coin-eth","name":"BabyDoge ETH","symbol":"BABYDOGE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xac8e13ecc30da7ff04b842f21a62a1fb0f10ebd5","decimalCount":9}]},{"id":"shirtum","name":"Shirtum","symbol":"SHI","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x7269d98af4aa705e0b1a5d8512fadb4d45817d5a","decimalCount":18}]},{"id":"ztcoin","name":"ZBG Token","symbol":"ZT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfe39e6a32acd2af7955cb3d406ba2b55c901f247","decimalCount":18}]},{"id":"spiritswap","name":"SpiritSwap","symbol":"SPIRIT","active":true,"networks":[{"networkId":"fantom","contractAddress":"0x5cc61a78f164885776aa610fb0fe1257df78e59b","decimalCount":18}]},{"id":"treasure-under-sea","name":"Treasure Under Sea","symbol":"TUS","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0xf693248f96fe03422fea95ac0afbbbc4a8fdd172","decimalCount":18}]},{"id":"etherisc","name":"Etherisc DIP Token","symbol":"DIP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc719d010b63e5bbf2c0551872cd5316ed26acd83","decimalCount":18}]},{"id":"new-order","name":"New Order","symbol":"NEWO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x98585dfc8d9e7d48f0b1ae47ce33332cf4237d96","decimalCount":18}]},{"id":"the-husl","name":"The HUSL","symbol":"HUSL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa2881f7f441267042f9778ffa0d4f834693426be","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x284ac5af363bde6ef5296036af8fb0e9cc347b41","decimalCount":18}]},{"id":"waltonchain","name":"Waltonchain","symbol":"WTC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb7cb1c96db6b22b0d3d9536e0108d062bd488f74","decimalCount":18}]},{"id":"cache-gold","name":"CACHE Gold","symbol":"CGT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf5238462e7235c7b62811567e63dd17d12c2eaa0","decimalCount":8}]},{"id":"acent","name":"Acent","symbol":"ACE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xec5483804e637d45cde22fa0869656b64b5ab1ab","decimalCount":18}]},{"id":"tokenclub","name":"TokenClub","symbol":"TCT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4824a7b64e3966b0133f4f4ffb1b9d6beb75fff7","decimalCount":18}]},{"id":"darwinia-network-native-token","name":"Darwinia Network Native Token","symbol":"RING","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9469d013805bffb7d3debe5e7839237e535ec483","decimalCount":18}]},{"id":"beekan","name":"BeeKan / Beenews","symbol":"BKBT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6a27348483d59150ae76ef4c0f3622a78b0ca698","decimalCount":18}]},{"id":"kccpad","name":"KCCPad","symbol":"KCCPAD","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x11582ef4642b1e7f0a023804b497656e2663bc9b","decimalCount":18}]},{"id":"acet-token","name":"Acet","symbol":"ACT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x9f3bcbe48e8b754f331dfc694a894e8e686ac31d","decimalCount":18}]},{"id":"realfevr","name":"RealFevr","symbol":"FEVR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9fb83c0635de2e815fd1c21b3a292277540c2e8d","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x82030cdbd9e4b7c5bb0b811a61da6360d69449cc","decimalCount":18}]},{"id":"the-abyss","name":"Abyss","symbol":"ABYSS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0e8d6b471e332f140e7d9dbb99e5e3822f728da6","decimalCount":18}]},{"id":"shill-token","name":"Project SEED SHILL","symbol":"SHILL","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xfb9c339b4bace4fe63ccc1dd9a3c3c531441d5fe","decimalCount":18},{"networkId":"solana","contractAddress":"6cVgJUqo4nmvQpbgrDZwyfd6RwWw5bfnCamS3M9N1fd","decimalCount":6}]},{"id":"bifi","name":"BiFi","symbol":"BIFI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2791bfd60d232150bff86b39b7146c0eaaa2ba81","decimalCount":18},{"networkId":"fantom","contractAddress":"0xad260f380c9a30b1d60e4548a75010ede630b665","decimalCount":18}]},{"id":"ferrum-network","name":"Ferrum Network","symbol":"FRM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe5caef4af8780e59df925470b050fb23c43ca68c","decimalCount":6},{"networkId":"binance-smart-chain","contractAddress":"0xa719b8ab7ea7af0ddb4358719a34631bb79d15dc","decimalCount":18},{"networkId":"avalanche","contractAddress":"0xe5caef4af8780e59df925470b050fb23c43ca68c","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xd99bafe5031cc8b345cb2e8c80135991f12d7130","decimalCount":18}]},{"id":"vcgamers","name":"VCGamers","symbol":"VCG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1f36fb2d91d9951cf58ae4c1956c0b77e224f1e9","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x1f36fb2d91d9951cf58ae4c1956c0b77e224f1e9","decimalCount":18}]},{"id":"tempus","name":"Tempus","symbol":"TEMP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa36fdbbae3c9d55a1d67ee5821d53b50b63a1ab9","decimalCount":18},{"networkId":"fantom","contractAddress":"0x1c174f6ab0753162befbb916c69def2cc1bfdec1","decimalCount":18}]},{"id":"torum","name":"Torum","symbol":"XTM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xcd1faff6e578fa5cac469d2418c95671ba1a62fe","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xcd1faff6e578fa5cac469d2418c95671ba1a62fe","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xe1c42be9699ff4e11674819c1885d43bd92e9d15","decimalCount":18}]},{"id":"metavpad","name":"MetaVPad","symbol":"METAV","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x62858686119135cc00c4a3102b436a0eb314d402","decimalCount":18}]},{"id":"tigercash","name":"TigerCash","symbol":"TCH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9b39a0b97319a9bd5fed217c1db7b030453bac91","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x5ecc4b299e23f526980c33fe35eff531a54aedb1","decimalCount":18}]},{"id":"btc-2x-flexible-leverage-index","name":"BTC 2x Flexible Leverage Index","symbol":"BTC2X-FLI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0b498ff89709d3838a063f1dfa463091f9801c2b","decimalCount":18}]},{"id":"crypto-raiders","name":"Crypto Raiders","symbol":"RAIDER","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0xcd7361ac3307d1c5a46b63086a90742ff44c63b3","decimalCount":18}]},{"id":"julswap","name":"JulSwap","symbol":"JULD","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x5a41f637c3f7553dba6ddc2d3ca92641096577ea","decimalCount":18}]},{"id":"trubadger","name":"TruBadger","symbol":"TRUBGR","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xc003f5193cabe3a6cbb56948dfeaae2276a6aa5e","decimalCount":18}]},{"id":"ethereans","name":"Ethereans","symbol":"OS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6100dd79fcaa88420750dcee3f735d168abcb771","decimalCount":18}]},{"id":"robot","name":"Robot","symbol":"ROBOT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfb5453340c03db5ade474b27e68b6a9c6b2823eb","decimalCount":18}]},{"id":"modefi","name":"Modefi","symbol":"MOD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xea1ea0972fa092dd463f2968f9bb51cc4c981d71","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xd4fbc57b6233f268e7fba3b66e62719d74deecbc","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x8346ab8d5ea7a9db0209aed2d1806afa0e2c4c21","decimalCount":18},{"networkId":"fantom","contractAddress":"0xe64b9fd040d1f9d4715c645e0d567ef69958d3d9","decimalCount":18}]},{"id":"rangers-protocol-gas","name":"Rangers Protocol","symbol":"RPG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0e5c8c387c5eba2ecbc137ad012aed5fe729e251","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xc2098a8938119a52b1f7661893c0153a6cb116d5","decimalCount":18}]},{"id":"databroker-dao","name":"DaTa eXchange Token","symbol":"DTX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x765f0c16d1ddc279295c1a7c24b0883f62d33f75","decimalCount":18}]},{"id":"tontoken","name":"TONToken","symbol":"TON","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6a6c2ada3ce053561c2fbc3ee211f23d9b8c520a","decimalCount":18}]},{"id":"cope","name":"Cope","symbol":"COPE","active":true,"networks":[{"networkId":"solana","contractAddress":"8HGyAAB1yoM1ttS7pXjHMa3dukTFGQggnFFH3hJZgzQh","decimalCount":6}]},{"id":"blocto-token","name":"Blocto","symbol":"BLT","active":true,"networks":[{"networkId":"solana","contractAddress":"BLT1noyNr3GttckEVrtcfC6oyK6yV1DpPgSyXbncMwef","decimalCount":8}]},{"id":"iqeon","name":"IQeon","symbol":"IQN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0db8d8b76bc361bacbb72e2c491e06085a97ab31","decimalCount":18}]},{"id":"realm","name":"Realm","symbol":"REALM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x464fdb8affc9bac185a7393fd4298137866dcfb8","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x464fdb8affc9bac185a7393fd4298137866dcfb8","decimalCount":18}]},{"id":"eqifi","name":"EQIFi","symbol":"EQX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbd3de9a069648c84d27d74d701c9fa3253098b15","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x436c52a8cee41d5e9c5e6f4cb146e66d552fb700","decimalCount":18}]},{"id":"cardstarter","name":"Cardstarter","symbol":"CARDS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3d6f0dea3ac3c607b3998e6ce14b6350721752d9","decimalCount":18}]},{"id":"robonomics-network","name":"Robonomics Network","symbol":"XRT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7de91b204c1c737bcee6f000aaa6569cf7061cb7","decimalCount":9}]},{"id":"bscex","name":"BSCEX","symbol":"BSCX","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x5ac52ee5b2a633895292ff6d8a89bb9190451587","decimalCount":18}]},{"id":"swash","name":"Swash","symbol":"SWASH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa130e3a33a4d84b04c3918c4e5762223ae252f80","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xba3cb8329d442e6f9eb70fafe1e214251df3d275","decimalCount":18}]},{"id":"adora-token","name":"Adora","symbol":"ARA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9ac5c63ddcb93612e316ab31dfc8192bc8961988","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xa9243aeb1e1038273d479436d4f4dece656c62f3","decimalCount":18}]},{"id":"vidya","name":"Vidya","symbol":"VIDYA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3d3d35bb9bec23b06ca00fe472b50e7a4c692c30","decimalCount":18}]},{"id":"cola-token","name":"Cola","symbol":"COLA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x19e98c4921aab7e3f5fd2adca36cfb669c63e926","decimalCount":18}]},{"id":"blockasset","name":"Blockasset","symbol":"BLOCK","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xbc7a566b85ef73f935e640a06b5a8b031cd975df","decimalCount":6}]},{"id":"onston","name":"Onston","symbol":"ONSTON","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x47b9f01b16e9c9cb99191dca68c9cc5bf6403957","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x72bc9d71dd9ad563f52270c6ce5fb30f617c7a1d","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xa4ce4a467e51aefec683a649c3f14427f104667f","decimalCount":18}]},{"id":"internxt","name":"Internxt","symbol":"INXT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4a8f5f96d5436e43112c2fbc6a9f70da9e4e16d4","decimalCount":8}]},{"id":"woofy","name":"Woofy","symbol":"WOOFY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd0660cd418a64a1d44e9214ad8e459324d8157f1","decimalCount":12},{"networkId":"polygon-pos","contractAddress":"0xd0660cd418a64a1d44e9214ad8e459324d8157f1","decimalCount":12},{"networkId":"fantom","contractAddress":"0xd0660cd418a64a1d44e9214ad8e459324d8157f1","decimalCount":12}]},{"id":"crypto-carbon-energy","name":"Crypto Carbon Energy","symbol":"CYCE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xeadd9b69f96140283f9ff75da5fd33bcf54e6296","decimalCount":6}]},{"id":"spartan-protocol-token","name":"Spartan Protocol Token","symbol":"SPARTA","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x3910db0600ea925f63c36ddb1351ab6e2c6eb102","decimalCount":18}]},{"id":"ix-swap","name":"IX Swap","symbol":"IXS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x73d7c860998ca3c01ce8c808f5577d94d545d1b4","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x1ba17c639bdaecd8dc4aac37df062d17ee43a1b8","decimalCount":18}]},{"id":"apy-finance","name":"APY.Finance","symbol":"APY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x95a4492f028aa1fd432ea71146b433e7b4446611","decimalCount":18}]},{"id":"connect-financial","name":"Connect Financial","symbol":"CNFI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xeabb8996ea1662cad2f7fb715127852cd3262ae9","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x6f5401c53e2769c858665621d22ddbf53d8d27c5","decimalCount":18}]},{"id":"mars4","name":"MARS4","symbol":"MARS4","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x16cda4028e9e872a38acb903176719299beaed87","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x9cd9c5a44cb8fab39b2ee3556f5c439e65e4fddd","decimalCount":18}]},{"id":"sin-city","name":"Sinverse","symbol":"SIN","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x6397de0f9aedc0f7a8fa8b438dde883b9c201010","decimalCount":18}]},{"id":"sidus","name":"Sidus","symbol":"SIDUS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x549020a9cb845220d66d3e9c6d9f9ef61c981102","decimalCount":18}]},{"id":"muse-2","name":"Muse DAO","symbol":"MUSE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb6ca7399b4f9ca56fc27cbff44f4d2e4eef1fc81","decimalCount":18}]},{"id":"green-climate-world","name":"Green Climate World","symbol":"WGC","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x1e4ffa373d94c95717fb83ec026b2e0e2f443bb0","decimalCount":16}]},{"id":"uno-re","name":"Uno Re","symbol":"UNO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x474021845c4643113458ea4414bdb7fb74a01a77","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x474021845c4643113458ea4414bdb7fb74a01a77","decimalCount":18}]},{"id":"dify-finance","name":"Dify.Finance","symbol":"YFIII","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4be40bc9681d0a7c24a99b4c92f85b9053fc2a45","decimalCount":18}]},{"id":"spankchain","name":"SpankChain","symbol":"SPANK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x42d6622dece394b54999fbd73d108123806f6a18","decimalCount":18}]},{"id":"unicly-bored-ape-yacht-club-collection","name":"Unicly Bored Ape Yacht Club Collection","symbol":"UAPE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x17e347aad89b30b96557bcbfbff8a14e75cc88a1","decimalCount":18}]},{"id":"ioi-token","name":"IOI","symbol":"IOI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8b3870df408ff4d7c3a26df852d41034eda11d81","decimalCount":6},{"networkId":"binance-smart-chain","contractAddress":"0x959229d94c9060552daea25ac17193bca65d7884","decimalCount":6},{"networkId":"polygon-pos","contractAddress":"0xaf24765f631c8830b5528b57002241ee7eef1c14","decimalCount":6}]},{"id":"wrapped-ampleforth","name":"Wrapped Ampleforth","symbol":"WAMPL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xedb171c18ce90b633db442f2a6f72874093b49ef","decimalCount":18}]},{"id":"dovu","name":"Dovu","symbol":"DOV","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xac3211a5025414af2866ff09c23fc18bc97e79b1","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xc9457161320210d22f0d0d5fc1309acb383d4609","decimalCount":18}]},{"id":"boringdao-btc","name":"BoringDAO BTC","symbol":"OBTC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8064d9ae6cdf087b1bcd5bdf3531bd5d8c537a68","decimalCount":18}]},{"id":"creampye","name":"Creampye [OLD]","symbol":"PYE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xaad87f47cdea777faf87e7602e91e3a6afbe4d57","decimalCount":18}]},{"id":"meta","name":"mStable Governance Token: Meta","symbol":"MTA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa3bed4e1c75d00fa6f4e5e6922db7261b5e9acd2","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xf501dd45a1198c2e1b5aef5314a68b9006d842e0","decimalCount":18}]},{"id":"plotx","name":"PlotX","symbol":"PLOT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x72f020f8f3e8fd9382705723cd26380f8d0c66bb","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xe82808eaa78339b06a691fd92e1be79671cad8d3","decimalCount":18}]},{"id":"fibo-token","name":"FibSwap DEX","symbol":"FIBO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x5067c6e9e6c443372f2e62946273abbf3cc2f2b3","decimalCount":9}]},{"id":"planet-finance","name":"Planet Finance","symbol":"AQUA","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x72b7d61e8fc8cf971960dd9cfa59b8c829d91991","decimalCount":18}]},{"id":"tokpie","name":"TOKPIE","symbol":"TKP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd31695a1d35e489252ce57b129fd4b1b05e6acac","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x7849ed1447250d0b896f89b58f3075b127ca29b3","decimalCount":18}]},{"id":"gains","name":"Gains","symbol":"GAINS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd9b312d77bc7bed9b9cecb56636300bed4fe5ce9","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xd9ea58350bf120e2169a35fa1afc31975b07de01","decimalCount":18}]},{"id":"dappradar","name":"DappRadar","symbol":"RADAR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x44709a920fccf795fbc57baa433cc3dd53c44dbe","decimalCount":18}]},{"id":"kromatika","name":"Kromatika","symbol":"KROM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3af33bef05c2dcb3c7288b77fe1c8d2aeba4d789","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x14af1f2f02dccb1e43402339099a05a5e363b83c","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x55ff62567f09906a85183b866df84bf599a4bf70","decimalCount":18}]},{"id":"reth2","name":"rETH2","symbol":"RETH2","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x20bc832ca081b91433ff6c17f85701b6e92486c5","decimalCount":18}]},{"id":"gamer","name":"GAMER","symbol":"GMR","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xadca52302e0a6c2d5d68edcdb4ac75deb5466884","decimalCount":18}]},{"id":"dafi-protocol","name":"Dafi Protocol","symbol":"DAFI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfc979087305a826c2b2a0056cfaba50aad3e6439","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x4e0fe270b856eebb91fb4b4364312be59f499a3f","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x638df98ad8069a15569da5a6b01181804c47e34c","decimalCount":18}]},{"id":"genre","name":"GENRE","symbol":"GENRE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa392c35ec6900346adec720abe50413f48ee5143","decimalCount":4}]},{"id":"gamma-strategies","name":"Gamma Strategies","symbol":"GAMMA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6bea7cfef803d1e3d5f7c0103f7ded065644e197","decimalCount":18}]},{"id":"charli3","name":"Charli3","symbol":"C3","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf1a91c7d44768070f711c68f33a7ca25c8d30268","decimalCount":18}]},{"id":"oiler","name":"Oiler","symbol":"OIL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0275e1001e293c46cfe158b3702aade0b99f88a5","decimalCount":18}]},{"id":"gyro","name":"Gyro","symbol":"GYRO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x1b239abe619e74232c827fbe5e49a4c072bd869d","decimalCount":9}]},{"id":"dhedge-dao","name":"dHEDGE DAO","symbol":"DHT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xca1207647ff814039530d7d35df0e1dd2e91fa84","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x8c92e38eca8210f4fcbf17f0951b198dd7668292","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x8038f3c971414fd1fc220ba727f2d4a0fc98cb65","decimalCount":18}]},{"id":"cerby-token","name":"Cerby Token","symbol":"CERBY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdef1fac7bf08f173d286bbbdcbeeade695129840","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xdef1fac7bf08f173d286bbbdcbeeade695129840","decimalCount":18},{"networkId":"avalanche","contractAddress":"0xdef1fac7bf08f173d286bbbdcbeeade695129840","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xdef1fac7bf08f173d286bbbdcbeeade695129840","decimalCount":18},{"networkId":"fantom","contractAddress":"0xdef1fac7bf08f173d286bbbdcbeeade695129840","decimalCount":18}]},{"id":"digits-dao","name":"Digits DAO","symbol":"DIGITS","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0x18e2269f98db2eda3cfc06e6cca384b291e553d9","decimalCount":18}]},{"id":"revomon","name":"Revomon","symbol":"REVO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x155040625d7ae3e9cada9a73e3e44f76d3ed1409","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x155040625d7ae3e9cada9a73e3e44f76d3ed1409","decimalCount":18}]},{"id":"shopping-io","name":"Shopping.io","symbol":"SPI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9b02dd390a603add5c07f9fd9175b7dabe8d63b7","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x78a18db278f9c7c9657f61da519e6ef43794dd5d","decimalCount":18}]},{"id":"unidex","name":"UniDex","symbol":"UNIDX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x95b3497bbcccc46a8f45f5cf54b0878b39f8d96c","decimalCount":18},{"networkId":"fantom","contractAddress":"0x2130d2a1e51112d349ccf78d2a1ee65843ba36e0","decimalCount":18}]},{"id":"tendieswap","name":"TendieSwap","symbol":"TENDIE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x9853a30c69474bed37595f9b149ad634b5c323d9","decimalCount":18}]},{"id":"phoenix-global","name":"Phoenix Global","symbol":"PHB","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x0409633a72d846fc5bbe2f98d88564d35987904d","decimalCount":18}]},{"id":"salt","name":"SALT","symbol":"SALT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4156d3342d5c385a87d264f90653733592000581","decimalCount":8}]},{"id":"polkabridge","name":"PolkaBridge","symbol":"PBR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x298d492e8c1d909d3f63bc4a36c66c64acb3d695","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x0d6ae2a429df13e44a07cd2969e085e4833f64a0","decimalCount":18}]},{"id":"nebulas","name":"Nebulas","symbol":"NAS","active":false,"networks":[{"networkId":"ethereum","contractAddress":"0x5d65d971895edc438f465c17db6992698a52318d","decimalCount":18}]},{"id":"uncl","name":"UNCL","symbol":"UNCL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2f4eb47a1b1f4488c71fc10e39a4aa56af33dd49","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x0e8d5504bf54d9e44260f8d153ecd5412130cabb","decimalCount":18}]},{"id":"deri-protocol","name":"Deri Protocol","symbol":"DERI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa487bf43cf3b10dffc97a9a744cbb7036965d3b9","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xe60eaf5a997dfae83739e035b005a33afdcc6df5","decimalCount":18}]},{"id":"juggernaut","name":"Juggernaut","symbol":"JGN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x73374ea518de7addd4c2b624c0e8b113955ee041","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xc13b7a43223bb9bf4b69bd68ab20ca1b79d81c75","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x4e3642603a75528489c2d94f86e9507260d3c5a1","decimalCount":18}]},{"id":"gameswap-org","name":"Gameswap","symbol":"GSWAP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xaac41ec512808d64625576eddd580e7ea40ef8b2","decimalCount":18}]},{"id":"strong","name":"Strong","symbol":"STRONG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x990f341946a3fdb507ae7e52d17851b87168017c","decimalCount":18}]},{"id":"onooks","name":"Onooks","symbol":"OOKS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x69d9905b2e5f6f5433212b7f3c954433f23c1572","decimalCount":18}]},{"id":"geeq","name":"GEEQ","symbol":"GEEQ","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6b9f031d718dded0d681c20cb754f97b3bb81b78","decimalCount":18}]},{"id":"oneswap-dao-token","name":"OneSwap DAO Token","symbol":"ONES","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0b342c51d1592c41068d5d4b4da4a68c0a04d5a4","decimalCount":18}]},{"id":"kira-network","name":"KIRA Network","symbol":"KEX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x16980b3b4a3f9d89e33311b5aa8f80303e5ca4f8","decimalCount":6},{"networkId":"binance-smart-chain","contractAddress":"0x8d11ec38a3eb5e956b052f67da8bdc9bef8abf3e","decimalCount":6}]},{"id":"secret-finance","name":"Secret Finance","symbol":"SEFI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x773258b03c730f84af10dfcb1bfaa7487558b8ac","decimalCount":6},{"networkId":"binance-smart-chain","contractAddress":"0xcd95350c69f229e72e57a44e8c05c436e65e4beb","decimalCount":6}]},{"id":"eco-value-coin","name":"Eco Value Coin","symbol":"EVC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xaa843f65872a25d6e9552ea0b360fb1d5e333124","decimalCount":18}]},{"id":"tranche-finance","name":"Tranche Finance","symbol":"SLICE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0aee8703d34dd9ae107386d3eff22ae75dd616d1","decimalCount":18}]},{"id":"cumrocket","name":"CumRocket","symbol":"CUMMIES","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x27ae27110350b98d564b9a3eed31baebc82d878d","decimalCount":18}]},{"id":"pinknode","name":"Pinknode","symbol":"PNODE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xaf691508ba57d416f895e32a1616da1024e882d2","decimalCount":18}]},{"id":"cap","name":"Cap","symbol":"CAP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x43044f861ec040db59a7e324c40507addb673142","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x031d35296154279dc1984dcd93e392b1f946737b","decimalCount":18}]},{"id":"xfund","name":"xFund","symbol":"XFUND","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x892a6f9df0147e5f079b0993f486f9aca3c87881","decimalCount":9}]},{"id":"tokenomy","name":"Tokenomy","symbol":"TEN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdd16ec0f66e54d453e6756713e533355989040e4","decimalCount":18}]},{"id":"allbridge","name":"Allbridge","symbol":"ABR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa11bd36801d8fa4448f0ac4ea7a62e3634ce8c7c","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x68784ffaa6ff05e3e04575df77960dc1d9f42b4a","decimalCount":18},{"networkId":"avalanche","contractAddress":"0xafc43610c7840b20b90caaf93759be5b54b291c9","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x04429fbb948bbd09327763214b45e505a5293346","decimalCount":18},{"networkId":"fantom","contractAddress":"0x543acd673960041eee1305500893260f1887b679","decimalCount":18}]},{"id":"nft-art-finance","name":"NFT Art Finance","symbol":"NFTART","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xf7844cb890f4c339c497aeab599abdc3c874b67a","decimalCount":9}]},{"id":"deepspace","name":"DEEPSPACE","symbol":"DPS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xf275e1ac303a4c9d987a2c48b8e555a77fec3f1c","decimalCount":9}]},{"id":"jarvis-reward-token","name":"Jarvis Reward Token","symbol":"JRT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8a9c67fee641579deba04928c4bc45f66e26343a","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x596ebe76e2db4470966ea395b0d063ac6197a8c5","decimalCount":18}]},{"id":"unicly","name":"Unicly","symbol":"UNIC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x94e0bab2f6ab1f19f4750e42d7349f2740513ad5","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x21ce5251d47aa72d2d1dc849b1bcce14d2467d1b","decimalCount":18}]},{"id":"drops-ownership-power","name":"Drops Ownership Power","symbol":"DOP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6bb61215298f296c55b19ad842d3df69021da2ef","decimalCount":18}]},{"id":"lamden","name":"Lamden","symbol":"TAU","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x70d7109d3afe13ee8f9015566272838519578c6b","decimalCount":18}]},{"id":"yield-yak","name":"Yield Yak","symbol":"YAK","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0x59414b3089ce2af0010e7523dea7e2b35d776ec7","decimalCount":18}]},{"id":"pooltogether","name":"PoolTogether","symbol":"POOL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0cec1a9154ff802e7934fc916ed7ca50bde6844e","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x25788a1a171ec66da6502f9975a15b609ff54cf6","decimalCount":18}]},{"id":"serey-coin","name":"Serey Coin","symbol":"SRY","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x2b618835a1eefcbf41e33497451ca1f3aa62f2d8","decimalCount":18}]},{"id":"xtblock-token","name":"XTblock","symbol":"XTT-B20","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x70b6c6a555507ee4ac91c15e5c80b7dc8ff3b489","decimalCount":18}]},{"id":"hara-token","name":"Hara Token","symbol":"HART","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x52928c95c4c7e934e0efcfab08853a0e4558861d","decimalCount":18}]},{"id":"saveplanetearth","name":"SavePlanetEarth","symbol":"SPE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x4ac81e3631dcda62109e3117c4cae7bf70bbbbd2","decimalCount":9}]},{"id":"oxbitcoin","name":"0xBitcoin","symbol":"0XBTC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb6ed7644c69416d67b522e20bc294a9a9b405b31","decimalCount":8},{"networkId":"polygon-pos","contractAddress":"0x71b821aa52a49f32eed535fca6eb5aa130085978","decimalCount":8},{"networkId":"arbitrum-one","contractAddress":"0x7cb16cb78ea464ad35c8a50abf95dff3c9e09d5d","decimalCount":8}]},{"id":"dogebonk","name":"DogeBonk","symbol":"DOBO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xae2df9f730c54400934c06a17462c41c08a06ed8","decimalCount":9}]},{"id":"charg-coin","name":"Charg Coin","symbol":"CHG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc4a86561cb0b7ea1214904f26e6d50fd357c7986","decimalCount":18}]},{"id":"sparkpoint","name":"SparkPoint","symbol":"SRK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0488401c3f535193fa8df029d9ffe615a06e74e6","decimalCount":18}]},{"id":"smart-mfg","name":"Smart MFG","symbol":"MFG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6710c63432a2de02954fc0f851db07146a6c0312","decimalCount":18}]},{"id":"thorstarter","name":"Thorstarter","symbol":"XRUNE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x69fa0fee221ad11012bab0fdb45d444d3d2ce71c","decimalCount":18},{"networkId":"fantom","contractAddress":"0xe1e6b01ae86ad82b1f1b4eb413b219ac32e17bf6","decimalCount":18}]},{"id":"tetu","name":"TETU","symbol":"TETU","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0x255707b70bf90aa112006e1b07b9aea6de021424","decimalCount":18},{"networkId":"fantom","contractAddress":"0x65c9d9d080714cda7b5d58989dc27f897f165179","decimalCount":18}]},{"id":"blank","name":"BlockWallet","symbol":"BLANK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x41a3dba3d677e573636ba691a70ff2d606c29666","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xf4c83080e80ae530d6f8180572cbbf1ac9d5d435","decimalCount":18}]},{"id":"cropbytes","name":"CropBytes","symbol":"CBX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x37fc4b48ce93469dbea9918468993c735049642a","decimalCount":18}]},{"id":"sport-and-leisure","name":"Sport and Leisure","symbol":"SNL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa806b3fed6891136940cf81c4085661500aa2709","decimalCount":6}]},{"id":"b-protocol","name":"B.Protocol","symbol":"BPRO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbbbbbbb5aa847a2003fbc6b5c16df0bd1e725f61","decimalCount":18}]},{"id":"pikachu","name":"Pika","symbol":"PIKA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x60f5672a271c7e39e787427a18353ba59a4a3578","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xffb89d7637cf4860884ed48b57ae5562bf64e10f","decimalCount":18}]},{"id":"siren","name":"Siren","symbol":"SI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd23ac27148af6a2f339bd82d0e3cff380b5093de","decimalCount":18}]},{"id":"kine-protocol","name":"Kine Protocol","symbol":"KINE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xcbfef8fdd706cde6f208460f2bf39aa9c785f05d","decimalCount":18}]},{"id":"quadrant-protocol","name":"Quadrant Protocol","symbol":"EQUAD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc28e931814725bbeb9e670676fabbcb694fe7df2","decimalCount":18}]},{"id":"duckdaodime","name":"DuckDaoDime","symbol":"DDIM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfbeea1c75e4c4465cb2fccc9c6d6afe984558e20","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xc9132c76060f6b319764ea075973a650a1a53bc9","decimalCount":18}]},{"id":"bedrock","name":"Bedrock","symbol":"ROCK","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xc3387e4285e9f80a7cfdf02b4ac6cdf2476a528a","decimalCount":18}]},{"id":"polydoge","name":"PolyDoge","symbol":"POLYDOGE","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0x8a953cfe442c5e8855cc6c61b1293fa648bae472","decimalCount":18}]},{"id":"dogsofelon","name":"Dogs Of Elon","symbol":"DOE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf8e9f10c22840b613cda05a0c5fdb59a4d6cd7ef","decimalCount":18}]},{"id":"wagerr","name":"Wagerr","symbol":"WGR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc237868a9c5729bdf3173dddacaa336a0a5bb6e0","decimalCount":8},{"networkId":"binance-smart-chain","contractAddress":"0xdbf8265b1d5244a13424f13977723acf5395eab2","decimalCount":18}]},{"id":"shibaverse","name":"Shibaverse","symbol":"VERSE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7ae0d42f23c33338de15bfa89c7405c068d9dc0a","decimalCount":18}]},{"id":"jenny-metaverse-dao-token","name":"Jenny Metaverse DAO Token","symbol":"UJENNY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa499648fd0e80fd911972bbeb069e4c20e68bf22","decimalCount":18}]},{"id":"geist-finance","name":"Geist Finance","symbol":"GEIST","active":true,"networks":[{"networkId":"fantom","contractAddress":"0xd8321aa83fb0a4ecd6348d4577431310a6e0814d","decimalCount":18}]},{"id":"bomber-coin","name":"Bomber Coin","symbol":"BCOIN","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x00e1656e45f18ec6747f5a8496fd39b50b38396d","decimalCount":18}]},{"id":"arable-protocol","name":"Arable Protocol","symbol":"ACRE","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0x00ee200df31b869a321b10400da10b561f3ee60d","decimalCount":18}]},{"id":"gton-capital","name":"GTON CAPITAL","symbol":"GTON","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x01e0e2e61f554ecaaec0cc933e739ad90f24a86d","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x64d5baf5ac030e2b7c435add967f787ae94d0205","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x4e720dd3ac5cfe1e1fbde4935f386bb1c66f4642","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xf480f38c366daac4305dc484b2ad7a496ff00cea","decimalCount":18},{"networkId":"fantom","contractAddress":"0xc1be9a4d5d45beeacae296a7bd5fadbfc14602c4","decimalCount":18}]},{"id":"upbots","name":"UpBots","symbol":"UBXT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8564653879a18c560e7c0ea0e084c516c62f5653","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xbbeb90cfb6fafa1f69aa130b7341089abeef5811","decimalCount":18}]},{"id":"dehub","name":"DeHub","symbol":"DEHUB","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xfc206f429d55c71cb7294eff40c6adb20dc21508","decimalCount":5}]},{"id":"1art","name":"OneArt","symbol":"1ART","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xd3c325848d7c6e29b574cb0789998b2ff901f17e","decimalCount":18},{"networkId":"fantom","contractAddress":"0xd3c325848d7c6e29b574cb0789998b2ff901f17e","decimalCount":18}]},{"id":"latoken","name":"LATOKEN","symbol":"LA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe50365f5d679cb98a1dd62d6f6e58e59321bcddf","decimalCount":18}]},{"id":"unix","name":"UniX","symbol":"UNIX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xddd6a0ecc3c6f6c102e5ea3d8af7b801d1a77ac8","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x8c4476dfec8e7eedf2de3e9e9461b7c14c828d46","decimalCount":18}]},{"id":"saud","name":"sAUD","symbol":"SAUD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf48e200eaf9906362bb1442fca31e0835773b8b4","decimalCount":18}]},{"id":"exnetwork-token","name":"ExNetwork Token","symbol":"EXNT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd6c67b93a7b248df608a653d82a100556144c5da","decimalCount":16}]},{"id":"decentral-games-old","name":"Decentral Games (Old)","symbol":"DG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xee06a81a695750e71a662b51066f2c74cf4478a0","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x9fdc3ae5c814b79dca2556564047c5e7e5449c19","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x2a93172c8dccbfbc60a39d56183b7279a2f647b4","decimalCount":18}]},{"id":"unmarshal","name":"Unmarshal","symbol":"MARSH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5a666c7d92e5fa7edcb6390e4efd6d0cdd69cf37","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x2fa5daf6fe0708fbd63b1a7d1592577284f52256","decimalCount":18}]},{"id":"xwin-finance","name":"xWIN Finance","symbol":"XWIN","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xd88ca08d8eec1e9e09562213ae83a7853ebb5d28","decimalCount":18}]},{"id":"tidal-finance","name":"Tidal Finance","symbol":"TIDAL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x29cbd0510eec0327992cd6006e63f9fa8e7f33b7","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xb41ec2c036f8a42da384dde6ada79884f8b84b26","decimalCount":18}]},{"id":"spheroid-universe","name":"Spheroid Universe","symbol":"SPH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa0cf46eb152656c7090e769916eb44a138aaa406","decimalCount":18}]},{"id":"crust-network","name":"Crust Network","symbol":"CRU","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x32a7c02e79c4ea1008dd6564b35f131428673c41","decimalCount":18}]},{"id":"ispolink","name":"Ispolink","symbol":"ISP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc8807f0f5ba3fa45ffbdc66928d71c5289249014","decimalCount":18}]},{"id":"public-mint","name":"Public Mint","symbol":"MINT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0cdf9acd87e940837ff21bb40c9fd55f68bba059","decimalCount":18}]},{"id":"cashaa","name":"Cashaa","symbol":"CAS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x780207b8c0fdc32cf60e957415bfa1f2d4d9718c","decimalCount":18}]},{"id":"wam","name":"Wam","symbol":"WAM","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xebbaeff6217d22e7744394061d874015709b8141","decimalCount":18}]},{"id":"million","name":"Million","symbol":"MM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6b4c7a5e3f0b99fcd83e9c089bddd6c7fce5c611","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xbf05279f9bf1ce69bbfed670813b7e431142afa4","decimalCount":18}]},{"id":"offshift","name":"Offshift","symbol":"XFT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xabe580e7ee158da464b51ee1a83ac0289622e6be","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xe138c66982fd5c890c60b94fdba1747faf092c20","decimalCount":18}]},{"id":"safemoon-inu","name":"SafeMoon Inu","symbol":"SMI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xcd7492db29e2ab436e819b249452ee1bbdf52214","decimalCount":8}]},{"id":"suterusu","name":"Suterusu","symbol":"SUTER","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xaa2ce7ae64066175e0b90497ce7d9c190c315db4","decimalCount":18}]},{"id":"nftb","name":"NFTb","symbol":"NFTB","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xde3dbbe30cfa9f437b293294d1fd64b26045c71a","decimalCount":18}]},{"id":"smartmesh","name":"SmartMesh","symbol":"SMT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x21f15966e07a10554c364b988e91dab01d32794a","decimalCount":18}]},{"id":"vulkania","name":"Vulkania [OLD]","symbol":"VLK","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x0921d788e7f7498f80adb0a0a62b8a9476f2db92","decimalCount":8}]},{"id":"bent-finance","name":"Bent Finance","symbol":"BENT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x01597e397605bf280674bf292623460b4204c375","decimalCount":18}]},{"id":"signata","name":"Signata","symbol":"SATA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3ebb4a4e91ad83be51f8d596533818b246f4bee1","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x6b1c8765c7eff0b60706b0ae489eb9bb9667465a","decimalCount":18}]},{"id":"rocket-vault-rocketx","name":"RocketX exchange","symbol":"RVF","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdc8af07a7861bedd104b8093ae3e9376fc8596d2","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x872a34ebb2d54af86827810eebc7b9dc6b2144aa","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x2ce13e4199443fdfff531abb30c9b6594446bbc7","decimalCount":18}]},{"id":"rebel-bots","name":"Rebel Bots","symbol":"RBLS","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0xe26cda27c13f4f87cffc2f437c5900b27ebb5bbb","decimalCount":8}]},{"id":"bbs-network","name":"BBS Network","symbol":"BBS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfe459828c90c0ba4bc8b42f5c5d44f316700b430","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xa477a79a118a84a0d371a53c8f46f8ce883ec1dd","decimalCount":18}]},{"id":"fortknoxter","name":"FortKnoxster","symbol":"FKX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x16484d73ac08d2355f466d448d2b79d2039f6ebb","decimalCount":18}]},{"id":"fear","name":"Fear","symbol":"FEAR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x88a9a52f944315d5b4e917b9689e65445c401e83","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x9ba6a67a6f3b21705a46b380a1b97373a33da311","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xa2ca40dbe72028d3ac78b5250a8cb8c404e7fb8c","decimalCount":18}]},{"id":"skey-network","name":"Skey Network","symbol":"SKEY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x06a01a4d579479dd5d884ebf61a31727a3d8d442","decimalCount":8}]},{"id":"bnpl-pay","name":"BNPL Pay","symbol":"BNPL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x84d821f7fbdd595c4c4a50842913e6b1e07d7a53","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x1263fea931b86f3e8ce8afbf29f66631b7be9347","decimalCount":18}]},{"id":"shopperoo","name":"Shopperoo","symbol":"SRO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x8d98a4e36ca048b8e4616564e5a8ebb78895ddff","decimalCount":18}]},{"id":"nifty-league","name":"Nifty League","symbol":"NFTL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3c8d2fce49906e11e71cb16fa0ffeb2b16c29638","decimalCount":18}]},{"id":"gather","name":"Gather","symbol":"GTH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xeb986da994e4a118d5956b02d8b7c3c7ce373674","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xeb986da994e4a118d5956b02d8b7c3c7ce373674","decimalCount":18}]},{"id":"imperium-empires","name":"Imperium Empires","symbol":"IME","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0xf891214fdcf9cdaa5fdc42369ee4f27f226adad6","decimalCount":18}]},{"id":"fiat-dao-token","name":"Fiat DAO","symbol":"FDT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xed1480d12be41d92f36f5f7bdd88212e381a3677","decimalCount":18}]},{"id":"elk-finance","name":"Elk Finance","symbol":"ELK","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0xeeeeeb57642040be42185f49c52f7e9b38f8eeee","decimalCount":18},{"networkId":"fantom","contractAddress":"0xeeeeeb57642040be42185f49c52f7e9b38f8eeee","decimalCount":18}]},{"id":"feisty-doge-nft","name":"Feisty Doge NFT","symbol":"NFD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdfdb7f72c1f195c5951a234e8db9806eb0635346","decimalCount":18}]},{"id":"pacoca","name":"Pacoca","symbol":"PACOCA","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x55671114d774ee99d653d6c12460c780a67f1d18","decimalCount":18}]},{"id":"galaxy-fight-club","name":"Galaxy Fight Club","symbol":"GCOIN","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0x071ac29d569a47ebffb9e57517f855cb577dcc4c","decimalCount":18}]},{"id":"fancy-games","name":"Fancy Games","symbol":"FNC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7f280dac515121dcda3eac69eb4c13a52392cace","decimalCount":18}]},{"id":"gm","name":"GM","symbol":"GM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbc7250c8c3eca1dfc1728620af835fca489bfdf3","decimalCount":9}]},{"id":"fringe-finance","name":"Fringe Finance","symbol":"FRIN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc9fe6e1c76210be83dc1b5b20ec7fd010b0b1d15","decimalCount":18}]},{"id":"degenerator","name":"Meme","symbol":"MEME","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd5525d397898e5502075ea5e830d8914f6f0affe","decimalCount":8}]},{"id":"decentral-games-ice","name":"Decentral Games ICE","symbol":"ICE","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0xc6c855ad634dcdad23e64da71ba85b8c51e5ad7c","decimalCount":18}]},{"id":"digg","name":"DIGG","symbol":"DIGG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x798d1be841a82a273720ce31c822c61a67a601c3","decimalCount":9}]},{"id":"giveth","name":"Giveth","symbol":"GIV","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x900db999074d9277c5da2a43f252d74366230da0","decimalCount":18}]},{"id":"froyo-games","name":"Froyo Games","symbol":"FROYO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xe369fec23380f9f14ffd07a1dc4b7c1a9fdd81c9","decimalCount":18}]},{"id":"trueflip","name":"TrueFlip","symbol":"TFL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa7f976c360ebbed4465c2855684d1aae5271efa9","decimalCount":8}]},{"id":"belt","name":"Belt","symbol":"BELT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xe0e514c71282b6f4e823703a39374cf58dc3ea4f","decimalCount":18}]},{"id":"micropets","name":"MicroPets","symbol":"PETS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xa77346760341460b42c230ca6d21d4c8e743fa9c","decimalCount":18}]},{"id":"shroom-finance","name":"Niftyx Protocol","symbol":"SHROOM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xed0439eacf4c4965ae4613d77a5c2efe10e5f183","decimalCount":18}]},{"id":"divergence-protocol","name":"Divergence Protocol","symbol":"DIVER","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfb782396c9b20e564a64896181c7ac8d8979d5f4","decimalCount":18}]},{"id":"clearpool","name":"Clearpool","symbol":"CPOOL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x66761fa41377003622aee3c7675fc7b5c1c2fac5","decimalCount":18}]},{"id":"solchicks-token","name":"SolChicks","symbol":"CHICKS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xa91c7bc1e07996a188c1a5b1cfdff450389d8acf","decimalCount":8},{"networkId":"solana","contractAddress":"cxxShYRVcepDudXhe7U62QHvw8uBJoKFifmzggGKVC2","decimalCount":9}]},{"id":"strips-finance","name":"Strips Finance","symbol":"STRP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x97872eafd79940c7b24f7bcc1eadb1457347adc9","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x326c33fd1113c1f29b35b4407f3d6312a8518431","decimalCount":18}]},{"id":"gerowallet","name":"GeroWallet","symbol":"GERO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3431f91b3a388115f00c5ba9fdb899851d005fb5","decimalCount":18}]},{"id":"defit","name":"Digital Fitness","symbol":"DEFIT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x84cffa78b2fbbeec8c37391d2b12a04d2030845e","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x428360b02c1269bc1c79fbc399ad31d58c1e8fda","decimalCount":18}]},{"id":"jumptoken","name":"Jump","symbol":"JMPT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x88d7e9b65dc24cf54f5edef929225fc3e1580c25","decimalCount":18}]},{"id":"sonar","name":"Sonar","symbol":"PING","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x5546600f77eda1dcf2e8817ef4d617382e7f71f5","decimalCount":9}]},{"id":"e1337","name":"1337","symbol":"1337","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x35872fea6a4843facbcdbce99e3b69596a3680b8","decimalCount":4}]},{"id":"waves-ducks","name":"Waves Ducks","symbol":"EGG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc2708a3a4ba7f64bddc1a49f92f941bc77cad23a","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x889efce29fa0bb9b26be9fda17a8003f4e8da4de","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x51de72b17c7bd12e9e6d69eb506a669eb6b5249e","decimalCount":18}]},{"id":"suncontract","name":"SunContract","symbol":"SNC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf4134146af2d511dd5ea8cdb1c4ac88c57d60404","decimalCount":18}]},{"id":"naos-finance","name":"NAOS Finance","symbol":"NAOS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4a615bb7166210cce20e6642a6f8fb5d4d044496","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x758d08864fb6cce3062667225ca10b8f00496cc2","decimalCount":18}]},{"id":"etherrock-72","name":"Etherrock #72","symbol":"PEBBLE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdc98c5543f3004debfaad8966ec403093d0aa4a8","decimalCount":18}]},{"id":"lith-token","name":"Lith","symbol":"LITH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf8a4a419c2d7140e49ef952a7e7ae1bd4a8b6b9c","decimalCount":18}]},{"id":"tarot","name":"Tarot","symbol":"TAROT","active":true,"networks":[{"networkId":"fantom","contractAddress":"0xc5e2b037d30a390e62180970b3aa4e91868764cd","decimalCount":18}]},{"id":"biconomy-exchange-token","name":"Biconomy Exchange","symbol":"BIT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xc864019047b864b6ab609a968ae2725dfaee808a","decimalCount":9}]},{"id":"viberate","name":"Viberate","symbol":"VIB","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2c974b2d0ba1716e644c1fc59982a89ddd2ff724","decimalCount":18}]},{"id":"faraland","name":"FaraLand","symbol":"FARA","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xf4ed363144981d3a65f42e7d0dc54ff9eef559a1","decimalCount":18}]},{"id":"vabble","name":"Vabble","symbol":"VAB","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe7ae6d0c56cacaf007b7e4d312f9af686a9e9a04","decimalCount":18}]},{"id":"dexioprotocol","name":"Dexioprotocol","symbol":"DEXI","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x29b1e39a529d3b3cacea55989594f71813e998bb","decimalCount":18}]},{"id":"starship","name":"StarShip","symbol":"STARSHIP","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x52419258e3fa44deac7e670eadd4c892b480a805","decimalCount":9}]},{"id":"crowns","name":"Seascape Crowns","symbol":"CWS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xac0104cca91d167873b8601d2e71eb3d4d8c33e0","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xbcf39f0edda668c58371e519af37ca705f2bfcbd","decimalCount":18}]},{"id":"fndz-token","name":"FNDZ","symbol":"FNDZ","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x7754c0584372d29510c019136220f91e25a8f706","decimalCount":18}]},{"id":"dfyn-network","name":"Dfyn Network","symbol":"DFYN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9695e0114e12c0d3a3636fab5a18e6b737529023","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xc168e40227e4ebd8c1cae80f7a55a4f0e6d66c97","decimalCount":18}]},{"id":"lithium-finance","name":"Lithium Finance","symbol":"LITH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x188e817b02e635d482ae4d81e25dda98a97c4a42","decimalCount":18}]},{"id":"xend-finance","name":"Xend Finance","symbol":"XEND","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe4cfe9eaa8cdb0942a80b7bc68fd8ab0f6d44903","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x4a080377f83d669d7bb83b3184a8a5e61b500608","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x86775d0b80b3df266af5377db34ba8f318d715ec","decimalCount":18}]},{"id":"clucoin","name":"CluCoin","symbol":"CLU","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x1162e2efce13f99ed259ffc24d99108aaa0ce935","decimalCount":9}]},{"id":"thorwallet","name":"THORWallet DEX","symbol":"TGT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x108a850856db3f85d0269a2693d896b394c80325","decimalCount":18}]},{"id":"bibox-token","name":"Bibox Token","symbol":"BIX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x009c43b42aefac590c719e971020575974122803","decimalCount":18}]},{"id":"cashbet-coin","name":"CBC.network","symbol":"CBC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x26db5439f651caf491a87d48799da81f191bdb6b","decimalCount":8}]},{"id":"kleekai","name":"KleeKai","symbol":"KLEE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa67e9f021b9d208f7e3365b2a155e3c55b27de71","decimalCount":9}]},{"id":"dinger-token","name":"Dinger","symbol":"DINGER","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9e5bd9d9fad182ff0a93ba8085b664bcab00fa68","decimalCount":9},{"networkId":"binance-smart-chain","contractAddress":"0x0d3843f92d622468ba67df5a6a4149b484a75af3","decimalCount":9}]},{"id":"labs-group","name":"LABS Group","symbol":"LABS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8b0e42f366ba502d787bb134478adfae966c8798","decimalCount":18}]},{"id":"growth-defi","name":"GROWTH DeFi","symbol":"GRO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x336ed56d8615271b38ecee6f4786b55d0ee91b96","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x72699ba15cc734f8db874fa9652c8de12093f187","decimalCount":18},{"networkId":"fantom","contractAddress":"0x91f1430833879272643658f8ed07d60257ddf321","decimalCount":18}]},{"id":"auruscoin","name":"AurusDeFi","symbol":"AWX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa51fc71422a30fa7ffa605b360c3b283501b5bf6","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x56a0efefc9f1fbb54fbd25629ac2aa764f1b56f7","decimalCount":18}]},{"id":"avaocado-dao","name":"Avocado DAO","symbol":"AVG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa41f142b6eb2b164f8164cae0716892ce02f311f","decimalCount":18}]},{"id":"oddz","name":"Oddz","symbol":"ODDZ","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xcd2828fc4d8e8a0ede91bb38cf64b1a81de65bf6","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xcd40f2670cf58720b694968698a5514e924f742d","decimalCount":18},{"networkId":"avalanche","contractAddress":"0xb0a6e056b587d0a85640b39b1cb44086f7a26a1e","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x4e830f67ec499e69930867f9017aeb5b3f629c73","decimalCount":18}]},{"id":"orclands-metaverse","name":"Orclands Metaverse","symbol":"ORC","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x968f9c44879f67a29b1bfccf93ea82d46a72881f","decimalCount":9}]},{"id":"convergence","name":"Convergence","symbol":"CONV","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc834fa996fa3bec7aad3693af486ae53d8aa8b50","decimalCount":18}]},{"id":"freedom-coin","name":"FREEdom coin","symbol":"FREE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2f141ce366a2462f02cea3d12cf93e4dca49e4fd","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x12e34cdf6a031a10fe241864c32fb03a4fdad739","decimalCount":18}]},{"id":"fuel-token","name":"Jetfuel Finance","symbol":"FUEL","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x2090c8295769791ab7a3cf1cc6e0aa19f35e441a","decimalCount":18}]},{"id":"minds","name":"Minds","symbol":"MINDS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb26631c6dda06ad89b93c71400d25692de89c068","decimalCount":18}]},{"id":"dragon-crypto-aurum","name":"Dragon Crypto Aurum","symbol":"DCAU","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0x100cc3a819dd3e8573fd2e46d1e66ee866068f30","decimalCount":18}]},{"id":"uniwhales","name":"UniWhales","symbol":"UWL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdbdd6f355a37b94e6c7d32fef548e98a280b8df5","decimalCount":18}]},{"id":"apwine","name":"APWine","symbol":"APW","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4104b135dbc9609fc1a9490e61369036497660c8","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x6c0ab120dbd11ba701aff6748568311668f63fe0","decimalCount":18}]},{"id":"lua-token","name":"LuaSwap","symbol":"LUA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb1f66997a5760428d3a87d68b90bfe0ae64121cc","decimalCount":18}]},{"id":"niob","name":"NIOB","symbol":"NIOB","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x5ac5e6af46ef285b3536833e65d245c49b608d9b","decimalCount":18}]},{"id":"oxbull-tech","name":"Oxbull Tech","symbol":"OXB","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x3fd5b5746315e3f8d43a46b09c826a001ebb977d","decimalCount":9}]},{"id":"league-of-ancients","name":"League of Ancients","symbol":"LOA","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x94b69263fca20119ae817b6f783fc0f13b02ad50","decimalCount":18}]},{"id":"armor","name":"ARMOR","symbol":"ARMOR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1337def16f9b486faed0293eb623dc8395dfe46a","decimalCount":18}]},{"id":"tokencard","name":"Monolith","symbol":"TKN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xaaaf91d9b90df800df4f55c205fd6989c977e73a","decimalCount":8}]},{"id":"waterfall-governance-token","name":"Waterfall Governance","symbol":"WTF","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xd73f32833b6d5d9c8070c23e599e283a3039823c","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x873801ae2ff12d816db9a7b082f5796bec64c82c","decimalCount":18}]},{"id":"autobahn-network","name":"Autobahn Network","symbol":"TXL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8eef5a82e6aa222a60f009ac18c24ee12dbf4b41","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x1ffd0b47127fdd4097e54521c9e2c7f0d66aafc5","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x8eef5a82e6aa222a60f009ac18c24ee12dbf4b41","decimalCount":18}]},{"id":"opium","name":"Opium","symbol":"OPIUM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x888888888889c00c67689029d7856aac1065ec11","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x566cedd201f67e542a6851a2959c1a449a041945","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xe8f157e041df3b28151b667364e9c90789da7923","decimalCount":18}]},{"id":"zodium","name":"Zodium","symbol":"ZODI","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x0cca2f5561bb0fca88e5b9b48b7fbf000349c357","decimalCount":18}]},{"id":"curate","name":"Curate","symbol":"XCUR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe1c7e30c42c24582888c758984f6e382096786bd","decimalCount":8},{"networkId":"binance-smart-chain","contractAddress":"0xd52669712f253cd6b2fe8a8638f66ed726cb770c","decimalCount":8}]},{"id":"wall-street-bets-dapp","name":"WallStreetBets DApp","symbol":"WSB","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe1590a6fa0cff9c960181cb77d8a873601772f64","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x22168882276e5d5e1da694343b41dd7726eeb288","decimalCount":18}]},{"id":"launchpool","name":"Launchpool","symbol":"LPOOL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6149c26cd2f7b5ccdb32029af817123f6e37df5b","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xcfb24d3c3767364391340a2e6d99c64f1cbd7a3d","decimalCount":18}]},{"id":"equos-origin","name":"EQO","symbol":"EQO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x46e9fe43470fafd690100c86037f9e566e24d480","decimalCount":18}]},{"id":"maximizer","name":"Maximizer","symbol":"MAXI","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0x7c08413cbf02202a1c13643db173f2694e0f73f0","decimalCount":9}]},{"id":"covesting","name":"Covesting","symbol":"COV","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xada86b1b313d1d5267e3fc0bb303f0a2b66d0ea7","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x0f237db17aa4e6de062e6f052bd9c805789b01c3","decimalCount":18}]},{"id":"kommunitas","name":"Kommunitas","symbol":"KOM","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x471ea49dd8e60e697f4cac262b5fafcc307506e4","decimalCount":8},{"networkId":"polygon-pos","contractAddress":"0xc004e2318722ea2b15499d6375905d75ee5390b8","decimalCount":8}]},{"id":"blocksquare","name":"Blocksquare","symbol":"BST","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x509a38b7a1cc0dcd83aa9d06214663d9ec7c7f4a","decimalCount":18}]},{"id":"vera","name":"Vera","symbol":"VERA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd7f0cc50ad69408ae58be033f4f85d2367c2e468","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x4a0a3902e091cdb3aec4279a6bfac50297f0a79e","decimalCount":18}]},{"id":"dogegf","name":"DogeGF","symbol":"DOGEGF","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfb130d93e49dca13264344966a611dc79a456bc5","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x0e7252706393470ffb0629da2caa39fc9340f2d4","decimalCount":18}]},{"id":"zeroswap","name":"ZeroSwap","symbol":"ZEE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2edf094db69d6dcd487f1b3db9febe2eec0dd4c5","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x44754455564474a89358b2c2265883df993b12f0","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xfd4959c06fbcc02250952daebf8e0fb38cf9fd8c","decimalCount":18}]},{"id":"moeda-loyalty-points","name":"Moeda Loyalty Points","symbol":"MDA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x51db5ad35c671a87207d88fc11d593ac0c8415bd","decimalCount":18}]},{"id":"locgame","name":"LOCGame","symbol":"LOCG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x60eb57d085c59932d5faa6c6026268a4386927d0","decimalCount":18}]},{"id":"pointpay","name":"PointPay","symbol":"PXP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x95aa5d2dbd3c16ee3fdea82d5c6ec3e38ce3314f","decimalCount":18}]},{"id":"monsta-infinite","name":"Monsta Infinite","symbol":"MONI","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x9573c88ae3e37508f87649f87c4dd5373c9f31e0","decimalCount":18}]},{"id":"warden","name":"Warden","symbol":"WAD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0b6f3c17e1626a7cbfa4302ce4e3c45522d23a83","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x0feadcc3824e7f3c12f40e324a60c23ca51627fc","decimalCount":18}]},{"id":"burency","name":"Burency","symbol":"BUY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x31fdd1c6607f47c14a2821f599211c67ac20fa96","decimalCount":18}]},{"id":"idavoll-network","name":"Idavoll DAO","symbol":"IDV","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x92ec47df1aa167806dfa4916d9cfb99da6953b8f","decimalCount":18}]},{"id":"gro-dao-token","name":"Gro DAO","symbol":"GRO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3ec8798b81485a254928b70cda1cf0a2bb0b74d7","decimalCount":18}]},{"id":"wabi","name":"Wabi","symbol":"WABI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x286bda1413a2df81731d4930ce2f862a35a609fe","decimalCount":18}]},{"id":"euler-tools","name":"Euler Tools","symbol":"EULER","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x3920123482070c1a2dff73aad695c60e7c6f6862","decimalCount":18}]},{"id":"charged-particles","name":"Charged Particles","symbol":"IONX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x02d3a27ac3f55d5d91fb0f52759842696a864217","decimalCount":18}]},{"id":"bondly","name":"Bondly","symbol":"BONDLY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x91dfbee3965baaee32784c2d546b7a0c62f268c9","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x5d0158a5c3ddf47d4ea4517d8db0d76aa2e87563","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x64ca1571d1476b7a21c5aaf9f1a750a193a103c0","decimalCount":18}]},{"id":"spacechain-erc-20","name":"SpaceChain (ERC-20)","symbol":"SPC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x86ed939b500e121c0c5f493f399084db596dad20","decimalCount":18}]},{"id":"plastiks","name":"Plastiks","symbol":"PLASTIK","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x2764be4756fec8de911d8d37efe4ae8aff178254","decimalCount":9}]},{"id":"usechain","name":"Usechain","symbol":"USE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd9485499499d66b175cf5ed54c0a19f1a6bcb61a","decimalCount":18}]},{"id":"spendcoin","name":"Spendcoin","symbol":"SPND","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xddd460bbd9f79847ea08681563e8a9696867210c","decimalCount":18}]},{"id":"binamon","name":"Binamon","symbol":"BMON","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x08ba0619b1e7a582e0bce5bbe9843322c954c340","decimalCount":18}]},{"id":"acryptos","name":"ACryptoS","symbol":"ACS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x4197c6ef3879a08cd51e5560da5064b773aa1d29","decimalCount":18}]},{"id":"lambda","name":"Lambda","symbol":"LAMB","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8971f9fd7196e5cee2c1032b50f656855af7dd26","decimalCount":18}]},{"id":"all-sports","name":"All Sports","symbol":"SOC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2d0e95bd4795d7ace0da3c0ff7b706a5970eb9d3","decimalCount":18}]},{"id":"impossible-finance","name":"Impossible Finance","symbol":"IF","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xb0e1fc65c1a741b4662b813eb787d369b8614af1","decimalCount":18}]},{"id":"verisafe","name":"VeriSafe","symbol":"VSF","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xac9ce326e95f51b5005e9fe1dd8085a01f18450c","decimalCount":18}]},{"id":"kattana","name":"Kattana","symbol":"KTN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x491e136ff7ff03e6ab097e54734697bb5802fc1c","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xdae6c2a48bfaa66b43815c5548b10800919c993e","decimalCount":18}]},{"id":"pegaxy-stone","name":"Pegaxy Stone","symbol":"PGX","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0xc1c93d475dc82fe72dbc7074d55f5a734f8ceeae","decimalCount":18}]},{"id":"dimitra","name":"Dimitra","symbol":"DMTR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x51cb253744189f11241becb29bedd3f1b5384fdb","decimalCount":18}]},{"id":"medical-token-currency","name":"Doc.com","symbol":"MTC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x905e337c6c8645263d3521205aa37bf4d034e745","decimalCount":18}]},{"id":"cleardao","name":"ClearDAO","symbol":"CLH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd7d8f3b8bc8bc48d3acc37879eaba7b85889fa52","decimalCount":18}]},{"id":"cybermiles","name":"CyberMiles","symbol":"CMT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf85feea2fdd81d51177f6b8f35f0e6734ce45f5f","decimalCount":18}]},{"id":"smartcredit-token","name":"SmartCredit Token","symbol":"SMARTCREDIT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x72e9d9038ce484ee986fea183f8d8df93f9ada13","decimalCount":18}]},{"id":"epik-protocol","name":"EpiK Protocol","symbol":"EPK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdaf88906ac1de12ba2b1d2f7bfc94e9638ac40c4","decimalCount":18}]},{"id":"pathdao","name":"PathDAO","symbol":"PATH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2a2550e0a75acec6d811ae3930732f7f3ad67588","decimalCount":18}]},{"id":"rio-defi","name":"RioDeFi","symbol":"RFUEL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xaf9f549774ecedbd0966c52f250acc548d3f36e5","decimalCount":18}]},{"id":"gaia-everworld","name":"Gaia Everworld","symbol":"GAIA","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x347e430b7cd1235e216be58ffa13394e5009e6e2","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x723b17718289a91af252d616de2c77944962d122","decimalCount":18}]},{"id":"unslashed-finance","name":"Unslashed Finance","symbol":"USF","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe0e05c43c097b0982db6c9d626c4eb9e95c3b9ce","decimalCount":18}]},{"id":"hyve","name":"Hyve","symbol":"HYVE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd794dd1cada4cf79c9eebaab8327a1b0507ef7d4","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xf6565a97dc832d93dc83b75ee9aa5c7e8ecb0f9d","decimalCount":18}]},{"id":"gunstar-metaverse","name":"Gunstar Metaverse","symbol":"GST","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x7edc0ec89f987ecd85617b891c44fe462a325869","decimalCount":18}]},{"id":"csp-dao-network","name":"CSP DAO Network","symbol":"NEBO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7f0c8b125040f707441cad9e5ed8a8408673b455","decimalCount":18}]},{"id":"openanx","name":"OAX","symbol":"OAX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x701c244b988a513c945973defa05de933b23fe1d","decimalCount":18}]},{"id":"dark-frontiers","name":"Dark Frontiers","symbol":"DARK","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x12fc07081fab7de60987cad8e8dc407b606fb2f8","decimalCount":8}]},{"id":"billionhappiness","name":"BillionHappiness","symbol":"BHC","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x6fd7c98458a943f469e1cf4ea85b173f5cd342f4","decimalCount":18}]},{"id":"revenue-coin","name":"Revenue Coin","symbol":"RVC","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xbcbdecf8e76a5c32dba69de16985882ace1678c6","decimalCount":18}]},{"id":"amepay","name":"AME Chain","symbol":"AME","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x12513335ffd5dafc2334e98625d27c1ca84bff86","decimalCount":18}]},{"id":"bitspawn","name":"Bitspawn","symbol":"SPWN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe516d78d784c77d479977be58905b3f2b1111126","decimalCount":18}]},{"id":"ripio-credit-network","name":"Ripio Credit Network","symbol":"RCN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf970b8e36e23f7fc3fd752eea86f8be8d83375a6","decimalCount":18}]},{"id":"botto","name":"Botto","symbol":"BOTTO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9dfad1b7102d46b1b197b90095b5c4e9f5845bba","decimalCount":18}]},{"id":"bnktothefuture","name":"BnkToTheFuture","symbol":"BFT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x01ff50f8b7f74e4f00580d9596cd3d0d6d6e326f","decimalCount":18}]},{"id":"par-stablecoin","name":"Parallel","symbol":"PAR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x68037790a0229e9ce6eaa8a99ea92964106c4703","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xe2aa7db6da1dae97c5f5c6914d285fbfcc32a128","decimalCount":18},{"networkId":"fantom","contractAddress":"0x13082681e8ce9bd0af505912d306403592490fc7","decimalCount":18}]},{"id":"honest-mining","name":"Honest","symbol":"HNST","active":true,"networks":[{"networkId":"binancecoin","contractAddress":"HNST-3C9","decimalCount":8}]},{"id":"enterdao","name":"EnterDAO","symbol":"ENTR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd779eea9936b4e323cddff2529eb6f13d0a4d66e","decimalCount":18}]},{"id":"lympo","name":"Lympo","symbol":"LYM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc690f7c7fcffa6a82b79fab7508c466fefdfc8c5","decimalCount":18}]},{"id":"inventoryclub","name":"InventoryClub","symbol":"VNT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe912b8ba2513d7e29b7b2e5b14398dbf77503fb4","decimalCount":18}]},{"id":"liquidus","name":"Liquidus","symbol":"LIQ","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xc7981767f644c7f8e483dabdc413e8a371b83079","decimalCount":18}]},{"id":"enjinstarter","name":"Enjinstarter","symbol":"EJS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x96610186f3ab8d73ebee1cf950c750f3b1fb79c2","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x09f423ac3c9babbff6f94d372b16e4206e71439f","decimalCount":18}]},{"id":"solace","name":"SOLACE","symbol":"SOLACE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x501ace9c35e60f03a2af4d484f49f9b1efde9f40","decimalCount":18}]},{"id":"xeta-reality","name":"Xeta Reality","symbol":"XETA","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x179960442ece8de9f390011b7f7c9b56c74e4d0a","decimalCount":9}]},{"id":"emanate","name":"Emanate","symbol":"EMT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x893700a1a86ee68b92536bf6fd4d3200d7369f7d","decimalCount":18}]},{"id":"tap","name":"Tap","symbol":"XTP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6368e1e18c4c419ddfc608a0bed1ccb87b9250fc","decimalCount":18}]},{"id":"exponential-capital","name":"Exponential Capital","symbol":"EXPO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xcfaf8edcea94ebaa080dc4983c3f9be5701d6613","decimalCount":18}]},{"id":"superbonds","name":"SuperBonds","symbol":"SB","active":true,"networks":[{"networkId":"solana","contractAddress":"SuperbZyz7TsSdSoFAZ6RYHfAWe9NmjXBLVQpS8hqdx","decimalCount":6}]},{"id":"garlicoin","name":"Garlicoin","symbol":"GRLC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x58f7345b5295e43aa454911571f13be186655be9","decimalCount":8},{"networkId":"binance-smart-chain","contractAddress":"0x7283dfa2d8d7e277b148cc263b5d8ae02f1076d3","decimalCount":8}]},{"id":"my-defi-pet","name":"My DeFi Pet","symbol":"DPET","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfb62ae373aca027177d1c18ee0862817f9080d08","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xfb62ae373aca027177d1c18ee0862817f9080d08","decimalCount":18}]},{"id":"unido-ep","name":"Unido","symbol":"UDO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xea3983fc6d0fbbc41fb6f6091f68f3e08894dc06","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x70802af0ba10dd5bb33276b5b37574b6451db3d9","decimalCount":18}]},{"id":"sheesha-finance-erc20","name":"Sheesha Finance (ERC20)","symbol":"SHEESHA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x232fb065d9d24c34708eedbf03724f2e95abe768","decimalCount":18}]},{"id":"apreum","name":"Apreum","symbol":"APU","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0xc155504787e9430180f33f35edd7c5ec06cd5761","decimalCount":18}]},{"id":"minidoge","name":"MiniDOGE","symbol":"MINIDOGE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xba07eed3d09055d60caef2bdfca1c05792f2dfad","decimalCount":9}]},{"id":"must","name":"Must","symbol":"MUST","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9c78ee466d6cb57a4d01fd887d2b5dfb2d46288f","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x9c78ee466d6cb57a4d01fd887d2b5dfb2d46288f","decimalCount":18}]},{"id":"stakehound-staked-ether","name":"StakeHound Staked Ether","symbol":"STETH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdfe66b14d37c77f4e9b180ceb433d1b164f0281d","decimalCount":18}]},{"id":"dappnode","name":"DAppNode","symbol":"NODE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xda007777d86ac6d989cc9f79a73261b3fc5e0da0","decimalCount":18}]},{"id":"b-cube-ai","name":"B-cube.ai","symbol":"BCUBE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x93c9175e26f57d2888c7df8b470c9eea5c0b0a93","decimalCount":18}]},{"id":"arc-governance","name":"ARC Governance","symbol":"ARCX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1321f1f1aa541a56c31682c57b80ecfccd9bb288","decimalCount":18}]},{"id":"lightcoin","name":"Lightcoin","symbol":"LHC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x320d31183100280ccdf69366cd56180ea442a3e8","decimalCount":8},{"networkId":"binance-smart-chain","contractAddress":"0x320d31183100280ccdf69366cd56180ea442a3e8","decimalCount":8}]},{"id":"unit-protocol-duck","name":"Unit Protocol New","symbol":"DUCK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x92e187a03b6cd19cb6af293ba17f2745fd2357d5","decimalCount":18},{"networkId":"fantom","contractAddress":"0x602a3ad311e66b6f5e567a13016b712aba0625c6","decimalCount":18}]},{"id":"varen","name":"Varen","symbol":"VRN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x72377f31e30a405282b522d588aebbea202b4f23","decimalCount":18}]},{"id":"vita-inu","name":"Vita Inu","symbol":"VINU","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xfebe8c1ed424dbf688551d4e2267e7a53698f0aa","decimalCount":18}]},{"id":"yam-2","name":"YAM","symbol":"YAM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0aacfbec6a24756c20d41914f2caba817c0d8521","decimalCount":18}]},{"id":"tierion","name":"Tierion","symbol":"TNT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x08f5a9235b08173b7569f83645d2c7fb55e8ccd8","decimalCount":8}]},{"id":"singularity","name":"Singularity","symbol":"SGLY","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x5f50411cde3eec27b0eac21691b4e500c69a5a2e","decimalCount":18}]},{"id":"boom-token","name":"Boom Token","symbol":"BOOM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdb7eab9ba6be88b869f738f6deeba96d49fe13fd","decimalCount":18}]},{"id":"xy-finance","name":"XY Finance","symbol":"XY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x77777777772cf0455fb38ee0e75f38034dfa50de","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x666666661f9b6d8c581602aaa2f76cbead06c401","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x55555555a687343c6ce28c8e1f6641dc71659fad","decimalCount":18},{"networkId":"fantom","contractAddress":"0x444444443b0fcb2733b93f23c910580fba52fffa","decimalCount":18}]},{"id":"innovaminex","name":"InnovaMinex","symbol":"MINX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xae353daeed8dcc7a9a12027f7e070c0a50b7b6a4","decimalCount":6}]},{"id":"sonm","name":"SONM","symbol":"SNM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x46d0dac0926fa16707042cadc23f1eb4141fe86b","decimalCount":18}]},{"id":"x-2","name":"X","symbol":"X","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7f3141c4d6b047fb930991b450f1ed996a51cb26","decimalCount":18}]},{"id":"king-shiba","name":"King Shiba","symbol":"KINGSHIB","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x84f4f7cdb4574c9556a494dab18ffc1d1d22316c","decimalCount":9}]},{"id":"idexo-token","name":"Idexo","symbol":"IDO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf9c53268e9de692ae1b2ea5216e24e1c3ad7cb1e","decimalCount":18}]},{"id":"mirrored-apple","name":"Mirrored Apple","symbol":"MAAPL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd36932143f6ebdedd872d5fb0651f4b72fd15a84","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x900aeb8c40b26a8f8dfaf283f884b03ee7abb3ec","decimalCount":18}]},{"id":"slink","name":"sLINK","symbol":"SLINK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbbc455cb4f1b9e4bfc4b73970d360c8f032efee6","decimalCount":18}]},{"id":"pog-coin","name":"PolygonumOnline","symbol":"POG","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xfcb0f2d2f83a32a847d8abb183b724c214cd7dd8","decimalCount":18}]},{"id":"degen-index","name":"DEGEN Index","symbol":"DEGEN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x126c121f99e1e211df2e5f8de2d96fa36647c855","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0xae6e3540e97b0b9ea8797b157b510e133afb6282","decimalCount":18}]},{"id":"phantasia","name":"Phantasia","symbol":"FANT","active":true,"networks":[{"networkId":"solana","contractAddress":"FANTafPFBAt93BNJVpdu25pGPmca3RfwdsDsRrT3LX1r","decimalCount":6}]},{"id":"1-up","name":"1-UP","symbol":"1-UP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc86817249634ac209bc73fca1712bbd75e37407d","decimalCount":18}]},{"id":"blockchain-certified-data-token","name":"EvidenZ","symbol":"BCDT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xacfa209fb73bf3dd5bbfb1101b9bc999c49062a5","decimalCount":18},{"networkId":"binancecoin","contractAddress":"0x8683e604cdf911cd72652a04bf9d571697a86a60","decimalCount":8}]},{"id":"agave-token","name":"Agave Token","symbol":"AGVE","active":true,"networks":[{"networkId":"arbitrum-one","contractAddress":"0x848e0ba28b637e8490d88bae51fa99c87116409b","decimalCount":18}]},{"id":"paint-swap","name":"Paint Swap","symbol":"BRUSH","active":true,"networks":[{"networkId":"fantom","contractAddress":"0x85dec8c4b2680793661bca91a8f129607571863d","decimalCount":18}]},{"id":"perth-mint-gold-token","name":"Perth Mint Gold Token","symbol":"PMGT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xaffcdd96531bcd66faed95fc61e443d08f79efef","decimalCount":5}]},{"id":"txa","name":"TXA","symbol":"TXA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4463e6a3ded0dbe3f6e15bc8420dfc55e5fea830","decimalCount":18}]},{"id":"dxsale-network","name":"DxSale Network","symbol":"SALE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf063fe1ab7a291c5d06a86e14730b00bf24cb589","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x04f73a09e2eb410205be256054794fb452f0d245","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x8f6196901a4a153d8ee8f3fa779a042f6092d908","decimalCount":18}]},{"id":"monavale","name":"Monavale","symbol":"MONA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x275f5ad03be0fa221b4c6649b8aee09a42d9412a","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x6968105460f67c3bf751be7c15f92f5286fd0ce5","decimalCount":18}]},{"id":"communifty","name":"Communifty","symbol":"CNFT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8e2b4badac15a4ec8c56020f4ce60faa7558c052","decimalCount":18}]},{"id":"ime-lab","name":"iMe Lab","symbol":"LIME","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9d0b65a76274645b29e4cc41b8f23081fa09f4a3","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x7bc75e291e656e8658d66be1cc8154a3769a35dd","decimalCount":18}]},{"id":"duel-network","name":"Duel Network","symbol":"DUEL","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x297817ce1a8de777e7ddbed86c3b7f9dc9349f2c","decimalCount":18}]},{"id":"snook","name":"Snook","symbol":"SNK","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0x689f8e5913c158ffb5ac5aeb83b3c875f5d20309","decimalCount":18}]},{"id":"arcona","name":"Arcona","symbol":"ARCONA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0f71b8de197a1c84d31de0f1fa7926c365f052b3","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x8fc4532be3003fb5a3a2f9afc7e95b3bfbd5faab","decimalCount":18}]},{"id":"wirtual","name":"Wirtual","symbol":"WIRTUAL","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xa19d3f4219e2ed6dc1cb595db20f70b8b6866734","decimalCount":18}]},{"id":"indexed-finance","name":"Indexed Finance","symbol":"NDX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x86772b1409b61c639eaac9ba0acfbb6e238e5f83","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0xb965029343d55189c25a7f3e0c9394dc0f5d41b1","decimalCount":18}]},{"id":"dfohub","name":"dfohub","symbol":"BUIDL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7b123f53421b1bf8533339bfbdc7c98aa94163db","decimalCount":18}]},{"id":"dingocoin","name":"Dingocoin","symbol":"DINGO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x9b208b117b2c4f76c1534b6f006b033220a681a4","decimalCount":8}]},{"id":"coinfirm-amlt","name":"AMLT Network","symbol":"AMLT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xca0e7269600d353f70b14ad118a49575455c0f2f","decimalCount":18}]},{"id":"you-chain","name":"YOU Chain","symbol":"YOU","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x34364bee11607b1963d66bca665fde93fca666a8","decimalCount":18}]},{"id":"pillar","name":"Pillar","symbol":"PLR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe3818504c1b32bf1557b16c238b2e01fd3149c17","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x790cfdc6ab2e0ee45a433aac5434f183be1f6a20","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xa6b37fc85d870711c56fbcb8afe2f8db049ae774","decimalCount":18}]},{"id":"qiibee","name":"qiibee","symbol":"QBX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2467aa6b5a2351416fd4c3def8462d841feeecec","decimalCount":18}]},{"id":"ok-lets-go","name":"ok.lets.go.","symbol":"OKLG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5dbb9f64cd96e2dbbca58d14863d615b67b42f2e","decimalCount":9},{"networkId":"binance-smart-chain","contractAddress":"0x55e8b37a3c43b049dedf56c77f462db095108651","decimalCount":9}]},{"id":"falcon-token","name":"Falcon Project","symbol":"FNT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdc5864ede28bd4405aa04d93e05a0531797d9d59","decimalCount":6}]},{"id":"roobee","name":"Roobee","symbol":"ROOBEE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa31b1767e09f842ecfd4bc471fe44f830e3891aa","decimalCount":18}]},{"id":"kick","name":"Kick","symbol":"KICK","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x824a50df33ac1b41afc52f4194e2e8356c17c3ac","decimalCount":10}]},{"id":"don-key","name":"Don-key","symbol":"DON","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x217ddead61a42369a266f1fb754eb5d3ebadc88a","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x86b3f23b6e90f5bbfac59b5b2661134ef8ffd255","decimalCount":18}]},{"id":"crosswallet","name":"CrossWallet","symbol":"CWT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x5a726a26edb0df8fd55f03cc30af8a7cea81e78d","decimalCount":18}]},{"id":"vesta-finance","name":"Vesta Finance","symbol":"VSTA","active":true,"networks":[{"networkId":"arbitrum-one","contractAddress":"0xa684cd057951541187f288294a1e1c2646aa2d24","decimalCount":18}]},{"id":"airbloc-protocol","name":"Airbloc","symbol":"ABL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf8b358b3397a8ea5464f8cc753645d42e14b79ea","decimalCount":18}]},{"id":"kainet","name":"KAINET","symbol":"KAINET","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x723b6795be37ad8a0376acfb50034fa21912b439","decimalCount":9}]},{"id":"dinox","name":"DinoX","symbol":"DNXC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x20a8cec5fffea65be7122bcab2ffe32ed4ebf03a","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x3c1748d647e6a56b37b66fcd2b5626d0461d3aa0","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xcaf5191fc480f43e4df80106c7695eca56e48b18","decimalCount":18}]},{"id":"kalao","name":"Kalao","symbol":"KLO","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0xb27c8941a7df8958a1778c0259f76d1f8b711c35","decimalCount":18}]},{"id":"hodl-finance","name":"Hodl Finance","symbol":"HFT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x186866858aef38c05829166a7711b37563e15994","decimalCount":9}]},{"id":"quidd","name":"Quidd","symbol":"QUIDD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xda9fdab21bc4a5811134a6e0ba6ca06624e67c07","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x7961ade0a767c0e5b67dd1a1f78ba44f727642ed","decimalCount":18}]},{"id":"nftlaunch","name":"NFTLaunch","symbol":"NFTL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe7f72bc0252ca7b16dbb72eeee1afcdb2429f2dd","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xe7f72bc0252ca7b16dbb72eeee1afcdb2429f2dd","decimalCount":18}]},{"id":"tenx","name":"TenX","symbol":"PAY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb97048628db6b661d4c2aa833e95dbe1a905b280","decimalCount":18}]},{"id":"ubiq","name":"Ubiq","symbol":"UBQ","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0xb1c5c9b97b35592777091cd34ffff141ae866abd","decimalCount":18}]},{"id":"monetha","name":"Monetha","symbol":"MTH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xaf4dce16da2877f8c9e00544c93b62ac40631f16","decimalCount":5}]},{"id":"bird-money","name":"Bird.Money","symbol":"BIRD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x70401dfd142a16dc7031c56e862fc88cb9537ce0","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x8780fea4c6b242677d4a397fe1110ac09ce99ad2","decimalCount":18}]},{"id":"linka","name":"LINKA","symbol":"LINKA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x578b49c45961f98d8df92854b53f1641af0a5036","decimalCount":18}]},{"id":"goal-token","name":"Goal","symbol":"GOAL","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x438fc473ba340d0734e2d05acdf5bee775d1b0a4","decimalCount":18}]},{"id":"scream","name":"Scream","symbol":"SCREAM","active":true,"networks":[{"networkId":"fantom","contractAddress":"0xe0654c8e6fd4d733349ac7e09f6f23da256bf475","decimalCount":18}]},{"id":"dlp-duck-token","name":"DLP Duck Token","symbol":"DUCK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc0ba369c8db6eb3924965e5c4fd0b4c1b91e305f","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x5d186e28934c6b0ff5fc2fece15d1f34f78cbd87","decimalCount":18}]},{"id":"wiva","name":"WIVA","symbol":"WIVA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa00055e6ee4d1f4169096ecb682f70caa8c29987","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x784641e51c300120a8d15bfdb3b45375d4352748","decimalCount":18}]},{"id":"archangel-token","name":"ArchAngel","symbol":"ARCHA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x36e43065e977bc72cb86dbd8405fae7057cdc7fd","decimalCount":9},{"networkId":"binance-smart-chain","contractAddress":"0xb0ff8188f374902bb180bd186d17967b5b1188f2","decimalCount":9},{"networkId":"fantom","contractAddress":"0x5e2e2d3ee4944d0e6c0b663625859cf8cc45ca88","decimalCount":9}]},{"id":"firestarter","name":"FireStarter","symbol":"FLAME","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0x22e3f02f86bc8ea0d73718a2ae8851854e62adc5","decimalCount":18}]},{"id":"king-floki","name":"King Floki V2","symbol":"KING","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xb872057ee478b3eb77e74c9aa7b50fe4ed650e58","decimalCount":9}]},{"id":"deblox","name":"Deblox","symbol":"DGS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x4ea636b489f51e2c332e2a6203bf3fcc0954a5f4","decimalCount":18}]},{"id":"nft-index","name":"NFT Index","symbol":"NFTI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe5feeac09d36b18b3fa757e5cf3f8da6b8e27f4c","decimalCount":18}]},{"id":"revolve-games","name":"Revolve Games","symbol":"RPG","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x01e0d17a533e5930a349c2bb71304f04f20ab12b","decimalCount":18}]},{"id":"decentr","name":"Decentr","symbol":"DEC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x30f271c9e86d2b7d00a6376cd96a1cfbd5f0b9b3","decimalCount":18}]},{"id":"woof-token","name":"WOOF","symbol":"WOOF","active":true,"networks":[{"networkId":"solana","contractAddress":"9nEqaUcb16sQ3Tn1psbkWqyhPdLmfHWjKGymREjsAgTE","decimalCount":6}]},{"id":"bloxmove-erc20","name":"bloXmove","symbol":"BLXM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x38d9eb07a7b8df7d86f440a4a5c4a4c1a27e1a08","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x40e51e0ec04283e300f12f6bb98da157bb22036e","decimalCount":18}]},{"id":"wall-street-games","name":"Wall Street Games","symbol":"WSG","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xa58950f05fea2277d2608748412bf9f802ea4901","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x3c1bb39bb696b443a1d80bb2b3a3d950ba9dee87","decimalCount":18}]},{"id":"brokoli","name":"Brokoli","symbol":"BRKL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4674a4f24c5f63d53f22490fb3a08eaaad739ff8","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x66cafcf6c32315623c7ffd3f2ff690aa36ebed38","decimalCount":18}]},{"id":"renzec","name":"renZEC","symbol":"RENZEC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1c5db575e2ff833e46a2e9864c22f4b22e0b37c2","decimalCount":8}]},{"id":"big-data-protocol","name":"Big Data Protocol","symbol":"BDP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf3dcbc6d72a4e1892f7917b7c43b74131df8480e","decimalCount":18}]},{"id":"unbound-finance","name":"Unbound Finance","symbol":"UNB","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8db253a1943dddf1af9bcf8706ac9a0ce939d922","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x301af3eff0c904dc5ddd06faa808f653474f7fcc","decimalCount":18}]},{"id":"roco-finance","name":"Roco Finance","symbol":"ROCO","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0xb2a85c5ecea99187a977ac34303b80acbddfa208","decimalCount":18}]},{"id":"bridge-mutual","name":"Bridge Mutual","symbol":"BMI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x725c263e32c72ddc3a19bea12c5a0479a81ee688","decimalCount":18}]},{"id":"gazetv","name":"GazeTV","symbol":"GAZE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd1e06952708771f71e6dd18f06ee418f6e8fc564","decimalCount":18}]},{"id":"abitshadow-token","name":"Abitshadow Token","symbol":"ABST","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x7e46d5eb5b7ca573b367275fee94af1945f5b636","decimalCount":8}]},{"id":"relevant","name":"Relevant","symbol":"REL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb6c4267c4877bb0d6b1685cfd85b0fbe82f105ec","decimalCount":18}]},{"id":"holyheld-2","name":"Mover","symbol":"MOVE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3fa729b4548becbad4eab6ef18413470e6d5324c","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x521cddc0cba84f14c69c1e99249f781aa73ee0bc","decimalCount":18},{"networkId":"fantom","contractAddress":"0xc055c698f3793577707b3e6979b089f50c314d3a","decimalCount":18}]},{"id":"cyberfi","name":"CyberFi","symbol":"CFI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x63b4f3e3fa4e438698ce330e365e831f7ccd1ef4","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x6a545f9c64d8f7b957d8d2e6410b52095a9e6c29","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xecf8f2fa183b1c4d2a269bf98a54fce86c812d3e","decimalCount":18},{"networkId":"fantom","contractAddress":"0x6a545f9c64d8f7b957d8d2e6410b52095a9e6c29","decimalCount":18}]},{"id":"kuma-inu","name":"Kuma Inu","symbol":"KUMA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x48c276e8d03813224bb1e55f953adb6d02fd3e02","decimalCount":18}]},{"id":"unilayer","name":"UniLayer","symbol":"LAYER","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0ff6ffcfda92c53f615a4a75d982f399c989366b","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xc2c23a86def9e9f5972a633b3d25f7ecbfa5e575","decimalCount":18}]},{"id":"elyfi","name":"ELYFI","symbol":"ELFI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4da34f8264cb33a5c9f17081b9ef5ff6091116f4","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x6c619006043eab742355395690c7b42d3411e8c0","decimalCount":18}]},{"id":"launchzone","name":"LaunchZone","symbol":"LZ","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x3b78458981eb7260d1f781cb8be2caac7027dbe2","decimalCount":18}]},{"id":"julien","name":"JULIEN","symbol":"JULIEN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe6710e0cda178f3d921f456902707b0d4c4a332b","decimalCount":4}]},{"id":"swingby","name":"Swingby","symbol":"SWINGBY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8287c7b963b405b7b8d467db9d79eec40625b13a","decimalCount":18},{"networkId":"binancecoin","contractAddress":"SWINGBY-888","decimalCount":8},{"networkId":"binance-smart-chain","contractAddress":"0x71de20e0c4616e7fcbfdd3f875d568492cbe4739","decimalCount":18}]},{"id":"xio","name":"Blockzero Labs","symbol":"XIO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0f7f961648ae6db43c75663ac7e5414eb79b5704","decimalCount":18}]},{"id":"float-protocol-float","name":"Float Protocol: Float","symbol":"FLOAT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb05097849bca421a3f51b249ba6cca4af4b97cb9","decimalCount":18}]},{"id":"phuture","name":"Phuture","symbol":"PHTR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe1fc4455f62a6e89476f1072530c20cf1a0622da","decimalCount":18}]},{"id":"pickle-finance","name":"Pickle Finance","symbol":"PICKLE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x429881672b9ae42b8eba0e26cd9c73711b891ca5","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x2b88ad57897a8b496595925f43048301c37615da","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x965772e0e9c84b6f359c8597c891108dcf1c5b1a","decimalCount":18}]},{"id":"oni-token","name":"ONINO","symbol":"ONI","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xea89199344a492853502a7a699cc4230854451b8","decimalCount":18},{"networkId":"fantom","contractAddress":"0x667c856f1a624baefe89fc4909c8701296c86c98","decimalCount":18}]},{"id":"transient","name":"Transient","symbol":"TSCT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x805ea9c07b49dd23ce11ec66dc6d8a2957385035","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xeeed90aa795c0e7d90fcec0fcfaa7bf6fc13c20a","decimalCount":18}]},{"id":"bitsong","name":"BitSong","symbol":"BTSG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x05079687d35b93538cbd59fe5596380cae9054a9","decimalCount":18}]},{"id":"piedao-dough-v2","name":"PieDAO DOUGH v2","symbol":"DOUGH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xad32a8e6220741182940c5abf610bde99e737b2d","decimalCount":18}]},{"id":"napoleon-x","name":"Napoleon X","symbol":"NPX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x28b5e12cce51f15594b0b91d5b5adaa70f684a02","decimalCount":2},{"networkId":"binance-smart-chain","contractAddress":"0xd8cb4c2369db13c94c90c7fd3bebc9757900ee6b","decimalCount":18}]},{"id":"reucoin","name":"REUCOIN","symbol":"REU","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa287fd349d80dfd2a8aee1c0d90f17281f24c061","decimalCount":18}]},{"id":"any-blocknet","name":"ANY Blocknet","symbol":"ABLOCK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe692c8d72bd4ac7764090d54842a305546dd1de5","decimalCount":8},{"networkId":"avalanche","contractAddress":"0xc931f61b1534eb21d8c11b24f3f5ab2471d4ab50","decimalCount":8}]},{"id":"blackdragon-token","name":"BlackDragon Token","symbol":"BDT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4efe8665e564bf454ccf5c90ee16817f7485d5cf","decimalCount":18}]},{"id":"ninneko","name":"Ninneko","symbol":"NINO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x6cad12b3618a3c7ef1feb6c91fdc3251f58c2a90","decimalCount":18}]},{"id":"wrapped-dgld","name":"Wrapped-DGLD","symbol":"WDGLD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x123151402076fc819b7564510989e475c9cd93ca","decimalCount":8}]},{"id":"jigstack","name":"Jigstack","symbol":"STAK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1f8a626883d7724dbd59ef51cbd4bf1cf2016d13","decimalCount":18}]},{"id":"cryptonovae","name":"Cryptonovae","symbol":"YAE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4ee438be38f8682abb089f2bfea48851c5e71eaf","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x4ee438be38f8682abb089f2bfea48851c5e71eaf","decimalCount":18}]},{"id":"shakita-inu","name":"Shakita Inu","symbol":"SHAK","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x76e08e1c693d42551dd6ba7c2a659f74ff5ba261","decimalCount":18}]},{"id":"nftfy","name":"Nftfy","symbol":"NFTFY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbf6ff49ffd3d104302ef0ab0f10f5a84324c091c","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xbf6ff49ffd3d104302ef0ab0f10f5a84324c091c","decimalCount":18}]},{"id":"hollygold","name":"HollyGold","symbol":"HGOLD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0c93b616933b0cd03b201b29cd8a22681dd9e0d9","decimalCount":8}]},{"id":"axpire","name":"aXpire","symbol":"AXPR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdd0020b1d5ba47a54e2eb16800d73beb6546f91a","decimalCount":18}]},{"id":"zyx","name":"ZYX","symbol":"ZYX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf974b5f9ac9c6632fee8b76c61b0242ce69c839d","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x377c6e37633e390aef9afb4f5e0b16689351eed4","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x377c6e37633e390aef9afb4f5e0b16689351eed4","decimalCount":18}]},{"id":"hundred-finance","name":"Hundred Finance","symbol":"HND","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x10010078a54396f62c96df8532dc2b4847d47ed3","decimalCount":18},{"networkId":"fantom","contractAddress":"0x10010078a54396f62c96df8532dc2b4847d47ed3","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x10010078a54396f62c96df8532dc2b4847d47ed3","decimalCount":18}]},{"id":"idle","name":"IDLE","symbol":"IDLE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x875773784af8135ea0ef43b5a374aad105c5d39e","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xc25351811983818c9fe6d8c580531819c8ade90f","decimalCount":18}]},{"id":"bankless-bed-index","name":"Bankless BED Index","symbol":"BED","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2af1df3ab0ab157e1e2ad8f88a7d04fbea0c7dc6","decimalCount":18}]},{"id":"konomi-network","name":"Konomi Network","symbol":"KONO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x850aab69f0e0171a9a49db8be3e71351c8247df4","decimalCount":18}]},{"id":"olyseum","name":"Olyseum","symbol":"OLY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6595b8fd9c920c81500dca94e53cdc712513fb1f","decimalCount":18}]},{"id":"yvault-lp-ycurve","name":"yUSD","symbol":"YVAULT-LP-YCURVE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5dbcf33d8c2e976c6b560249878e6f1491bca25c","decimalCount":18}]},{"id":"bloom","name":"Bloom","symbol":"BLT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x107c4504cd79c5d2696ea0030a8dd4e92601b82e","decimalCount":18}]},{"id":"gspi","name":"Shopping.io Governance","symbol":"GSPI","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xb42e1c3902b85b410334f5fff79cdc51fbee6950","decimalCount":18}]},{"id":"nabox","name":"Nabox","symbol":"NABOX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x03d1e72765545729a035e909edd9371a405f77fb","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x755f34709e369d37c6fa52808ae84a32007d1155","decimalCount":18}]},{"id":"defi-yield-protocol","name":"DeFi Yield Protocol","symbol":"DYP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x961c8c0b1aad0c0b10a51fef6a867e3091bcef17","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x961c8c0b1aad0c0b10a51fef6a867e3091bcef17","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x961c8c0b1aad0c0b10a51fef6a867e3091bcef17","decimalCount":18}]},{"id":"slam-token","name":"Slam Token","symbol":"SLAM","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x000851476180bfc499ea68450a5327d21c9b050e","decimalCount":18}]},{"id":"musk-gold","name":"MUSK Gold","symbol":"MUSK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6069c9223e8a5da1ec49ac5525d4bb757af72cd8","decimalCount":18}]},{"id":"impermax","name":"Impermax","symbol":"IMX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7b35ce522cb72e4077baeb96cb923a5529764a00","decimalCount":18},{"networkId":"avalanche","contractAddress":"0xea6887e4a9cda1b77e70129e5fba830cdb5cddef","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x60bb3d364b765c497c8ce50ae0ae3f0882c5bd05","decimalCount":18},{"networkId":"fantom","contractAddress":"0xea38f1ccf77bf43f352636241b05dd8f6f5f52b2","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x9c67ee39e3c4954396b9142010653f17257dd39c","decimalCount":18}]},{"id":"top-network","name":"TOP Network","symbol":"TOP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdcd85914b8ae28c1e62f1c488e1d968d5aaffe2b","decimalCount":18}]},{"id":"furucombo","name":"Furucombo","symbol":"COMBO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xffffffff2ba8f66d4e51811c5190992176930278","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x6ddb31002abc64e1479fc439692f7ea061e78165","decimalCount":18}]},{"id":"enigma","name":"Enigma","symbol":"ENG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf0ee6b27b759c9893ce4f094b49ad28fd15a23e4","decimalCount":8}]},{"id":"yin-finance","name":"YIN Finance","symbol":"YIN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x794baab6b878467f93ef17e2f2851ce04e3e34c8","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x794baab6b878467f93ef17e2f2851ce04e3e34c8","decimalCount":18}]},{"id":"nord-finance","name":"Nord Finance","symbol":"NORD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6e9730ecffbed43fd876a264c982e254ef05a0de","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x6e9730ecffbed43fd876a264c982e254ef05a0de","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xf6f85b3f9fd581c2ee717c404f7684486f057f95","decimalCount":18},{"networkId":"fantom","contractAddress":"0xeaf26191ac1d35ae30baa19a5ad5558dd8156aef","decimalCount":18}]},{"id":"bios","name":"0x_nodes","symbol":"BIOS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xaaca86b876ca011844b5798eca7a67591a9743c8","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xcf87d3d50a98a7832f5cfdf99ae1b88c7cfba4a7","decimalCount":18},{"networkId":"avalanche","contractAddress":"0xd7783a275e53fc6746dedfbad4a06059937502a4","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xe20d2df5041f8ed06976846470f727295cdd4d23","decimalCount":18},{"networkId":"fantom","contractAddress":"0x75e0eb8e6d92ab832bb11e46c041d06a89ac5f0d","decimalCount":18}]},{"id":"cogiverse","name":"9D NFT","symbol":"COGI","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x6cb755c4b82e11e727c05f697c790fdbc4253957","decimalCount":18}]},{"id":"sdefi","name":"sDEFI","symbol":"SDEFI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe1afe1fd76fd88f78cbf599ea1846231b8ba3b6b","decimalCount":18}]},{"id":"futurecoin","name":"FutureCoin","symbol":"FUTURE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x9fbff386a9405b4c98329824418ec02b5c20976b","decimalCount":18}]},{"id":"kineko","name":"Kineko","symbol":"KKO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x368c5290b13caa10284db58b4ad4f3e9ee8bf4c9","decimalCount":18},{"networkId":"solana","contractAddress":"kiNeKo77w1WBEzFFCXrTDRWGRWGP8yHvKC9rX6dqjQh","decimalCount":9}]},{"id":"bean","name":"Bean","symbol":"BEAN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdc59ac4fefa32293a95889dc396682858d52e5db","decimalCount":6}]},{"id":"elon-doge-token","name":"ElonDoge.io","symbol":"EDOGE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x163f182c32d24a09d91eb75820cde9fd5832b329","decimalCount":9}]},{"id":"yflink","name":"YF Link","symbol":"YFL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x28cb7e841ee97947a86b06fa4090c8451f64c0be","decimalCount":18}]},{"id":"yel-finance","name":"Yel.Finance","symbol":"YEL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7815bda662050d84718b988735218cffd32f75ea","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xd3b71117e6c1558c1553305b44988cd944e97300","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xd3b71117e6c1558c1553305b44988cd944e97300","decimalCount":18},{"networkId":"fantom","contractAddress":"0xd3b71117e6c1558c1553305b44988cd944e97300","decimalCount":18}]},{"id":"afin-coin","name":"Asian Fintech","symbol":"AFIN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xee9e5eff401ee921b138490d00ca8d1f13f67a72","decimalCount":8},{"networkId":"binance-smart-chain","contractAddress":"0xb955b4cab9aa3b49e23aeb5204ebc5ff6678e86d","decimalCount":18}]},{"id":"cryptowar-xblade","name":"OpenWorld","symbol":"OPEN","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x27a339d9b59b21390d7209b78a839868e319301b","decimalCount":18}]},{"id":"tokenplace","name":"Tokenplace","symbol":"TOK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4fb721ef3bf99e0f2c193847afa296b9257d3c30","decimalCount":8},{"networkId":"avalanche","contractAddress":"0xae9d2385ff2e2951dd4fa061e74c4d3dedd24347","decimalCount":8}]},{"id":"devour","name":"Devour","symbol":"RESTAURANTS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdffc63f92c939deb112d88735ade3b4d21b6d491","decimalCount":18}]},{"id":"rac","name":"RAC","symbol":"RAC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc22b30e4cce6b78aaaadae91e44e73593929a3e9","decimalCount":18}]},{"id":"life-crypto","name":"Life Crypto","symbol":"LIFE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6c936d4ae98e6d2172db18c16c4b601c99918ee6","decimalCount":18}]},{"id":"finxflo","name":"FINXFLO","symbol":"FXF","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8a40c222996f9f3431f63bf80244c36822060f12","decimalCount":18}]},{"id":"howdoo","name":"Hyprr","symbol":"UDOO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x12f649a9e821f90bb143089a6e56846945892ffb","decimalCount":18}]},{"id":"defi-for-you","name":"Defi For You","symbol":"DFY","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xd98560689c6e748dc37bc410b4d3096b1aa3d8c2","decimalCount":18}]},{"id":"warp-finance","name":"Warp Finance","symbol":"WARP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xed40834a13129509a89be39a9be9c0e96a0ddd71","decimalCount":18}]},{"id":"tadpole-finance","name":"Tadpole","symbol":"TAD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9f7229af0c4b9740e207ea283b9094983f78ba04","decimalCount":18}]},{"id":"gas-dao","name":"Gas DAO","symbol":"GAS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6bba316c48b49bd1eac44573c5c871ff02958469","decimalCount":18}]},{"id":"hedget","name":"Hedget","symbol":"HGET","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7968bc6a03017ea2de509aaa816f163db0f35148","decimalCount":6}]},{"id":"alyattes","name":"Alyattes","symbol":"ALYA","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x49a9f9a2271d8c5da44c57e7102aca79c222f4a9","decimalCount":9}]},{"id":"daex","name":"DAEX","symbol":"DAX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0b4bdc478791897274652dc15ef5c135cae61e60","decimalCount":18}]},{"id":"ethichub","name":"EthicHub","symbol":"ETHIX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfd09911130e6930bf87f2b0554c44f400bd80d3e","decimalCount":18}]},{"id":"resfinex-token","name":"Resfinex Token","symbol":"RES","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0a9f693fce6f00a51a8e0db4351b5a8078b4242e","decimalCount":5}]},{"id":"1world","name":"1World","symbol":"1WO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfdbc1adc26f0f8f8606a5d63b7d3a3cd21c22b23","decimalCount":8}]},{"id":"citadel-one","name":"Citadel.one","symbol":"XCT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xe8670901e86818745b28c8b30b17986958fce8cc","decimalCount":6}]},{"id":"zap","name":"Zap","symbol":"ZAP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6781a0f84c7e9e846dcb84a9a5bd49333067b104","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xc5326b32e8baef125acd68f8bc646fd646104f1c","decimalCount":18}]},{"id":"wanaka-farm","name":"Wanaka Farm","symbol":"WANA","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x339c72829ab7dd45c3c52f965e7abe358dd8761e","decimalCount":18}]},{"id":"nft-protocol","name":"NFT Protocol","symbol":"NFT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xcb8d1260f9c92a3a545d409466280ffdd7af7042","decimalCount":18}]},{"id":"swapr","name":"Swapr","symbol":"SWPR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6cacdb97e3fc8136805a9e7c342d866ab77d0957","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0xde903e2712288a1da82942dddf2c20529565ac30","decimalCount":18}]},{"id":"ureeqa","name":"UREEQA","symbol":"URQA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1735db6ab5baa19ea55d0adceed7bcdc008b3136","decimalCount":18},{"networkId":"avalanche","contractAddress":"0xbd3936ec8d83a5d4e73eca625ecfa006da8c8f52","decimalCount":18}]},{"id":"acryptosi","name":"ACryptoSI","symbol":"ACSI","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x5b17b4d5e4009b5c43e3e3d63a5229f794cba389","decimalCount":18}]},{"id":"tycoon","name":"Tycoon","symbol":"TYC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3a82d3111ab5faf39d847d46023d9090261a658f","decimalCount":18}]},{"id":"equalizer","name":"Equalizer","symbol":"EQZ","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1da87b114f35e1dc91f72bf57fc07a768ad40bb0","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x1da87b114f35e1dc91f72bf57fc07a768ad40bb0","decimalCount":18}]},{"id":"dogey-inu","name":"Dogey-Inu","symbol":"DINU","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbb1ee07d6c7baeb702949904080eb61f5d5e7732","decimalCount":18}]},{"id":"cryptopolis","name":"Cryptopolis","symbol":"CPO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xea395dfafed39924988b475f2ca7f4c72655203a","decimalCount":18}]},{"id":"unimex-network","name":"UniMex Network","symbol":"UMX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x10be9a8dae441d276a5027936c3aaded2d82bc15","decimalCount":18}]},{"id":"wagyuswap","name":"WagyuSwap","symbol":"WAG","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x7fa7df4996ac59f398476892cfb195ed38543520","decimalCount":18}]},{"id":"powertrade-fuel","name":"PowerTrade Fuel","symbol":"PTF","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc57d533c50bc22247d49a368880fb49a1caa39f7","decimalCount":18}]},{"id":"astroswap","name":"AstroSwap","symbol":"ASTRO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x72eb7ca07399ec402c5b7aa6a65752b6a1dc0c27","decimalCount":18}]},{"id":"genaro-network","name":"Genaro Network","symbol":"GNX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6ec8a24cabdc339a06a172f8223ea557055adaa5","decimalCount":9}]},{"id":"edenchain","name":"Edenchain","symbol":"EDN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x89020f0d5c5af4f3407eb5fe185416c457b0e93e","decimalCount":18}]},{"id":"everlens","name":"Everlens","symbol":"ELEN","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xca2483727292ba552aec12dfee4dc105cb1376b9","decimalCount":18}]},{"id":"aurora","name":"Aurora Chain","symbol":"AOA","active":false,"networks":[{"networkId":"ethereum","contractAddress":"0x9ab165d795019b6d8b3e971dda91071421305e5a","decimalCount":18}]},{"id":"algovest","name":"AlgoVest","symbol":"AVS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x94d916873b22c9c1b53695f1c002f78537b9b3b2","decimalCount":18}]},{"id":"sync-network","name":"Sync Network","symbol":"SYNC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb6ff96b8a8d214544ca0dbc9b33f7ad6503efd32","decimalCount":18}]},{"id":"aichain","name":"AICHAIN","symbol":"AIT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x79650799e7899a802cb96c0bc33a6a8d4ce4936c","decimalCount":18}]},{"id":"masq","name":"MASQ","symbol":"MASQ","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x06f3c323f0238c72bf35011071f2b5b7f43a054c","decimalCount":18}]},{"id":"cpchain","name":"CPChain","symbol":"CPC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfae4ee59cdd86e3be9e8b90b53aa866327d7c090","decimalCount":18}]},{"id":"metagods","name":"MetaGods","symbol":"MGOD","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x10a12969cb08a8d88d4bfb5d1fa317d41e0fdab3","decimalCount":18}]},{"id":"ideaology","name":"Ideaology","symbol":"IDEA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5d3a4f62124498092ce665f865e0b38ff6f5fbea","decimalCount":18}]},{"id":"shopnext","name":"ShopNEXT","symbol":"NEXT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x9809e877192b510d767a94ba39a79429219a5afb","decimalCount":18}]},{"id":"game-ace-token","name":"Game Ace","symbol":"GAT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xf315cfc8550f6fca969d397ca8b807c5033fa122","decimalCount":18}]},{"id":"mist","name":"Mist","symbol":"MIST","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x68e374f856bf25468d365e539b700b648bf94b67","decimalCount":18}]},{"id":"senate","name":"SENATE","symbol":"SENATE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x34be5b8c30ee4fde069dc878989686abe9884470","decimalCount":18}]},{"id":"ether-1","name":"Etho Protocol","symbol":"ETHO","active":false,"networks":[{"networkId":"ethereum","contractAddress":"0x99676c9fa4c77848aeb2383fcfbd7e980dc25027","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x0e900aa6ed4244c43d597e6d2f8fb3994303ed99","decimalCount":18}]},{"id":"smoothy","name":"Smoothy","symbol":"SMTY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbf776e4fca664d791c4ee3a71e2722990e003283","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xbf776e4fca664d791c4ee3a71e2722990e003283","decimalCount":18}]},{"id":"sw-dao","name":"SW DAO","symbol":"SWD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1fd154b4d0e3753b714b511a53fe1fb72dc7ae1c","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xaee24d5296444c007a532696aada9de5ce6cafd0","decimalCount":18}]},{"id":"horizon-protocol","name":"Horizon Protocol","symbol":"HZN","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xc0eff7749b125444953ef89682201fb8c6a917cd","decimalCount":18}]},{"id":"gami-world","name":"GAMI World","symbol":"GAMI","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x1236a887ef31b4d32e1f0a2b5e4531f52cec7e75","decimalCount":6}]},{"id":"leaguedao-governance-token","name":"LeagueDAO Governance","symbol":"LEAG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7b39917f9562c8bc83c7a6c2950ff571375d505d","decimalCount":18}]},{"id":"angel-nodes","name":"Angel Nodes","symbol":"ANGEL","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x623974fa31d79d12dc8a2ec8dfea9bcdf8938889","decimalCount":8}]},{"id":"polker","name":"Polker","symbol":"PKR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x001a8ffcb0f03e99141652ebcdecdb0384e3bd6c","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xc49dde62b4a0810074721faca54aab52369f486a","decimalCount":18}]},{"id":"chronicle","name":"Chronicle","symbol":"XNL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x06a00715e6f92210af9d7680b584931faf71a833","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x5f26fa0c2ee5d3c0323d861d0c503f31ac212662","decimalCount":18}]},{"id":"index-coop-eth-2x-flexible-leverage-index","name":"Index Coop - ETH 2x Flexible Leverage Index (Polygon)","symbol":"ETH2X-FLI-P","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0x3ad707da309f3845cd602059901e39c4dcd66473","decimalCount":18}]},{"id":"polis","name":"Polis","symbol":"POLIS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xb5bea8a26d587cf665f2d78f077cca3c7f6341bd","decimalCount":18}]},{"id":"green-planet","name":"Green Planet","symbol":"GAMMA","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xb3cb6d2f8f2fde203a022201c81a96c167607f15","decimalCount":18}]},{"id":"inpulse-x","name":"InpulseX","symbol":"IPX","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x1a3ee33da561642ba6be4671a06267ee0f36cedd","decimalCount":18}]},{"id":"heroes-empires","name":"Heroes & Empires","symbol":"HE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x20d39a5130f799b95b55a930e5b7ebc589ea9ed8","decimalCount":18}]},{"id":"hord","name":"Hord","symbol":"HORD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x43a96962254855f16b925556f9e97be436a43448","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x39d4549908e7adcee9b439429294eeb4c65c2c9e","decimalCount":18}]},{"id":"zusd","name":"ZUSD","symbol":"ZUSD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc56c2b7e71b54d38aab6d52e94a04cbfa8f604fa","decimalCount":6}]},{"id":"otterclam","name":"OtterClam","symbol":"CLAM","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0xc250e9987a032acac293d838726c511e6e1c029d","decimalCount":9}]},{"id":"kanpeki","name":"Kanpeki","symbol":"KAE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x65def5029a0e7591e46b38742bfedd1fb7b24436","decimalCount":18},{"networkId":"fantom","contractAddress":"0x65def5029a0e7591e46b38742bfedd1fb7b24436","decimalCount":18}]},{"id":"basketdao-defi-index","name":"BasketDAO DeFi Index","symbol":"BDI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0309c98b1bffa350bcb3f9fb9780970ca32a5060","decimalCount":18}]},{"id":"subx-finance","name":"SUBX FINANCE LAB","symbol":"SFX","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x4cbda3d23c031cd403db2d24512ad920bf22f205","decimalCount":9}]},{"id":"rhythm","name":"Rhythm","symbol":"RHYTHM","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xe4318f2acf2b9c3f518a3a03b5412f4999970ddb","decimalCount":9}]},{"id":"razor-network","name":"Razor Network","symbol":"RAZOR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x50de6856358cc35f3a9a57eaaa34bd4cb707d2cd","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x50de6856358cc35f3a9a57eaaa34bd4cb707d2cd","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xc91c06db0f7bffba61e2a5645cc15686f0a8c828","decimalCount":18}]},{"id":"nix-bridge-token","name":"Voice Token","symbol":"VOICE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2e2364966267b5d7d2ce6cd9a9b5bd19d9c7c6a9","decimalCount":18}]},{"id":"ojamu","name":"Ojamu","symbol":"OJA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0aa7efe4945db24d95ca6e117bba65ed326e291a","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x26373ec913876c9e6d38494dde458cb8649cb30c","decimalCount":18}]},{"id":"xaurum","name":"Xaurum","symbol":"XAUR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4df812f6064def1e5e029f1ca858777cc98d2d81","decimalCount":8}]},{"id":"plasma-finance","name":"Plasma Finance","symbol":"PPAY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x054d64b73d3d8a21af3d764efd76bcaa774f3bb2","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xfb288d60d3b66f9c3e231a9a39ed3f158a4269aa","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x08158a6b5d4018340387d1a302f882e98a8bc5b4","decimalCount":18}]},{"id":"standard-protocol","name":"Standard Protocol","symbol":"STND","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9040e237c3bf18347bb00957dc22167d0f2b999d","decimalCount":18}]},{"id":"leon-token","name":"Leonicorn LEON","symbol":"LEON","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x27e873bee690c8e161813de3566e9e18a64b0381","decimalCount":18}]},{"id":"matrix-ai-network","name":"Matrix AI Network","symbol":"MAN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe25bcec5d3801ce3a794079bf94adf1b8ccd802d","decimalCount":18}]},{"id":"bundles","name":"Bundles","symbol":"BUND","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8d3e855f3f55109d473735ab76f753218400fe96","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x9c1a3e3a69f83bdf98a51e4a552bbc2e479d45e7","decimalCount":18}]},{"id":"artem","name":"Artem","symbol":"ARTEM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9b83f827928abdf18cf1f7e67053572b9bceff3a","decimalCount":18}]},{"id":"panda-girl","name":"Panda Girl","symbol":"PGIRL","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x4c4da68d45f23e38ec8407272ee4f38f280263c0","decimalCount":6}]},{"id":"swapz-app","name":"SWAPZ.app","symbol":"SWAPZ","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xd522a1dce1ca4b138dda042a78672307eb124cc2","decimalCount":18}]},{"id":"projectx","name":"ProjectX","symbol":"XIL","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xf3be1a4a47576208c1592cc027087ce154b00672","decimalCount":18}]},{"id":"kollect","name":"Kollect","symbol":"KOL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1cc30e2eac975416060ec6fe682041408420d414","decimalCount":18}]},{"id":"yield-optimization-platform","name":"Yield Optimization Platform & Protocol","symbol":"YOP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xae1eaae3f627aaca434127644371b67b18444051","decimalCount":8}]},{"id":"revest-finance","name":"Revest Finance","symbol":"RVST","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x120a3879da835a5af037bb2d1456bebd6b54d4ba","decimalCount":18}]},{"id":"perion","name":"Perion","symbol":"PERC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x60be1e1fe41c1370adaf5d8e66f07cf1c2df2268","decimalCount":18}]},{"id":"pawthereum","name":"Pawthereum","symbol":"PAWTH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xaecc217a749c2405b5ebc9857a16d58bdc1c367f","decimalCount":9},{"networkId":"binance-smart-chain","contractAddress":"0x409e215738e31d8ab252016369c2dd9c2008fee0","decimalCount":9}]},{"id":"unipilot","name":"Unipilot","symbol":"PILOT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x37c997b35c619c21323f3518b9357914e8b99525","decimalCount":18}]},{"id":"unicly-mystic-axies-collection","name":"Unicly Mystic Axies Collection","symbol":"UAXIE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x68b1cadb8d5ab0c97fe9d9fbe0eb60acb329fe3f","decimalCount":18}]},{"id":"poodle","name":"Poodl Token","symbol":"POODL","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x4a68c250486a116dc8d6a0c5b0677de07cc09c5d","decimalCount":9}]},{"id":"dev-protocol","name":"Dev Protocol","symbol":"DEV","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5caf454ba92e6f2c929df14667ee360ed9fd5b26","decimalCount":18}]},{"id":"kaiba-defi","name":"Kaiba Defi","symbol":"KAIBA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf2210f65235c2fb391ab8650520237e6378e5c5a","decimalCount":9}]},{"id":"disbalancer","name":"disBalancer","symbol":"DDOS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7fbec0bb6a7152e77c30d005b5d49cbc08a602c3","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x7fbec0bb6a7152e77c30d005b5d49cbc08a602c3","decimalCount":18}]},{"id":"orion-money","name":"Orion Money","symbol":"ORION","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x727f064a78dc734d33eec18d5370aef32ffd46e4","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x3dcb18569425930954feb191122e574b87f66abd","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x5e0294af1732498c77f8db015a2d52a76298542b","decimalCount":18}]},{"id":"plant-vs-undead-token","name":"Plant vs Undead","symbol":"PVU","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x31471e0791fcdbe82fbf4c44943255e923f1b794","decimalCount":18}]},{"id":"relay-token","name":"Relay Chain","symbol":"RELAY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5d843fa9495d23de997c394296ac7b4d721e841c","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xe338d4250a4d959f88ff8789eaae8c32700bd175","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x78c42324016cd91d1827924711563fb66e33a83a","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x904371845bc56dcbbcf0225ef84a669b2fd6bd0d","decimalCount":18}]},{"id":"hybrix","name":"Hybrix","symbol":"HY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9b53e429b0badd98ef7f01f03702986c516a5715","decimalCount":18}]},{"id":"sentinel-group","name":"Sentinel [OLD]","symbol":"DVPN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa44e5137293e855b1b7bc7e2c6f8cd796ffcb037","decimalCount":8}]},{"id":"shard","name":"Shard Coin","symbol":"SHARD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbebdab6da046bc49ffbb61fbd7b33157eb270d05","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xd8a1734945b9ba38eb19a291b475e31f49e59877","decimalCount":18}]},{"id":"pist-trust","name":"Pist Trust","symbol":"PIST","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x315dc1b524de57ae8e809a2e97699dbc895b8a21","decimalCount":9}]},{"id":"the-crypto-prophecies","name":"The Crypto Prophecies","symbol":"TCP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x06576eb3b212d605b797dc15523d9dc9f4f66db4","decimalCount":18}]},{"id":"cornichon","name":"Cornichon","symbol":"CORN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa456b515303b2ce344e9d2601f91270f8c2fea5e","decimalCount":18}]},{"id":"xtoken","name":"xToken","symbol":"XTK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7f3edcdd180dbe4819bd98fee8929b5cedb3adeb","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0xf0a5717ec0883ee56438932b0fe4a20822735fba","decimalCount":18}]},{"id":"kondux","name":"Kondux","symbol":"KNDX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7ff7a55a7c637e3953ab25569c335e04b96c475b","decimalCount":9}]},{"id":"unit-protocol","name":"Unit Protocol","symbol":"COL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc76fb75950536d98fa62ea968e1d6b45ffea2a55","decimalCount":18}]},{"id":"meme-inu","name":"Meme Inu","symbol":"MEME","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x74b988156925937bd4e082f0ed7429da8eaea8db","decimalCount":18}]},{"id":"obortech","name":"Obortech","symbol":"OBOT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xedadeb5faa413e6c8623461849dfd0b7c3790c32","decimalCount":18}]},{"id":"tia","name":"TIA","symbol":"TIA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x824e35f7a75324f99300afac75ecf7354e17ea26","decimalCount":9}]},{"id":"uniqly","name":"Uniqly","symbol":"UNIQ","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3758e00b100876c854636ef8db61988931bb8025","decimalCount":18}]},{"id":"degis","name":"Degis","symbol":"DEG","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0x9f285507ea5b4f33822ca7abb5ec8953ce37a645","decimalCount":18}]},{"id":"unistake","name":"Unistake","symbol":"UNISTAKE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9ed8e7c9604790f7ec589f99b94361d8aab64e5e","decimalCount":18}]},{"id":"coinspaid","name":"CoinsPaid","symbol":"CPD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9b31bb425d8263fa1b8b9d090b83cf0c31665355","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x2406dce4da5ab125a18295f4fb9fd36a0f7879a2","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x1ce4a2c355f0dcc24e32a9af19f1836d6f4f98ae","decimalCount":18}]},{"id":"verox","name":"Verox","symbol":"VRX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x87de305311d5788e8da38d19bb427645b09cb4e5","decimalCount":18}]},{"id":"mars-ecosystem-token","name":"Mars Ecosystem","symbol":"XMS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x7859b01bbf675d67da8cd128a50d155cd881b576","decimalCount":18}]},{"id":"ruff","name":"Ruff","symbol":"RUFF","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf278c1ca969095ffddded020290cf8b5c424ace2","decimalCount":18}]},{"id":"wowswap","name":"WOWswap","symbol":"WOW","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3405a1bd46b85c5c029483fbecf2f3e611026e45","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x4da996c5fe84755c80e108cf96fe705174c5e36a","decimalCount":18},{"networkId":"avalanche","contractAddress":"0xa384bc7cdc0a93e686da9e7b8c0807cd040f4e0b","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x855d4248672a1fce482165e8dbe1207b94b1968a","decimalCount":18}]},{"id":"whiteheart","name":"Whiteheart","symbol":"WHITE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5f0e628b693018f639d10e4a4f59bd4d8b2b6b44","decimalCount":18}]},{"id":"asia-coin","name":"Asia Coin","symbol":"ASIA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf519381791c03dd7666c142d4e49fd94d3536011","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xebaffc2d2ea7c66fb848c48124b753f93a0a90ec","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x50bcbc40306230713239ae1bddd5eefeeaa273dc","decimalCount":18}]},{"id":"verso","name":"Verso","symbol":"VSO","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0x846d50248baf8b7ceaa9d9b53bfd12d7d7fbb25a","decimalCount":18}]},{"id":"chronobase","name":"ChronoBase","symbol":"TIK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0922f1d808adc3a4444bed2f73fac53a1a2a5859","decimalCount":18}]},{"id":"wild-credit","name":"Wild Credit","symbol":"WILD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x403d512ab96103562dcafe4635545e8ee2753f6e","decimalCount":18}]},{"id":"rewards-bunny","name":"Rewards Bunny","symbol":"RBUNNY","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x68848e1d1ffd7b38d103106c74220c1ad3494afc","decimalCount":18}]},{"id":"dapp-com","name":"Dapp.com","symbol":"DAPPT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x96184d9c811ea0624fc30c80233b1d749b9e485b","decimalCount":18}]},{"id":"baanx","name":"Baanx","symbol":"BXX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6b1a8f210ec6b7b6643cea3583fb0c079f367898","decimalCount":18}]},{"id":"graphlinq-protocol","name":"GraphLinq Protocol","symbol":"GLQ","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9f9c8ec3534c3ce16f928381372bfbfbfb9f4d24","decimalCount":18}]},{"id":"mettalex","name":"Mettalex","symbol":"MTLX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2e1e15c44ffe4df6a0cb7371cd00d5028e571d14","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x5921dee8556c4593eefcfad3ca5e2f618606483b","decimalCount":18}]},{"id":"flare-token","name":"Flare","symbol":"1FLR","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0x5f0197ba06860dac7e31258bdf749f92b6a636d4","decimalCount":18}]},{"id":"pussy-financial","name":"Pussy Financial","symbol":"PUSSY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9196e18bc349b1f64bc08784eae259525329a1ad","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xd9e8d20bde081600fac0d94b88eafaddce55aa43","decimalCount":18}]},{"id":"nitro-league","name":"Nitro League","symbol":"NITRO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0335a7610d817aeca1bebbefbd392ecc2ed587b8","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x695fc8b80f344411f34bdbcb4e621aa69ada384b","decimalCount":18}]},{"id":"apy-vision","name":"APY.vision","symbol":"VISION","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf406f7a9046793267bc276908778b29563323996","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x034b2090b579228482520c589dbd397c53fc51cc","decimalCount":18}]},{"id":"decentraweb","name":"DecentraWeb","symbol":"DWEB","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe7f58a92476056627f9fdb92286778abd83b285f","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x8839e639f210b80ffea73aedf51baed8dac04499","decimalCount":18}]},{"id":"unifarm","name":"UniFarm","symbol":"UFARM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x40986a85b4cfcdb054a6cbfb1210194fee51af88","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x0a356f512f6fce740111ee04ab1699017a908680","decimalCount":18},{"networkId":"avalanche","contractAddress":"0xd60effed653f3f1b69047f2d2dc4e808a548767b","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xa7305ae84519ff8be02484cda45834c4e7d13dd6","decimalCount":18}]},{"id":"sekuritance","name":"Sekuritance","symbol":"SKRT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x887168120cb89fb06f3e74dc4af20d67df0977f6","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xe51e88dd08499762b8e4eb3a9f3da9b8e79608c3","decimalCount":18}]},{"id":"waultswap","name":"WaultSwap","symbol":"WEX","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xa9c41a46a6b3531d28d5c32f6633dd2ff05dfb90","decimalCount":18}]},{"id":"kambria","name":"Kambria","symbol":"KAT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x14da230d6726c50f759bc1838717f8ce6373509c","decimalCount":18}]},{"id":"newdex-token","name":"Newdex Token","symbol":"DEX","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x996f56299a5b7c4f825a44886e07dafc4660b794","decimalCount":8}]},{"id":"puli-inu","name":"Puli","symbol":"PULI","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xaef0a177c8c329cbc8508292bb7e06c00786bbfc","decimalCount":9}]},{"id":"ucash","name":"U.CASH","symbol":"UCASH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x92e52a1a235d9a103d970901066ce910aacefd37","decimalCount":8}]},{"id":"kiwigo","name":"Kiwigo","symbol":"KGO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x5d3afba1924ad748776e4ca62213bf7acf39d773","decimalCount":5}]},{"id":"swarm-markets","name":"Swarm Markets","symbol":"SMT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb17548c7b510427baac4e267bea62e800b247173","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xe631dabef60c37a37d70d3b4f812871df663226f","decimalCount":18}]},{"id":"cindicator","name":"Cindicator","symbol":"CND","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd4c435f5b09f855c3317c8524cb1f586e42795fa","decimalCount":18}]},{"id":"coinmerge-bsc","name":"CoinMerge (BEP20)","symbol":"CMERGE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x8d3e3a57c5f140b5f9feb0d43d37a347ee01c851","decimalCount":9}]},{"id":"carvertical","name":"carVertical","symbol":"CV","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x50bc2ecc0bfdf5666640048038c1aba7b7525683","decimalCount":18}]},{"id":"solape-token","name":"SOLAPE","symbol":"SOLAPE","active":true,"networks":[{"networkId":"solana","contractAddress":"GHvFFSZ9BctWsEc5nujR1MTmmJWY7tgQz2AXE6WVFtGN","decimalCount":9}]},{"id":"coinxpad","name":"CoinxPad","symbol":"CXPAD","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xe90d1567ecef9282cc1ab348d9e9e2ac95659b99","decimalCount":18}]},{"id":"egretia","name":"Egretia","symbol":"EGT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8e1b448ec7adfc7fa35fc2e885678bd323176e34","decimalCount":18}]},{"id":"gridzone","name":"GridZone.io","symbol":"ZONE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc1d9b5a0776d7c8b98b8a838e5a0dd1bc5fdd53c","decimalCount":18}]},{"id":"ulti-arena","name":"Ulti Arena","symbol":"ULTI","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x42bfe4a3e023f2c90aebffbd9b667599fa38514f","decimalCount":18}]},{"id":"elvantis","name":"Elvantis","symbol":"ELV","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4734baf528766ec4c420a6c13f8dba7bb1920181","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xe942c48044fb1c7f4c9eb456f6097fa4a1a17b8f","decimalCount":18}]},{"id":"ari10","name":"Ari10","symbol":"ARI10","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x80262f604acac839724f66846f290a2cc8b48662","decimalCount":18}]},{"id":"veriblock","name":"VeriBlock","symbol":"VBK","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xd347deffbb2e750c752b2d4aa5c26fd57ab90d64","decimalCount":18}]},{"id":"dexkit","name":"DexKit","symbol":"KIT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7866e48c74cbfb8183cd1a929cd9b95a7a5cb4f4","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x314593fa9a2fa16432913dbccc96104541d32d11","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x4d0def42cf57d6f27cd4983042a55dce1c9f853c","decimalCount":18}]},{"id":"unitrade","name":"Unitrade","symbol":"TRADE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6f87d756daf0503d08eb8993686c7fc01dc44fb1","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x7af173f350d916358af3e218bdf2178494beb748","decimalCount":18}]},{"id":"chainium","name":"WeOwn","symbol":"CHX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1460a58096d80a50a2f1f956dda497611fa4f165","decimalCount":18}]},{"id":"prcy-coin","name":"PRivaCY Coin","symbol":"PRCY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdfc3829b127761a3218bfcee7fc92e1232c9d116","decimalCount":8},{"networkId":"binance-smart-chain","contractAddress":"0xdfc3829b127761a3218bfcee7fc92e1232c9d116","decimalCount":8},{"networkId":"polygon-pos","contractAddress":"0xdfc3829b127761a3218bfcee7fc92e1232c9d116","decimalCount":8}]},{"id":"swag-finance","name":"SWAG Finance","symbol":"SWAG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x87edffde3e14c7a66c9b9724747a1c5696b742e6","decimalCount":18}]},{"id":"oin-finance","name":"OIN Finance","symbol":"OIN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9aeb50f542050172359a0e1a25a9933bc8c01259","decimalCount":8},{"networkId":"binance-smart-chain","contractAddress":"0x658e64ffcf40d240a43d52ca9342140316ae44fa","decimalCount":8}]},{"id":"doubloon","name":"Doubloon","symbol":"DBL","active":true,"networks":[{"networkId":"arbitrum-one","contractAddress":"0xd3f1da62cafb7e7bc6531ff1cef6f414291f03d3","decimalCount":18}]},{"id":"statera","name":"Statera","symbol":"STA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa7de087329bfcda5639247f96140f9dabe3deed1","decimalCount":18},{"networkId":"fantom","contractAddress":"0x89d5e71e275b4be094df9551627bcf4e3b24ce22","decimalCount":18}]},{"id":"eve-exchange","name":"EVE","symbol":"EVE","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0xae29ac47a9e3b0a52840e547adf74b912999f7fc","decimalCount":18}]},{"id":"thx-network","name":"THX Network","symbol":"THX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe632ea2ef2cfd8fc4a2731c76f99078aef6a4b31","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x2934b36ca9a4b31e633c5be670c8c8b28b6aa015","decimalCount":18}]},{"id":"hiveterminal","name":"Hiveterminal token","symbol":"HVN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc0eb85285d83217cd7c891702bcbc0fc401e2d9d","decimalCount":8}]},{"id":"humandao","name":"humanDAO","symbol":"HDAO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdac657ffd44a3b9d8aba8749830bf14beb66ff2d","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x72928d5436ff65e57f72d5566dcd3baedc649a88","decimalCount":18}]},{"id":"b20","name":"B20","symbol":"B20","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc4de189abf94c57f396bd4c52ab13b954febefd8","decimalCount":18}]},{"id":"raven-protocol","name":"Raven Protocol","symbol":"RAVEN","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xcd7c5025753a49f1881b31c48caa7c517bb46308","decimalCount":18},{"networkId":"binancecoin","contractAddress":"RAVEN-F66","decimalCount":8}]},{"id":"peri-finance","name":"PERI Finance","symbol":"PERI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5d30ad9c6374bf925d0a75454fa327aacf778492","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xb49b7e0742ecb4240ffe91661d2a580677460b6a","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xdc0e17eae3b9651875030244b971fa0223a1764f","decimalCount":18}]},{"id":"unfederalreserve","name":"unFederalReserve","symbol":"ERSDL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5218e472cfcfe0b64a064f055b43b4cdc9efd3a6","decimalCount":18}]},{"id":"cryptocart","name":"CryptoCart V2","symbol":"CCV2","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x612e1726435fe38dd49a0b35b4065b56f49c8f11","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x612e1726435fe38dd49a0b35b4065b56f49c8f11","decimalCount":18}]},{"id":"catapult","name":"Catapult","symbol":"ATD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8052327f1baf94a9dc8b26b9100f211ee3774f54","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x1ce440d1a64eea6aa1db2a5aa51c9b326930957c","decimalCount":18}]},{"id":"ubxs-token","name":"UBXS","symbol":"UBXS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x4f1960e29b2ca581a38c5c474e123f420f8092db","decimalCount":6}]},{"id":"vibe","name":"VIBE","symbol":"VIBE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe8ff5c9c75deb346acac493c463c8950be03dfba","decimalCount":18}]},{"id":"nodeseeds","name":"Nodeseeds","symbol":"NDS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x747f564d258612ec5c4e24742c5fd4110bcbe46b","decimalCount":18}]},{"id":"autonio","name":"Autonio","symbol":"NIOX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc813ea5e3b48bebeedb796ab42a30c5599b01740","decimalCount":4},{"networkId":"polygon-pos","contractAddress":"0xad684e79ce4b6d464f2ff7c3fd51646892e24b96","decimalCount":4}]},{"id":"aircoins","name":"Aircoins","symbol":"AIRX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8cb1d155a5a1d5d667611b7710920fd9d1cd727f","decimalCount":8},{"networkId":"binance-smart-chain","contractAddress":"0x6fb05b156788e88c8ad1e057e729362ff8c39d93","decimalCount":8}]},{"id":"mirrored-ishares-silver-trust","name":"Mirrored iShares Silver Trust","symbol":"MSLV","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9d1555d8cb3c846bb4f7d5b1b1080872c3166676","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x211e763d0b9311c08ec92d72ddc20ab024b6572a","decimalCount":18}]},{"id":"the-parallel","name":"The Parallel","symbol":"PRL","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xd07e82440a395f3f3551b42da9210cd1ef4f8b24","decimalCount":18}]},{"id":"paypolitan-token","name":"Paypolitan Token","symbol":"EPAN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x72630b1e3b42874bf335020ba0249e3e9e47bafc","decimalCount":18}]},{"id":"cryptoids-admin-coin","name":"Cryptoids Admin Coin","symbol":"CAC","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x5b7d8a53e63f1817b68d40dc997cb7394db0ff1a","decimalCount":18}]},{"id":"mch-coin","name":"MCH Coin","symbol":"MCHC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd69f306549e9d96f183b1aeca30b8f4353c2ecc3","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xee7666aacaefaa6efeef62ea40176d3eb21953b9","decimalCount":18}]},{"id":"swapfolio","name":"Swapfolio","symbol":"SWFL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xba21ef4c9f433ede00badefcc2754b8e74bd538a","decimalCount":18}]},{"id":"herocoin","name":"HEROcoin","symbol":"PLAY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe477292f1b3268687a29376116b0ed27a9c76170","decimalCount":18}]},{"id":"scalara-nft-index","name":"Scalara NFT Index","symbol":"NFTI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x525ef76138bf76118d786dbedeae5f87aabf4a81","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xc75ea0c71023c14952f3c7b9101ecbbaa14aa27a","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0xcfe3fbc98d80f7eca0bc76cd1f406a19dd425896","decimalCount":18}]},{"id":"polylastic","name":"Polylastic","symbol":"POLX","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0x187ae45f2d361cbce37c6a8622119c91148f261b","decimalCount":18}]},{"id":"unicly-fewocious-collection","name":"Unicly Fewocious Collection","symbol":"UFEWO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xcccf837f40d334f8602f031e64b52ad4cd2b6601","decimalCount":18}]},{"id":"soldex","name":"Soldex","symbol":"SOLX","active":true,"networks":[{"networkId":"solana","contractAddress":"CH74tuRLTYcxG7qNJCsV9rghfLXJCQJbsu7i52a8F1Gn","decimalCount":9}]},{"id":"somee-social-old","name":"SoMee.Social [OLD]","symbol":"ONG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd341d1680eeee3255b8c4c75bcce7eb57f144dae","decimalCount":18}]},{"id":"moonstarter","name":"MoonStarter","symbol":"MNST","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x6a6ccf15b38da4b5b0ef4c8fe9fefcb472a893f9","decimalCount":18}]},{"id":"fastswap-bsc","name":"Fastswap (BSC)","symbol":"FAST","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x2322afaac81697e770c19a58df587d8739777536","decimalCount":18}]},{"id":"wasabix","name":"WasabiX","symbol":"WASABI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x896e145568624a498c5a909187363ae947631503","decimalCount":18}]},{"id":"piedao-balanced-crypto-pie","name":"PieDAO Balanced Crypto Pie","symbol":"BCP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe4f726adc8e89c6a6017f01eada77865db22da14","decimalCount":18},{"networkId":"fantom","contractAddress":"0x9611579c926294b0e29e5371a81a3e463650be17","decimalCount":18}]},{"id":"savage","name":"SAVAGE","symbol":"SAVG","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0x981aecc6eb4d382b96a02b75e931900705e95a31","decimalCount":18}]},{"id":"hakka-finance","name":"Hakka Finance","symbol":"HAKKA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0e29e5abbb5fd88e28b2d355774e73bd47de3bcd","decimalCount":18}]},{"id":"ethermon","name":"Ethermon","symbol":"EMON","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd6a5ab46ead26f49b03bbb1f9eb1ad5c1767974a","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xd6a5ab46ead26f49b03bbb1f9eb1ad5c1767974a","decimalCount":18}]},{"id":"treatdao-v2","name":"TreatDAO","symbol":"TREAT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x01bd7acb6ff3b6dd5aefa05cf085f2104f3fc53f","decimalCount":18}]},{"id":"roge","name":"Rogue Doge","symbol":"ROGE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x45734927fa2f616fbe19e65f42a0ef3d37d1c80a","decimalCount":9}]},{"id":"coinmerge","name":"CoinMerge (ERC20)","symbol":"CMERGE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc48b4814faed1ccc885dd6fde62a6474aecbb19a","decimalCount":9}]},{"id":"moonedge","name":"MoonEdge","symbol":"MOONED","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0x7e4c577ca35913af564ee2a24d882a4946ec492b","decimalCount":18}]},{"id":"beholder","name":"Behodler","symbol":"EYE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x155ff1a85f440ee0a382ea949f24ce4e0b751c65","decimalCount":18}]},{"id":"sheesha-finance-polygon","name":"Sheesha Finance Polygon","symbol":"MSHEESHA","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0x88c949b4eb85a90071f2c0bef861bddee1a7479d","decimalCount":18}]},{"id":"neumark","name":"Neumark","symbol":"NEU","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa823e6722006afe99e91c30ff5295052fe6b8e32","decimalCount":18}]},{"id":"defi-warrior","name":"Defi Warrior","symbol":"FIWA","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x633237c6fa30fae46cc5bb22014da30e50a718cc","decimalCount":18}]},{"id":"bankless-defi-innovation-index","name":"Bankless DeFi Innovation Index","symbol":"GMI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x47110d43175f7f2c2425e7d15792acc5817eb44f","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x7fb27ee135db455de5ab1ccec66a24cbc82e712d","decimalCount":18}]},{"id":"gogocoin","name":"GOGOcoin","symbol":"GOGO","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0xdd2af2e723547088d3846841fbdcc6a8093313d6","decimalCount":18}]},{"id":"ethpad","name":"ETHPad","symbol":"ETHPAD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8db1d28ee0d822367af8d220c0dc7cb6fe9dc442","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x8db1d28ee0d822367af8d220c0dc7cb6fe9dc442","decimalCount":18}]},{"id":"en-tan-mo","name":"En-Tan-Mo","symbol":"ETM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6020da0f7c1857dbe4431ec92a15cc318d933eaa","decimalCount":18}]},{"id":"geyser","name":"Geyser","symbol":"GYSR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbea98c05eeae2f3bc8c3565db7551eb738c8ccab","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xc48f61a288a08f1b80c2edd74652e1276b6a168c","decimalCount":18}]},{"id":"ionchain-token","name":"IONChain","symbol":"IONC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbc647aad10114b89564c0a7aabe542bd0cf2c5af","decimalCount":18}]},{"id":"chads-vc","name":"CHADS VC","symbol":"CHADS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x69692d3345010a207b759a7d1af6fc7f38b35c5e","decimalCount":18}]},{"id":"metastrike","name":"Metastrike","symbol":"MTS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x496cc0b4ee12aa2ac4c42e93067484e7ff50294b","decimalCount":18}]},{"id":"unicly-aavegotchi-astronauts-collection","name":"Unicly Aavegotchi Astronauts Collection","symbol":"UGOTCHI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x30c2a84aed6db30e31cf4d7059b1836c12c68068","decimalCount":18}]},{"id":"nearpad","name":"NearPad","symbol":"PAD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xea7cc765ebc94c4805e3bff28d7e4ae48d06468a","decimalCount":18}]},{"id":"katana-inu","name":"Katana Inu","symbol":"KATA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2e85ae1c47602f7927bcabc2ff99c40aa222ae15","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x6d6ba21e4c4b29ca7bfa1c344ba1e35b8dae7205","decimalCount":18}]},{"id":"bsc-station","name":"BSC Station","symbol":"BSCS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xbcb24afb019be7e93ea9c43b7e22bb55d5b7f45d","decimalCount":18}]},{"id":"humaniq","name":"Humaniq","symbol":"HMQ","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xcbcc0f036ed4788f63fc0fee32873d6a7487b908","decimalCount":8}]},{"id":"meme-lordz","name":"Meme Lordz","symbol":"$LORDZ","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x2541be91fe0d220ffcbe65f11d88217a87a43bda","decimalCount":9}]},{"id":"zenfuse","name":"Zenfuse","symbol":"ZEFU","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb1e9157c2fdcc5a856c8da8b2d89b6c32b3c1229","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x23ec58e45ac5313bcb6681f4f7827b8a8453ac45","decimalCount":18}]},{"id":"ftribe-fighters","name":"Ftribe Fighters","symbol":"F2C","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x657b632714e08ac66b79444ad3f3875526ee6689","decimalCount":18}]},{"id":"freerossdao","name":"FreeRossDAO","symbol":"FREE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4cd0c43b0d53bc318cc5342b77eb6f124e47f526","decimalCount":18}]},{"id":"pulsepad","name":"PulsePad","symbol":"PLSPAD","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x8a74bc8c372bc7f0e9ca3f6ac0df51be15aec47a","decimalCount":18}]},{"id":"portion","name":"Portion","symbol":"PRT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6d0f5149c502faf215c89ab306ec3e50b15e2892","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xaf00aac2431b04ef6afd904d19b08d5146e3a9a0","decimalCount":18}]},{"id":"silva-token","name":"Silva","symbol":"SILVA","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x68b5edb385b59e30a7a7db1e681a449e94df0213","decimalCount":9}]},{"id":"museum-of-crypto-art","name":"Museum of Crypto Art","symbol":"MOCA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9ac07635ddbde5db18648c360defb00f5f22537e","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xce899f26928a2b21c6a2fddd393ef37c61dba918","decimalCount":18}]},{"id":"pontoon","name":"Pontoon","symbol":"TOON","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xaee433adebe0fbb88daa47ef0c1a513caa52ef02","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xaee433adebe0fbb88daa47ef0c1a513caa52ef02","decimalCount":18}]},{"id":"dogecola","name":"DogeCola","symbol":"DOGECOLA","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xe320df552e78d57e95cf1182b6960746d5016561","decimalCount":9}]},{"id":"odyssey","name":"Odyssey","symbol":"OCN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4092678e4e78230f46a1534c0fbc8fa39780892b","decimalCount":18}]},{"id":"polytrade","name":"Polytrade","symbol":"TRADE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6e5970dbd6fc7eb1f29c6d2edf2bc4c36124c0c1","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x6ba7a8f9063c712c1c8cabc776b1da7126805f3b","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x692ac1e363ae34b6b489148152b12e2785a3d8d6","decimalCount":18}]},{"id":"terablock","name":"TeraBlock","symbol":"TBC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9798df2f5d213a872c787bd03b2b91f54d0d04a1","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x9798df2f5d213a872c787bd03b2b91f54d0d04a1","decimalCount":18}]},{"id":"formation-fi","name":"Formation FI","symbol":"FORM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x21381e026ad6d8266244f2a583b35f9e4413fa2a","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x25a528af62e56512a19ce8c3cab427807c28cc19","decimalCount":18}]},{"id":"rendoge","name":"renDOGE","symbol":"RENDOGE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3832d2f059e55934220881f831be501d180671a7","decimalCount":8},{"networkId":"polygon-pos","contractAddress":"0xce829a89d4a55a63418bcc43f00145adef0edb8e","decimalCount":8}]},{"id":"utu-coin","name":"UTU Coin","symbol":"UTU","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa58a4f5c4bb043d2cc1e170613b74e767c94189b","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xed4bb33f20f32e989af975196e86019773a7cff0","decimalCount":18}]},{"id":"prosper","name":"Prosper","symbol":"PROS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8642a849d0dcb7a15a974794668adcfbe4794b56","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xed8c8aa8299c10f067496bb66f8cc7fb338a3405","decimalCount":18}]},{"id":"eddaswap","name":"EDDASwap","symbol":"EDDA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfbbe9b1142c699512545f47937ee6fae0e4b0aa9","decimalCount":18}]},{"id":"sirin-labs-token","name":"Sirin Labs Token","symbol":"SRN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x68d57c9a1c35f63e2c83ee8e49a64e9d70528d25","decimalCount":18}]},{"id":"dragon-kart-token","name":"Dragon Kart","symbol":"KART","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x8bdd8dbcbdf0c066ca5f3286d33673aa7a553c10","decimalCount":18}]},{"id":"anrkey-x","name":"AnRKey X","symbol":"$ANRX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xcae72a7a0fd9046cf6b165ca54c9e3a3872109e0","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xe2e7329499e8ddb1f2b04ee4b35a8d7f6881e4ea","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x554f074d9ccda8f483d1812d4874cbebd682644e","decimalCount":18}]},{"id":"impactmarket","name":"impactMarket","symbol":"PACT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xee9d08840554c9f8d30d0e3833d4906d3f39a49e","decimalCount":18}]},{"id":"coin","name":"Coin","symbol":"COIN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe61fdaf474fac07063f2234fb9e60c1163cfa850","decimalCount":18}]},{"id":"potentiam","name":"Potentiam","symbol":"PTM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7c32db0645a259fae61353c1f891151a2e7f8c1e","decimalCount":18}]},{"id":"total-crypto-market-cap-token","name":"Total Crypto Market Cap","symbol":"TCAP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x16c52ceece2ed57dad87319d91b5e3637d50afa4","decimalCount":18}]},{"id":"vegawallet-token","name":"VegaWallet Token","symbol":"VGW","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x94236591125e935f5ac128bb3d5062944c24958c","decimalCount":5}]},{"id":"kampay","name":"Kampay","symbol":"KAMPAY","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x8e984e03ab35795c60242c902ece2450242c90e9","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x39fc9e94caeacb435842fadedecb783589f50f5f","decimalCount":18}]},{"id":"velhalla","name":"Velhalla","symbol":"SCAR","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x8d9fb713587174ee97e91866050c383b5cee6209","decimalCount":18}]},{"id":"bitlocus","name":"Bitlocus","symbol":"BTL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x93e32efafd24973d45f363a76d73ccb9edf59986","decimalCount":6},{"networkId":"binance-smart-chain","contractAddress":"0x51e7b598c9155b9dccb04eb42519f6eec9c841e9","decimalCount":6}]},{"id":"somee-social","name":"SoMee.Social","symbol":"SOMEE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x65f9a292f1aeed5d755aa2fd2fb17ab2e9431447","decimalCount":18}]},{"id":"xp-network","name":"XP Network","symbol":"XPNET","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x8cf8238abf7b933bf8bb5ea2c7e4be101c11de2a","decimalCount":18}]},{"id":"unique-utility-token","name":"Unique Utility","symbol":"UNQT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa80f2c8f61c56546001f5fc2eb8d6e4e72c45d4c","decimalCount":18}]},{"id":"shuey-rhon-inu","name":"Shuey Rhon Inu","symbol":"SHUEY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xcdca1b81dbb543baa92c97b701396cd3ba315e5d","decimalCount":18}]},{"id":"wepower","name":"WePower","symbol":"WPR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4cf488387f035ff08c371515562cba712f9015d4","decimalCount":18}]},{"id":"legolas-exchange","name":"LGO Token","symbol":"LGO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0a50c93c762fdd6e56d86215c24aaad43ab629aa","decimalCount":8}]},{"id":"topbidder","name":"TopBidder","symbol":"BID","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x00000000000045166c45af0fc6e4cf31d9e14b9a","decimalCount":18}]},{"id":"lendingblock","name":"Lendingblock","symbol":"LND","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0947b0e6d821378805c9598291385ce7c791a6b2","decimalCount":18}]},{"id":"cofix","name":"CoFiX","symbol":"COFI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1a23a6bfbadb59fa563008c0fb7cf96dfcf34ea1","decimalCount":18}]},{"id":"unifi","name":"Covenants","symbol":"UNIFI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9e78b8274e1d6a76a0dbbf90418894df27cbceb5","decimalCount":18}]},{"id":"golden-doge","name":"Golden Doge","symbol":"GDOGE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xa53e61578ff54f1ad70186be99332a6e20b6ffa9","decimalCount":9}]},{"id":"moonscape","name":"Moonscape","symbol":"MSCP","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x27d72484f1910f5d0226afa4e03742c9cd2b297a","decimalCount":18}]},{"id":"treatdao","name":"TreatDAO [OLD]","symbol":"TREAT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xac0c7d9b063ed2c0946982ddb378e03886c064e6","decimalCount":18}]},{"id":"coreto","name":"Coreto","symbol":"COR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9c2dc0c3cc2badde84b0025cf4df1c5af288d835","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xa4b6573c9ae09d81e4d1360e6402b81f52557098","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x4fdce518fe527439fe76883e6b51a1c522b61b7c","decimalCount":18}]},{"id":"anji","name":"Anji","symbol":"ANJI","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xfc619ffcc0e0f30427bf938f9a1b2bfae15bdf84","decimalCount":9}]},{"id":"nanobyte","name":"NanoByte","symbol":"NBT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x1d3437e570e93581bd94b2fd8fbf202d4a65654a","decimalCount":18}]},{"id":"etna-network","name":"ETNA Network","symbol":"ETNA","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x51f35073ff7cf54c9e86b7042e59a8cc9709fc46","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x015c425f6dfabc31e1464cc4339954339f096061","decimalCount":18}]},{"id":"sarcophagus","name":"Sarcophagus","symbol":"SARCO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7697b462a7c4ff5f8b55bdbc2f4076c2af9cf51a","decimalCount":18}]},{"id":"footballstars","name":"FootballStars","symbol":"FTS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x6507458bb53aec6be863161641ec28739c41cc97","decimalCount":18}]},{"id":"milk","name":"Cool Cats Milk","symbol":"MILK","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0x1599fe55cda767b1f631ee7d414b41f5d6de393d","decimalCount":18}]},{"id":"polkawar","name":"PolkaWar","symbol":"PWAR","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x16153214e683018d5aa318864c8e692b66e16778","decimalCount":18}]},{"id":"husky-avax","name":"Husky AVAX","symbol":"HUSKY","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x52d88a9a2a20a840d7a336d21e427e9ad093deea","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x65378b697853568da9ff8eab60c13e1ee9f4a654","decimalCount":18}]},{"id":"digix-gold","name":"Digix Gold","symbol":"DGX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4f3afec4e5a3f2a6a1a411def7d7dfe50ee057bf","decimalCount":9}]},{"id":"hydro-protocol","name":"Hydro Protocol","symbol":"HOT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9af839687f6c94542ac5ece2e317daae355493a1","decimalCount":18}]},{"id":"invest-like-stakeborg-index","name":"Invest Like Stakeborg Index","symbol":"ILSI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0acc0fee1d86d2cd5af372615bf59b298d50cd69","decimalCount":18}]},{"id":"potcoin","name":"Potcoin","symbol":"POT","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0xd7c8469c7ec40f853da5f651de81b45aed47e5ab","decimalCount":18}]},{"id":"shih-tzu","name":"Shih Tzu","symbol":"SHIH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x841fb148863454a3b3570f515414759be9091465","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x1e8150ea46e2a7fbb795459198fbb4b35715196c","decimalCount":18}]},{"id":"onx-finance","name":"OnX Finance","symbol":"ONX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe0ad1806fd3e7edf6ff52fdb822432e847411033","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x3d8f74620857dd8ed6d0da02ceb13fd0ed8ba678","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xeb94a5e2c643403e29fa1d7197e7e0708b09ad84","decimalCount":18},{"networkId":"fantom","contractAddress":"0x27749e79ad796c4251e0a0564aef45235493a0b6","decimalCount":18}]},{"id":"ally-direct","name":"Ally Direct","symbol":"DRCT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9d561d63375672abd02119b9bc4fb90eb9e307ca","decimalCount":18}]},{"id":"stream-protocol","name":"Stream Protocol","symbol":"STPL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9b5c2be869a19e84bdbcb1386dad83a2ec8dae82","decimalCount":18}]},{"id":"skull","name":"Skull","symbol":"SKULL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbcc66ed2ab491e9ae7bf8386541fb17421fa9d35","decimalCount":4}]},{"id":"energyfi","name":"Energyfi","symbol":"EFT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xae98e63db1c4646bf5b40b29c664bc922f71bc65","decimalCount":18}]},{"id":"bullieverse","name":"Bullieverse","symbol":"BULL","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0x9f95e17b2668afe01f8fbd157068b0a4405cc08d","decimalCount":18}]},{"id":"beach-token-bsc","name":"Beach BSC","symbol":"BEACH","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x1a57dc4e3bc63b06c2b263774859f227b99ab031","decimalCount":9}]},{"id":"fairgame","name":"FairGame","symbol":"FAIR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9b20dabcec77f6289113e61893f7beefaeb1990a","decimalCount":18}]},{"id":"zuki-moba","name":"Zuki Moba","symbol":"ZUKI","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xe81257d932280ae440b17afc5f07c8a110d21432","decimalCount":18}]},{"id":"arth","name":"ARTH","symbol":"ARTH","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0xe52509181feb30eb4979e29ec70d50fd5c44d590","decimalCount":18}]},{"id":"swerve-dao","name":"Swerve","symbol":"SWRV","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb8baa0e4287890a5f79863ab62b7f175cecbd433","decimalCount":18}]},{"id":"dav","name":"DAV Network","symbol":"DAV","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd82df0abd3f51425eb15ef7580fda55727875f14","decimalCount":18}]},{"id":"cover-protocol","name":"Cover Protocol","symbol":"COVER","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4688a8b1f292fdab17e9a90c8bc379dc1dbd8713","decimalCount":18},{"networkId":"fantom","contractAddress":"0xb01e8419d842beebf1b70a7b5f7142abbaf7159d","decimalCount":18}]},{"id":"superlauncher-dao","name":"SuperLauncher DAO","symbol":"LAUNCH","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xb5389a679151c4b8621b1098c6e0961a3cfee8d4","decimalCount":18}]},{"id":"leonicorn-swap","name":"Leonicorn Swap","symbol":"LEOS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x2c8368f8f474ed9af49b87eac77061beb986c2f1","decimalCount":8}]},{"id":"carbon","name":"Carbon","symbol":"CRBN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xcdeee767bed58c5325f68500115d4b722b3724ee","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x5a4fb10e7c4cbb9a2b9d9a942f9a875ebd3489ea","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x89ef0900b0a6b5548ab2ff58ef588f9433b5fcf5","decimalCount":18}]},{"id":"spaceswap-milk2","name":"Spaceswap MILK2","symbol":"MILK2","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x80c8c3dcfb854f9542567c8dac3f44d709ebc1de","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x4a5a34212404f30c5ab7eb61b078fa4a55adc5a5","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x721c299e6bf7d6a430d9bea3364ea197314bce09","decimalCount":18}]},{"id":"purefi","name":"PureFi","symbol":"UFI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xcda4e840411c00a614ad9205caec807c7458a0e3","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xe2a59d5e33c6540e18aaa46bf98917ac3158db0d","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x3c205c8b3e02421da82064646788c82f7bd753b9","decimalCount":18}]},{"id":"spice-finance","name":"SPICE","symbol":"SPICE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1fdab294eda5112b7d066ed8f2e4e562d5bcc664","decimalCount":18}]},{"id":"helmet-insure","name":"Helmet Insure","symbol":"HELMET","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x948d2a81086a075b3130bac19e4c6dee1d2e3fe8","decimalCount":18}]},{"id":"luxfi","name":"LuxFi","symbol":"LXF","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa799c4adcf62e025ce4d8abe6a77cebc487d772a","decimalCount":18}]},{"id":"clintex-cti","name":"ClinTex CTi","symbol":"CTI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8c18d6a985ef69744b9d57248a45c0861874f244","decimalCount":18}]},{"id":"atn","name":"ATN","symbol":"ATN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x461733c17b0755ca5649b6db08b3e213fcf22546","decimalCount":18}]},{"id":"fsw-token","name":"Falconswap","symbol":"FSW","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfffffffff15abf397da76f1dcc1a1604f45126db","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xad5dc12e88c6534eea8cfe2265851d9d4a1472ad","decimalCount":18}]},{"id":"inmediate","name":"Direct Insurance Token","symbol":"DIT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf14922001a2fb8541a433905437ae954419c2439","decimalCount":8}]},{"id":"quiverx","name":"QuiverX","symbol":"QRX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6e0dade58d2d89ebbe7afc384e3e4f15b70b14d8","decimalCount":18}]},{"id":"dinoswap","name":"DinoSwap","symbol":"DINO","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0xaa9654becca45b5bdfa5ac646c939c62b527d394","decimalCount":18}]},{"id":"stone-token","name":"Stone Token","symbol":"STN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe63d6b308bce0f6193aec6b7e6eba005f41e36ab","decimalCount":18},{"networkId":"fantom","contractAddress":"0xfa9343c3897324496a05fc75abed6bac29f8a40f","decimalCount":18}]},{"id":"tryhards","name":"TryHards","symbol":"TRY","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x75d107de2217ffe2cd574a1b3297c70c8fafd159","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xefee2de82343be622dcb4e545f75a3b9f50c272d","decimalCount":18}]},{"id":"penguin-finance","name":"Penguin Finance","symbol":"PEFI","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0xe896cdeaac9615145c0ca09c8cd5c25bced6384c","decimalCount":18}]},{"id":"bright-union","name":"Bright Union","symbol":"BRIGHT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbeab712832112bd7664226db7cd025b153d3af55","decimalCount":18}]},{"id":"fortressdao","name":"Fortress","symbol":"FORT","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0xf6d46849db378ae01d93732585bec2c4480d1fd5","decimalCount":9}]},{"id":"genesis-vision","name":"Genesis Vision","symbol":"GVT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x103c3a209da59d3e7c4a89307e66521e081cfdf0","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xf25868b9e9c62f12192650ac668a2aa69f965f44","decimalCount":18}]},{"id":"tastenft","name":"TasteNFT","symbol":"TASTE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xdb238123939637d65a03e4b2b485650b4f9d91cb","decimalCount":9}]},{"id":"tripcandy","name":"TripCandy","symbol":"CANDY","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x639ad7c49ec616a64e074c21a58608c0d843a8a3","decimalCount":18}]},{"id":"swarm","name":"Swarm Network","symbol":"SWM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3505f494c3f0fed0b594e01fa41dd3967645ca39","decimalCount":18}]},{"id":"raze-network","name":"Raze Network","symbol":"RAZE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5eaa69b29f99c84fe5de8200340b4e9b4ab38eac","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x65e66a61d0a8f1e686c2d6083ad611a10d84d97a","decimalCount":18}]},{"id":"nextexchange","name":"NEXT","symbol":"NEXT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x377d552914e7a104bc22b4f3b6268ddc69615be7","decimalCount":18}]},{"id":"portify","name":"Portify","symbol":"PFY","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x69083b64988933e8b4783e8302b9bbf90163280e","decimalCount":9}]},{"id":"pocket-arena","name":"Pocket Arena","symbol":"POC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x095cf7f3e82a1dcadbf0fbc59023f419883ea296","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x1b6609830c695f1c0692123bd2fd6d01f6794b98","decimalCount":18}]},{"id":"seen","name":"SEEN","symbol":"SEEN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xca3fe04c7ee111f0bbb02c328c699226acf9fd33","decimalCount":18}]},{"id":"playnity","name":"PlayNity","symbol":"PLY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x20d60c6eb195868d4643f2c9b0809e4de6cc003d","decimalCount":6},{"networkId":"binance-smart-chain","contractAddress":"0x5f39dd1bb6db20f3e792c4489f514794cac6392c","decimalCount":6}]},{"id":"night-life-crypto","name":"Night Life Crypto","symbol":"NLIFE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1951ab088141e69a3713a351b0d55ba3acda192c","decimalCount":8},{"networkId":"binance-smart-chain","contractAddress":"0x86cbbedca621ae78a421a40365081caafda24296","decimalCount":8}]},{"id":"eurocoinpay","name":"EurocoinToken","symbol":"ECTE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe9fa21e671bcfb04e6868784b89c19d5aa2424ea","decimalCount":18}]},{"id":"paypie","name":"PayPie","symbol":"PPP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc42209accc14029c1012fb5680d95fbd6036e2a0","decimalCount":18}]},{"id":"quasacoin","name":"Quasacoin","symbol":"QUA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4daeb4a06f70f4b1a5c329115731fe4b89c0b227","decimalCount":18}]},{"id":"ceres","name":"Ceres","symbol":"CERES","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2e7b0d4f9b2eaf782ed3d160e3a0a4b1a7930ada","decimalCount":18}]},{"id":"tanks","name":"Tanks","symbol":"TANKS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xd20738760aededa73f6cd91a3d357746e0283a0e","decimalCount":18}]},{"id":"xfinance","name":"Xfinance","symbol":"XFI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5befbb272290dd5b8521d4a938f6c4757742c430","decimalCount":18}]},{"id":"revault-network","name":"Revault Network","symbol":"REVA","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x4fdd92bd67acf0676bfc45ab7168b3996f7b4a3b","decimalCount":18}]},{"id":"dogewhale","name":"Dogewhale","symbol":"DOGEWHALE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x43adc41cf63666ebb1938b11256f0ea3f16e6932","decimalCount":18}]},{"id":"float-protocol","name":"Float Protocol","symbol":"BANK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x24a6a37576377f63f194caa5f518a60f45b42921","decimalCount":18}]},{"id":"citizen-finance-old","name":"Citizen Finance (OLD)","symbol":"CIFI","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x89f2a5463ef4e4176e57eef2b2fdd256bf4bc2bd","decimalCount":18}]},{"id":"elpis-battle","name":"Elpis Battle","symbol":"EBA","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x3944ac66b9b9b40a6474022d6962b6caa001b5e3","decimalCount":18}]},{"id":"bitball","name":"Bitball","symbol":"BTB","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x06e0feb0d74106c7ada8497754074d222ec6bcdf","decimalCount":18}]},{"id":"vynk-chain","name":"VYNK Chain","symbol":"VYNC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xee1ae38be4ce0074c4a4a8dc821cc784778f378c","decimalCount":4},{"networkId":"binance-smart-chain","contractAddress":"0xee1ae38be4ce0074c4a4a8dc821cc784778f378c","decimalCount":4}]},{"id":"metafabric","name":"MetaFabric","symbol":"FABRIC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8c6fa66c21ae3fc435790e451946a9ea82e6e523","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x73ff5dd853cb87c144f463a555dce0e43954220d","decimalCount":18}]},{"id":"crd-network","name":"CRD Network","symbol":"CRD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xcaaa93712bdac37f736c323c93d4d5fdefcc31cc","decimalCount":18}]},{"id":"ara-token","name":"Ara Token","symbol":"ARA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa92e7c82b11d10716ab534051b271d2f6aef7df5","decimalCount":18}]},{"id":"askobar-network","name":"Asko","symbol":"ASKO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xeeee2a622330e6d2036691e983dee87330588603","decimalCount":18}]},{"id":"mu-continent","name":"Mu Continent","symbol":"MU","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xce262761df57c72999146b7a6a752da03835db4a","decimalCount":9}]},{"id":"ixicash","name":"IxiCash","symbol":"IXI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x179cd91631d96e8fafee6a744eac6ffdbb923520","decimalCount":8}]},{"id":"coinary-token","name":"Coinary","symbol":"CYT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xd9025e25bb6cf39f8c926a704039d2dd51088063","decimalCount":18}]},{"id":"demole","name":"Demole","symbol":"DMLG","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x1c796c140de269e255372ea687ef7644bab87935","decimalCount":18}]},{"id":"8pay","name":"8Pay","symbol":"8PAY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfeea0bdd3d07eb6fe305938878c0cadbfa169042","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xfeea0bdd3d07eb6fe305938878c0cadbfa169042","decimalCount":18}]},{"id":"metabrands","name":"MetaBrands","symbol":"MAGE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd52aae39a2b5cc7812f7b9450ebb61dfef702b15","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x921f99719eb6c01b4b8f0ba7973a7c24891e740a","decimalCount":18}]},{"id":"defidollar","name":"DefiDollar","symbol":"DUSD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5bc25f649fc4e26069ddf4cf4010f9f706c23831","decimalCount":18}]},{"id":"nidhi-dao","name":"Nidhi Dao","symbol":"GURU","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0x057e0bd9b797f9eeeb8307b35dbc8c12e534c41e","decimalCount":9}]},{"id":"openalexa-protocol","name":"OpenAlexa Protocol","symbol":"OAP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1788430620960f9a70e3dc14202a3a35dde1a316","decimalCount":18}]},{"id":"integral","name":"Integral","symbol":"ITGR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd502f487e1841fdc805130e13eae80c61186bc98","decimalCount":18}]},{"id":"metaverse-nft-index","name":"Metaverse NFT Index","symbol":"PLAY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x33e18a092a93ff21ad04746c7da12e35d34dc7c4","decimalCount":18}]},{"id":"dogemon-go","name":"DogemonGo","symbol":"DOGO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x9e6b3e35c8f563b45d864f9ff697a144ad28a371","decimalCount":18},{"networkId":"solana","contractAddress":"5LSFpvLDkcdV2a3Kiyzmg5YmJsj2XDLySaXvnfP1cgLT","decimalCount":6}]},{"id":"domraider","name":"DomRaider","symbol":"DRT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9af4f26941677c706cfecf6d3379ff01bb85d5ab","decimalCount":8}]},{"id":"flypme","name":"FlypMe","symbol":"FYP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8f0921f30555624143d427b340b1156914882c10","decimalCount":18}]},{"id":"zeptagram","name":"Zeptacoin","symbol":"ZPTC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x39ae6d231d831756079ec23589d2d37a739f2e89","decimalCount":4},{"networkId":"binance-smart-chain","contractAddress":"0x39ae6d231d831756079ec23589d2d37a739f2e89","decimalCount":4}]},{"id":"reward-hunters-token","name":"Reward Hunters","symbol":"RHT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xf1018c71eebe32dd85012ad413bab6b940d0d51e","decimalCount":18}]},{"id":"parex","name":"Parex","symbol":"PRX","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x90e3414e00e231b962666bd94adb811d5bcd0c2a","decimalCount":8}]},{"id":"data-economy-index","name":"Data Economy Index","symbol":"DATA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x33d63ba1e57e54779f7ddaeaa7109349344cf5f1","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x1d607faa0a51518a7728580c238d912747e71f7a","decimalCount":18}]},{"id":"libra-credit","name":"LibraToken","symbol":"LBA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfe5f141bf94fe84bc28ded0ab966c16b17490657","decimalCount":18}]},{"id":"the-three-kingdoms","name":"The Three Kingdoms","symbol":"TTK","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x39703a67bac0e39f9244d97f4c842d15fbad9c1f","decimalCount":18}]},{"id":"centric-cash","name":"Centric Swap","symbol":"CNS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xf6cb4ad242bab681effc5de40f7c8ff921a12d63","decimalCount":8}]},{"id":"fabwelt","name":"Fabwelt","symbol":"WELT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x1785113910847770290f5f840b4c74fc46451201","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x23e8b6a3f6891254988b84da3738d2bfe5e703b9","decimalCount":18}]},{"id":"happycoin","name":"HappyCoin","symbol":"HAPPY","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xb0b924c4a31b7d4581a7f78f57cee1e65736be1d","decimalCount":9}]},{"id":"cat-token","name":"Cat Token","symbol":"CAT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x56015bbe3c01fe05bc30a8a9a9fd9a88917e7db3","decimalCount":18}]},{"id":"snovio","name":"Snovian.Space","symbol":"SNOV","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbdc5bac39dbe132b1e030e898ae3830017d7d969","decimalCount":18}]},{"id":"pumapay","name":"PumaPay","symbol":"PMA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x846c66cf71c43f80403b51fe3906b3599d63336f","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x43a167b15a6f24913a8b4d35488b36ac15d39200","decimalCount":18}]},{"id":"surf-finance","name":"Surf.Finance","symbol":"SURF","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xea319e87cf06203dae107dd8e5672175e3ee976c","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x1e42edbe5376e717c1b22904c59e406426e8173f","decimalCount":18}]},{"id":"decubate","name":"Decubate","symbol":"DCB","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xeac9873291ddaca754ea5642114151f3035c67a2","decimalCount":18}]},{"id":"cryptozoon","name":"CryptoZoon","symbol":"ZOON","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x9d173e6c594f479b4d47001f8e6a95a7adda42bc","decimalCount":18}]},{"id":"beach-token","name":"Beach","symbol":"BEACH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbd15c4c8cd28a08e43846e3155c01a1f648d8d42","decimalCount":9}]},{"id":"polyient-games-governance-token","name":"Polyient Games Governance Token","symbol":"PGT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xeaccb6e0f24d66cf4aa6cbda33971b9231d332a1","decimalCount":18}]},{"id":"genesis-worlds","name":"Genesis Worlds","symbol":"GENESIS","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0x51869836681bce74a514625c856afb697a013797","decimalCount":18}]},{"id":"octofi","name":"OctoFi","symbol":"OCTO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7240ac91f01233baaf8b064248e80feaa5912ba3","decimalCount":18},{"networkId":"fantom","contractAddress":"0x639a647fbe20b6c8ac19e48e2de44ea792c62c5c","decimalCount":18}]},{"id":"subme","name":"Subme","symbol":"SUB","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xfd290c590866f8282d89671a85ac9964b165d682","decimalCount":4}]},{"id":"shoot","name":"SHOOT","symbol":"SHOO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x0fcc11f873360450a1afd8cb7cfe0a9d787cc25e","decimalCount":18}]},{"id":"redpanda-earth","name":"RedPanda Earth","symbol":"REDPANDA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x514cdb9cd8a2fb2bdcf7a3b8ddd098caf466e548","decimalCount":9}]},{"id":"momento","name":"Momento","symbol":"MOMENTO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0ae8b74cd2d566853715800c9927f879d6b76a37","decimalCount":9},{"networkId":"binance-smart-chain","contractAddress":"0x1b9a8c4f2df5dc7b8744b1a170d8d727360c67ee","decimalCount":9}]},{"id":"snetwork","name":"Snetwork","symbol":"SNET","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xff19138b039d938db46bdda0067dc4ba132ec71c","decimalCount":8}]},{"id":"debitum-network","name":"Debitum Network","symbol":"DEB","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x151202c9c18e495656f372281f493eb7698961d5","decimalCount":18}]},{"id":"seba","name":"Seba","symbol":"SEBA","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xd15d3baf3f40988810c5f9da54394ffb5246ded6","decimalCount":18}]},{"id":"gsenetwork","name":"GSENetwork","symbol":"GSE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe530441f4f73bdb6dc2fa5af7c3fc5fd551ec838","decimalCount":4}]},{"id":"empty-set-dollar","name":"Empty Set Dollar","symbol":"ESD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x36f3fd68e7325a35eb768f1aedaae9ea0689d723","decimalCount":18}]},{"id":"my-master-war","name":"My Master War","symbol":"MAT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xf3147987a00d35eecc10c731269003ca093740ca","decimalCount":18}]},{"id":"battle-pets","name":"Battle Pets","symbol":"PET","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x4d4e595d643dc61ea7fcbf12e4b1aaa39f9975b8","decimalCount":18}]},{"id":"tribeone","name":"TribeOne","symbol":"HAKA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd85ad783cc94bd04196a13dc042a3054a9b52210","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xd85ad783cc94bd04196a13dc042a3054a9b52210","decimalCount":18}]},{"id":"templardao","name":"Templar DAO","symbol":"TEM","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x19e6bfc1a6e4b042fb20531244d47e252445df01","decimalCount":9}]},{"id":"linkeye","name":"Linkeye","symbol":"LET","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfa3118b34522580c35ae27f6cf52da1dbb756288","decimalCount":6}]},{"id":"fantom-maker","name":"Fantom Maker","symbol":"FAME","active":true,"networks":[{"networkId":"fantom","contractAddress":"0x904f51a2e7eeaf76aaf0418cbaf0b71149686f4a","decimalCount":18}]},{"id":"aircoin-2","name":"AirCoin","symbol":"AIR","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xd8a2ae43fd061d24acd538e3866ffc2c05151b53","decimalCount":18}]},{"id":"handle-fi","name":"handle.fi","symbol":"FOREX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdb298285fe4c5410b05390ca80e8fbe9de1f259b","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xdb298285fe4c5410b05390ca80e8fbe9de1f259b","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0xdb298285fe4c5410b05390ca80e8fbe9de1f259b","decimalCount":18}]},{"id":"thorus","name":"Thorus","symbol":"THO","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0xae4aa155d2987b454c29450ef4f862cf00907b61","decimalCount":18}]},{"id":"babylons","name":"Babylons","symbol":"BABI","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xec15a508a187e8ddfe572a5423faa82bbdd65120","decimalCount":18}]},{"id":"power-index-pool-token","name":"Power Index Pool Token","symbol":"PIPT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x26607ac599266b21d13c7acf7942c7701a8b699c","decimalCount":18}]},{"id":"face","name":"Faceter","symbol":"FACE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1ccaa0f2a7210d76e1fdec740d5f323e2e1b1672","decimalCount":18}]},{"id":"market-ledger","name":"Market Ledger","symbol":"ML","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xc4fb957e3f1c04c8dc4000525e55920861f25bfc","decimalCount":18}]},{"id":"milkshakeswap","name":"Milkshake Swap","symbol":"MILK","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xc9bcf3f71e37579a4a42591b09c9dd93dfe27965","decimalCount":18}]},{"id":"rise-of-defenders","name":"Rise of Defenders","symbol":"RDR","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x92da433da84d58dfe2aade1943349e491cbd6820","decimalCount":18}]},{"id":"pop-chest-token","name":"POP Network","symbol":"POP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5d858bcd53e085920620549214a8b27ce2f04670","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x1bb76a939d6b7f5be6b95c4f9f822b02b4d62ced","decimalCount":18}]},{"id":"evedo","name":"Evedo","symbol":"EVED","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5aaefe84e0fb3dd1f0fcff6fa7468124986b91bd","decimalCount":18}]},{"id":"overlord","name":"Overlord","symbol":"LORD","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x2daf1a83aa348afbcbc73f63bb5ee3154d9f5776","decimalCount":18}]},{"id":"talecraft","name":"TaleCraft","symbol":"CRAFT","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0x8ae8be25c23833e0a01aa200403e826f611f9cd2","decimalCount":18}]},{"id":"synchrolife","name":"SynchroLife","symbol":"SYC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe49214e4c92dc9bcb3b56c1309afe0d626dd730e","decimalCount":18}]},{"id":"golff","name":"Golff","symbol":"GOF","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x488e0369f9bc5c40c002ea7c1fe4fd01a198801c","decimalCount":18}]},{"id":"wallstreetninja","name":"WallStreetNinja","symbol":"WSN","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x7fa4cd8aeedcb8d36dbc5d856e3a1bee490d7b36","decimalCount":18}]},{"id":"gny","name":"GNY","symbol":"GNY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb1f871ae9462f1b2c6826e88a7827e76f86751d4","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xe4a4ad6e0b773f47d28f548742a23efd73798332","decimalCount":18}]},{"id":"exmo-coin","name":"EXMO Coin","symbol":"EXM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x83869de76b9ad8125e22b857f519f001588c0f62","decimalCount":8}]},{"id":"luna-rush","name":"Luna Rush","symbol":"LUS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xde301d6a2569aefcfe271b9d98f318baee1d30a4","decimalCount":18}]},{"id":"polylauncher","name":"Polylauncher","symbol":"ANGEL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6c7b97c7e09e790d161769a52f155125fac6d5a1","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x0b6afe834dab840335f87d99b45c2a4bd81a93c7","decimalCount":18}]},{"id":"bondappetite-usd","name":"BondAppetite USD","symbol":"USDAP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9a1997c130f4b2997166975d9aff92797d5134c2","decimalCount":18}]},{"id":"nuco-cloud","name":"Nuco.Cloud","symbol":"NCDT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe0c8b298db4cffe05d1bea0bb1ba414522b33c1b","decimalCount":18}]},{"id":"ideas","name":"IDEAS","symbol":"IDS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x1c61a220a0f1dfc750d28188a97a6c7bf14e9851","decimalCount":18}]},{"id":"archer-dao-governance-token","name":"Archer DAO Governance Token","symbol":"ARCH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1f3f9d3068568f8040775be2e8c03c103c61f3af","decimalCount":18}]},{"id":"sav3","name":"SAV3","symbol":"SAV3","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6e10aacb89a28d6fa0fe68790777fec7e7f01890","decimalCount":18}]},{"id":"polinate","name":"Polinate","symbol":"POLI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa1a36d3537bbe375cc9694795f663ddc8d516db9","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x6fb54ffe60386ac33b722be13d2549dd87bf63af","decimalCount":18}]},{"id":"omni-real-estate-token","name":"Omni Real Estate Token","symbol":"ORT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x1d64327c74d6519afef54e58730ad6fc797f05ba","decimalCount":18}]},{"id":"dmm-governance","name":"DMM: Governance","symbol":"DMG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xed91879919b71bb6905f23af0a68d231ecf87b14","decimalCount":18}]},{"id":"iot-chain","name":"IoT Chain","symbol":"ITC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5e6b6d9abad9093fdc861ea1600eba1b355cd940","decimalCount":18}]},{"id":"finance-vote","name":"Finance Vote","symbol":"FVT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x45080a6531d671ddff20db42f93792a489685e32","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x0a232cb2005bda62d3de7ab5deb3ffe4c456165a","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x72a5a58f79ffc2102227b92faeba93b169a3a3f1","decimalCount":18}]},{"id":"mirrored-invesco-qqq-trust","name":"Mirrored Invesco QQQ Trust","symbol":"MQQQ","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x13b02c8de71680e71f0820c996e4be43c2f57d15","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x1cb4183ac708e07511ac57a2e45a835f048d7c56","decimalCount":18}]},{"id":"yieldwatch","name":"Yieldwatch","symbol":"WATCH","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x7a9f28eb62c791422aa23ceae1da9c847cbec9b0","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x09211dc67f9fe98fb7bbb91be0ef05f4a12fa2b2","decimalCount":18}]},{"id":"roseon-finance","name":"Roseon Finance","symbol":"ROSN","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x651cd665bd558175a956fb3d72206ea08eb3df5b","decimalCount":18}]},{"id":"piedao-defi-large-cap","name":"PieDAO DEFI Large Cap","symbol":"DEFI+L","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x78f225869c08d478c34e5f645d07a87d3fe8eb78","decimalCount":18}]},{"id":"infinito","name":"Infinito","symbol":"INFT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x83d60e7aed59c6829fb251229061a55f35432c4d","decimalCount":6}]},{"id":"nafter","name":"Nafter","symbol":"NAFT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xd7730681b1dc8f6f969166b29d8a5ea8568616a3","decimalCount":18}]},{"id":"daostack","name":"DAOstack","symbol":"GEN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x543ff227f64aa17ea132bf9886cab5db55dcaddf","decimalCount":18}]},{"id":"mobifi","name":"MobiFi","symbol":"MOFI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb2dbf14d0b47ed3ba02bdb7c954e05a72deb7544","decimalCount":18}]},{"id":"oikos","name":"Oikos","symbol":"OKS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x18acf236eb40c0d4824fb8f2582ebbecd325ef6a","decimalCount":18}]},{"id":"megacryptopolis","name":"MegaCryptoPolis","symbol":"MEGA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3218a02f8f8b5c3894ce30eb255f10bcba13e654","decimalCount":18}]},{"id":"cook","name":"Cook","symbol":"COOK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xff75ced57419bcaebe5f05254983b013b0646ef5","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x965b0df5bda0e7a0649324d78f03d5f7f2de086a","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x637afeff75ca669ff92e4570b14d6399a658902f","decimalCount":18}]},{"id":"defire","name":"DeFIRE","symbol":"CWAP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe74dc43867e0cbeb208f1a012fc60dcbbf0e3044","decimalCount":18}]},{"id":"hoqu","name":"HOQU","symbol":"HQX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1b957dc4aefeed3b4a2351a6a6d5cbfbba0cecfa","decimalCount":18}]},{"id":"zippie","name":"Zippie","symbol":"ZIPT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xedd7c94fd7b4971b916d15067bc454b9e1bad980","decimalCount":18}]},{"id":"verve","name":"Verve","symbol":"VERVE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x32561fa6d2d3e2191bf50f813df2c34fb3c89b62","decimalCount":18}]},{"id":"vault-hill-city","name":"Vault Hill City","symbol":"VHC","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0x51b5619f5180e333d18b6310c8d540aea43a0371","decimalCount":18}]},{"id":"fintrux","name":"FintruX","symbol":"FTX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd559f20296ff4895da39b5bd9add54b442596a61","decimalCount":18}]},{"id":"wicrypt","name":"Wicrypt","symbol":"WNT","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0x82a0e6c02b91ec9f6ff943c0a933c03dbaa19689","decimalCount":18}]},{"id":"cub-finance","name":"Cub Finance","symbol":"CUB","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x50d809c74e0b8e49e7b4c65bb3109abe3ff4c1c1","decimalCount":18}]},{"id":"onering","name":"OneRing","symbol":"RING","active":true,"networks":[{"networkId":"fantom","contractAddress":"0x582423c10c9e83387a96d00a69ba3d11ee47b7b5","decimalCount":18}]},{"id":"origin-sport","name":"Origin Sport","symbol":"ORS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xeb9a4b185816c354db92db09cc3b50be60b901b6","decimalCount":18}]},{"id":"ghostmarket","name":"GhostMarket","symbol":"GM","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x0b53b5da7d0f275c31a6a182622bdf02474af253","decimalCount":8},{"networkId":"polygon-pos","contractAddress":"0x6a335ac6a3cdf444967fe03e7b6b273c86043990","decimalCount":8}]},{"id":"acestarter","name":"AceStarter","symbol":"ASTAR","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x9eeddb9da3bcbfdcfbf075441a9e14c6a8899999","decimalCount":18}]},{"id":"komet","name":"Komet","symbol":"KOMET","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6cfb6df56bbdb00226aeffcdb2cd1fe8da1abda7","decimalCount":18}]},{"id":"cave","name":"Crypto Cavemen","symbol":"CAVE","active":true,"networks":[{"networkId":"solana","contractAddress":"4SZjjNABoqhbd4hnapbvoEPEqT8mnNkfbEoAwALf1V8t","decimalCount":6}]},{"id":"ultralpha","name":"UltrAlpha","symbol":"UAT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x01c0987e88f778df6640787226bc96354e1a9766","decimalCount":18}]},{"id":"crypto-phoenix","name":"Crypto Phoenix","symbol":"CPHX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8689d850cdf3b74a1f6a5eb60302c785b71c2fc7","decimalCount":18}]},{"id":"dprating","name":"DPRating","symbol":"RATING","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe8663a64a96169ff4d95b4299e7ae9a76b905b31","decimalCount":8}]},{"id":"bobs_repair","name":"Bob's Repair","symbol":"BOB","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdf347911910b6c9a4286ba8e2ee5ea4a39eb2134","decimalCount":18}]},{"id":"openswap","name":"OpenSwap","symbol":"OSWAP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb32ac3c79a94ac1eb258f3c830bbdbc676483c93","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xb32ac3c79a94ac1eb258f3c830bbdbc676483c93","decimalCount":18}]},{"id":"fire-lotto","name":"Fire Lotto","symbol":"FLOT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x049399a6b048d52971f7d122ae21a1532722285f","decimalCount":18}]},{"id":"release-ico-project","name":"RELEASE","symbol":"REL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x61bfc979ea8160ede9b862798b7833a97bafa02a","decimalCount":18}]},{"id":"value-liquidity","name":"Value DeFi","symbol":"VALUE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x49e833337ece7afe375e44f4e3e8481029218e5c","decimalCount":18}]},{"id":"waultswap-polygon","name":"WaultSwap Polygon","symbol":"WEXPOLY","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0x4c4bf319237d98a30a929a96112effa8da3510eb","decimalCount":18}]},{"id":"butterfly-protocol-2","name":"Butterfly Protocol","symbol":"BFLY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf680429328caaacabee69b7a9fdb21a71419c063","decimalCount":18}]},{"id":"indahash","name":"indaHash","symbol":"IDH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5136c98a80811c3f46bdda8b5c4555cfd9f812f0","decimalCount":6}]},{"id":"spherium","name":"Spherium","symbol":"SPHRI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8a0cdfab62ed35b836dc0633482798421c81b3ec","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x8ea93d00cc6252e2bd02a34782487eed65738152","decimalCount":18}]},{"id":"revain","name":"Revain","symbol":"REV","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2ef52ed7de8c5ce03a4ef0efbe9b7450f2d7edc9","decimalCount":6}]},{"id":"moneytoken","name":"MoneyToken","symbol":"IMT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x13119e34e140097a507b07a5564bde1bc375d9e6","decimalCount":18}]},{"id":"zero-exchange","name":"0.exchange","symbol":"ZERO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf0939011a9bb95c3b791f0cb546377ed2693a574","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x1f534d2b1ee2933f1fdf8e4b63a44b2249d77eaf","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x008e26068b3eb40b443d3ea88c1ff99b789c10f7","decimalCount":18}]},{"id":"privapp-network","name":"Privapp Network","symbol":"BPRIVA","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xd0f4afa85a667d27837e9c07c81169869c16dd16","decimalCount":8}]},{"id":"xmooney","name":"xMooney","symbol":"XM","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x98631c69602083d04f83934576a53e2a133d482f","decimalCount":9}]},{"id":"paint","name":"MurAll","symbol":"PAINT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4c6ec08cf3fc987c6c4beb03184d335a2dfc4042","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x7c28f627ea3aec8b882b51eb1935f66e5b875714","decimalCount":18}]},{"id":"niftify","name":"Niftify","symbol":"NIFT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4a1d542b52a95ad01ddc70c2e7df0c7bbaadc56f","decimalCount":18}]},{"id":"pancake-hunny","name":"Hunny Finance","symbol":"HUNNY","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x565b72163f17849832a692a3c5928cc502f46d69","decimalCount":18}]},{"id":"echidna","name":"Echidna","symbol":"ECD","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0xeb8343d5284caec921f035207ca94db6baaacbcd","decimalCount":18}]},{"id":"governor-dao","name":"Governor DAO","symbol":"GDAO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x515d7e9d75e2b76db60f8a051cd890eba23286bc","decimalCount":18}]},{"id":"metawars","name":"MetaWars","symbol":"WARS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x50e756a22ff5cee3559d18b9d9576bc38f09fa7c","decimalCount":18}]},{"id":"kaka-nft-world","name":"KAKA NFT World","symbol":"KAKA","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x26a1bdfa3bb86b2744c4a42ebfdd205761d13a8a","decimalCount":18}]},{"id":"skrumble-network","name":"Skrumble Network","symbol":"SKM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x048fe49be32adfc9ed68c37d32b5ec9df17b3603","decimalCount":18}]},{"id":"public-index-network","name":"Public Index Network","symbol":"PIN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc1f976b91217e240885536af8b63bc8b5269a9be","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x3b79a28264fc52c7b4cea90558aa0b162f7faf57","decimalCount":18}]},{"id":"polkaparty","name":"PolkaParty","symbol":"POLP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x48592de8cded16f6bb56c896fe1affc37630889c","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x6e3bf2fff13e18413d3780f93753d6cff5aee3e1","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x2d72a97a31dc920db03330780d30074626e39c8a","decimalCount":18}]},{"id":"beatbind","name":"BeatBind","symbol":"BBND","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbc0d84fa6260e065f330d51621d682d2630f4aa2","decimalCount":18}]},{"id":"dexsport","name":"Dexsport","symbol":"DESU","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x32f1518baace69e85b9e5ff844ebd617c52573ac","decimalCount":18}]},{"id":"azuki","name":"Azuki","symbol":"AZUKI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x910524678c0b1b23ffb9285a81f99c29c11cbaed","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x7cdc0421469398e0f3aa8890693d86c840ac8931","decimalCount":18}]},{"id":"mirrored-microsoft","name":"Mirrored Microsoft","symbol":"MMSFT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x41bbedd7286daab5910a1f15d12cbda839852bd7","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x0ab06caa3ca5d6299925efaa752a2d2154ece929","decimalCount":18}]},{"id":"x8-project","name":"X8X Token","symbol":"X8X","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x910dfc18d6ea3d6a7124a6f8b5458f281060fa4c","decimalCount":18}]},{"id":"trustfi-network-token","name":"TrustFi Network","symbol":"TFI","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x7565ab68d3f9dadff127f864103c8c706cf28235","decimalCount":18}]},{"id":"abcc-token","name":"ABCC Token","symbol":"AT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbf8fb919a8bbf28e590852aef2d284494ebc0657","decimalCount":18}]},{"id":"evereth","name":"EverETH","symbol":"EVERETH","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x16dcc0ec78e91e868dca64be86aec62bf7c61037","decimalCount":9}]},{"id":"exrt-network","name":"EXRT Network","symbol":"EXRT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb20043f149817bff5322f1b928e89abfc65a9925","decimalCount":8}]},{"id":"the-fire-token","name":"The Fire","symbol":"XFR","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x11c3f759c0aae61078ec923af15f2f6fa2d326ce","decimalCount":18}]},{"id":"sapien","name":"Sapien","symbol":"SPN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x20f7a3ddf244dc9299975b4da1c39f8d5d75f05a","decimalCount":6}]},{"id":"graphene","name":"Graphene","symbol":"GFN","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xf209ce1960fb7e750ff30ba7794ea11c6acdc1f3","decimalCount":18}]},{"id":"trava-finance","name":"Trava Finance","symbol":"TRAVA","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x0391be54e72f7e001f6bbc331777710b4f2999ef","decimalCount":18},{"networkId":"fantom","contractAddress":"0x477a9d5df9beda06f6b021136a2efe7be242fcc9","decimalCount":18}]},{"id":"denarius","name":"Denarius","symbol":"D","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xf6b53b4c982b9b7e87af9dc5c66c85117a5df303","decimalCount":8}]},{"id":"essentia","name":"Essentia","symbol":"ESS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfc05987bd2be489accf0f509e44b0145d68240f7","decimalCount":18}]},{"id":"centaur","name":"Centaur","symbol":"CNTR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x03042482d64577a7bdb282260e2ea4c8a89c064b","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xdae89da41a96956e9e70320ac9c0dd077070d3a5","decimalCount":18}]},{"id":"darwinia-commitment-token","name":"Darwinia Commitment Token","symbol":"KTON","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9f284e1337a815fe77d2ff4ae46544645b20c5ff","decimalCount":18}]},{"id":"nsure-network","name":"Nsure Network","symbol":"NSURE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x20945ca1df56d237fd40036d47e866c7dccd2114","decimalCount":18}]},{"id":"defidollar-dao","name":"DefiDollar DAO","symbol":"DFD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x20c36f062a31865bed8a5b1e512d9a1a20aa333a","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x9899a98b222fcb2f3dbee7df45d943093a4ff9ff","decimalCount":18}]},{"id":"mirrored-alibaba","name":"Mirrored Alibaba","symbol":"MBABA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x56aa298a19c93c6801fdde870fa63ef75cc0af72","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xca2f75930912b85d8b2914ad06166483c0992945","decimalCount":18}]},{"id":"ten","name":"TEN","symbol":"TENFI","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xd15c444f1199ae72795eba15e8c1db44e47abf62","decimalCount":18}]},{"id":"kingdom-game-4-0","name":"Kingdom Game 4.0","symbol":"KDG","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x87a2d9a9a6b2d61b2a57798f1b4b2ddd19458fb6","decimalCount":18}]},{"id":"widiland","name":"WidiLand","symbol":"WIDI","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xa361c79783833524dc7838399a4862b5f47038b8","decimalCount":18}]},{"id":"soakmont","name":"Soakmont","symbol":"SOAK","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x841dc7a49e0825bdf3ee585cfb6e553495915ace","decimalCount":18}]},{"id":"darleygo-essence","name":"DarleyGo Essence","symbol":"DGE","active":true,"networks":[{"networkId":"solana","contractAddress":"AAXng5czWLNtTXHdWEn9Ef7kXMXEaraHj2JQKo7ZoLux","decimalCount":9}]},{"id":"dark-magic","name":"Dark Magic","symbol":"DMAGIC","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0x61daecab65ee2a1d5b6032df030f3faa3d116aa7","decimalCount":18}]},{"id":"pixl-coin-2","name":"Pixl Coin","symbol":"PXLC","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x72d2946094e6e57c2fade4964777a9af2b7a51f9","decimalCount":9}]},{"id":"simple-token","name":"OST","symbol":"OST","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2c4e8f2d746113d0696ce89b35f0d8bf88e0aeca","decimalCount":18}]},{"id":"safemooncash","name":"SafeMoonCash","symbol":"SAFEMOONCASH","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xf017e2773e4ee0590c81d79ccbcf1b2de1d22877","decimalCount":9}]},{"id":"spores-network","name":"Spores Network","symbol":"SPO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xcbe771323587ea16dacb6016e269d7f08a7acc4e","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x8357c604c5533fa0053beaaa1494da552cea38f7","decimalCount":18}]},{"id":"defactor","name":"Defactor","symbol":"FACTR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdefac16715671b7b6aeefe012125f1e19ee4b7d7","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xdefac16715671b7b6aeefe012125f1e19ee4b7d7","decimalCount":18}]},{"id":"project-oasis","name":"ProjectOasis","symbol":"OASIS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xb19289b436b2f7a92891ac391d8f52580d3087e4","decimalCount":18}]},{"id":"mrweb-finance","name":"MrWeb Finance","symbol":"AMA","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xfc3da4a1b6fadab364039525dd2ab7c0c16521cd","decimalCount":18},{"networkId":"tron","contractAddress":"TVocZFCRZ6tg8MqKCKXzZ9H2qSg29T75tK","decimalCount":6}]},{"id":"sether","name":"Sether","symbol":"SETH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x78b039921e84e726eb72e7b1212bb35504c645ca","decimalCount":18}]},{"id":"kawakami","name":"Kawakami","symbol":"KAWA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5552e5a89a70cb2ef5adbbc45a6be442fe7160ec","decimalCount":18}]},{"id":"rocki","name":"Rocki","symbol":"ROCKI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xff44b937788215eca197baaf9af69dbdc214aa04","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xa01000c52b234a92563ba61e5649b7c76e1ba0f3","decimalCount":18}]},{"id":"piedao-defi","name":"PieDAO DEFI++","symbol":"DEFI++","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8d1ce361eb68e9e05573443c407d4a3bed23b033","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x5b6ab5078bd2bbf1a215fffba16a94b7df7f639d","decimalCount":18}]},{"id":"blizz-finance","name":"Blizz Finance","symbol":"BLZZ","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0x0f34919404a290e71fc6a510cb4a6acb8d764b24","decimalCount":18}]},{"id":"nanjcoin","name":"NANJCOIN","symbol":"NANJ","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xffe02ee4c69edf1b340fcad64fbd6b37a7b9e265","decimalCount":8}]},{"id":"multiplier","name":"Multiplier","symbol":"MXX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8a6f3bf52a26a21531514e23016eeae8ba7e7018","decimalCount":8}]},{"id":"franklin","name":"Franklin","symbol":"FLY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x85f6eb2bd5a062f5f8560be93fb7147e16c81472","decimalCount":4},{"networkId":"binance-smart-chain","contractAddress":"0x681fd3e49a6188fc526784ee70aa1c269ee2b887","decimalCount":4}]},{"id":"2key","name":"2key.network","symbol":"2KEY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe48972fcd82a274411c01834e2f031d4377fa2c0","decimalCount":18}]},{"id":"matrix-2","name":"Matrix","symbol":"MTIX","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x33b783a4833f7613ccb6569a9f39a261b311afbb","decimalCount":9}]},{"id":"spore","name":"Spore","symbol":"SPORE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x33a3d962955a3862c8093d1273344719f03ca17c","decimalCount":9},{"networkId":"avalanche","contractAddress":"0x6e7f5c0b9f4432716bdd0a77a3601291b9d9e985","decimalCount":9}]},{"id":"calicoin","name":"CaliCoin","symbol":"CALI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb8fa12f8409da31a4fc43d15c4c78c33d8213b9b","decimalCount":18}]},{"id":"coldstack","name":"Coldstack","symbol":"CLS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x675bbc7514013e2073db7a919f6e4cbef576de37","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x668048e70284107a6afab1711f28d88df3e72948","decimalCount":18}]},{"id":"iron-bank","name":"Iron Bank","symbol":"IB","active":true,"networks":[{"networkId":"fantom","contractAddress":"0x00a35fd824c717879bf370e70ac6868b95870dfb","decimalCount":18}]},{"id":"hitchain","name":"HitChain","symbol":"HIT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7995ab36bb307afa6a683c24a25d90dc1ea83566","decimalCount":6}]},{"id":"wings","name":"Wings","symbol":"WINGS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x667088b212ce3d06a1b553a7221e1fd19000d9af","decimalCount":18}]},{"id":"crystl-finance","name":"Crystl Finance","symbol":"CRYSTL","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0x76bf0c28e604cc3fe9967c83b3c3f31c213cfe64","decimalCount":18}]},{"id":"menlo-one","name":"Menlo One","symbol":"ONE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4d807509aece24c0fa5a102b6a3b059ec6e14392","decimalCount":18}]},{"id":"play-it-forward-dao","name":"Play It Forward DAO","symbol":"PIF","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb30f5d11b94efbbfdeaa4de38edffceec0be6513","decimalCount":18}]},{"id":"landshare","name":"Landshare","symbol":"LAND","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x9d986a3f147212327dd658f712d5264a73a1fdb0","decimalCount":18}]},{"id":"bgogo","name":"Bgogo Token","symbol":"BGG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xea54c81fe0f72de8e86b6dc78a9271aa3925e3b5","decimalCount":18}]},{"id":"dehive","name":"DeHive","symbol":"DHV","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x62dc4817588d53a056cbbd18231d91ffccd34b2a","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x58759dd469ae5631c42cf8a473992335575b58d7","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x5fcb9de282af6122ce3518cde28b7089c9f97b26","decimalCount":18}]},{"id":"marginswap","name":"Marginswap","symbol":"MFI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xaa4e3edb11afa93c41db59842b29de64b72e355b","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x9fda7ceec4c18008096c2fe2b85f05dc300f94d0","decimalCount":18}]},{"id":"forefront","name":"Forefront","symbol":"FF","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7e9d8f07a64e363e97a648904a89fb4cd5fb94cd","decimalCount":18}]},{"id":"bittoken","name":"BITToken","symbol":"BITT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9f9913853f749b3fe6d6d4e16a1cc3c1656b6d51","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x518445f0db93863e5e93a7f70617c05afa8048f1","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xfd0cbddec28a93bb86b9db4a62258f5ef25fefde","decimalCount":18}]},{"id":"dos-network","name":"DOS Network","symbol":"DOS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0a913bead80f321e7ac35285ee10d9d922659cb7","decimalCount":18}]},{"id":"arcs","name":"ARCS","symbol":"ARX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7d8daff6d70cead12c6f077048552cf89130a2b1","decimalCount":18}]},{"id":"complifi","name":"CompliFi","symbol":"COMFI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x752efadc0a7e05ad1bcccda22c141d01a75ef1e4","decimalCount":18}]},{"id":"flixxo","name":"Flixxo","symbol":"FLIXX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf04a8ac553fcedb5ba99a64799155826c136b0be","decimalCount":18}]},{"id":"food-farmer-finance","name":"Food Farmer Finance","symbol":"FFF","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc16b2419494ae0604432297d40cdf0e8d68de8d6","decimalCount":18},{"networkId":"fantom","contractAddress":"0xc16b2419494ae0604432297d40cdf0e8d68de8d6","decimalCount":18}]},{"id":"solanax","name":"Solanax","symbol":"SOLD","active":true,"networks":[{"networkId":"solana","contractAddress":"5v6tZ1SiAi7G8Qg4rBF1ZdAn4cn6aeQtefewMr1NLy61","decimalCount":9}]},{"id":"hummingbot","name":"Hummingbot","symbol":"HBOT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe5097d9baeafb89f9bcb78c9290d545db5f9e9cb","decimalCount":18}]},{"id":"goose-finance","name":"Goose Finance","symbol":"EGG","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xf952fc3ca7325cc27d15885d37117676d25bfda6","decimalCount":18}]},{"id":"delta-theta","name":"delta.theta","symbol":"DLTA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0000000de40dfa9b17854cbc7869d80f9f98d823","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x3a06212763caf64bf101daa4b0cebb0cd393fa1a","decimalCount":18}]},{"id":"superbid","name":"SuperBid","symbol":"SUPERBID","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0563dce613d559a47877ffd1593549fb9d3510d6","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xee9762352f63f4387af40d58291612067727457d","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xa3860f969075045d82de85b06bb665f93c4bae32","decimalCount":18}]},{"id":"aga-token","name":"AGA Token","symbol":"AGA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2d80f5f5328fdcb6eceb7cacf5dd8aedaec94e20","decimalCount":4},{"networkId":"binance-smart-chain","contractAddress":"0x976e33b07565b0c05b08b2e13affd3113e3d178d","decimalCount":4},{"networkId":"polygon-pos","contractAddress":"0x033d942a6b495c4071083f4cde1f17e986fe856c","decimalCount":4}]},{"id":"mywish","name":"MyWish","symbol":"WISH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd123575d94a7ad9bff3ad037ae9d4d52f41a7518","decimalCount":8},{"networkId":"binancecoin","contractAddress":"WISH-2D5","decimalCount":8},{"networkId":"binance-smart-chain","contractAddress":"0x8aed24bf6e0247be51c57d68ad32a176bf86f4d9","decimalCount":8}]},{"id":"starbots","name":"Starbots","symbol":"BOT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xdbccd9131405dd1fe7320090af337952b9845dfa","decimalCount":8}]},{"id":"cotrader","name":"CoTrader","symbol":"COT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5c872500c00565505f3624ab435c222e558e9ff8","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x304fc73e86601a61a6c6db5b0eafea587622acdc","decimalCount":18}]},{"id":"crypto-fight-club","name":"Crypto Fight Club","symbol":"FIGHT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x4f39c3319188a723003670c3f9b9e7ef991e52f3","decimalCount":18}]},{"id":"berry-data","name":"Berry Data","symbol":"BRY","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xf859bf77cbe8699013d6dbc7c2b926aaf307f830","decimalCount":18}]},{"id":"definity","name":"DeFinity","symbol":"DEFX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5f474906637bdcda05f29c74653f6962bb0f8eda","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xbe4cb2c354480042a39350a0c6c26bf54786539f","decimalCount":18}]},{"id":"yield-protocol","name":"Yield Protocol","symbol":"YIELD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa8b61cff52564758a204f841e636265bebc8db9b","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xf9d906a8dd25c4a4966bc075cdc946702219e62c","decimalCount":18}]},{"id":"shibavax","name":"Shibavax","symbol":"SHIBX","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0x440abbf18c54b2782a4917b80a1746d3a2c2cce1","decimalCount":18}]},{"id":"merkle-network","name":"Merkle Network","symbol":"MERKLE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x000000000ca5171087c18fb271ca844a2370fc0a","decimalCount":18}]},{"id":"base-protocol","name":"Base Protocol","symbol":"BASE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x07150e919b4de5fd6a63de1f9384828396f25fdc","decimalCount":9}]},{"id":"nolimitcoin","name":"NoLimitCoin","symbol":"NLC","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x6519cb1f694ccbcc72417570b364f2d051eefb9d","decimalCount":8}]},{"id":"warena","name":"Warena","symbol":"RENA","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xa9d75cc3405f0450955050c520843f99aff8749d","decimalCount":18}]},{"id":"rabbit-finance","name":"Rabbit Finance","symbol":"RABBIT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x95a1199eba84ac5f19546519e287d43d2f0e1b41","decimalCount":18}]},{"id":"minersdefi","name":"MinersDefi","symbol":"MINERS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xeb6b00f8c7e1da78fb919c810c30dde95475bdde","decimalCount":18}]},{"id":"nucleus-vision","name":"Nucleus Vision","symbol":"NCASH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x809826cceab68c387726af962713b64cb5cb3cca","decimalCount":18}]},{"id":"rainbowtoken","name":"RainbowToken","symbol":"RAINBOWTOKEN","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x673da443da2f6ae7c5c660a9f0d3dd24d1643d36","decimalCount":9}]},{"id":"katalyo","name":"Katalyo","symbol":"KTLYO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x24e3794605c84e580eea4972738d633e8a7127c8","decimalCount":18}]},{"id":"polkally","name":"Kally","symbol":"KALLY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfd30c9bea1a952feeed2ef2c6b2ff8a8fc4aad07","decimalCount":18}]},{"id":"cockapoo","name":"Cockapoo","symbol":"CPOO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x71809c4ff017ceade03038a8b597ecabb6519918","decimalCount":18}]},{"id":"medicalchain","name":"Medicalchain","symbol":"MTN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x41dbecc1cdc5517c6f76f6a6e836adbee2754de3","decimalCount":18}]},{"id":"yee","name":"Yee","symbol":"YEE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x922105fad8153f516bcfb829f56dc097a0e1d705","decimalCount":18}]},{"id":"herofi","name":"HeroFi","symbol":"HEROEGG","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xcfbb1bfa710cb2eba070cc3bec0c35226fea4baf","decimalCount":18}]},{"id":"solidex","name":"Solidex","symbol":"SEX","active":true,"networks":[{"networkId":"fantom","contractAddress":"0xd31fcd1f7ba190dbc75354046f6024a9b86014d7","decimalCount":18}]},{"id":"definer","name":"DeFiner","symbol":"FIN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x054f76beed60ab6dbeb23502178c52d6c5debe40","decimalCount":18}]},{"id":"golden-ball","name":"Golden Ball","symbol":"GLB","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x52eb6c887a4691f10bee396778603927c23be1fc","decimalCount":9}]},{"id":"mobilego","name":"MobileGo","symbol":"MGO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x40395044ac3c0c57051906da938b54bd6557f212","decimalCount":8}]},{"id":"defiato","name":"DeFiato","symbol":"DFIAT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1045f5ccb01daea4f8eab055f5fcbb7c0e7c89f0","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xf64ed9ad397a1ae657f31131d4b189220a7f1cc7","decimalCount":18},{"networkId":"avalanche","contractAddress":"0xafe3d2a31231230875dee1fa1eef14a412443d22","decimalCount":18}]},{"id":"genesis-pool","name":"Genesis Pool","symbol":"GPOOL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x797de1dc0b9faf5e25c1f7efe8df9599138fa09d","decimalCount":18}]},{"id":"scifi-index","name":"SCIFI Index","symbol":"SCIFI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfdc4a3fc36df16a78edcaf1b837d3acaaedb2cb4","decimalCount":18}]},{"id":"ukrainedao-flag-nft","name":"UkraineDAO Flag NFT","symbol":"LOVE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5380442d3c4ec4f5777f551f5edd2fa0f691a27c","decimalCount":18}]},{"id":"mercor-finance","name":"Mercor Finance","symbol":"MRCR","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x155dab50f1dded25c099e209e7b375456a70e504","decimalCount":18}]},{"id":"sportsicon","name":"SportsIcon","symbol":"$ICONS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3f68e7b44e9bcb486c2feadb7a2289d9cdfc9088","decimalCount":18}]},{"id":"zoracles","name":"Zoracles","symbol":"ZORA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd8e3fb3b08eba982f2754988d70d57edc0055ae6","decimalCount":9}]},{"id":"sekuya","name":"Sekuya","symbol":"SKUY","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xe327ce757cd206721e100812e744fc56e4e0a969","decimalCount":9}]},{"id":"true-pnl","name":"True PNL","symbol":"PNL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9fc8f0ca1668e87294941b7f627e9c15ea06b459","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xb346c52874c7023df183068c39478c3b7b2515bc","decimalCount":18}]},{"id":"props","name":"Props Token","symbol":"PROPS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6fe56c0bcdd471359019fcbc48863d6c3e9d4f41","decimalCount":18}]},{"id":"eosdac","name":"eosDAC","symbol":"EOSDAC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7e9e431a0b8c4d532c745b1043c7fa29a48d4fba","decimalCount":18}]},{"id":"ptokens-ore","name":"ORE Network","symbol":"ORE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4f640f2529ee0cf119a2881485845fa8e61a782a","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x4ef285c8cbe52267c022c39da98b97ca4b7e2ff9","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xd52f6ca48882be8fbaa98ce390db18e1dbe1062d","decimalCount":18}]},{"id":"throne","name":"Throne","symbol":"THN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2e95cea14dd384429eb3c4331b776c4cfbb6fcd9","decimalCount":18}]},{"id":"data","name":"DATA","symbol":"DTA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x69b148395ce0015c13e36bffbad63f49ef874e03","decimalCount":18}]},{"id":"etherland","name":"Etherland","symbol":"ELAND","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x33e07f5055173cf8febede8b21b12d1e2b523205","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x708cb02ad77e1b245b1640cee51b3cc844bcaef4","decimalCount":18}]},{"id":"feeder-finance","name":"Feeder Finance","symbol":"FEED","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x67d66e8ec1fd25d98b3ccd3b19b7dc4b4b7fc493","decimalCount":18},{"networkId":"fantom","contractAddress":"0x5d5530eb3147152fe78d5c4bfeede054c8d1442a","decimalCount":18}]},{"id":"ring","name":"Ring","symbol":"RING","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x021988d2c89b1a9ff56641b2f247942358ff05c9","decimalCount":5}]},{"id":"metavault","name":"Metavault","symbol":"MVD","active":true,"networks":[{"networkId":"fantom","contractAddress":"0x27746007e821aeec6f9c65cbfda04870c236346c","decimalCount":9}]},{"id":"playermon","name":"Playermon","symbol":"PYM","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0x0bd49815ea8e2682220bcb41524c0dd10ba71d41","decimalCount":18}]},{"id":"rigoblock","name":"RigoBlock","symbol":"GRG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4fbb350052bca5417566f188eb2ebce5b19bc964","decimalCount":18}]},{"id":"ubex","name":"Ubex","symbol":"UBEX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6704b673c70de9bf74c8fba4b4bd748f0e2190e1","decimalCount":18}]},{"id":"traxia","name":"Traxia","symbol":"TMT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3209f98bebf0149b769ce26d71f7aea8e435efea","decimalCount":18}]},{"id":"amon","name":"Amon","symbol":"AMN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x737f98ac8ca59f2c68ad658e3c3d8c8963e40a4c","decimalCount":18}]},{"id":"lepasa","name":"Lepasa","symbol":"LEPA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbba6c7c7d673c48d90069ad2e9d2fe587fcb6bc3","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xa4050aa9b76ccdae1a6a8b2f3e8627cdc1546d86","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xf9a4bbaa7fa1dd2352f1a47d6d3fcff259a6d05f","decimalCount":18}]},{"id":"rage-fan","name":"Rage.Fan","symbol":"RAGE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x94804dc4948184ffd7355f62ccbb221c9765886f","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xd38c1b7b95d359978996e01b8a85286f65b3c011","decimalCount":18}]},{"id":"neurotoken","name":"Neurotoken","symbol":"NTK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x69beab403438253f13b6e92db91f7fb849258263","decimalCount":18}]},{"id":"plethori","name":"Plethori","symbol":"PLE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3873965e73d9a21f88e645ce40b7db187fde4931","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x47aa3650cff9930f277d4670db138da818e1a3ca","decimalCount":18}]},{"id":"islander","name":"Islander","symbol":"ISA","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0x3eefb18003d033661f84e48360ebecd181a84709","decimalCount":18}]},{"id":"union-protocol-governance-token","name":"UNION Protocol Governance Token","symbol":"UNN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x226f7b842e0f0120b7e194d05432b3fd14773a9d","decimalCount":18}]},{"id":"ysl","name":"YSL","symbol":"YSL","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x95e7c70b58790a1cbd377bc403cd7e9be7e0afb1","decimalCount":18}]},{"id":"merculet","name":"Merculet","symbol":"MVP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x432a2c54de2dde941a36d2eb8c424ed666f74aef","decimalCount":18}]},{"id":"triall","name":"Triall","symbol":"TRL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x58f9102bf53cf186682bd9a281d3cd3c616eec41","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xe2eb47954e821dc94e19013677004cd59be0b17f","decimalCount":18}]},{"id":"alphatoken","name":".Alpha","symbol":".ALPHA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x48af7b1c9dac8871c064f62fcec0d9d6f7c269f5","decimalCount":18}]},{"id":"kangal","name":"Kangal","symbol":"KANGAL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6e765d26388a17a6e86c49a8e41df3f58abcd337","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xd632bd021a07af70592ce1e18717ab9aa126decb","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x34f380a4e3389e99c0369264453523bbe5af7fab","decimalCount":18}]},{"id":"substratum","name":"Substratum","symbol":"SUB","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8d75959f1e61ec2571aa72798237101f084de63a","decimalCount":18}]},{"id":"polkarare","name":"Polkarare","symbol":"PRARE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2c2f7e7c5604d162d75641256b80f1bf6f4dc796","decimalCount":18}]},{"id":"rentible","name":"Rentible","symbol":"RNB","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2a039b1d9bbdccbb91be28691b730ca893e5e743","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xadec335a2e3881303a9b0203eb99de12202280df","decimalCount":18}]},{"id":"aimedis-2","name":"Aimedis","symbol":"AIMX","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xd376f64bb7db90e11e78c91cbd58b756e1b8e7a1","decimalCount":18}]},{"id":"spiderdao","name":"SpiderDAO","symbol":"SPDR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbcd4b7de6fde81025f74426d43165a5b0d790fdd","decimalCount":18}]},{"id":"shadows","name":"Shadows","symbol":"DOWS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x661ab0ed68000491d98c796146bcf28c20d7c559","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xfb7400707df3d76084fbeae0109f41b178f71c02","decimalCount":18}]},{"id":"benzene","name":"Benzene","symbol":"BZN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6524b87960c2d573ae514fd4181777e7842435d4","decimalCount":18}]},{"id":"palletone","name":"PalletOneToken","symbol":"PTN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfe76be9cec465ed3219a9972c21655d57d21aec6","decimalCount":18}]},{"id":"lotto","name":"Lotto","symbol":"LOTTO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb0dfd28d3cf7a5897c694904ace292539242f858","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xf301c8435d4dfa51641f71b0615add794b52c8e9","decimalCount":18}]},{"id":"accel-defi","name":"Accel Defi","symbol":"ACCEL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7475c42f8bf2c19f4eaf12feaababa859fdc8914","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x2cace984dab08bd192a7fd044276060cb955dd9c","decimalCount":18}]},{"id":"bnsd-finance","name":"BNSD Finance","symbol":"BNSD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x668dbf100635f593a3847c0bdaf21f0a09380188","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xc1165227519ffd22fdc77ceb1037b9b284eef068","decimalCount":18}]},{"id":"xmax","name":"XMax","symbol":"XMX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0f8c45b896784a1e408526b9300519ef8660209c","decimalCount":8}]},{"id":"solana-ecosystem-index","name":"Solana Ecosystem Index","symbol":"SOLI","active":true,"networks":[{"networkId":"solana","contractAddress":"8JnNWJ46yfdq8sKgT1Lk4G7VWkAA8Rhh7LhqgJ6WY41G","decimalCount":6}]},{"id":"shield-finance","name":"Coliquidity","symbol":"COLI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd49efa7bc0d339d74f487959c573d518ba3f8437","decimalCount":18}]},{"id":"axioms","name":"Axioms","symbol":"AXI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x73ee6d7e6b203125add89320e9f343d65ec7c39a","decimalCount":18}]},{"id":"bitto-exchange","name":"BITTO","symbol":"BITTO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x55a290f08bb4cae8dcf1ea5635a3fcfd4da60456","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x816e9e589f8c07149da4e2496c547952338b27e2","decimalCount":18}]},{"id":"niobium-coin","name":"Niobium Coin","symbol":"NBC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9f195617fa8fbad9540c5d113a99a0a0172aaedc","decimalCount":18}]},{"id":"scry-info","name":"Scry.info","symbol":"DDD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9f5f3cfd7a32700c93f971637407ff17b91c7342","decimalCount":18}]},{"id":"sak3","name":"SAKE","symbol":"SAK3","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe9f84de264e91529af07fa2c746e934397810334","decimalCount":18}]},{"id":"zasset-zusd","name":"Zasset zUSD","symbol":"ZUSD","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xf0186490b18cb74619816cfc7feb51cdbe4ae7b9","decimalCount":18}]},{"id":"basis-cash","name":"Basis Cash","symbol":"BAC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3449fc1cd036255ba1eb19d65ff4ba2b8903a69a","decimalCount":18}]},{"id":"imo","name":"IMO","symbol":"IMO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x94d79c325268c898d2902050730f27a478c56cc1","decimalCount":18}]},{"id":"tripio","name":"Tripio","symbol":"TRIO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8b40761142b9aa6dc8964e61d0585995425c3d94","decimalCount":18}]},{"id":"cryptokek","name":"Cryptokek","symbol":"KEK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3fa400483487a489ec9b1db29c4129063eec4654","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x627524d78b4fc840c887ffec90563c7a42b671fd","decimalCount":18},{"networkId":"fantom","contractAddress":"0x627524d78b4fc840c887ffec90563c7a42b671fd","decimalCount":18}]},{"id":"sashimi","name":"Sashimi","symbol":"SASHIMI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc28e27870558cf22add83540d2126da2e4b464c2","decimalCount":18}]},{"id":"travel-care-2","name":"Travel Care","symbol":"TRAVEL","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x826e5ec70dbc5607ff9218011fbb97f9a8d97953","decimalCount":18}]},{"id":"unlimitedip","name":"UnlimitedIP","symbol":"UIP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4290563c2d7c255b5eec87f2d3bd10389f991d68","decimalCount":18}]},{"id":"cnns","name":"CNNS","symbol":"CNNS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6c3be406174349cfa4501654313d97e6a31072e1","decimalCount":18}]},{"id":"tolar","name":"Tolar","symbol":"TOL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd07d9fe2d2cc067015e2b4917d24933804f42cfa","decimalCount":18}]},{"id":"corgicoin","name":"CorgiCoin","symbol":"CORGI","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x450dcf93160a30be156a4600802c91bf64dffd2e","decimalCount":18}]},{"id":"peachfolio","name":"Peachfolio","symbol":"PCHF","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xc1cbfb96a1d5361590b8df04ef78de2fa3178390","decimalCount":18}]},{"id":"smaugs-nft","name":"Smaugs NFT","symbol":"SMG","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x6bfd576220e8444ca4cc5f89efbd7f02a4c94c16","decimalCount":8}]},{"id":"rainbow-token","name":"HaloDAO","symbol":"RNBW","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe94b97b6b43639e238c851a7e693f50033efd75c","decimalCount":18}]},{"id":"avaxlauncher","name":"Avaxlauncher","symbol":"AVXL","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xbd29490383edfd560426c3b63d01534408bc2da6","decimalCount":18},{"networkId":"avalanche","contractAddress":"0xbee994ad257dcc84672c0c6e6168a4701041f39f","decimalCount":18}]},{"id":"litex","name":"LITEX","symbol":"LXT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbc46d9961a3932f7d6b64abfdec80c1816c4b835","decimalCount":18}]},{"id":"defhold","name":"DefHold","symbol":"DEFO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe481f2311c774564d517d015e678c2736a25ddd3","decimalCount":18}]},{"id":"wrapped-gen-0-cryptokitties","name":"Wrapped Gen-0 CryptoKitties","symbol":"WG0","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa10740ff9ff6852eac84cdcff9184e1d6d27c057","decimalCount":18}]},{"id":"exzocoin","name":"ExzoCoin 2.0","symbol":"EXZO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xf8fc63200e181439823251020d691312fdcf5090","decimalCount":9}]},{"id":"change","name":"Change","symbol":"CAG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7d4b8cce0591c9044a22ee543533b72e976e36c3","decimalCount":18}]},{"id":"centaurify","name":"Centaurify","symbol":"CENT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x08ba718f288c3b12b01146816bef9fa03cc635bc","decimalCount":18}]},{"id":"oh-finance","name":"Oh! Finance","symbol":"OH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x16ba8efe847ebdfef99d399902ec29397d403c30","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x937e077abaea52d3abf879c9b9d3f2ebd15baa21","decimalCount":18}]},{"id":"carbon-gems","name":"Carbon GEMS","symbol":"GEMS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe74ac81b14021d0cfb835f269f48f25918c5cae6","decimalCount":18}]},{"id":"social-good-project","name":"SocialGood","symbol":"SG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xddf7fd345d54ff4b40079579d4c4670415dbfd0a","decimalCount":18}]},{"id":"canyacoin","name":"CanYaCoin","symbol":"CAN","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x007ea5c0ea75a8df45d288a4debdd5bb633f9e56","decimalCount":18}]},{"id":"ultrain","name":"Ultrain","symbol":"UGAS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8716fc5da009d3a208f0178b637a50f4ef42400f","decimalCount":18}]},{"id":"aluna","name":"Aluna","symbol":"ALN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8185bc4757572da2a610f887561c32298f1a5748","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xf44fb887334fa17d2c5c0f970b5d320ab53ed557","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xa8fcee762642f156b5d757b6fabc36e06b6d4a1a","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x9b3fa2a7c3eb36d048a5d38d81e7fafc6bc47b25","decimalCount":18}]},{"id":"dough","name":"Dough","symbol":"DOUGH","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xede5020492be8e265db6141cb0a1d2df9dbae9bb","decimalCount":18}]},{"id":"airight","name":"aiRight","symbol":"AIRI","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x7e2a35c746f2f7c240b664f1da4dd100141ae71f","decimalCount":18}]},{"id":"piedao-btc","name":"PieDAO BTC++","symbol":"BTC++","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0327112423f3a68efdf1fcf402f6c5cb9f7c33fd","decimalCount":18}]},{"id":"fanstime","name":"FansTime","symbol":"FTI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x943ed852dadb5c3938ecdc6883718df8142de4c8","decimalCount":18}]},{"id":"lepricon","name":"Lepricon","symbol":"L3P","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdef1da03061ddd2a5ef6c59220c135dec623116d","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xdef1da03061ddd2a5ef6c59220c135dec623116d","decimalCount":18}]},{"id":"baked-token","name":"Baked","symbol":"BAKED","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa4cb0dce4849bdcad2d553e9e68644cf40e26cce","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x32515ffdc3a84cfbf9ad4db14ef8f0a535c7afd6","decimalCount":18}]},{"id":"machix","name":"Machi X","symbol":"MCX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd15ecdcf5ea68e3995b2d0527a0ae0a3258302f8","decimalCount":18}]},{"id":"tradestars","name":"TradeStars","symbol":"TSX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x734c90044a0ba31b3f2e640c10dc5d3540499bfd","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x270388e0ca29cfd7c7e73903d9d933a23d1bab39","decimalCount":18}]},{"id":"kittenfinance","name":"KittenFinance","symbol":"KIF","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x177ba0cac51bfc7ea24bad39d81dcefd59d74faa","decimalCount":18}]},{"id":"phoenixdao","name":"PhoenixDAO","symbol":"PHNX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x38a2fdc11f526ddd5a607c1f251c065f40fbf2f7","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x92c59f1cc9a322670cca29594e4d994d48bdfd36","decimalCount":18}]},{"id":"mirrored-tesla","name":"Mirrored Tesla","symbol":"MTSLA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x21ca39943e91d704678f5d00b6616650f066fd63","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xf215a127a196e3988c09d052e16bcfd365cd7aa3","decimalCount":18}]},{"id":"iteration-syndicate","name":"Iteration Syndicate","symbol":"ITS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc32cc5b70bee4bd54aa62b9aefb91346d18821c4","decimalCount":18}]},{"id":"royale","name":"Royale","symbol":"ROYA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7eaf9c89037e4814dc0d9952ac7f888c784548db","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x99415856b37be9e75c0153615c7954f9ddb97a6e","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x0bd820ad2d7ab7305b5c9538ba824c9b9beb0561","decimalCount":18}]},{"id":"unitedcrowd","name":"UnitedCrowd","symbol":"UCT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6d1dc3928604b00180bb570bdae94b9698d33b79","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x6d1dc3928604b00180bb570bdae94b9698d33b79","decimalCount":18}]},{"id":"playcent","name":"Playcent","symbol":"PCNT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x657b83a0336561c8f64389a6f5ade675c04b0c3b","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xe9b9c1c38dab5eab3b7e2ad295425e89bd8db066","decimalCount":18}]},{"id":"the-bitcoin-family","name":"The Bitcoin Family","symbol":"FAMILY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x833e4c02c47b7e38f5b9a80b26eb07d23d1961f4","decimalCount":4}]},{"id":"ticoex-token","name":"TICOEX Token","symbol":"TICO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x36b60a425b82483004487abc7adcb0002918fc56","decimalCount":8}]},{"id":"follow-token","name":"Alpha Impact","symbol":"FOLO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb2a63a5dd36c91ec2da59b188ff047f66fac122a","decimalCount":18}]},{"id":"gg-token","name":"GG Token","symbol":"GGTK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfa99a87b14b02e2240c79240c5a20f945ca5ef76","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x49b1be61a8ca3f9a9f178d6550e41e00d9162159","decimalCount":18}]},{"id":"payrue","name":"Propel","symbol":"PROPEL","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x9b44df3318972be845d83f961735609137c4c23c","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xe0ce60af0850bf54072635e66e79df17082a1109","decimalCount":18}]},{"id":"lunachow","name":"LunaChow","symbol":"LUCHOW","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa5ef74068d04ba0809b7379dd76af5ce34ab7c57","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xe4e8e6878718bfe533702d4a6571eb74d79b0915","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xc4bb7277a74678f053259cb1f96140347efbfd46","decimalCount":18}]},{"id":"oneroot-network","name":"OneRoot Network","symbol":"RNT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xff603f43946a3a28df5e6a73172555d8c8b02386","decimalCount":18}]},{"id":"snowswap","name":"Snowswap","symbol":"SNOW","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xfe9a29ab92522d14fc65880d817214261d8479ae","decimalCount":18}]},{"id":"localtrade","name":"LocalTrade","symbol":"LTT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x1dc84fc11e48ae640d48044f22a603bbe914a612","decimalCount":9}]},{"id":"localcoinswap","name":"LocalCoinSwap","symbol":"LCS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xaa19961b6b858d9f18a115f25aa1d98abc1fdba8","decimalCount":18}]},{"id":"nami-corporation-token","name":"Nami Corporation Token","symbol":"NAMI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2f7b618993cc3848d6c7ed9cdd5e835e4fe22b98","decimalCount":18}]},{"id":"b21","name":"B21","symbol":"B21","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6faa826af0568d1866fca570da79b318ef114dab","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x70512c7f3d3009be997559d279b991461c451d70","decimalCount":18}]},{"id":"coin-artist","name":"Coin Artist","symbol":"COIN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x87b008e57f640d94ee44fd893f0323af933f9195","decimalCount":18}]},{"id":"robotina","name":"Robotina","symbol":"ROX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x574f84108a98c575794f75483d801d1d5dc861a5","decimalCount":18}]},{"id":"infomatix","name":"Infomatix","symbol":"INFO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xdf727040d3997b5d95dee8c661fa96e3c13ee0c9","decimalCount":18}]},{"id":"lunaland","name":"LunaLand","symbol":"LLN","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x2a354f59ed1dd485129891e718865eb55ebdb8b3","decimalCount":18}]},{"id":"contentbox","name":"ContentBox","symbol":"BOX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x63f584fa56e60e4d0fe8802b27c7e6e3b33e007f","decimalCount":18}]},{"id":"multiverse-capital","name":"Multiverse Capital","symbol":"MVC","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x80d04e44955aa9c3f24041b2a824a20a88e735a8","decimalCount":18}]},{"id":"alpaca","name":"Alpaca City","symbol":"ALPA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7ca4408137eb639570f8e647d9bd7b7e8717514a","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xc5e6689c9c8b02be7c49912ef19e79cf24977f03","decimalCount":18}]},{"id":"joincoin","name":"JoinCoin","symbol":"JOIN","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x003771227d08ac9961b9160b1219fef136546e90","decimalCount":18}]},{"id":"cryptomeda","name":"Cryptomeda","symbol":"TECH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6286a9e6f7e745a6d884561d88f94542d6715698","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x6286a9e6f7e745a6d884561d88f94542d6715698","decimalCount":18}]},{"id":"qchi","name":"QChi","symbol":"QCH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x687bfc3e73f6af55f0ccca8450114d107e781a0e","decimalCount":18}]},{"id":"crossswap","name":"CrossSwap","symbol":"CSWAP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe0b0c16038845bed3fcf70304d3e167df81ce225","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xe0b0c16038845bed3fcf70304d3e167df81ce225","decimalCount":18}]},{"id":"peanut","name":"Peanut","symbol":"NUX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x89bd2e7e388fab44ae88bef4e1ad12b4f1e0911c","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x6d8734002fbffe1c86495e32c95f732fc77f6f2a","decimalCount":18}]},{"id":"block-commerce-protocol","name":"Block Commerce Protocol","symbol":"BCP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4612021c75809160be60db21fbc9d6add0b32def","decimalCount":18}]},{"id":"polkadomain","name":"PolkaDomain","symbol":"NAME","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe1a4c5bbb704a92599fedb191f451e0d3a1ed842","decimalCount":18}]},{"id":"piedao-defi-small-cap","name":"PieDAO DEFI Small Cap","symbol":"DEFI+S","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xad6a626ae2b43dcb1b39430ce496d2fa0365ba9c","decimalCount":18}]},{"id":"dracula","name":"Dracula","symbol":"DRC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb78b3320493a4efaa1028130c5ba26f0b6085ef8","decimalCount":18}]},{"id":"decentralized-nations","name":"Decentralized Nations","symbol":"DENA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x15f0eedf9ce24fc4b6826e590a8292ce5524a1da","decimalCount":18}]},{"id":"stacker-ventures","name":"Stacker Ventures","symbol":"STACK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe0955f26515d22e347b17669993fcefcc73c3a0a","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xccbe9b810d6574701d324fd6dbe0a1b68f9d5bf7","decimalCount":18}]},{"id":"primas","name":"Primas","symbol":"PST","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe3fedaecd47aa8eab6b23227b0ee56f092c967a9","decimalCount":18}]},{"id":"racex","name":"RaceX","symbol":"RACEX","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0x7086e045b78e1e72f741f25231c08d238812cf8a","decimalCount":18}]},{"id":"papel","name":"Papel Token","symbol":"PAPEL","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x557dd6700e66818af340cce17fd4508ced81fbc1","decimalCount":9}]},{"id":"merge","name":"Merge","symbol":"MERGE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x2d5c9167fdd5c068c8fcb8992e6af639b42fbf70","decimalCount":18}]},{"id":"toshi-token","name":"Toshimon","symbol":"TOSHI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf136d7b0b7ae5b86d21e7b78dfa95375a7360f19","decimalCount":18}]},{"id":"ethereum-yield","name":"Ethereum Yield","symbol":"ETHY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd1afbccc9a2c2187ea544363b986ea0ab6ef08b5","decimalCount":18}]},{"id":"lovelace-world","name":"Lovelace World","symbol":"LACE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xa3499dd7dbbbd93cb0f8303f8a8ace8d02508e73","decimalCount":18}]},{"id":"alchemy-dao","name":"AlchemyDAO","symbol":"ALCH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0000a1c00009a619684135b824ba02f7fbf3a572","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x87b078cf94b188efb9d2208cae47a66ea7fea09a","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0x0e15258734300290a651fdbae8deb039a8e7a2fa","decimalCount":18}]},{"id":"meta-doge","name":"Meta Doge","symbol":"METADOGE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8530b66ca3ddf50e0447eae8ad7ea7d5e62762ed","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x8530b66ca3ddf50e0447eae8ad7ea7d5e62762ed","decimalCount":18}]},{"id":"rasko","name":"rASKO","symbol":"RASKO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xd118f42edbc839f7e1e85d5269a25288792c141b","decimalCount":18}]},{"id":"nft-platform-index","name":"NFT Platform Index","symbol":"NFTP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x68bb81b3f67f7aab5fd1390ecb0b8e1a806f2465","decimalCount":18}]},{"id":"atlantis-loans","name":"Atlantis Loans","symbol":"ATL","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x1fd991fb6c3102873ba68a4e6e6a87b3a5c10271","decimalCount":18}]},{"id":"cougar-token","name":"CougarSwap","symbol":"CGS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x26d88b1e61e22da3f1a1ba95a1ba278f6fcef00b","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x047fd3b3d2366f9babe105ade4598e263d6c699c","decimalCount":18},{"networkId":"fantom","contractAddress":"0x5a2e451fb1b46fde7718315661013ae1ae68e28c","decimalCount":18}]},{"id":"omnitude","name":"Omnitude","symbol":"ECOM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x171d750d42d661b62c277a6b486adb82348c3eca","decimalCount":18}]},{"id":"netcoincapital","name":"Netcoincapital","symbol":"NCC","active":true,"networks":[{"networkId":"tron","contractAddress":"TCDgp5bwtixaShPifUm7HpZ71C1pe6zif1","decimalCount":6}]},{"id":"squid-moon","name":"Squid Moon","symbol":"SQM","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x2766cc2537538ac68816b6b5a393fa978a4a8931","decimalCount":18}]},{"id":"ties-network","name":"Ties.DB","symbol":"TIE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x999967e2ec8a74b7c8e9db19e039d920b31d39d0","decimalCount":18}]},{"id":"soul-swap","name":"Soul Swap","symbol":"SOUL","active":true,"networks":[{"networkId":"fantom","contractAddress":"0xe2fb177009ff39f52c0134e8007fa0e4baacbd07","decimalCount":18}]},{"id":"lead-token","name":"Lead Token","symbol":"LEAD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1dd80016e3d4ae146ee2ebb484e8edd92dacc4ce","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x2ed9e96edd11a1ff5163599a66fb6f1c77fa9c66","decimalCount":18}]},{"id":"kerman","name":"KERMAN","symbol":"KERMAN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7841b2a48d1f6e78acec359fed6d874eb8a0f63c","decimalCount":4}]},{"id":"parachute","name":"Parachute","symbol":"PAR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1beef31946fbbb40b877a72e4ae04a8d1a5cee06","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x19c91764a976ac6c1e2c2e4c5856f2939342a814","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xf521d590fb1e0b432fd0e020cdbd6c6397d652c2","decimalCount":18}]},{"id":"banca","name":"Banca","symbol":"BANCA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x998b3b82bc9dba173990be7afb772788b5acb8bd","decimalCount":18}]},{"id":"dyor","name":"DYOR","symbol":"DYOR","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x10051147418c42218986cedd0adc266441f8a14f","decimalCount":9}]},{"id":"moonienft","name":"MoonieNFT","symbol":"MNY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa6f7645ed967faf708a614a2fca8d4790138586f","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xa6f7645ed967faf708a614a2fca8d4790138586f","decimalCount":18}]},{"id":"chainswap","name":"Chainswap","symbol":"ASAP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xcc665390b03c5d324d8faf81c15ecee29a73bcb4","decimalCount":18}]},{"id":"aetherv2","name":"AetherV2","symbol":"ATH","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x6d3a0fb0070ea61f901ebc0b675c30450acac737","decimalCount":9}]},{"id":"medishares","name":"MediShares","symbol":"MDS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x66186008c1050627f979d464eabb258860563dbe","decimalCount":18}]},{"id":"liquidifty","name":"Liquidifty","symbol":"LQT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xbd2c43da85d007b0b3cd856fd55c299578d832bc","decimalCount":18}]},{"id":"ledgerscore","name":"LedgerScore","symbol":"LED","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x72de803b67b6ab05b61efab2efdcd414d16ebf6d","decimalCount":18}]},{"id":"community-metaverse","name":"Community Metaverse","symbol":"COMT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x45b239cc0a760d1afd276b749141c7e404844ee6","decimalCount":18}]},{"id":"blockspace-token","name":"Blocks Space","symbol":"BLS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x34aa9099d924f3fb2377ff20d81b235311c15346","decimalCount":18}]},{"id":"upfiring","name":"Upfiring","symbol":"UFR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xea097a2b1db00627b2fa17460ad260c016016977","decimalCount":18}]},{"id":"polygon-ecosystem-index","name":"Amun Polygon Ecosystem Index","symbol":"PECO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9d3ee6b64e69ebe12a4bf0b01d031cb80f556ee4","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xa9536b9c75a9e0fae3b56a96ac8edf76abc91978","decimalCount":18}]},{"id":"red","name":"Red","symbol":"RED","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x76960dccd5a1fe799f7c29be9f19ceb4627aeb2f","decimalCount":18}]},{"id":"spacecowboy","name":"SpaceCowBoy","symbol":"SCB","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x0d36cc179019db9a65aa3b85db59e4bb52df0b12","decimalCount":18}]},{"id":"argo","name":"ArGoApp","symbol":"ARGO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x28cca76f6e8ec81e4550ecd761f899110b060e97","decimalCount":18}]},{"id":"apyswap","name":"APYSwap","symbol":"APYS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf7413489c474ca4399eee604716c72879eea3615","decimalCount":18}]},{"id":"quai-dao","name":"Quai Dao","symbol":"QUAI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x40821cd074dfecb1524286923bc69315075b5c89","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x3dc2d7434bdbb4ca1a8a6bcc8a8075aeae2d2179","decimalCount":18}]},{"id":"foresight","name":"Foresight","symbol":"FORS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb1ec548f296270bc96b8a1b3b3c8f3f04b494215","decimalCount":18}]},{"id":"wenlambo","name":"Wenlambo","symbol":"WENLAMBO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xd8a31016cd7da048ca21ffe04256c6d08c3a2251","decimalCount":18}]},{"id":"ares-protocol","name":"Ares Protocol","symbol":"ARES","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x358aa737e033f34df7c54306960a38d09aabd523","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xf9752a6e8a5e5f5e6eb3ab4e7d8492460fb319f0","decimalCount":18}]},{"id":"ebox","name":"Ebox","symbol":"EBOX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x33840024177a7daca3468912363bed8b425015c5","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xb41c43fabd22a6c6ea135e975769e9051f9ee8ad","decimalCount":18}]},{"id":"lendefi","name":"Lendefi","symbol":"LDFI","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x8f1e60d84182db487ac235acc65825e50b5477a1","decimalCount":18}]},{"id":"gamerse","name":"Gamerse","symbol":"LFG","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xf93f6b686f4a6557151455189a9173735d668154","decimalCount":18}]},{"id":"inheritance-art","name":"inheritance Art","symbol":"IAI","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xe495b7155fbd040065491092b02893c8e17629ed","decimalCount":18}]},{"id":"blockster","name":"Blockster","symbol":"BXR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x97a3bd8a445cc187c6a751f392e15c3b2134d695","decimalCount":18}]},{"id":"unvest","name":"Unvest","symbol":"UNV","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf009f5531de69067435e32c4b9d36077f4c4a673","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xf915fdda4c882731c0456a4214548cd13a822886","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x64ee4f41a15d6c431ab6607d4e95462169d50f6c","decimalCount":18}]},{"id":"starbase","name":"Starbase","symbol":"STAR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf70a642bd387f94380ffb90451c2c81d4eb82cbc","decimalCount":18}]},{"id":"electrify-asia","name":"Electrify.Asia","symbol":"ELEC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd49ff13661451313ca1553fd6954bd1d9b6e02b9","decimalCount":18}]},{"id":"cryptex","name":"CryptEx","symbol":"CRX","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x97a30c692ece9c317235d48287d23d358170fc40","decimalCount":18}]},{"id":"matrixswap","name":"Matrix Labs","symbol":"MATRIX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc8d3dcb63c38607cb0c9d3f55e8ecce628a01c36","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xc32bb619966b9a56cf2472528a36fd099ce979e0","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x211f4e76fcb811ed2b310a232a24b3445d95e3bc","decimalCount":18}]},{"id":"happyfans","name":"HappyFans","symbol":"HAPPY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3079f61704e9efa2bcf1db412f735d8d4cfa26f4","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xf5d8a096cccb31b9d7bce5afe812be23e3d4690d","decimalCount":18}]},{"id":"friendz","name":"Friendz","symbol":"FDZ","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x23352036e911a22cfc692b5e2e196692658aded9","decimalCount":18}]},{"id":"typerium","name":"Typerium","symbol":"TYPE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xeaf61fc150cd5c3bea75744e830d916e60ea5a9f","decimalCount":4}]},{"id":"hashcoin","name":"HashCoin","symbol":"HSC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2bba3cf6de6058cc1b4457ce00deb359e2703d7f","decimalCount":18}]},{"id":"zeedex","name":"Zeedex","symbol":"ZDEX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5150956e082c748ca837a5dfa0a7c10ca4697f9c","decimalCount":18}]},{"id":"robust-token","name":"Robust","symbol":"RBT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x891e4554227385c5c740f9b483e935e3cbc29f01","decimalCount":18}]},{"id":"the-4th-pillar","name":"4thpillar technologies","symbol":"FOUR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4730fb1463a6f1f44aeb45f6c5c422427f37f4d0","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xd882739fca9cbae00f3821c4c65189e2d7e26147","decimalCount":18},{"networkId":"solana","contractAddress":"DAtU322C23YpoZyWBm8szk12QyqHa9rUQe1EYXzbm1JE","decimalCount":9},{"networkId":"polygon-pos","contractAddress":"0x48cbc913de09317df2365e6827df50da083701d5","decimalCount":18}]},{"id":"bitorbit","name":"BitOrbit","symbol":"BITORB","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xed0c1c9c64ff7c7cc37c3af0dfcf5b02efe0bb5f","decimalCount":18}]},{"id":"gamyfi-token","name":"GamyFi Token","symbol":"GFX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x65ad6a2288b2dd23e466226397c8f5d1794e58fc","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x65ad6a2288b2dd23e466226397c8f5d1794e58fc","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x65ad6a2288b2dd23e466226397c8f5d1794e58fc","decimalCount":18}]},{"id":"dether","name":"Dether","symbol":"DTH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5adc961d6ac3f7062d2ea45fefb8d8167d44b190","decimalCount":18}]},{"id":"nftify","name":"NFTify","symbol":"N1","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xacbd826394189cf2623c6df98a18b41fc8ffc16d","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x5989d72a559eb0192f2d20170a43a4bd28a1b174","decimalCount":18}]},{"id":"lympo-market-token","name":"Lympo Market Token","symbol":"LMT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x327673ae6b33bd3d90f0096870059994f30dc8af","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x9617857e191354dbea0b714d78bc59e57c411087","decimalCount":18}]},{"id":"recharge-finance","name":"Recharge Finance","symbol":"R3FI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x13572851103bed49ff743af4c4bb5ace88b22e2f","decimalCount":9},{"networkId":"binance-smart-chain","contractAddress":"0x4f55ab914ce8a633c7eb5d8b4d190a96e9ed7f90","decimalCount":9}]},{"id":"tapmydata","name":"TapX","symbol":"TAP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7f1f2d3dfa99678675ece1c243d3f7bc3746db5d","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x10635bf5c17f5e4c0ed9012aef7c12f96a57a4dd","decimalCount":18}]},{"id":"token-tkx","name":"Xixo TKX","symbol":"TKX","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x4d864e4f542b4b40acb3151c9dad2e2c9236a88f","decimalCount":6}]},{"id":"robonomics-web-services","name":"Robonomics Web Services","symbol":"RWS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x08ad83d779bdf2bbe1ad9cc0f78aa0d24ab97802","decimalCount":18}]},{"id":"teneo","name":"Teneo","symbol":"TEN","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x25b9d4b9535920194c359d2879db6a1382c2ff26","decimalCount":18}]},{"id":"nyan-v2","name":"Nyan V2","symbol":"NYAN-2","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbf4a9a37ecfc21825011285222c36ab35de51f14","decimalCount":18}]},{"id":"cardence","name":"Cardence","symbol":"$CRDN","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xfa17b330bcc4e7f3e2456996d89a5a54ab044831","decimalCount":18}]},{"id":"pinkmoon","name":"PinkMoon","symbol":"PINKM","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xb6090a50f66046e3c6afb9311846a6432e45060a","decimalCount":9}]},{"id":"patientory","name":"Patientory","symbol":"PTOY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8ae4bf2c33a8e667de34b54938b0ccd03eb8cc06","decimalCount":8}]},{"id":"media-eye","name":"MeDIA eYe","symbol":"EYE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9a257c90fa239fba07771ef7da2d554d148c2e89","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x9a257c90fa239fba07771ef7da2d554d148c2e89","decimalCount":18}]},{"id":"black-phoenix","name":"Black Phoenix","symbol":"BPX","active":true,"networks":[{"networkId":"tron","contractAddress":"TXBcx59eDVndV5upFQnTR2xdvqFd5reXET","decimalCount":18}]},{"id":"chain-wars-essence","name":"Chain Wars","symbol":"CWE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x9c6b7221cdda3b8136fbf9d27ac07aeecc1087b5","decimalCount":18}]},{"id":"mirrored-amazon","name":"Mirrored Amazon","symbol":"MAMZN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0cae9e4d663793c2a2a0b211c1cf4bbca2b9caa7","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x3947b992dc0147d2d89df0392213781b04b25075","decimalCount":18}]},{"id":"aga-rewards-2","name":"AGA Rewards","symbol":"AGAR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb453f1f2ee776daf2586501361c457db70e1ca0f","decimalCount":8},{"networkId":"binance-smart-chain","contractAddress":"0x4ec16da4c9007462de151c0da9f5426c69978a7b","decimalCount":8},{"networkId":"polygon-pos","contractAddress":"0xf84bd51eab957c2e7b7d646a3427c5a50848281d","decimalCount":8}]},{"id":"minikishu","name":"MINIKISHU","symbol":"MINIKISHU","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x47fd00664661058546fddada3eecc9f2cd41020e","decimalCount":9}]},{"id":"yfdai-finance","name":"YfDAI.finance","symbol":"YF-DAI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf4cd3d3fda8d7fd6c5a500203e38640a70bf9577","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x7e7ff932fab08a0af569f93ce65e7b8b23698ad8","decimalCount":18}]},{"id":"dextf","name":"Domani Protocol","symbol":"DEXTF","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x5f64ab1544d28732f0a24f4713c2c8ec0da089f0","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x03e8d118a1864c7dc53bf91e007ab7d91f5a06fa","decimalCount":18}]},{"id":"hyperchain-x","name":"HyperChain X","symbol":"HYPER","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x0469f8ca65ce318888cc0d6459d0c7cbe5912c98","decimalCount":7}]},{"id":"cerberusdao","name":"CerberusDAO","symbol":"3DOG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8a14897ea5f668f36671678593fae44ae23b39fb","decimalCount":9}]},{"id":"kittycoin","name":"Kitty Coin","symbol":"KITTY","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0xb4228798ff437ecd8fa43429664e9992256fe6ac","decimalCount":18}]},{"id":"kuramainu","name":"KuramaInu","symbol":"KUNU","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe49cb97091b5bde1e8b7043e3d5717e64fde825e","decimalCount":9}]},{"id":"bottos","name":"Bottos","symbol":"BTO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x36905fc93280f52362a1cbab151f25dc46742fb5","decimalCount":18}]},{"id":"tosdis","name":"TosDis","symbol":"DIS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x220b71671b649c03714da9c621285943f3cbcdc6","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x57effde2759b68d86c544e88f7977e3314144859","decimalCount":18},{"networkId":"fantom","contractAddress":"0x0e121961dd741c9d49c9a04379da944a9d2fac7a","decimalCount":18}]},{"id":"santa-coin-2","name":"Santa Coin","symbol":"SANTA","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x4f1a6fc6a7b65dc7ebc4eb692dc3641be997c2f2","decimalCount":9}]},{"id":"meta-bsc","name":"Meta BSC","symbol":"META","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x26165a5a3dd21fa528becf3ff7f114d00a517344","decimalCount":9}]},{"id":"bull-coin","name":"Bull Coin","symbol":"BULL","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xf483af09917ba63f1e274056978036d266eb56e6","decimalCount":18}]},{"id":"polygen","name":"Polygen","symbol":"PGEN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf6719e1a8fcbb1b9c290019e37e004966a8916c9","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x01d35cbc2070a3b76693ce2b6364eae24eb88591","decimalCount":18}]},{"id":"swarm-city","name":"Swarm City","symbol":"SWT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb9e7f8568e08d5659f5d29c4997173d84cdf2607","decimalCount":18}]},{"id":"snowball-token","name":"Snowball","symbol":"SNOB","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0xc38f41a296a4493ff429f1238e030924a1542e50","decimalCount":18}]},{"id":"avaware","name":"Avaware","symbol":"AVE","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0x78ea17559b3d2cf85a7f9c2c704eda119db5e6de","decimalCount":18}]},{"id":"phoenix-token","name":"Phoenix Finance","symbol":"PHX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xaec65404ddc3af3c897ad89571d5772c1a695f22","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xac86e5f9ba48d680516df50c72928c2ec50f3025","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x9c6bfedc14b5c23e3900889436edca7805170f01","decimalCount":18}]},{"id":"option-room","name":"OptionRoom","symbol":"ROOM","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x3c45a24d36ab6fc1925533c1f57bc7e1b6fba8a4","decimalCount":18}]},{"id":"auctus","name":"Auctus","symbol":"AUC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc12d099be31567add4e4e4d0d45691c3f58f5663","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x3028b4395f98777123c7da327010c40f3c7cc4ef","decimalCount":18},{"networkId":"arbitrum-one","contractAddress":"0xea986d33ef8a20a96120ecc44dbdd49830192043","decimalCount":18}]},{"id":"delphy","name":"Delphy","symbol":"DPY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6c2adc2073994fb2ccc5032cc2906fa221e9b391","decimalCount":18}]},{"id":"credefi","name":"Credefi","symbol":"CREDI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xae6e307c3fe9e922e5674dbd7f830ed49c014c6b","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x2235e79086dd23135119366da45851c741874e5b","decimalCount":18}]},{"id":"blue","name":"Blue Protocol","symbol":"BLUE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x539efe69bcdd21a83efd9122571a64cc25e0282b","decimalCount":8}]},{"id":"reverse","name":"Reverse","symbol":"RVRS","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0x5dd175a4242afe19e5c1051d8cd13fc8979f2329","decimalCount":9}]},{"id":"koromaru","name":"KOROMARU","symbol":"KOROMARU","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd0d42005e7b3c0812b1268f0e5faf97ff2423651","decimalCount":9}]},{"id":"channels","name":"Channels","symbol":"CAN","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xde9a73272bc2f28189ce3c243e36fafda2485212","decimalCount":18}]},{"id":"nftlootbox","name":"LootBox.io","symbol":"LOOT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7b3d36eb606f873a75a6ab68f8c999848b04f935","decimalCount":18}]},{"id":"adbank","name":"adbank","symbol":"ADB","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2baac9330cf9ac479d819195794d79ad0c7616e3","decimalCount":18}]},{"id":"keyfi","name":"KeyFi","symbol":"KEYFI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb8647e90c0645152fccf4d9abb6b59eb4aa99052","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x4b6000f9163de2e3f0a01ec37e06e1469dbbce9d","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xd1a5f2a049343fc4d5f8d478f734eba51b22375e","decimalCount":18}]},{"id":"sator","name":"Sator","symbol":"SAO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3ef389f264e07fff3106a3926f2a166d1393086f","decimalCount":9}]},{"id":"geodb","name":"GeoDB","symbol":"GEO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x147faf8de9d8d8daae129b187f0d02d819126750","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xc342774492b54ce5f8ac662113ed702fc1b34972","decimalCount":18}]},{"id":"potent-coin","name":"Potent Coin","symbol":"PTT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x057aff3e314e1ca15bed75510df81a20098ce456","decimalCount":18}]},{"id":"project-inverse","name":"Planet Inverse","symbol":"XIV","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x44f262622248027f8e2a8fb1090c4cf85072392c","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x00518f36d2e0e514e8eb94d34124fc18ee756f10","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xde799636af0d8d65a17aaa83b66cbbe9b185eb01","decimalCount":18}]},{"id":"moonpoly","name":"Moonpoly","symbol":"CMP","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xcfd947b1ad06c39522fb67fb00b21a3fda906e34","decimalCount":9}]},{"id":"add-xyz-new","name":"Add.xyz (NEW)","symbol":"ADD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x635d081fd8f6670135d8a3640e2cf78220787d56","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xcd7e445175ff67475f0079b13aa6bed8a4e01809","decimalCount":18}]},{"id":"relite-finance","name":"Relite Finance","symbol":"RELI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0e58ed58e150dba5fd8e5d4a49f54c7e1e880124","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x7015a4b6ec17b64e09252a99f9f6e7feee6c37eb","decimalCount":18}]},{"id":"sake-token","name":"SakeToken","symbol":"SAKE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x066798d9ef0833ccc719076dab77199ecbd178b0","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x8bd778b12b15416359a227f0533ce2d91844e1ed","decimalCount":18}]},{"id":"ibuffer-token","name":"iBuffer","symbol":"IBFR","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xa296ad1c47fe6bdc133f39555c1d1177bd51fbc5","decimalCount":18}]},{"id":"arcane-token","name":"Arcane Token","symbol":"ARCANE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x477565b356b3973d16e8cd837c6970613f13e24a","decimalCount":9}]},{"id":"unicake","name":"UniCAKE","symbol":"UCT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x802fc33f170aedeca12e4f04a959bec9c16bc836","decimalCount":18}]},{"id":"tacos","name":"Tacos","symbol":"TACO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x00d1793d7c3aae506257ba985b34c76aaf642557","decimalCount":18}]},{"id":"bscstarter","name":"Starter.xyz","symbol":"START","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1d7ca62f6af49ec66f6680b8606e634e55ef22c1","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x31d0a7ada4d4c131eb612db48861211f63e57610","decimalCount":18},{"networkId":"avalanche","contractAddress":"0xf44fb887334fa17d2c5c0f970b5d320ab53ed557","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x6ccf12b480a99c54b23647c995f4525d544a7e72","decimalCount":18}]},{"id":"depocket","name":"DePocket","symbol":"DEPO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x7d99eda556388ad7743a1b658b9c4fc67d7a9d74","decimalCount":18}]},{"id":"zlot","name":"zLOT","symbol":"ZLOT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa8e7ad77c60ee6f30bac54e2e7c0617bd7b5a03e","decimalCount":18},{"networkId":"fantom","contractAddress":"0x2f60c28fb2fdc90a2a5644442d0f6d8998101e76","decimalCount":18}]},{"id":"smartofgiving","name":"smARTOFGIVING","symbol":"AOG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8578530205cecbe5db83f7f29ecfeec860c297c2","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xb32d4817908f001c2a53c15bff8c14d8813109be","decimalCount":18}]},{"id":"deficliq","name":"DefiCliq","symbol":"CLIQ","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0def8d8adde14c9ef7c2a986df3ea4bd65826767","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xe795347731bc547f4e4643f7945738ce2bc18529","decimalCount":18}]},{"id":"hyperion","name":"Hyperion","symbol":"HYN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe99a894a69d7c2e3c92e61b64c505a6a57d2bc07","decimalCount":18}]},{"id":"covercompared","name":"CoverCompared","symbol":"CVR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3c03b4ec9477809072ff9cc9292c9b25d4a8e6c6","decimalCount":18}]},{"id":"crabada-amulet","name":"Crabada Amulet","symbol":"CRAM","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0xd2cd7a59aa8f8fdc68d01b1e8a95747730b927d3","decimalCount":18}]},{"id":"unclemine","name":"UncleMine","symbol":"UM","active":true,"networks":[{"networkId":"solana","contractAddress":"DMCUFm2ZAnSU7UgsdVq23gRogMU3MEBjPgQF1gK53rEn","decimalCount":6}]},{"id":"legend-of-fantasy-war","name":"Legend of Fantasy War","symbol":"LFW","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xd71239a33c8542bd42130c1b4aca0673b4e4f48b","decimalCount":18}]},{"id":"ladz","name":"LADZ","symbol":"LADZ","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1287c0509df9a475ef178471ab2132b9dfd312b3","decimalCount":4}]},{"id":"donut","name":"Donut","symbol":"DONUT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc0f9bd5fa5698b6505f643900ffa515ea5df54a9","decimalCount":18}]},{"id":"cardwallet","name":"CardWallet","symbol":"CW","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd55236d48606c295adebf129dad04fc74bfaa708","decimalCount":18}]},{"id":"work-quest","name":"Work Quest","symbol":"WQT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x06677dc4fe12d3ba3c7ccfd0df8cd45e4d4095bf","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xe89508d74579a06a65b907c91f697cf4f8d9fac7","decimalCount":18}]},{"id":"zip","name":"Zipper Network","symbol":"ZIP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa9d2927d3a04309e008b6af6e2e282ae2952e7fd","decimalCount":18}]},{"id":"moonfarm-finance","name":"MoonFarm Finance","symbol":"MFO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xb46049c79d77ff1d555a67835fba6978536581af","decimalCount":18}]},{"id":"genomesdao","name":"GenomesDAO","symbol":"$GENE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x21413c119b0c11c5d96ae1bd328917bc5c8ed67e","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x34667ed7c36cbbbf2d5d5c5c8d6eb76a094edb9f","decimalCount":18}]},{"id":"appcoins","name":"AppCoins","symbol":"APPC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1a7a8bd9106f2b8d977e08582dc7d24c723ab0db","decimalCount":18}]},{"id":"bountymarketcap","name":"BountyMarketCap","symbol":"BMC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd945d2031b4c63c0e363304fb771f709b502dc0a","decimalCount":18}]},{"id":"metagamehub-dao","name":"MetaGameHub DAO","symbol":"MGH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8765b1a0eb57ca49be7eacd35b24a574d0203656","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xc3c604f1943b8c619c5d65cd11a876e9c8edcf10","decimalCount":18}]},{"id":"metarun","name":"Metarun","symbol":"MRUN","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xca0d640a401406f3405b4c252a5d0c4d17f38ebb","decimalCount":18}]},{"id":"dfsocial-gaming-2","name":"DFSocial Gaming","symbol":"DFSG","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x612c49b95c9121107be3a2fe1fcf1efc1c4730ad","decimalCount":18}]},{"id":"world-token","name":"World Token","symbol":"WORLD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbf494f02ee3fde1f20bee6242bce2d1ed0c15e47","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x31ffbe9bf84b4d9d02cd40eccab4af1e2877bbc6","decimalCount":18}]},{"id":"libre-defi","name":"Libre DeFi","symbol":"LIBRE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x63db060697b01c6f4a26561b1494685dcbbd998c","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x8afa62fa8dde8888405c899d7da077a61a87eed3","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xf52d69bc301be21cbed7d3ca652d1708ff8a1162","decimalCount":18}]},{"id":"axial-token","name":"Axial Token","symbol":"AXIAL","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0xcf8419a615c57511807236751c0af38db4ba3351","decimalCount":18}]},{"id":"sugarbounce","name":"SugarBounce","symbol":"TIP","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x40f906e19b14100d5247686e08053c4873c66192","decimalCount":18}]},{"id":"defrost-finance","name":"Defrost Finance","symbol":"MELT","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0x47eb6f7525c1aa999fbc9ee92715f5231eb1241d","decimalCount":18}]},{"id":"kurobi","name":"Kurobi","symbol":"KURO","active":true,"networks":[{"networkId":"solana","contractAddress":"2Kc38rfQ49DFaKHQaWbijkE7fcymUMLY5guUiUsDmFfn","decimalCount":6}]},{"id":"avme","name":"AVME","symbol":"AVME","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0x1ecd47ff4d9598f89721a2866bfeb99505a413ed","decimalCount":18}]},{"id":"lavax-labs","name":"LavaX Labs","symbol":"LAVAX","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xa9be3cd803fa19f2af24412ff0a2a4a67a29de88","decimalCount":18}]},{"id":"silverstonks","name":"Silver Stonks","symbol":"SSTX","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x5396734569e26101677eb39c89413f7fa7d8006f","decimalCount":7}]},{"id":"ethernaal","name":"Ethernaal","symbol":"NAAL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc133529e57681b2999708f9458be5634e293995e","decimalCount":18}]},{"id":"aca-token","name":"ACA","symbol":"ACA","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x9eb6935aea6afb5bc6d1a74be0c2f78280ab6448","decimalCount":9}]},{"id":"dynamix","name":"Dynamix","symbol":"DYNA","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xc41689a727469c1573009757200371edf36d540e","decimalCount":9}]},{"id":"bobo-cash","name":"Bobo Cash","symbol":"BOBO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf53c24f7729c88c110265929c7124e6259efccab","decimalCount":9}]},{"id":"tardigrades-finance","name":"Tardigrades Finance","symbol":"TRDG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x92a42db88ed0f02c71d439e55962ca7cab0168b5","decimalCount":9},{"networkId":"binance-smart-chain","contractAddress":"0x92a42db88ed0f02c71d439e55962ca7cab0168b5","decimalCount":9}]},{"id":"kingspeed","name":"KingSpeed","symbol":"KSC","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x3ac0f8cecc1fb0ee6c2017a072d52e85b00c6694","decimalCount":18}]},{"id":"spindle","name":"SPINDLE","symbol":"SPD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1dea979ae76f26071870f824088da78979eb91c8","decimalCount":18}]},{"id":"blockmason-credit-protocol","name":"Blockmason Credit Protocol","symbol":"BCPT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1c4481750daa5ff521a2a7490d9981ed46465dbd","decimalCount":18}]},{"id":"coinfi","name":"CoinFi","symbol":"COFI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3136ef851592acf49ca4c825131e364170fa32b3","decimalCount":18}]},{"id":"vether","name":"Vether","symbol":"VETH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4ba6ddd7b89ed838fed25d208d4f644106e34279","decimalCount":18}]},{"id":"nemesis-dao","name":"Nemesis DAO","symbol":"NMS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x8ac9dc3358a2db19fdd57f433ff45d1fc357afb3","decimalCount":9}]},{"id":"etherparty","name":"Etherparty","symbol":"FUEL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xea38eaa3c86c8f9b751533ba2e562deb9acded40","decimalCount":18}]},{"id":"krown","name":"KROWN","symbol":"KRW","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x499568c250ab2a42292261d6121525d70691894b","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x1446f3cedf4d86a9399e49f7937766e6de2a3aab","decimalCount":18},{"networkId":"avalanche","contractAddress":"0xa5acfeca5270bc9768633fbc86caa959b85ec8b7","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x6c3b2f402cd7d22ae2c319b9d2f16f57927a4a17","decimalCount":18}]},{"id":"aidcoin","name":"AidCoin","symbol":"AID","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x37e8789bb9996cac9156cd5f5fd32599e6b91289","decimalCount":18}]},{"id":"meliora","name":"Meliora","symbol":"MORA","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xeb633ec737889eba802478aea7eb0f5203eb8deb","decimalCount":18}]},{"id":"argon","name":"Argon","symbol":"ARGON","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x851f7a700c5d67db59612b871338a85526752c25","decimalCount":18}]},{"id":"adaboy","name":"ADABoy","symbol":"ADABOY","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x1e653794a6849bc8a78be50c4d48981afad6359d","decimalCount":18}]},{"id":"ethereum-stake","name":"Ethereum Stake","symbol":"ETHYS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd0d3ebcad6a20ce69bc3bc0e1ec964075425e533","decimalCount":18}]},{"id":"bartertrade","name":"BarterTrade","symbol":"BART","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x54c9ea2e9c9e8ed865db4a4ce6711c2a0d5063ba","decimalCount":18}]},{"id":"daoventures","name":"DAOventures","symbol":"DVD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x77dce26c03a9b833fc2d7c31c22da4f42e9d9582","decimalCount":18}]},{"id":"ghospers-game","name":"Ghospers Game","symbol":"GHSP","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x4a0cc0876ec16428a4fa4a7c4c300de2db73b75b","decimalCount":18}]},{"id":"macaronswap","name":"MacaronSwap","symbol":"MCRN","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xacb2d47827c9813ae26de80965845d80935afd0b","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xba25b552c8a098afdf276324c32c71fe28e0ad40","decimalCount":18}]},{"id":"goldmint","name":"Goldmint","symbol":"MNTP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x83cee9e086a77e492ee0bb93c2b0437ad6fdeccc","decimalCount":18}]},{"id":"totemfi","name":"TotemFi","symbol":"TOTM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6ff1bfa14a57594a5874b37ff6ac5efbd9f9599a","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x6ff1bfa14a57594a5874b37ff6ac5efbd9f9599a","decimalCount":18}]},{"id":"hugo-finance","name":"Hugo Game","symbol":"HUGO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xce195c777e1ce96c30ebec54c91d20417a068706","decimalCount":9}]},{"id":"investdex","name":"InvestDex","symbol":"INVEST","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x853a8ab1c365ea54719eb13a54d6b22f1fbe7feb","decimalCount":18}]},{"id":"defipie","name":"DeFiPie","symbol":"PIE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x607c794cda77efb21f8848b7910ecf27451ae842","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xc4b35d3a24e3e8941c5d87fd21d0725642f50308","decimalCount":18}]},{"id":"blitzpredict","name":"BlitzPick","symbol":"XBP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x28dee01d53fed0edf5f6e310bf8ef9311513ae40","decimalCount":18}]},{"id":"yup","name":"Yup","symbol":"YUP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x69bbc3f8787d573f1bbdd0a5f40c7ba0aee9bcc9","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x086373fad3447f7f86252fb59d56107e9e0faafa","decimalCount":18}]},{"id":"iht-real-estate-protocol","name":"IHT Real Estate Protocol","symbol":"IHT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xeda8b016efa8b1161208cf041cd86972eee0f31e","decimalCount":18}]},{"id":"mmaon","name":"MMAON","symbol":"MMAON","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8315472bae77f9a2b856a67eb0796480aafcd51c","decimalCount":18}]},{"id":"metaverse-exchange","name":"Metaverse Exchange","symbol":"METACEX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd796b8eff23d5c4c71f43c99ffd7d8a3119f7475","decimalCount":18}]},{"id":"remme","name":"Remme","symbol":"REM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x83984d6142934bb535793a82adb0a46ef0f66b6d","decimalCount":4}]},{"id":"spaceswap-shake","name":"Spaceswap SHAKE","symbol":"SHAKE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6006fc2a849fedaba8330ce36f5133de01f96189","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xba8a6ef5f15ed18e7184f44a775060a6bf91d8d0","decimalCount":18},{"networkId":"avalanche","contractAddress":"0xc1d02e488a9ce2481bfdcd797d5373dd2e70a9c2","decimalCount":18}]},{"id":"cashcow","name":"CashCow","symbol":"COW","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x8b6fa031c7d2e60fbfe4e663ec1b8f37df1ba483","decimalCount":9}]},{"id":"vodi-x","name":"Vodi X","symbol":"VDX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x91e64f39c1fe14492e8fdf5a8b0f305bd218c8a1","decimalCount":18}]},{"id":"dmarket","name":"DMarket","symbol":"DMT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2ccbff3a042c68716ed2a2cb0c544a9f1d1935e1","decimalCount":8}]},{"id":"otcbtc-token","name":"OTCBTC Token","symbol":"OTB","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa86a0da9d05d0771955df05b44ca120661af16de","decimalCount":18}]},{"id":"indorse","name":"Indorse","symbol":"IND","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf8e386eda857484f5a12e4b5daa9984e06e73705","decimalCount":18}]},{"id":"blind-boxes","name":"Blind Boxes","symbol":"BLES","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe796d6ca1ceb1b022ece5296226bf784110031cd","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x393d87e44c7b1f5ba521b351532c24ece253b849","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x1b599beb7b1f50807dd58fd7e8ffcf073b435e71","decimalCount":18}]},{"id":"tiki-token","name":"Tiki","symbol":"TIKI","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x9b76d1b12ff738c113200eb043350022ebf12ff0","decimalCount":18}]},{"id":"stobox-token","name":"Stobox","symbol":"STBU","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa6422e3e219ee6d4c1b18895275fe43556fd50ed","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xb0c4080a8fa7afa11a09473f3be14d44af3f8743","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xcf403036bc139d30080d2cf0f5b48066f98191bb","decimalCount":18}]},{"id":"crypto-inu","name":"Crypto Inu","symbol":"ABCD","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xa0cc3a881aef241d6cb3b7db3168bd26094560be","decimalCount":9}]},{"id":"privateum","name":"Privateum","symbol":"PVM","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x71aff23750db1f4edbe32c942157a478349035b2","decimalCount":18}]},{"id":"decentbet","name":"DecentBet","symbol":"DBET","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9b68bfae21df5a510931a262cecf63f41338f264","decimalCount":18}]},{"id":"dogeswap","name":"Dogeswap","symbol":"DOGES","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb4fbed161bebcb37afb1cb4a6f7ca18b977ccb25","decimalCount":18}]},{"id":"deathroad","name":"DeathRoad","symbol":"DRACE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xa6c897caaca3db7fd6e2d2ce1a00744f40ab87bb","decimalCount":18}]},{"id":"mirrored-united-states-oil-fund","name":"Mirrored United States Oil Fund","symbol":"MUSO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x31c63146a635eb7465e5853020b39713ac356991","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x9cddf33466ce007676c827c76e799f5109f1843c","decimalCount":18}]},{"id":"umi-digital","name":"Umi Digital","symbol":"UMI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x61107a409fffe1965126aa456af679719695c69c","decimalCount":18}]},{"id":"graviton-zero","name":"Graviton Zero","symbol":"GRAV","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xa6168c7e5eb7c5c379f3a1d7cf1073e09b2f031e","decimalCount":18}]},{"id":"mars","name":"Mars","symbol":"MARS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x66c0dded8433c9ea86c8cf91237b14e10b4d70b7","decimalCount":18}]},{"id":"unipower","name":"UniPower","symbol":"POWER","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf2f9a7e93f845b3ce154efbeb64fb9346fcce509","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x00d5149cdf7cec8725bf50073c51c4fa58ecca12","decimalCount":18}]},{"id":"dopewarz","name":"DopeWarz","symbol":"DRUG","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x27e2a0e643c7f17959f84c345d2123b77bbd412c","decimalCount":18}]},{"id":"kawaii-islands","name":"Kawaii Islands","symbol":"KWT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x257a8d1e03d17b8535a182301f15290f11674b53","decimalCount":18}]},{"id":"benchmark-protocol","name":"Benchmark Protocol","symbol":"MARK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x67c597624b17b16fb77959217360b7cd18284253","decimalCount":9}]},{"id":"xsigma","name":"xSigma","symbol":"SIG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7777777777697cfeecf846a76326da79cc606517","decimalCount":18}]},{"id":"liquidity-dividends-protocol","name":"Liquidity Dividends Protocol","symbol":"LID","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0417912b3a7af768051765040a55bb0925d4ddcf","decimalCount":18}]},{"id":"hakuswap","name":"HakuSwap","symbol":"HAKU","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0x695fa794d59106cebd40ab5f5ca19f458c723829","decimalCount":18}]},{"id":"adamant-coin","name":"Adamant Coin","symbol":"ADMC","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xa55ef2fb2b7b6a60371fd3def9b806e74a48be69","decimalCount":9}]},{"id":"name-changing-token","name":"Name Change Token","symbol":"NCT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8a9c4dfe8b9d8962b31e4e16f8321c44d48e246e","decimalCount":18}]},{"id":"xion-finance","name":"Xion Finance","symbol":"XGT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xc25af3123d2420054c8fcd144c21113aa2853f39","decimalCount":18}]},{"id":"bondappetit-gov-token","name":"BondAppetit Governance Token","symbol":"BAG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x28a06c02287e657ec3f8e151a13c36a1d43814b0","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x1ad0132d8b5ef3cebda1a9692f36ac30be871b6b","decimalCount":18}]},{"id":"doki-doki-finance","name":"Doki Doki","symbol":"DOKI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9ceb84f92a0561fa3cc4132ab9c0b76a59787544","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x5c7f7fe4766fe8f0fa9b41e2e4194d939488ff1c","decimalCount":18}]},{"id":"balpha","name":"bAlpha","symbol":"BALPHA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7a5ce6abd131ea6b148a022cb76fc180ae3315a6","decimalCount":18}]},{"id":"wrapped-cryptokitties","name":"Wrapped CryptoKitties","symbol":"WCK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x09fe5f0236f0ea5d930197dce254d77b04128075","decimalCount":18}]},{"id":"bintex-futures","name":"Bintex Futures","symbol":"BNTX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x86d1d12523b65203851c571fcc029bf90903fb6d","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x0ec04ece89609e545b8768e303986421ffc32eaf","decimalCount":18}]},{"id":"non-fungible-toke","name":"Non-Fungible TOKE","symbol":"TOKE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x98ddc72bd02d448f68c4226f26122c66c5bd711e","decimalCount":18}]},{"id":"astrotools","name":"AstroTools","symbol":"ASTRO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xcbd55d4ffc43467142761a764763652b48b969ff","decimalCount":18}]},{"id":"xiasi-inu","name":"Xiasi Inu","symbol":"XIASI","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x0e20e3216ea172fcf9eaa19723b119e090fd353f","decimalCount":9}]},{"id":"united-emirate-decentralized-coin","name":"United Emirate Decentralized Coin","symbol":"UEDC","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xf0b6e29c429bbb8e1448340f0776be933805344e","decimalCount":18}]},{"id":"pinkslip-finance","name":"Pinkslip Finance","symbol":"PSLIP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x36ce7a52cda404b8fa87a98d0d17ec7dd0b144ed","decimalCount":18}]},{"id":"wault-usd","name":"Wault USD","symbol":"WUSD","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x3ff997eaea488a082fb7efc8e6b9951990d0c3ab","decimalCount":18}]},{"id":"gameflip","name":"Gameflip","symbol":"FLP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3a1bda28adb5b0a812a7cf10a1950c920f79bcd3","decimalCount":18}]},{"id":"keytango","name":"keyTango","symbol":"TANGO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x182f4c4c97cd1c24e1df8fc4c053e5c47bf53bef","decimalCount":18}]},{"id":"ttcoin","name":"TTcoin","symbol":"TC","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x659049786cb66e4486b8c0e0ccc90a5929a21162","decimalCount":4},{"networkId":"tron","contractAddress":"TCMwzYUUCxLkTNpXjkYSBgXgqXwt7KJ82y","decimalCount":4}]},{"id":"sacks","name":"Sacks","symbol":"SACKS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa6610ed604047e7b76c1da288172d15bcda57596","decimalCount":18}]},{"id":"endor","name":"Endor Protocol Token","symbol":"EDR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc528c28fec0a90c083328bc45f587ee215760a0f","decimalCount":18}]},{"id":"nil-dao","name":"Nil DAO","symbol":"NIL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x47252a63c723889814aebcac0683e615624cec64","decimalCount":18}]},{"id":"moontools","name":"MoonTools","symbol":"MOONS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x260e63d91fccc499606bae3fe945c4ed1cf56a56","decimalCount":18}]},{"id":"dogedi","name":"DOGEDI","symbol":"DOGEDI","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xdc49d53330317cbc6924fa53042e0c9bca0a8d63","decimalCount":12}]},{"id":"yoyow","name":"YOYOW","symbol":"YOYOW","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xcbeaec699431857fdb4d37addbbdc20e132d4903","decimalCount":18}]},{"id":"dogeville","name":"DogeVille","symbol":"DVILLE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xd3b6bfd18b34ae0e3165738bf66ebc64cad1b944","decimalCount":18}]},{"id":"satopay","name":"SatoPay","symbol":"STOP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8c3ee4f778e282b59d42d693a97b80b1ed80f4ee","decimalCount":18}]},{"id":"open-governance-token","name":"OPEN Governance Token","symbol":"OPEN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x69e8b9528cabda89fe846c67675b5d73d463a916","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xf35262a9d427f96d2437379ef090db986eae5d42","decimalCount":18}]},{"id":"golden-ratio-token","name":"Golden Ratio Token","symbol":"GRT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb83cd8d39462b761bb0092437d38b37812dd80a2","decimalCount":18}]},{"id":"myra-ai","name":"Myra AI","symbol":"MYRA","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x5cd7d317d9cb4d46ff0b4f6a20d9547069fe0f27","decimalCount":18}]},{"id":"structure-finance","name":"Structure Finance","symbol":"STF","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1f4cb968b76931c494ff92ed80ccb169ad641cb1","decimalCount":18}]},{"id":"gaj","name":"Gaj Finance","symbol":"GAJ","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9fda7ceec4c18008096c2fe2b85f05dc300f94d0","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x595c8481c48894771ce8fade54ac6bf59093f9e8","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xf4b0903774532aee5ee567c02aab681a81539e92","decimalCount":18}]},{"id":"keep4r","name":"Keep4r","symbol":"KP4R","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa89ac6e529acf391cfbbd377f3ac9d93eae9664e","decimalCount":18}]},{"id":"alex","name":"Alex","symbol":"ALEX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8ba6dcc667d3ff64c1a2123ce72ff5f0199e5315","decimalCount":4}]},{"id":"plutos-network","name":"Plutos Network","symbol":"PLUT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x2984f825bfe72e55e1725d5c020258e81ff97450","decimalCount":18}]},{"id":"yetiswap","name":"YetiSwap","symbol":"YTS","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0x488f73cddda1de3664775ffd91623637383d6404","decimalCount":18}]},{"id":"squid","name":"SquidDao","symbol":"SQUID","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x21ad647b8f4fe333212e735bfc1f36b4941e6ad2","decimalCount":9}]},{"id":"gowithmi","name":"GoWithMi","symbol":"GMAT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb13de094cc5cee6c4cc0a3737bf0290166d9ca5d","decimalCount":18}]},{"id":"wrapped-virgin-gen-0-cryptokitties","name":"Wrapped Virgin Gen-0 CryptoKittties","symbol":"WVG0","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x25c7b64a93eb1261e130ec21a3e9918caa38b611","decimalCount":18}]},{"id":"cnn","name":"Content Neutrality Network","symbol":"CNN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8713d26637cf49e1b6b4a7ce57106aabc9325343","decimalCount":18}]},{"id":"basis-share","name":"Basis Share","symbol":"BAS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x106538cc16f938776c7c180186975bca23875287","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x83a6da342099835bcaa9c219dd76a5033c837de5","decimalCount":18}]},{"id":"wetrust","name":"WeTrust","symbol":"TRST","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xcb94be6f13a1182e4a4b6140cb7bf2025d28e41b","decimalCount":6}]},{"id":"nftmall","name":"NFTmall","symbol":"GEM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9b17baadf0f21f03e35249e0e59723f34994f806","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xbac1df744df160877cdc45e13d0394c06bc388ff","decimalCount":18},{"networkId":"avalanche","contractAddress":"0xdebb1d6a2196f2335ad51fbde7ca587205889360","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x4a7b9a4589a88a06ca29f99556db08234078d727","decimalCount":18}]},{"id":"tradao","name":"TraDAO","symbol":"TOD","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x21d5fa5ecf2605c0e835ae054af9bba0468e5951","decimalCount":9}]},{"id":"dragonbite","name":"DragonBite","symbol":"BITE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4eed0fa8de12d5a86517f214c2f11586ba2ed88d","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xde69c05e8121ef0db29c3d9ceceda6ef6b606d0c","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x280724409b288de06c6d66c05965d3d456e2283a","decimalCount":18}]},{"id":"shar-pei","name":"Shar Pei","symbol":"SHARPEI","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xfe3af7376e412a377358d5894c790bb3e00d0dc1","decimalCount":18}]},{"id":"givly-coin","name":"GIV Token","symbol":"GIV","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf6537fe0df7f0cc0985cf00792cc98249e73efa0","decimalCount":8}]},{"id":"yam-v2","name":"YAM v2","symbol":"YAMV2","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xaba8cac6866b83ae4eec97dd07ed254282f6ad8a","decimalCount":24}]},{"id":"catbread","name":"CatBread","symbol":"CATBREAD","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x74a6e371f95073005b3a5faf4a9e25ae30290f94","decimalCount":9}]},{"id":"stox","name":"Stox","symbol":"STX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x006bea43baa3f7a6f765f14f10a1a1b08334ef45","decimalCount":18}]},{"id":"nfx-coin","name":"NFX Coin","symbol":"NFXC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2d39ec4da54329d28d230b4973f5aa27886c3aee","decimalCount":18}]},{"id":"seigniorage-shares","name":"Seigniorage Shares","symbol":"SHARE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x39795344cbcc76cc3fb94b9d1b15c23c2070c66d","decimalCount":9}]},{"id":"chartex","name":"ChartEx","symbol":"CHART","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1d37986f252d0e349522ea6c3b98cb935495e63e","decimalCount":18}]},{"id":"cream-eth2","name":"Cream ETH 2","symbol":"CRETH2","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xcbc1065255cbc3ab41a6868c22d1f1c573ab89fd","decimalCount":18}]},{"id":"bscwin-bulls","name":"BSCWIN Bulls","symbol":"BSCWIN","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x73b01a9c8379a9d3009f2351f22583f8b75cc1ba","decimalCount":9}]},{"id":"u-network","name":"U Network","symbol":"UUU","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3543638ed4a9006e4840b105944271bcea15605d","decimalCount":18}]},{"id":"mytoken","name":"MyToken","symbol":"MT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9b4e2b4b13d125238aa0480dd42b4f6fc71b37cc","decimalCount":18}]},{"id":"wallfair","name":"Wallfair","symbol":"WFAIR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc6065b9fc8171ad3d29bad510709249681758972","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xb6b5cdf74606181a1b05bfc0b9f17fc2a64b0cd5","decimalCount":18}]},{"id":"zerogoki","name":"Zerogoki","symbol":"REI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x011864d37035439e078d64630777ec518138af05","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x765b85839717ebfc84378b83381a4814897a0506","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xb9f9e37c2cdbaff928c3da730b02f06fe09ae70e","decimalCount":18}]},{"id":"avaxtars","name":"Avaxtars","symbol":"AVXT","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0x397bbd6a0e41bdf4c3f971731e180db8ad06ebc1","decimalCount":6}]},{"id":"rare","name":"Rare","symbol":"RARE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x81b1bfd6cb9ad42db395c2a27f73d4dcf5777e2d","decimalCount":4}]},{"id":"dark-matter","name":"Dark Matter","symbol":"DMT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x79126d32a86e6663f3aaac4527732d0701c1ae6c","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xd28449bb9bb659725accad52947677cce3719fd7","decimalCount":18}]},{"id":"xiotri","name":"Xiotri","symbol":"XIOT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x31024a4c3e9aeeb256b825790f5cb7ac645e7cd5","decimalCount":3}]},{"id":"mochi-market","name":"Mochi Market","symbol":"MOMA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbd1848e1491d4308ad18287a745dd4db2a4bd55b","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xb72842d6f5fedf91d22d56202802bb9a79c6322e","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xe3ab61371ecc88534c522922a026f2296116c109","decimalCount":18}]},{"id":"node-squared","name":"Node Squared","symbol":"N2","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6110c64219621ce5b02fb8e8e57b54c01b83bf85","decimalCount":9}]},{"id":"metafluence","name":"Metafluence","symbol":"METO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xa78775bba7a542f291e5ef7f13c6204e704a90ba","decimalCount":18}]},{"id":"hydro","name":"Hydro","symbol":"HYDRO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x946112efab61c3636cbd52de2e1392d7a75a6f01","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xf3dbb49999b25c9d6641a9423c7ad84168d00071","decimalCount":18}]},{"id":"flurry","name":"Flurry Finance","symbol":"FLURRY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x60f63b76e2fc1649e57a3489162732a90acf59fe","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x47c9bcef4fe2dbcdf3abf508f147f1bbe8d4fef2","decimalCount":18}]},{"id":"dexfolio","name":"Dexfolio","symbol":"DEXF","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xb9844a9cb6abd9f86bb0b3ad159e37eecce08987","decimalCount":18}]},{"id":"sharder-protocol","name":"Sharder protocol","symbol":"SS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbbff862d906e348e9946bfb2132ecb157da3d4b4","decimalCount":18}]},{"id":"dfund","name":"dFund","symbol":"DFND","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd2adc1c84443ad06f0017adca346bd9b6fc52cab","decimalCount":18}]},{"id":"acoconut","name":"ACoconut","symbol":"AC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9a0aba393aac4dfbff4333b06c407458002c6183","decimalCount":18}]},{"id":"reflect-finance","name":"reflect.finance","symbol":"RFI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa1afffe3f4d611d252010e3eaf6f4d77088b0cd7","decimalCount":9}]},{"id":"maincoin","name":"MainCoin","symbol":"MNC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9f0f1be08591ab7d990faf910b38ed5d60e4d5bf","decimalCount":18}]},{"id":"odem","name":"ODEM","symbol":"ODE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbf52f2ab39e26e0951d2a02b49b7702abe30406a","decimalCount":18}]},{"id":"catex-token","name":"Catex Token","symbol":"CATT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6e605c269e0c92e70beeb85486f1fc550f9380bd","decimalCount":18}]},{"id":"lys-capital","name":"LYS Capital","symbol":"LYS","active":true,"networks":[{"networkId":"arbitrum-one","contractAddress":"0xa4f595ba35161c9ffe3db8c03991b9c2cbb26c6b","decimalCount":18}]},{"id":"bonfi","name":"BonFi","symbol":"BNF","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1de5e000c41c8d35b9f1f4985c23988f05831057","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xca14caf9e8dd2793e7010fc48dfe6c6af8445136","decimalCount":18}]},{"id":"cryptotask-2","name":"CryptoTask","symbol":"CTASK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x196c81385bc536467433014042788eb707703934","decimalCount":18}]},{"id":"jade-currency","name":"Jade Currency","symbol":"JADE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x330f4fe5ef44b4d0742fe8bed8ca5e29359870df","decimalCount":18}]},{"id":"fufu","name":"Fufu","symbol":"FUFU","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x509a51394cc4d6bb474fefb2994b8975a55a6e79","decimalCount":18}]},{"id":"stater","name":"Stater","symbol":"STR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x84bb947fcedba6b9c7dcead42df07e113bb03007","decimalCount":18}]},{"id":"alt-estate","name":"AltEstate Token","symbol":"ALT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x419b8ed155180a8c9c64145e76dad49c0a4efb97","decimalCount":18}]},{"id":"crdt","name":"CRDT","symbol":"CRDT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xdaab5e695bb0e8ce8384ee56ba38fa8290618e52","decimalCount":18}]},{"id":"knit-finance","name":"Knit Finance","symbol":"KFT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xef53462838000184f35f7d991452e5f25110b207","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x1b41a1ba7722e6431b1a782327dbe466fe1ee9f9","decimalCount":18}]},{"id":"keysians-network","name":"Keysians Network","symbol":"KEN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6a7ef4998eb9d0f706238756949f311a59e05745","decimalCount":18}]},{"id":"yearn-secure","name":"Yearn Secure","symbol":"YSEC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xeea9ae787f3a620072d13b2cdc8cabffb9c0ab96","decimalCount":18}]},{"id":"leverj-gluon","name":"Leverj Gluon","symbol":"L2","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbbff34e47e559ef680067a6b1c980639eeb64d24","decimalCount":18}]},{"id":"twinci","name":"Twinci","symbol":"TWIN","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xaf83f292fced83032f52ced45ef7dbddb586441a","decimalCount":18}]},{"id":"ydragon","name":"YDragon","symbol":"YDR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x3757232b55e60da4a8793183ac030cfce4c3865d","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x3757232b55e60da4a8793183ac030cfce4c3865d","decimalCount":18},{"networkId":"avalanche","contractAddress":"0xf03dccaec9a28200a6708c686cf0b8bf26ddc356","decimalCount":18}]},{"id":"everex","name":"Everex","symbol":"EVX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf3db5fa2c66b7af3eb0c0b782510816cbe4813b8","decimalCount":4}]},{"id":"checkdot","name":"CheckDot","symbol":"CDT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x0cbd6fadcf8096cc9a43d90b45f65826102e3ece","decimalCount":18}]},{"id":"vicewrld","name":"Vicewrld","symbol":"VICE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xeea06fc74182b195f679f31d735d95ee502f03f3","decimalCount":18}]},{"id":"hackspace-capital","name":"Hackspace Capital","symbol":"HAC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x43567eb78638a55bbe51e9f9fb5b2d7ad1f125aa","decimalCount":4}]},{"id":"somee-advertising-token","name":"SoMee Advertising","symbol":"SAT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc9f1016d336ef77aee75fc11ad64c5ecf9121332","decimalCount":18}]},{"id":"safewhale","name":"SafeWhale","symbol":"SWHAL","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x4048a31e0a4fa577d343290835b34ebb4e3dbb1b","decimalCount":18}]},{"id":"riskmoon","name":"Riskmoon","symbol":"RISKMOON","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xa96f3414334f5a0a529ff5d9d8ea95f42147b8c9","decimalCount":9}]},{"id":"proton-token","name":"Proton Token","symbol":"PTT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4689a4e169eb39cc9078c0940e21ff1aa8a39b9c","decimalCount":18}]},{"id":"ethereum-gold-project","name":"Ethereum Gold Project","symbol":"ETGP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa96f31f1c187c28980176c3a27ba7069f48abde4","decimalCount":8}]},{"id":"solchicks-shards","name":"SolChicks Shards","symbol":"SHARDS","active":true,"networks":[{"networkId":"solana","contractAddress":"8j3hXRK5rdoZ2vSpGLRmXtWmW6iYaRUw5xVk4Kzmc9Hp","decimalCount":9}]},{"id":"diamond-coin","name":"Diamond Coin","symbol":"DIAMOND","active":true,"networks":[{"networkId":"fantom","contractAddress":"0xdda0f0e1081b8d64ab1d64621eb2679f93086705","decimalCount":18}]},{"id":"gambit","name":"Gambit","symbol":"GMT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x99e92123eb77bc8f999316f622e5222498438784","decimalCount":18}]},{"id":"lever-network","name":"Lever Network","symbol":"LEV","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbc194e6f748a222754c3e8b9946922c09e7d4e91","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xbc194e6f748a222754c3e8b9946922c09e7d4e91","decimalCount":18}]},{"id":"hanu-yokia","name":"Hanu Yokia","symbol":"HANU","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x72e5390edb7727e3d4e3436451dadaff675dbcc0","decimalCount":12},{"networkId":"binance-smart-chain","contractAddress":"0xdae4f1dca49408288b55250022f67195eff2445a","decimalCount":12},{"networkId":"polygon-pos","contractAddress":"0x709a4b6217584188ddb93c82f5d716d969acce1c","decimalCount":12}]},{"id":"cryptotycoon","name":"CryptoTycoon","symbol":"CTT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x464863745ed3af8b9f8871f1082211c55f8f884d","decimalCount":18}]},{"id":"bethereum","name":"Bethereum","symbol":"BETHER","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x14c926f2290044b647e1bf2072e67b495eff1905","decimalCount":18}]},{"id":"smartshare","name":"Smartshare","symbol":"SSP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x624d520bab2e4ad83935fa503fb130614374e850","decimalCount":4}]},{"id":"curio-governance","name":"Curio Governance","symbol":"CGT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf56b164efd3cfc02ba739b719b6526a6fa1ca32a","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x3d04edc843e74935c09f54cc4b2fe1870e347ac9","decimalCount":18}]},{"id":"merchdao","name":"MerchDAO","symbol":"MRCH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbed4ab0019ff361d83ddeb74883dac8a70f5ea1e","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x4df071fb2d145be595b767f997c91818694a6ce1","decimalCount":18}]},{"id":"fantomstarter","name":"FantomStarter","symbol":"FS","active":true,"networks":[{"networkId":"fantom","contractAddress":"0xc758295cd1a564cdb020a78a681a838cf8e0627d","decimalCount":18}]},{"id":"more-token","name":"More","symbol":"MORE","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0xd9d90f882cddd6063959a9d837b05cb748718a05","decimalCount":18}]},{"id":"obtoken","name":"OB","symbol":"OBT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x8da6113655309f84127e0837fcf5c389892578b3","decimalCount":18}]},{"id":"afen-blockchain","name":"AFEN Blockchain","symbol":"AFEN","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xd0840d5f67206f865aee7cce075bd4484cd3cc81","decimalCount":18}]},{"id":"flux","name":"Datamine FLUX","symbol":"FLUX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x469eda64aed3a3ad6f868c44564291aa415cb1d9","decimalCount":18}]},{"id":"kassandra","name":"Kassandra","symbol":"KACY","active":true,"networks":[{"networkId":"avalanche","contractAddress":"0xf32398dae246c5f672b52a54e9b413dffcae1a44","decimalCount":18}]},{"id":"mirrored-netflix","name":"Mirrored Netflix","symbol":"MNFLX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc8d674114bac90148d11d3c1d33c61835a0f9dcd","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xa04f060077d90fe2647b61e4da4ad1f97d6649dc","decimalCount":18}]},{"id":"stronghands-finance","name":"StrongHands Finance","symbol":"ISHND","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x1cc1aca0dae2d6c4a0e8ae7b4f2d01eabbc435ee","decimalCount":18}]},{"id":"mirrored-google","name":"Mirrored Google","symbol":"MGOOGL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x59a921db27dd6d4d974745b7ffc5c33932653442","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x62d71b23bf15218c7d2d7e48dbbd9e9c650b173f","decimalCount":18}]},{"id":"moonbear-finance","name":"MoonBear.Finance","symbol":"MBF","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xe2997ae926c7a76af782923a7fef89f36d86c98f","decimalCount":9}]},{"id":"coinsbit-token","name":"Coinsbit Token","symbol":"CNB","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc538143202f3b11382d8606aae90a96b042a19db","decimalCount":18}]},{"id":"cryption-network","name":"Cryption Network","symbol":"CNT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x429876c4a6f89fb470e92456b8313879df98b63c","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xd1e6354fb05bf72a8909266203dab80947dceccf","decimalCount":18}]},{"id":"0xcert","name":"0xcert","symbol":"ZXC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x83e2be8d114f9661221384b3a50d24b96a5653f5","decimalCount":18}]},{"id":"hero-inu","name":"Heros","symbol":"HEROS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xb622400807765e73107b7196f444866d7edf6f62","decimalCount":9},{"networkId":"binance-smart-chain","contractAddress":"0xd1673c00ac7010bf2c376ebea43633dd61a81016","decimalCount":9}]},{"id":"srcoin","name":"SRH","symbol":"SRH","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc350e846e2c57f9eece90febc253d14c8080871b","decimalCount":18}]},{"id":"0xmonero","name":"0xMonero","symbol":"0XMR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x035df12e0f3ac6671126525f1015e47d79dfeddf","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x22a213852cee93eb6d41601133414d180c5684c2","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x52ede6bba83b7b4ba1d738df0df713d6a2036b71","decimalCount":18},{"networkId":"fantom","contractAddress":"0xab41861399eb56896b24fbaabaa8bce45e4a626b","decimalCount":18}]},{"id":"index-coop-matic-2x-flexible-leverage-index","name":"Index Coop - MATIC 2x Flexible Leverage Index","symbol":"MATIC2X-FLI-P","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0xf287d97b6345bad3d88856b26fb7c0ab3f2c7976","decimalCount":18}]},{"id":"noderunners","name":"Node Runners","symbol":"NDR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x739763a258640919981f9ba610ae65492455be53","decimalCount":18}]},{"id":"degenvc","name":"DegenVC","symbol":"DGVC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x26e43759551333e57f073bb0772f50329a957b30","decimalCount":18}]},{"id":"krypto-kitty","name":"Krypto Kitty","symbol":"KTY","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x86296279c147bd40cbe5b353f83cea9e9cc9b7bb","decimalCount":9}]},{"id":"lien","name":"Lien","symbol":"LIEN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xab37e1358b639fd877f015027bb62d3ddaa7557e","decimalCount":8},{"networkId":"binance-smart-chain","contractAddress":"0x5d684adaf3fcfe9cfb5cede3abf02f0cdd1012e3","decimalCount":8}]},{"id":"value-finance","name":"Value Finance","symbol":"VFT","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x14e8bcd053e68a22f239b9e9bead87932465d245","decimalCount":18}]},{"id":"yeld-finance","name":"Yeld Finance","symbol":"YELD","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x468ab3b1f63a1c14b361bc367c3cc92277588da1","decimalCount":18}]},{"id":"infinitypad","name":"InfinityPad","symbol":"INFP","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xfe82eff54a58c21ffc9523c4998d5dad84dcbd50","decimalCount":18}]},{"id":"wtf-token","name":"Fees.wtf","symbol":"WTF","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa68dd8cb83097765263adad881af6eed479c4a33","decimalCount":18}]},{"id":"defiville-island","name":"DefiVille Island","symbol":"ISLA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x20a68f9e34076b2dc15ce726d7eebb83b694702d","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xfe6a2342f7c5d234e8496df12c468be17e0c181f","decimalCount":18}]},{"id":"mirrored-ishares-gold-trust","name":"Mirrored iShares Gold Trust","symbol":"MIAU","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1d350417d9787e000cc1b95d70e9536dcd91f373","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x1658aed6c7dbab2ddbd8f5d898b0e9eab0305813","decimalCount":18}]},{"id":"one-cash","name":"One Cash","symbol":"ONC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd90e69f67203ebe02c917b5128629e77b4cd92dc","decimalCount":18}]},{"id":"medi-token","name":"Medi","symbol":"MEDI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x24b20da7a2fa0d1d5afcd693e1c8afff20507efd","decimalCount":9}]},{"id":"sechain","name":"SeChain","symbol":"SNN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf5717f5df41ea67ef67dfd3c1d02f9940bcf5d08","decimalCount":3},{"networkId":"binance-smart-chain","contractAddress":"0xa997e5aaae60987eb0b59a336dce6b158b113100","decimalCount":3}]},{"id":"skyrim-finance","name":"Skyrim Finance","symbol":"SKYRIM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2610f0bfc21ef389fe4d03cfb7de9ac1e6c99d6e","decimalCount":18}]},{"id":"melalie","name":"MELX","symbol":"MEL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xed0889f7e1c7c7267407222be277e1f1ef4d4892","decimalCount":18}]},{"id":"etha-lend","name":"ETHA Lend","symbol":"ETHA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x59e9261255644c411afdd00bd89162d09d862e38","decimalCount":18}]},{"id":"crusaders-of-crypto","name":"Crusaders of Crypto","symbol":"CRUSADER","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x6289812163af9421e566b3d74774074fac2a0441","decimalCount":9}]},{"id":"cryptobonusmiles","name":"CryptoBonusMiles","symbol":"CBM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x95efd1fe6099f65a7ed524def487483221094947","decimalCount":18},{"networkId":"binancecoin","contractAddress":"CBM-4B2","decimalCount":8}]},{"id":"buymainstreet","name":"BuyMainStreet","symbol":"$MAINST","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x8fc1a944c149762b6b578a06c0de2abd6b7d2b89","decimalCount":9}]},{"id":"tendies","name":"Tendies","symbol":"TEND","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1453dbb8a29551ade11d89825ca812e05317eaeb","decimalCount":18}]},{"id":"nasdex-token","name":"NASDEX","symbol":"NSDX","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0xe8d17b127ba8b9899a160d9a07b69bca8e08bfc6","decimalCount":18}]},{"id":"morphie","name":"Morphie","symbol":"MRFI","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xaf1167b1f90e4f27d9f520a4cd3a1e452e011cea","decimalCount":18},{"networkId":"avalanche","contractAddress":"0x05e481b19129b560e921e487adb281e70bdba463","decimalCount":18}]},{"id":"safeswap-token","name":"Safeswap SSGTX","symbol":"SSGTX","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0xd0cfd20e8bbdb7621b705a4fd61de2e80c2cd02f","decimalCount":18}]},{"id":"wault","name":"Wault","symbol":"WAULTX","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xb64e638e60d154b43f660a6bf8fd8a3b249a6a21","decimalCount":18}]},{"id":"lucha","name":"Lucha","symbol":"LUCHA","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0x6749441fdc8650b5b5a854ed255c82ef361f1596","decimalCount":18}]},{"id":"datamine","name":"Datamine","symbol":"DAM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf80d589b3dbe130c270a69f1a69d050f268786df","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0xb75bbd79985a8092b05224f62d7fed25924b075d","decimalCount":18}]},{"id":"polkacipher","name":"PolkaCipher","symbol":"CPHR","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x7428be82fd79d4c98650a7c67de9682a64fcab71","decimalCount":18}]},{"id":"updog","name":"UpDog","symbol":"UPDOG","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x400613f184d1207f5c07a67d67040a4e23e92feb","decimalCount":9}]},{"id":"catbonk","name":"Catbonk","symbol":"CABO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xdfaabaa57dec10c049335bdaa2e949b4ce2ead30","decimalCount":9}]},{"id":"app-alliance-association","name":"AAAchain","symbol":"AAA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6aba1623ea906d1164cbb007e764ebde2514a2ba","decimalCount":10}]},{"id":"ownly","name":"Ownly","symbol":"OWN","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x7665cb7b0d01df1c9f9b9cc66019f00abd6959ba","decimalCount":18}]},{"id":"mib-coin","name":"MIB Coin","symbol":"MIB","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x146d8d942048ad517479c9bab1788712af180fde","decimalCount":18}]},{"id":"collateral-pay","name":"Collateral Pay","symbol":"COLL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x957891c11616d3e0b0a76a76fb42724c382e0ef3","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xa4cb040b85e94f5c0c32ea1151b20d3ab40b3493","decimalCount":18}]},{"id":"unity-network","name":"Unity Network","symbol":"UNT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8d610e20481f4c4f3acb87bba9c46bef7795fdfe","decimalCount":18}]},{"id":"piplcoin","name":"PiplCoin","symbol":"PIPL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe64509f0bf07ce2d29a7ef19a8a9bc065477c1b4","decimalCount":8}]},{"id":"fuzex","name":"FuzeX","symbol":"FXT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1829aa045e21e0d59580024a951db48096e01782","decimalCount":18}]},{"id":"jetcoin","name":"Jetcoin","symbol":"JET","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8727c112c712c4a03371ac87a74dd6ab104af768","decimalCount":18}]},{"id":"2gether-2","name":"2gether","symbol":"2GT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc96c1609a1a45ccc667b2b7fa6508e29617f7b69","decimalCount":18}]},{"id":"bcv","name":"BitCapitalVendor","symbol":"BCV","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1014613e2b3cbc4d575054d4982e580d9b99d7b1","decimalCount":8}]},{"id":"1million-token","name":"1Million Token","symbol":"1MT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xf0bc1ae4ef7ffb126a8347d06ac6f8add770e1ce","decimalCount":7},{"networkId":"binance-smart-chain","contractAddress":"0x8d67448d4f6231abc070a42a8905084b79e09136","decimalCount":7}]},{"id":"insula","name":"Insula","symbol":"ISLA","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x697ef32b4a3f5a4c39de1cb7563f24ca7bfc5947","decimalCount":18}]},{"id":"typhoon-network","name":"Typhoon Network","symbol":"TYPH","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x4090e535f2e251f5f88518998b18b54d26b3b07c","decimalCount":18}]},{"id":"zeusshield","name":"Zeusshield","symbol":"ZSC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7a41e0517a5eca4fdbc7fbeba4d4c47b9ff6dc63","decimalCount":18}]},{"id":"x-consoles","name":"X-Consoles","symbol":"GAME","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x882e5b370d595e50c24b2a0e7a94e87cc32adda1","decimalCount":18}]},{"id":"impulseven","name":"ImpulseVen","symbol":"I7","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x560cc7de81b2a594f6518713cbe122bcf297a6e8","decimalCount":18}]},{"id":"hellogold","name":"HelloGold","symbol":"HGT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xba2184520a1cc49a6159c57e61e1844e085615b6","decimalCount":8}]},{"id":"avaluse","name":"Avaluse","symbol":"AVAL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbcf9dbf8b14ed096b2ba08b7269356197fdd1b5d","decimalCount":18}]},{"id":"dust-token","name":"DUST Token","symbol":"DUST","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xbca3c97837a39099ec3082df97e28ce91be14472","decimalCount":8},{"networkId":"polygon-pos","contractAddress":"0x556f501cf8a43216df5bc9cc57eb04d4ffaa9e6d","decimalCount":8}]},{"id":"bitdegree","name":"BitDegree","symbol":"BDG","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1961b3331969ed52770751fc718ef530838b6dee","decimalCount":18}]},{"id":"hnk-orijent-1919-token","name":"HNK Orijent 1919","symbol":"ORI","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x54cc4db6f878a1cde6bdd0c8befcf70f5dabf206","decimalCount":5}]},{"id":"dios-finance","name":"Dios Finance","symbol":"DIOS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x08eecf5d03bda3df2467f6af46b160c24d931de7","decimalCount":9}]},{"id":"gamex","name":"GameX","symbol":"GMX","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xc62ef0d8e137499833abb05dee47007d2b334ba6","decimalCount":9}]},{"id":"sentinel-chain","name":"Sentinel Chain","symbol":"SENC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa13f0743951b4f6e3e3aa039f682e17279f52bc3","decimalCount":18}]},{"id":"rentberry","name":"Rentberry","symbol":"BERRY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6aeb95f06cda84ca345c2de0f3b7f96923a44f4c","decimalCount":14}]},{"id":"oro","name":"ORO","symbol":"ORO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc3eb2622190c57429aac3901808994443b64b466","decimalCount":18}]},{"id":"better-money","name":"Better Money","symbol":"BETTER","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa7925aa2a6e4575ab0c74d169f3bc3e03d4c319a","decimalCount":4}]},{"id":"nft-stars","name":"NFT Stars","symbol":"NFTS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x08037036451c768465369431da5c671ad9b37dbc","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x08037036451c768465369431da5c671ad9b37dbc","decimalCount":18}]},{"id":"midas-protocol","name":"Midas Protocol","symbol":"MAS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x23ccc43365d9dd3882eab88f43d515208f832430","decimalCount":18}]},{"id":"blocsport-one","name":"blocsport.one","symbol":"BLS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x708739980021a0b0b2e555383fe1283697e140e9","decimalCount":18}]},{"id":"micromoney","name":"MicroMoney","symbol":"AMM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8b1f49491477e0fb46a29fef53f1ea320d13c349","decimalCount":6}]},{"id":"pancakepoll","name":"PancakePoll","symbol":"PPOLL","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xc29000a4b1ecd326b6dafae17bda636475fea1e7","decimalCount":9}]},{"id":"jetoken","name":"JeToken","symbol":"JETS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x0f005dfe97c5041e538b7075915b2ee706677c26","decimalCount":9}]},{"id":"fortress","name":"Fortress Loans","symbol":"FTS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x4437743ac02957068995c48e08465e0ee1769fbe","decimalCount":18}]},{"id":"blockcdn","name":"BlockCDN","symbol":"BCDN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1e797ce986c3cff4472f7d38d5c4aba55dfefe40","decimalCount":15}]},{"id":"bounty0x","name":"Bounty0x","symbol":"BNTY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd2d6158683aee4cc838067727209a0aaf4359de3","decimalCount":18}]},{"id":"owndata","name":"OWNDATA","symbol":"OWN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x170b275ced089fffaebfe927f445a350ed9160dc","decimalCount":8}]},{"id":"battle-saga","name":"Battle Saga","symbol":"BTL","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x708955db0d4c52ffbf9aa34af7f3ca8bf07390a8","decimalCount":18}]},{"id":"unicly-doki-doki-collection","name":"Unicly Doki Doki Collection","symbol":"UDOKI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7e6c38d007740931e4b419bf15a68c79a0fb0c66","decimalCount":18}]},{"id":"non-fungible-yearn","name":"Non-Fungible Yearn","symbol":"NFY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1cbb83ebcd552d5ebf8131ef8c9cd9d9bab342bc","decimalCount":18}]},{"id":"trendering","name":"Trendering","symbol":"TRND","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc3dd23a0a854b4f9ae80670f528094e9eb607ccb","decimalCount":18}]},{"id":"latiumx","name":"LatiumX","symbol":"LATX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x2f85e502a988af76f7ee6d83b7db8d6c0a823bf9","decimalCount":8}]},{"id":"facts","name":"FACTS","symbol":"BKC","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x34bdf48a8f753de4822a6cfb1fee275f9b4d662e","decimalCount":18}]},{"id":"pivot-token","name":"Pivot Token","symbol":"PVT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x7869c4a1a3f6f8684fbcc422a21ad7abe3167834","decimalCount":18}]},{"id":"babyswap","name":"BabySwap","symbol":"BABY","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x53e562b9b7e5e94b81f10e96ee70ad06df3d2657","decimalCount":18}]},{"id":"pink-panther","name":"PINK PANTHER","symbol":"PINK","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xa113b79c09f0794568b8864a24197e0b817041ea","decimalCount":18}]},{"id":"gencoin-capital","name":"GenCoin Capital","symbol":"GENCAP","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x0b569fa433faa7f01f3ea880193de38044b41de0","decimalCount":9}]},{"id":"greeneum-network","name":"Greeneum Network","symbol":"GREEN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe0a16435df493bd17a58cb2ee58675f5ea069517","decimalCount":18}]},{"id":"kickpad","name":"KickPad","symbol":"KPAD","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xcfefa64b0ddd611b125157c41cd3827f2e8e8615","decimalCount":18}]},{"id":"mirrored-twitter","name":"Mirrored Twitter","symbol":"MTWTR","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xedb0414627e6f1e3f082de65cd4f9c693d78cca9","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0x7426ab52a0e057691e2544fae9c8222e958b2cfb","decimalCount":18}]},{"id":"polkainsure-finance","name":"Polkainsure Finance","symbol":"PIS","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x834ce7ad163ab3be0c5fd4e0a81e67ac8f51e00c","decimalCount":18}]},{"id":"sparkpoint-fuel","name":"SparkPoint Fuel","symbol":"SFUEL","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x37ac4d6140e54304d77437a5c11924f61a2d976f","decimalCount":18}]},{"id":"omni-consumer-protocol","name":"Omni Consumer Protocol","symbol":"OCP","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x3c70260eee0a2bfc4b375feb810325801f289fbd","decimalCount":18}]},{"id":"parkgene","name":"Parkgene","symbol":"GENE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x6dd4e4aad29a40edd6a409b9c1625186c9855b4d","decimalCount":8}]},{"id":"protector-roge","name":"Protector Roge","symbol":"PROGE","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x282d0ad1fa03dfbdb88243b958e77349c73737d1","decimalCount":9}]},{"id":"ailink-token","name":"AiLink Token","symbol":"ALI","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x4289c043a12392f1027307fb58272d8ebd853912","decimalCount":18}]},{"id":"porta","name":"Porta","symbol":"KIAN","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x5ece3f1542c4e1a06767457e4d8286bea772fc41","decimalCount":18}]},{"id":"auric-network","name":"Auric Network","symbol":"AUSCM","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x1c7bbadc81e18f7177a95eb1593e5f5f35861b10","decimalCount":18}]},{"id":"vox-finance","name":"Vox.Finance","symbol":"VOX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x12d102f06da35cc0111eb58017fd2cd28537d0e1","decimalCount":18},{"networkId":"binance-smart-chain","contractAddress":"0xc227f8eecc481a8e8baa30a4754b109b81c4dfa4","decimalCount":18}]},{"id":"bigbom-eco","name":"Bigbom","symbol":"BBO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x84f7c44b6fed1080f647e354d552595be2cc602f","decimalCount":18}]},{"id":"firdaos","name":"Firdaos","symbol":"FDO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x361887c1d1b73557018c47c8001711168128cf69","decimalCount":18}]},{"id":"staysafu","name":"StaySAFU","symbol":"SAFU","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x890cc7d14948478c98a6cd7f511e1f7f7f99f397","decimalCount":9}]},{"id":"marsx","name":"MarsX","symbol":"MX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xe0df31d06d72b2f5231489af0edc422b372f49f1","decimalCount":18}]},{"id":"ark-of-the-universe","name":"Ark Of The Universe","symbol":"ARKS","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x4c3d5af5c43dbecee525327e93d51eb4d6ddabec","decimalCount":18}]},{"id":"flokibonk","name":"FlokiBonk","symbol":"FLOBO","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x9d3e14b607b2f569cfafe29af71e811d7e575cfe","decimalCount":9}]},{"id":"pinkelon","name":"PinkElon","symbol":"PINKE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x8da0f18e4deb7ba81dbd061df57325a894014b5a","decimalCount":9}]},{"id":"rune","name":"Rune","symbol":"RUNE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xa9776b590bfc2f956711b3419910a5ec1f63153e","decimalCount":18}]},{"id":"bepay","name":"bePAY Finance","symbol":"BECOIN","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x8f081eb884fd47b79536d28e2dd9d4886773f783","decimalCount":6},{"networkId":"binance-smart-chain","contractAddress":"0x8f081eb884fd47b79536d28e2dd9d4886773f783","decimalCount":6}]},{"id":"revival","name":"REVIVAL","symbol":"RVL","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x7eaee60040135f20f508a393ca400ded339d654e","decimalCount":9}]},{"id":"dogeyield","name":"DogeYield","symbol":"DOGY","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x9c405acf8688afb61b3197421cdeec1a266c6839","decimalCount":18}]},{"id":"verify","name":"Verify","symbol":"CRED","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x672a1ad4f667fb18a333af13667aa0af1f5b5bdd","decimalCount":18}]},{"id":"origo","name":"Origo","symbol":"OGO","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xff0e5e014cf97e0615cb50f6f39da6388e2fae6e","decimalCount":18}]},{"id":"richochet","name":"Ricochet","symbol":"RIC","active":true,"networks":[{"networkId":"polygon-pos","contractAddress":"0x263026e7e53dbfdce5ae55ade22493f828922965","decimalCount":18}]},{"id":"akropolis-delphi","name":"Delphi","symbol":"ADEL","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x94d863173ee77439e4292284ff13fad54b3ba182","decimalCount":18}]},{"id":"adtoken","name":"adToken","symbol":"ADT","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xd0d6d6c5fe4a677d343cc433536bb717bae167dd","decimalCount":9}]},{"id":"savix","name":"Savix","symbol":"SVX","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0xc434b27736a6882d33094d34792999702860a13c","decimalCount":9}]},{"id":"colligo","name":"Colligo","symbol":"COTK","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0xea738b6f1c888b2eced0fad66918defefe7c4494","decimalCount":18}]},{"id":"brick-token","name":"Brick","symbol":"BRICK","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x4e5ab517719a2bdbafefc22c712d7b5bc5f5544e","decimalCount":18}]},{"id":"pancaketools","name":"PancakeTools","symbol":"TCAKE","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x3b831d36ed418e893f42d46ff308c326c239429f","decimalCount":18}]},{"id":"axia","name":"Axia","symbol":"AXIAV3","active":true,"networks":[{"networkId":"ethereum","contractAddress":"0x793786e2dd4cc492ed366a94b88a3ff9ba5e7546","decimalCount":18},{"networkId":"polygon-pos","contractAddress":"0x49690541e3f6e933a9aa3cffee6010a7bb5b72d7","decimalCount":18}]},{"id":"token-kennel","name":"Token Kennel","symbol":"KENNEL","active":true,"networks":[{"networkId":"binance-smart-chain","contractAddress":"0x2c319cde4e46f85f7a1004b9a81d4a52d896e208","decimalCount":18}]}],"total":2498} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/ApplicationEntryPoint.kt b/app/src/main/java/com/tangem/tap/ApplicationEntryPoint.kt index 21ab576e7f..62ba2f5b49 100644 --- a/app/src/main/java/com/tangem/tap/ApplicationEntryPoint.kt +++ b/app/src/main/java/com/tangem/tap/ApplicationEntryPoint.kt @@ -8,8 +8,8 @@ import com.tangem.core.featuretoggle.manager.FeatureTogglesManager import com.tangem.core.navigation.share.ShareManager import com.tangem.core.navigation.url.UrlOpener import com.tangem.datasource.asset.loader.AssetLoader -import com.tangem.datasource.config.ConfigManager import com.tangem.datasource.connection.NetworkConnectionManager +import com.tangem.datasource.local.config.environment.EnvironmentConfigStorage import com.tangem.datasource.local.preferences.AppPreferencesStore import com.tangem.domain.appcurrency.repository.AppCurrencyRepository import com.tangem.domain.apptheme.GetAppThemeModeUseCase @@ -17,24 +17,23 @@ import com.tangem.domain.apptheme.repository.AppThemeModeRepository import com.tangem.domain.balancehiding.repositories.BalanceHidingRepository import com.tangem.domain.card.ScanCardProcessor import com.tangem.domain.card.repository.CardRepository -import com.tangem.domain.feedback.FeedbackManagerFeatureToggles import com.tangem.domain.feedback.GetCardInfoUseCase -import com.tangem.domain.feedback.GetFeedbackEmailUseCase import com.tangem.domain.feedback.SaveBlockchainErrorUseCase +import com.tangem.domain.feedback.SendFeedbackEmailUseCase import com.tangem.domain.onboarding.SaveTwinsOnboardingShownUseCase import com.tangem.domain.onboarding.WasTwinsOnboardingShownUseCase import com.tangem.domain.settings.repositories.SettingsRepository +import com.tangem.domain.settings.usercountry.GetUserCountryUseCase import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.tokens.repository.NetworksRepository import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.repository.WalletsRepository import com.tangem.domain.wallets.usecase.GenerateWalletNameUseCase -import com.tangem.features.details.DetailsFeatureToggles -import com.tangem.features.pushnotifications.api.featuretoggles.PushNotificationsFeatureToggles import com.tangem.tap.common.log.TangemAppLoggerInitializer +import com.tangem.tap.domain.scanCard.CardScanningFeatureToggles import com.tangem.tap.domain.walletconnect2.domain.WalletConnectSessionsRepository -import com.tangem.tap.features.customtoken.api.featuretoggles.CustomTokenFeatureToggles +import com.tangem.tap.features.home.featuretoggles.HomeFeatureToggles import com.tangem.tap.proxy.AppStateHolder import dagger.hilt.EntryPoint import dagger.hilt.InstallIn @@ -46,7 +45,7 @@ import com.tangem.tap.domain.walletconnect2.domain.LegacyWalletConnectRepository @Suppress("TooManyFunctions") interface ApplicationEntryPoint { - fun getConfigManager(): ConfigManager + fun getEnvironmentConfigStorage(): EnvironmentConfigStorage fun getAppStateHolder(): AppStateHolder @@ -56,7 +55,7 @@ interface ApplicationEntryPoint { fun getNetworkConnectionManager(): NetworkConnectionManager - fun getCustomTokenFeatureToggles(): CustomTokenFeatureToggles + fun getCardScanningFeatureToggles(): CardScanningFeatureToggles fun getWalletConnect2Repository(): WalletConnect2Repository @@ -94,20 +93,16 @@ interface ApplicationEntryPoint { fun getCardRepository(): CardRepository - fun getFeedbackManagerFeatureToggles(): FeedbackManagerFeatureToggles - fun getTangemSdkLogger(): TangemSdkLogger fun getSettingsRepository(): SettingsRepository fun getBlockchainSDKFactory(): BlockchainSDKFactory - fun getGetFeedbackEmailUseCase(): GetFeedbackEmailUseCase + fun getSendFeedbackEmailUseCase(): SendFeedbackEmailUseCase fun getSaveBlockchainErrorUseCase(): SaveBlockchainErrorUseCase - fun getDetailsFeatureToggles(): DetailsFeatureToggles - fun getGetCardInfoUseCase(): GetCardInfoUseCase fun getUrlOpener(): UrlOpener @@ -116,7 +111,9 @@ interface ApplicationEntryPoint { fun getAppRouter(): AppRouter - fun getPushNotificationsFeatureToggles(): PushNotificationsFeatureToggles - fun getTangemAppLogger(): TangemAppLoggerInitializer + + fun getHomeFeatureToggles(): HomeFeatureToggles + + fun getGetUserCountryCodeUseCase(): GetUserCountryUseCase } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/MainActivity.kt b/app/src/main/java/com/tangem/tap/MainActivity.kt index 10d69f7704..169f30bc6c 100644 --- a/app/src/main/java/com/tangem/tap/MainActivity.kt +++ b/app/src/main/java/com/tangem/tap/MainActivity.kt @@ -67,7 +67,6 @@ import com.tangem.tap.common.OnActivityResultCallback import com.tangem.tap.common.SnackbarHandler import com.tangem.tap.common.apptheme.MutableAppThemeModeHolder import com.tangem.tap.common.extensions.dispatchNavigationAction -import com.tangem.tap.common.extensions.inject import com.tangem.tap.common.extensions.showFragmentAllowingStateLoss import com.tangem.tap.common.redux.NotificationsHandler import com.tangem.tap.domain.sdk.TangemSdkManager @@ -80,7 +79,6 @@ import com.tangem.tap.features.main.model.Toast import com.tangem.tap.features.onboarding.products.wallet.redux.BackupAction import com.tangem.tap.proxy.AppStateHolder import com.tangem.tap.proxy.redux.DaggerGraphAction -import com.tangem.tap.proxy.redux.DaggerGraphState import com.tangem.tap.routing.RoutingComponent import com.tangem.tap.routing.configurator.AppRouterConfig import com.tangem.utils.coroutines.FeatureCoroutineExceptionHandler @@ -550,11 +548,8 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac } } else { lifecycleScope.launch { - val toggles = store.inject(getDependency = DaggerGraphState::pushNotificationsFeatureToggles) - val isPushPermissionEnabled = toggles.isPushNotificationsEnabled - val shouldShowTos = !cardRepository.isTangemTOSAccepted() && isPushPermissionEnabled - val wasPushInitiallyAsked = shouldInitiallyAskPermissionUseCase(PUSH_PERMISSION).getOrElse { false } - val shouldShowInitialPush = wasPushInitiallyAsked && isPushPermissionEnabled + val shouldShowTos = !cardRepository.isTangemTOSAccepted() + val shouldShowInitialPush = shouldInitiallyAskPermissionUseCase(PUSH_PERMISSION).getOrElse { false } val route = when { shouldShowTos -> AppRoute.Disclaimer(isTosAccepted = false) diff --git a/app/src/main/java/com/tangem/tap/TangemApplication.kt b/app/src/main/java/com/tangem/tap/TangemApplication.kt index ef8490029a..073068f66c 100644 --- a/app/src/main/java/com/tangem/tap/TangemApplication.kt +++ b/app/src/main/java/com/tangem/tap/TangemApplication.kt @@ -1,13 +1,10 @@ package com.tangem.tap import android.app.Application -import android.content.Context -import android.content.pm.PackageManager import coil.ImageLoader import coil.ImageLoaderFactory import com.chuckerteam.chucker.api.ChuckerInterceptor import com.tangem.Log -import com.tangem.LogFormat import com.tangem.TangemSdkLogger import com.tangem.blockchain.network.BlockchainSdkRetrofitBuilder import com.tangem.blockchainsdk.BlockchainSDKFactory @@ -18,10 +15,9 @@ import com.tangem.core.featuretoggle.manager.FeatureTogglesManager import com.tangem.datasource.api.common.MoshiConverter import com.tangem.datasource.api.common.createNetworkLoggingInterceptor import com.tangem.datasource.asset.loader.AssetLoader -import com.tangem.datasource.config.ConfigManager -import com.tangem.datasource.config.FeaturesLocalLoader -import com.tangem.datasource.config.models.Config import com.tangem.datasource.connection.NetworkConnectionManager +import com.tangem.datasource.local.config.environment.EnvironmentConfig +import com.tangem.datasource.local.config.environment.EnvironmentConfigStorage import com.tangem.datasource.local.preferences.AppPreferencesStore import com.tangem.domain.appcurrency.repository.AppCurrencyRepository import com.tangem.domain.apptheme.GetAppThemeModeUseCase @@ -30,36 +26,32 @@ import com.tangem.domain.balancehiding.repositories.BalanceHidingRepository import com.tangem.domain.card.ScanCardProcessor import com.tangem.domain.card.repository.CardRepository import com.tangem.domain.common.LogConfig -import com.tangem.domain.feedback.FeedbackManagerFeatureToggles import com.tangem.domain.feedback.GetCardInfoUseCase -import com.tangem.domain.feedback.GetFeedbackEmailUseCase import com.tangem.domain.feedback.SaveBlockchainErrorUseCase +import com.tangem.domain.feedback.SendFeedbackEmailUseCase import com.tangem.domain.onboarding.SaveTwinsOnboardingShownUseCase import com.tangem.domain.onboarding.WasTwinsOnboardingShownUseCase import com.tangem.domain.settings.repositories.SettingsRepository +import com.tangem.domain.settings.usercountry.GetUserCountryUseCase import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.tokens.repository.NetworksRepository import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.repository.WalletsRepository import com.tangem.domain.wallets.usecase.GenerateWalletNameUseCase -import com.tangem.features.details.DetailsFeatureToggles -import com.tangem.features.pushnotifications.api.featuretoggles.PushNotificationsFeatureToggles import com.tangem.tap.common.analytics.AnalyticsFactory import com.tangem.tap.common.analytics.api.AnalyticsHandlerBuilder import com.tangem.tap.common.analytics.handlers.amplitude.AmplitudeAnalyticsHandler import com.tangem.tap.common.analytics.handlers.firebase.FirebaseAnalyticsHandler -import com.tangem.tap.common.feedback.AdditionalFeedbackInfo -import com.tangem.tap.common.feedback.LegacyFeedbackManager import com.tangem.tap.common.images.createCoilImageLoader import com.tangem.tap.common.log.TangemAppLoggerInitializer -import com.tangem.tap.common.log.TangemLogCollector import com.tangem.tap.common.redux.AppState import com.tangem.tap.common.redux.appReducer import com.tangem.tap.common.redux.global.GlobalAction +import com.tangem.tap.domain.scanCard.CardScanningFeatureToggles import com.tangem.tap.domain.tasks.product.DerivationsFinder import com.tangem.tap.domain.walletconnect2.domain.WalletConnectSessionsRepository -import com.tangem.tap.features.customtoken.api.featuretoggles.CustomTokenFeatureToggles +import com.tangem.tap.features.home.featuretoggles.HomeFeatureToggles import com.tangem.tap.proxy.AppStateHolder import com.tangem.tap.proxy.redux.DaggerGraphState import com.tangem.utils.coroutines.AppCoroutineDispatcherProvider @@ -84,8 +76,8 @@ abstract class TangemApplication : Application(), ImageLoaderFactory { private val appStateHolder: AppStateHolder get() = entryPoint.getAppStateHolder() - private val configManager: ConfigManager - get() = entryPoint.getConfigManager() + private val environmentConfigStorage: EnvironmentConfigStorage + get() = entryPoint.getEnvironmentConfigStorage() private val assetLoader: AssetLoader get() = entryPoint.getAssetLoader() @@ -96,8 +88,8 @@ abstract class TangemApplication : Application(), ImageLoaderFactory { private val networkConnectionManager: NetworkConnectionManager get() = entryPoint.getNetworkConnectionManager() - private val customTokenFeatureToggles: CustomTokenFeatureToggles - get() = entryPoint.getCustomTokenFeatureToggles() + private val cardScanningFeatureToggles: CardScanningFeatureToggles + get() = entryPoint.getCardScanningFeatureToggles() private val walletConnect2Repository: WalletConnect2Repository get() = entryPoint.getWalletConnect2Repository() @@ -153,9 +145,6 @@ abstract class TangemApplication : Application(), ImageLoaderFactory { private val cardRepository: CardRepository get() = entryPoint.getCardRepository() - private val feedbackManagerFeatureToggles: FeedbackManagerFeatureToggles - get() = entryPoint.getFeedbackManagerFeatureToggles() - private val tangemSdkLogger: TangemSdkLogger get() = entryPoint.getTangemSdkLogger() @@ -165,8 +154,8 @@ abstract class TangemApplication : Application(), ImageLoaderFactory { private val blockchainSDKFactory: BlockchainSDKFactory get() = entryPoint.getBlockchainSDKFactory() - private val getFeedbackEmailUseCase: GetFeedbackEmailUseCase - get() = entryPoint.getGetFeedbackEmailUseCase() + private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase + get() = entryPoint.getSendFeedbackEmailUseCase() private val saveBlockchainErrorUseCase: SaveBlockchainErrorUseCase get() = entryPoint.getSaveBlockchainErrorUseCase() @@ -174,9 +163,6 @@ abstract class TangemApplication : Application(), ImageLoaderFactory { private val getCardInfoUseCase: GetCardInfoUseCase get() = entryPoint.getGetCardInfoUseCase() - private val detailsFeatureToggles: DetailsFeatureToggles - get() = entryPoint.getDetailsFeatureToggles() - private val urlOpener get() = entryPoint.getUrlOpener() @@ -186,11 +172,14 @@ abstract class TangemApplication : Application(), ImageLoaderFactory { private val appRouter: AppRouter get() = entryPoint.getAppRouter() - private val pushNotificationsFeatureToggles: PushNotificationsFeatureToggles - get() = entryPoint.getPushNotificationsFeatureToggles() - private val tangemAppLoggerInitializer: TangemAppLoggerInitializer get() = entryPoint.getTangemAppLogger() + + private val homeFeatureToggles: HomeFeatureToggles + get() = entryPoint.getHomeFeatureToggles() + + private val getUserCountryUseCase: GetUserCountryUseCase + get() = entryPoint.getGetUserCountryCodeUseCase() // endregion override fun onCreate() { @@ -212,10 +201,11 @@ abstract class TangemApplication : Application(), ImageLoaderFactory { // [REDACTED_JIRA] runBlocking { featureTogglesManager.init() - initConfigManager( - loader = FeaturesLocalLoader(assetLoader, BuildConfig.ENVIRONMENT), - onComplete = ::initWithConfigDependency, - ) + + val config = environmentConfigStorage.initialize() + store.dispatch(GlobalAction.SetConfigManager(environmentConfigStorage)) + + initWithConfigDependency(environmentConfig = config) } loadNativeLibraries() @@ -233,7 +223,7 @@ abstract class TangemApplication : Application(), ImageLoaderFactory { ) appStateHolder.mainStore = store - walletConnect2Repository.init(projectId = configManager.config.walletConnectProjectId) + walletConnect2Repository.init(projectId = environmentConfigStorage.getConfigSync().walletConnectProjectId) } private fun createReduxStore(): Store { @@ -243,7 +233,7 @@ abstract class TangemApplication : Application(), ImageLoaderFactory { state = AppState( daggerGraphState = DaggerGraphState( networkConnectionManager = networkConnectionManager, - customTokenFeatureToggles = customTokenFeatureToggles, + cardScanningFeatureToggles = cardScanningFeatureToggles, walletConnectRepository = walletConnect2Repository, walletConnectSessionsRepository = walletConnectSessionsRepository, scanCardProcessor = scanCardProcessor, @@ -260,19 +250,18 @@ abstract class TangemApplication : Application(), ImageLoaderFactory { saveTwinsOnboardingShownUseCase = saveTwinsOnboardingShownUseCase, generateWalletNameUseCase = generateWalletNameUseCase, cardRepository = cardRepository, - feedbackManagerFeatureToggles = feedbackManagerFeatureToggles, tangemSdkLogger = tangemSdkLogger, settingsRepository = settingsRepository, blockchainSDKFactory = blockchainSDKFactory, saveBlockchainErrorUseCase = saveBlockchainErrorUseCase, - getFeedbackEmailUseCase = getFeedbackEmailUseCase, + sendFeedbackEmailUseCase = sendFeedbackEmailUseCase, getCardInfoUseCase = getCardInfoUseCase, assetLoader = assetLoader, - detailsFeatureToggles = detailsFeatureToggles, urlOpener = urlOpener, shareManager = shareManager, appRouter = appRouter, - pushNotificationsFeatureToggles = pushNotificationsFeatureToggles, + homeFeatureToggles = homeFeatureToggles, + getUserCountryUseCase = getUserCountryUseCase, ), ), ) @@ -289,19 +278,12 @@ abstract class TangemApplication : Application(), ImageLoaderFactory { System.loadLibrary("TrustWalletCore") } - private suspend fun initConfigManager(loader: FeaturesLocalLoader, onComplete: (Config) -> Unit) { - configManager.load(loader) { config -> - store.dispatch(GlobalAction.SetConfigManager(configManager)) - onComplete(config) - } + private fun initWithConfigDependency(environmentConfig: EnvironmentConfig) { + initAnalytics(this, environmentConfig) + Log.addLogger(logger = tangemSdkLogger) } - private fun initWithConfigDependency(config: Config) { - initAnalytics(this, config) - initFeedbackManager(this, store) - } - - private fun initAnalytics(application: Application, config: Config) { + private fun initAnalytics(application: Application, environmentConfig: EnvironmentConfig) { val factory = AnalyticsFactory() factory.addHandlerBuilder(AmplitudeAnalyticsHandler.Builder()) factory.addHandlerBuilder(FirebaseAnalyticsHandler.Builder()) @@ -310,7 +292,7 @@ abstract class TangemApplication : Application(), ImageLoaderFactory { val buildData = AnalyticsHandlerBuilder.Data( application = application, - config = config, + config = environmentConfig, isDebug = BuildConfig.DEBUG, logConfig = LogConfig.analyticsHandlers, jsonConverter = MoshiConverter.sdkMoshiConverter, @@ -318,51 +300,4 @@ abstract class TangemApplication : Application(), ImageLoaderFactory { factory.build(Analytics, buildData) // ExceptionHandler.append(blockchainExceptionHandler) TODO: [REDACTED_JIRA] } - - private fun initFeedbackManager(context: Context, store: Store) { - fun initAdditionalFeedbackInfo(context: Context): AdditionalFeedbackInfo { - return AdditionalFeedbackInfo().apply { - appVersion = try { - // TODO don't use deprecated method - val pInfo = context.packageManager.getPackageInfo(context.packageName, 0) - pInfo.versionName - } catch (e: PackageManager.NameNotFoundException) { - e.printStackTrace() - "x.y.z" - } - } - } - - fun initTangemLogCollector(): TangemLogCollector { - val logLevels = listOf( - Log.Level.ApduCommand, - Log.Level.Apdu, - Log.Level.Tlv, - Log.Level.Nfc, - Log.Level.Command, - Log.Level.Session, - Log.Level.View, - Log.Level.Network, - Log.Level.Error, - Log.Level.Biometric, - Log.Level.Info, - ) - return TangemLogCollector(logLevels, LogFormat.StairsFormatter()) - } - - val additionalFeedbackInfo = initAdditionalFeedbackInfo(context) - val tangemLogCollector = initTangemLogCollector() - - Log.addLogger( - logger = if (feedbackManagerFeatureToggles.isLocalLogsEnabled) tangemSdkLogger else tangemLogCollector, - ) - - val feedbackManager = LegacyFeedbackManager( - infoHolder = additionalFeedbackInfo, - logCollector = tangemLogCollector, - feedbackManagerFeatureToggles = feedbackManagerFeatureToggles, - getFeedbackEmailUseCase = getFeedbackEmailUseCase, - ) - store.dispatch(GlobalAction.SetFeedbackManager(feedbackManager)) - } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/analytics/api/AnalyticsHandlerBuilder.kt b/app/src/main/java/com/tangem/tap/common/analytics/api/AnalyticsHandlerBuilder.kt index 4727772b38..742a2178bc 100644 --- a/app/src/main/java/com/tangem/tap/common/analytics/api/AnalyticsHandlerBuilder.kt +++ b/app/src/main/java/com/tangem/tap/common/analytics/api/AnalyticsHandlerBuilder.kt @@ -3,15 +3,15 @@ package com.tangem.tap.common.analytics.api import android.app.Application import com.tangem.common.json.MoshiJsonConverter import com.tangem.core.analytics.api.AnalyticsHandler +import com.tangem.datasource.local.config.environment.EnvironmentConfig import com.tangem.domain.common.AnalyticsHandlersLogConfig -import com.tangem.datasource.config.models.Config interface AnalyticsHandlerBuilder { fun build(data: Data): AnalyticsHandler? data class Data( val application: Application, - val config: Config, + val config: EnvironmentConfig, val isDebug: Boolean, val logConfig: AnalyticsHandlersLogConfig, val jsonConverter: MoshiJsonConverter, diff --git a/app/src/main/java/com/tangem/tap/common/analytics/events/ManageTokens.kt b/app/src/main/java/com/tangem/tap/common/analytics/events/ManageTokens.kt deleted file mode 100644 index 9bf97f2250..0000000000 --- a/app/src/main/java/com/tangem/tap/common/analytics/events/ManageTokens.kt +++ /dev/null @@ -1,91 +0,0 @@ -package com.tangem.tap.common.analytics.events - -import com.tangem.blockchainsdk.utils.toNetworkId -import com.tangem.core.analytics.models.AnalyticsEvent -import com.tangem.domain.features.addCustomToken.CustomCurrency -import com.tangem.tap.common.extensions.filterNotNull - -/** -[REDACTED_AUTHOR] - */ -sealed class ManageTokens( - event: String, - params: Map = mapOf(), -) : AnalyticsEvent("Manage Tokens", event, params) { - - class ScreenOpened : ManageTokens("Manage Tokens Screen Opened") - class TokenSearched : ManageTokens("Token Searched") - - class TokenSwitcherChanged( - type: AnalyticsParam.CurrencyType, - state: AnalyticsParam.OnOffState, - ) : ManageTokens( - "Token Switcher Changed", - params = mapOf( - "Token" to type.value, - "State" to state.value, - ), - ) - - class ButtonSaveChanges : ManageTokens("Button - Save Changes") - class ButtonCustomToken : ManageTokens("Button - Custom Token") - - sealed class CustomToken( - event: String, - params: Map = mapOf(), - ) : ManageTokens(event, params) { - - object ScreenOpened : ManageTokens(event = "Custom Token Screen Opened") - - // TODO("Get rid of strong binding (CustomCurrency) - open class TokenWasAdded(customCurrency: CustomCurrency) : ManageTokens( - event = "Custom Token Was Added", - params = convertToParam(customCurrency), - ) { - - data class Token( - val symbol: String, - val derivationPath: String?, - val blockchain: com.tangem.blockchain.common.Blockchain, - val contractAddress: String, - ) : ManageTokens( - event = "Custom Token Was Added", - params = mapOf( - "Token" to symbol, - "Derivation Path" to derivationPath, - "Network Id" to blockchain.currency, - "Contract Address" to contractAddress, - ).filterNotNull(), - ) - - data class Blockchain( - val derivationPath: String?, - val blockchain: com.tangem.blockchain.common.Blockchain, - ) : ManageTokens( - event = "Custom Token Was Added", - params = mapOf( - "Token" to blockchain.currency, - "Derivation Path" to derivationPath, - ).filterNotNull(), - ) - - companion object { - private fun convertToParam(customCurrency: CustomCurrency): Map = with(customCurrency) { - return when (this) { - is CustomCurrency.CustomBlockchain -> mapOf( - "Token" to network.currency, - "Derivation Path" to derivationPath?.rawPath, - ).filterNotNull() - - is CustomCurrency.CustomToken -> mapOf( - "Token" to token.symbol, - "Derivation Path" to derivationPath?.rawPath, - "Network Id" to network.toNetworkId(), - "Contract Address" to token.contractAddress, - ).filterNotNull() - } - } - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/analytics/events/Settings.kt b/app/src/main/java/com/tangem/tap/common/analytics/events/Settings.kt index 8ba8e26539..98b0289289 100644 --- a/app/src/main/java/com/tangem/tap/common/analytics/events/Settings.kt +++ b/app/src/main/java/com/tangem/tap/common/analytics/events/Settings.kt @@ -1,7 +1,6 @@ package com.tangem.tap.common.analytics.events import com.tangem.core.analytics.models.AnalyticsEvent -import com.tangem.tap.features.details.ui.details.SocialNetwork /** [REDACTED_AUTHOR] @@ -14,20 +13,8 @@ sealed class Settings( ) : AnalyticsEvent(category, event, params, error) { class ScreenOpened : Settings(event = "Settings Screen Opened") - class ButtonChat : Settings(event = "Button - Chat") - class ButtonSendFeedback : Settings(event = "Button - Send Feedback") class ButtonStartWalletConnectSession : Settings(event = "Button - Start Wallet Connect Session") class ButtonStopWalletConnectSession : Settings(event = "Button - Stop Wallet Connect Session") - class ButtonCardSettings : Settings(event = "Button - Card Settings") - class ButtonAppSettings : Settings(event = "Button - App Settings") - class ButtonCreateBackup : Settings(event = "Button - Create Backup") - class ButtonWalletConnect : Settings(event = "Button - Wallet Connect") - object ScanNewCard : Settings(event = "Button - Scan New Card") - - class ButtonSocialNetwork(network: SocialNetwork) : Settings( - event = "Button - Social Network", - params = mapOf("Network" to network.id), - ) sealed class CardSettings( event: String, @@ -63,8 +50,6 @@ sealed class Settings( error = error, ) - class AccessCodeRecoveryButton : CardSettings("Button - Access Code Recovery") - class AccessCodeRecoveryChanged(status: AnalyticsParam.AccessCodeRecoveryStatus) : CardSettings( event = "Access Code Recovery Changed", params = mapOf(status.key to status.value), diff --git a/app/src/main/java/com/tangem/tap/common/extensions/Specific.kt b/app/src/main/java/com/tangem/tap/common/extensions/Specific.kt index 773bca1bd5..0dfce4b8c7 100644 --- a/app/src/main/java/com/tangem/tap/common/extensions/Specific.kt +++ b/app/src/main/java/com/tangem/tap/common/extensions/Specific.kt @@ -20,8 +20,4 @@ fun BigDecimal.toFormattedString( df.isGroupingUsed = true df.roundingMode = roundingMode return df.format(this) -} - -fun BigDecimal.stripZeroPlainString(): String = this.stripTrailingZeros().toPlainString() - -fun BigDecimal.isPositive(): Boolean = this.signum() == 1 \ No newline at end of file +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/feedback/AdditionalFeedbackInfo.kt b/app/src/main/java/com/tangem/tap/common/feedback/AdditionalFeedbackInfo.kt deleted file mode 100644 index 21fc321bbe..0000000000 --- a/app/src/main/java/com/tangem/tap/common/feedback/AdditionalFeedbackInfo.kt +++ /dev/null @@ -1,147 +0,0 @@ -package com.tangem.tap.common.feedback - -import android.os.Build -import com.tangem.blockchain.common.* -import com.tangem.blockchain.common.address.Address -import com.tangem.crypto.NetworkType -import com.tangem.domain.models.scan.CardDTO -import com.tangem.domain.models.scan.ScanResponse -import com.tangem.domain.wallets.builder.UserWalletIdBuilder -import com.tangem.tap.common.extensions.stripZeroPlainString -import java.util.concurrent.CopyOnWriteArrayList - -class AdditionalFeedbackInfo { - - class EmailWalletInfo( - val blockchain: Blockchain = Blockchain.Unknown, - val derivationPath: String = "", - val outputsCount: String? = null, - val host: String = "", - val addresses: String = "", - val explorerLink: String = "", - val tokens: List = emptyList(), - ) - - class EmailTokenInfo( - val id: String?, - val name: String, - val contractAddress: String, - ) - - var appVersion: String = "" - - // card - var cardId: String = "" - var cardFirmwareVersion: String = "" - var cardIssuer: String = "" - var cardBlockchain: String = "" - var userWalletId: String = "" - var extendedPublicKey: String = "" - - // wallets - val walletsInfo = CopyOnWriteArrayList() - var onSendErrorWalletInfo: EmailWalletInfo? = null - private set - var signedHashesCount: String = "" - private set - - // device - var phoneModel: String = Build.MODEL - private set - var osVersion: String = Build.VERSION.SDK_INT.toString() - private set - - // send error - var destinationAddress: String = "" - private set - var amount: String = "" - private set - var fee: String = "" - private set - var token: String = "" - private set - - private val Address.name: String - get() = type.javaClass.simpleName - - @Deprecated("Don't use it directly") - fun setCardInfo(data: ScanResponse) { - cardId = data.card.cardId - cardBlockchain = data.walletData?.blockchain ?: "" - cardFirmwareVersion = data.card.firmwareVersion.stringValue - cardIssuer = data.card.issuer.name - signedHashesCount = formatSignedHashes(data.card.wallets) - userWalletId = UserWalletIdBuilder.scanResponse(data).build()?.stringValue ?: "" - extendedPublicKey = runCatching { - data.card.wallets.firstOrNull { it.extendedPublicKey != null } - ?.extendedPublicKey - ?.serialize(networkType = NetworkType.Mainnet).orEmpty() - }.getOrDefault("couldn't retrieve extended public key") - } - - @Deprecated("Don't use it directly") - fun setWalletsInfo(walletManagers: List) { - synchronized(walletsInfo) { - walletsInfo.clear() - walletsInfo.addAll(elements = walletManagers.map(::createEmailWalletInfo)) - } - } - - fun updateOnSendError( - walletManager: WalletManager, - amountToSend: Amount?, - feeAmount: Amount?, - destinationAddress: String?, - ) { - onSendErrorWalletInfo = createEmailWalletInfo(walletManager) - this.destinationAddress = destinationAddress ?: "0" - amount = amountToSend?.value?.stripZeroPlainString() ?: "0" - fee = if (feeAmount != null) { - feeAmount.value?.stripZeroPlainString() ?: "0" - } else { - "Unable to receive" - } - token = if (amountToSend?.type is AmountType.Token) amountToSend.currencySymbol else "" - } - - private fun createEmailWalletInfo(walletManager: WalletManager): EmailWalletInfo { - return EmailWalletInfo( - blockchain = walletManager.wallet.blockchain, - derivationPath = walletManager.wallet.publicKey.derivationPath?.rawPath ?: "", - outputsCount = walletManager.outputsCount?.toString(), - host = walletManager.currentHost, - addresses = formatAddresses(walletManager.wallet), - explorerLink = formatExploreUrls(walletManager.wallet), - tokens = walletManager.cardTokens.map { token -> - EmailTokenInfo(token.id, token.name, token.contractAddress) - }, - ) - } - - private fun formatSignedHashes(wallets: List): String { - return wallets.joinToString("\n") { "Signed hashes: ${it.curve.curve} - ${it.totalSignedHashes}" } - } - - private fun formatAddresses(wallet: Wallet): String { - return wallet.formatAddressWith("Multiple address:") { - "${it.name} - ${it.value}" - } - } - - private fun formatExploreUrls(wallet: Wallet): String { - return wallet.formatAddressWith("Multiple explorers links:") { - "${it.name} - ${wallet.getExploreUrl(it.value)}" - } - } - - @Suppress("MagicNumber") - private fun Wallet.formatAddressWith(with: String, mapAddress: (Address) -> String): String { - return if (addresses.size == 1) { - getExploreUrl(address) - } else { - addresses.map { mapAddress(it) }.toMutableList() - .apply { add(0, with) } - .joinToString("\n") - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/feedback/DefaultFeedbackManagerFeatureToggles.kt b/app/src/main/java/com/tangem/tap/common/feedback/DefaultFeedbackManagerFeatureToggles.kt deleted file mode 100644 index 85acfd9af6..0000000000 --- a/app/src/main/java/com/tangem/tap/common/feedback/DefaultFeedbackManagerFeatureToggles.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.tangem.tap.common.feedback - -import com.tangem.core.featuretoggle.manager.FeatureTogglesManager -import com.tangem.domain.feedback.FeedbackManagerFeatureToggles - -internal class DefaultFeedbackManagerFeatureToggles( - private val featureTogglesManager: FeatureTogglesManager, -) : FeedbackManagerFeatureToggles { - - override val isLocalLogsEnabled: Boolean - get() = featureTogglesManager.isFeatureEnabled(name = "LOCAL_USER_LOGS_ENABLED") -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/feedback/FeedbackData.kt b/app/src/main/java/com/tangem/tap/common/feedback/FeedbackData.kt deleted file mode 100644 index 7e878f6e69..0000000000 --- a/app/src/main/java/com/tangem/tap/common/feedback/FeedbackData.kt +++ /dev/null @@ -1,105 +0,0 @@ -package com.tangem.tap.common.feedback - -import android.content.Context -import com.tangem.domain.common.TapWorkarounds -import com.tangem.tap.common.extensions.breakLine -import com.tangem.wallet.R - -interface FeedbackData { - val subjectResId: Int - val mainMessageResId: Int - - fun getDataCollectionMessageResId(): Int = R.string.feedback_data_collection_message - - fun prepare(infoHolder: AdditionalFeedbackInfo) {} - - fun createOptionalMessage(infoHolder: AdditionalFeedbackInfo): String - - @Suppress("MagicNumber") - fun joinTogether(context: Context, infoHolder: AdditionalFeedbackInfo): String { - return StringBuilder().apply { - append(context.getString(mainMessageResId)) - breakLine(3) - append(context.getString(getDataCollectionMessageResId())) - breakLine() - append(createOptionalMessage(infoHolder)) - }.toString() - } -} - -class RateCanBeBetterEmail : FeedbackData { - override val subjectResId: Int = R.string.feedback_subject_rate_negative - override val mainMessageResId: Int = R.string.feedback_preface_rate_negative - - override fun createOptionalMessage(infoHolder: AdditionalFeedbackInfo): String = FeedbackDataBuilder(infoHolder) - .appendCardInfo() - .breakLine() - .appendPhoneInfo() - .build() -} - -class ScanFailsEmail : FeedbackData { - - override val subjectResId: Int = R.string.feedback_subject_scan_failed - override val mainMessageResId: Int = R.string.feedback_preface_scan_failed - - @Suppress("MagicNumber") - override fun joinTogether(context: Context, infoHolder: AdditionalFeedbackInfo): String = StringBuilder().apply { - append(context.getString(mainMessageResId)) - breakLine(4) - append(createOptionalMessage(infoHolder)) - }.toString() - - override fun createOptionalMessage(infoHolder: AdditionalFeedbackInfo): String = FeedbackDataBuilder(infoHolder) - .appendPhoneInfo() - .build() -} - -class SendTransactionFailedEmail( - val error: String, -) : FeedbackData { - - override val subjectResId: Int = R.string.feedback_subject_tx_failed - override val mainMessageResId: Int = R.string.feedback_preface_tx_failed - - override fun createOptionalMessage(infoHolder: AdditionalFeedbackInfo): String = FeedbackDataBuilder(infoHolder) - .appendCardInfo() - .appendDelimiter() - .appendTxFailedBlockchainInfo(error) - .breakLine() - .appendPhoneInfo() - .build() -} - -class FeedbackEmail : FeedbackData { - override val subjectResId: Int - get() = if (isS2CCard) R.string.feedback_subject_support else R.string.feedback_subject_support_tangem - - override val mainMessageResId: Int = R.string.feedback_preface_support - - private var isS2CCard = false - - override fun prepare(infoHolder: AdditionalFeedbackInfo) { - isS2CCard = TapWorkarounds.isStart2CoinIssuer(infoHolder.cardIssuer) - } - - override fun createOptionalMessage(infoHolder: AdditionalFeedbackInfo): String = FeedbackDataBuilder(infoHolder) - .appendCardInfo() - .appendWalletsInfo() - .breakLine() - .appendPhoneInfo() - .build() -} - -class SupportInfo : FeedbackData { - override val subjectResId: Int = R.string.details_chat - override val mainMessageResId: Int = R.string.details_chat - - override fun createOptionalMessage(infoHolder: AdditionalFeedbackInfo): String { - return FeedbackDataBuilder(infoHolder) - .appendCardInfo() - .appendDelimiter() - .appendPhoneInfo() - .build() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/feedback/FeedbackDataBuilder.kt b/app/src/main/java/com/tangem/tap/common/feedback/FeedbackDataBuilder.kt deleted file mode 100644 index e9432205b9..0000000000 --- a/app/src/main/java/com/tangem/tap/common/feedback/FeedbackDataBuilder.kt +++ /dev/null @@ -1,85 +0,0 @@ -package com.tangem.tap.common.feedback - -import com.tangem.tap.common.extensions.breakLine - -class FeedbackDataBuilder( - private val infoHolder: AdditionalFeedbackInfo, -) { - val builder = StringBuilder() - - fun appendDelimiter(): FeedbackDataBuilder { - builder.appendDelimiter() - return this - } - - fun breakLine(count: Int = 1): FeedbackDataBuilder { - builder.breakLine(count) - return this - } - - fun appendCardInfo(): FeedbackDataBuilder { - builder.appendKeyValue("Card ID", infoHolder.cardId) - builder.appendKeyValue("Firmware version", infoHolder.cardFirmwareVersion) - builder.appendKeyValue("Card Blockchain", infoHolder.cardBlockchain) - builder.appendKeyValue("", infoHolder.signedHashesCount) - builder.appendKeyValue("User Wallet ID", infoHolder.userWalletId) - return this - } - - fun appendWalletsInfo(): FeedbackDataBuilder { - infoHolder.walletsInfo.forEach { walletInfo -> - builder.appendDelimiter() - builder.appendKeyValue("Blockchain", walletInfo.blockchain.fullName) - builder.appendKeyValue("Derivation path", walletInfo.derivationPath) - builder.appendKeyValue("Outputs count", walletInfo.outputsCount) - - if (walletInfo.tokens.isNotEmpty()) { - builder.append("Tokens:") - breakLine() - walletInfo.tokens.forEach { token -> - builder.appendKeyValue("ID", token.id ?: "[custom token]") - builder.appendKeyValue("Name", token.name) - builder.appendKeyValue("Contract address", token.contractAddress) - } - } - - builder.appendKeyValue("Host", walletInfo.host) - builder.appendKeyValue("Wallet address", walletInfo.addresses) - builder.appendKeyValue("Explorer link", walletInfo.explorerLink) - } - - return this - } - - fun appendTxFailedBlockchainInfo(error: String): FeedbackDataBuilder { - val walletInfo = infoHolder.onSendErrorWalletInfo ?: AdditionalFeedbackInfo.EmailWalletInfo() - builder.appendKeyValue("Blockchain", walletInfo.blockchain.fullName) - builder.appendKeyValue("Derivation path", walletInfo.derivationPath) - builder.appendKeyValue("Host", walletInfo.host) - builder.appendKeyValue("Token", infoHolder.token) - builder.appendKeyValue("Error", error) - builder.appendDelimiter() - builder.appendKeyValue("Source address", walletInfo.addresses) - builder.appendKeyValue("Destination address", infoHolder.destinationAddress) - builder.appendKeyValue("Amount", infoHolder.amount) - builder.appendKeyValue("Fee", infoHolder.fee) - return this - } - - fun appendPhoneInfo(): FeedbackDataBuilder { - builder.appendKeyValue("Phone model", infoHolder.phoneModel) - builder.appendKeyValue("OS version", infoHolder.osVersion) - builder.appendKeyValue("App version", infoHolder.appVersion) - return this - } - - fun build(): String = builder.toString() -} - -private fun StringBuilder.appendKeyValue(key: String, value: String?): StringBuilder = when { - value.isNullOrBlank() -> this - key.isBlank() -> this.append("$value\n") - else -> this.append("$key: $value\n") -} - -private fun StringBuilder.appendDelimiter(): StringBuilder = append("----------\n") \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/feedback/LegacyFeedbackManager.kt b/app/src/main/java/com/tangem/tap/common/feedback/LegacyFeedbackManager.kt deleted file mode 100644 index e7713995ac..0000000000 --- a/app/src/main/java/com/tangem/tap/common/feedback/LegacyFeedbackManager.kt +++ /dev/null @@ -1,136 +0,0 @@ -package com.tangem.tap.common.feedback - -import android.content.Context -import com.tangem.core.navigation.email.EmailSender -import com.tangem.domain.common.TapWorkarounds -import com.tangem.domain.feedback.FeedbackManagerFeatureToggles -import com.tangem.domain.feedback.GetFeedbackEmailUseCase -import com.tangem.domain.feedback.models.FeedbackEmailType -import com.tangem.domain.models.scan.ScanResponse -import com.tangem.tap.common.extensions.inject -import com.tangem.tap.common.extensions.sendEmail -import com.tangem.tap.common.log.TangemLogCollector -import com.tangem.tap.foregroundActivityObserver -import com.tangem.tap.proxy.redux.DaggerGraphState -import com.tangem.tap.scope -import com.tangem.tap.store -import com.tangem.tap.withForegroundActivity -import kotlinx.coroutines.launch -import timber.log.Timber -import java.io.File -import java.io.FileWriter -import java.io.StringWriter - -/** -[REDACTED_AUTHOR] - */ -class LegacyFeedbackManager( - val infoHolder: AdditionalFeedbackInfo, - private val logCollector: TangemLogCollector, - private val feedbackManagerFeatureToggles: FeedbackManagerFeatureToggles, - private val getFeedbackEmailUseCase: GetFeedbackEmailUseCase, -) { - - private var sessionLogsFile: File? = null - - fun sendEmail(feedbackData: FeedbackData, scanResponse: ScanResponse?) { - if (feedbackManagerFeatureToggles.isLocalLogsEnabled) { - scope.launch { - val getCardInfo = suspend { - scanResponse ?: error("ScanResponse must be not null") - store.inject(DaggerGraphState::getCardInfoUseCase).invoke(scanResponse).getOrNull() - ?: error("CardInfo must be not null") - } - - val email = getFeedbackEmailUseCase( - type = when (feedbackData) { - is FeedbackEmail -> FeedbackEmailType.DirectUserRequest(cardInfo = getCardInfo()) - is RateCanBeBetterEmail -> FeedbackEmailType.RateCanBeBetter(cardInfo = getCardInfo()) - is ScanFailsEmail -> FeedbackEmailType.ScanningProblem - is SendTransactionFailedEmail -> { - FeedbackEmailType.TransactionSendingProblem(cardInfo = getCardInfo()) - } - else -> FeedbackEmailType.DirectUserRequest(cardInfo = getCardInfo()) - }, - ) - - store.inject(DaggerGraphState::emailSender).send( - email = EmailSender.Email( - address = email.address, - subject = email.subject, - message = email.message, - attachment = email.file, - ), - ) - } - } else { - feedbackData.prepare(infoHolder) - foregroundActivityObserver.withForegroundActivity { activity -> - activity.sendEmail( - email = getSupportEmail(), - subject = activity.getString(feedbackData.subjectResId), - message = feedbackData.joinTogether(activity, infoHolder), - file = getLogFile(activity), - ) - } - } - } - - fun sendEmail(type: FeedbackEmailType) { - if (!feedbackManagerFeatureToggles.isLocalLogsEnabled) error("LOCAL_LOGS feature toggle must be enabled") - - scope.launch { - val email = getFeedbackEmailUseCase(type = type) - - store.inject(DaggerGraphState::emailSender).send( - email = EmailSender.Email( - address = email.address, - subject = email.subject, - message = email.message, - attachment = email.file, - ), - ) - } - } - - private fun getLogFile(context: Context): File? { - return try { - if (sessionLogsFile != null) { - return sessionLogsFile - } - val file = File(context.filesDir, LOGS_FILE) - file.delete() - file.createNewFile() - - val stringWriter = StringWriter() - logCollector.getLogs().forEach { stringWriter.append(it) } - val fileWriter = FileWriter(file) - fileWriter.write(stringWriter.toString()) - fileWriter.close() - logCollector.clearLogs() - if (file.exists()) { - sessionLogsFile = file - sessionLogsFile - } else { - null - } - } catch (ex: Exception) { - Timber.e(ex, "Can't create the logs file") - null - } - } - - private fun getSupportEmail(): String { - return if (TapWorkarounds.isStart2CoinIssuer(infoHolder.cardIssuer)) { - S2C_SUPPORT_EMAIL - } else { - DEFAULT_SUPPORT_EMAIL - } - } - - private companion object { - const val DEFAULT_SUPPORT_EMAIL = "support@tangem.com" - const val S2C_SUPPORT_EMAIL = "cardsupport@start2coin.com" - const val LOGS_FILE = "logs.txt" - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/feedback/ProxyFeedbackManager.kt b/app/src/main/java/com/tangem/tap/common/feedback/ProxyFeedbackManager.kt deleted file mode 100644 index d013937813..0000000000 --- a/app/src/main/java/com/tangem/tap/common/feedback/ProxyFeedbackManager.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.tangem.tap.common.feedback - -import com.tangem.domain.feedback.FeedbackManager -import com.tangem.domain.feedback.models.FeedbackEmailType -import com.tangem.tap.store -import timber.log.Timber - -internal class ProxyFeedbackManager : FeedbackManager { - - override fun sendEmail(type: FeedbackEmailType) { - val manager = store.state.globalState.feedbackManager - - if (manager == null) { - Timber.e("Feedback manager is not initialized") - return - } - - manager.sendEmail(type) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/log/TangemLogCollector.kt b/app/src/main/java/com/tangem/tap/common/log/TangemLogCollector.kt deleted file mode 100644 index 54a56e17c3..0000000000 --- a/app/src/main/java/com/tangem/tap/common/log/TangemLogCollector.kt +++ /dev/null @@ -1,31 +0,0 @@ -package com.tangem.tap.common.log - -import com.tangem.Log -import com.tangem.LogFormat -import com.tangem.TangemSdkLogger -import java.text.SimpleDateFormat -import java.util.* - -class TangemLogCollector( - private val levels: List, - private val messageFormatter: LogFormat, -) : TangemSdkLogger { - - private val dateFormatter = SimpleDateFormat("HH:mm:ss.SSS") - private val logs = mutableListOf() - private val mutex = Object() - - override fun log(message: () -> String, level: Log.Level) { - if (!levels.contains(level)) return - - synchronized(mutex) { - val formattedMessage = messageFormatter.format(message, level) - val logMessage = "${dateFormatter.format(Date())}: $formattedMessage" - logs.add("$logMessage\n") - } - } - - fun getLogs(): List = synchronized(mutex) { logs.toList() } - - fun clearLogs() = synchronized(mutex) { logs.clear() } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/redux/AppReducer.kt b/app/src/main/java/com/tangem/tap/common/redux/AppReducer.kt index cdc2bed475..38732f69ce 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/AppReducer.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/AppReducer.kt @@ -3,14 +3,12 @@ package com.tangem.tap.common.redux import com.tangem.tap.common.redux.global.globalReducer import com.tangem.tap.features.details.redux.DetailsReducer import com.tangem.tap.features.details.redux.walletconnect.WalletConnectReducer -import com.tangem.tap.features.disclaimer.redux.DisclaimerReducer import com.tangem.tap.features.home.redux.HomeReducer import com.tangem.tap.features.onboarding.products.note.redux.OnboardingNoteReducer import com.tangem.tap.features.onboarding.products.otherCards.redux.OnboardingOtherCardsReducer import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsReducer import com.tangem.tap.features.onboarding.products.wallet.redux.OnboardingWalletReducer import com.tangem.tap.features.saveWallet.redux.SaveWalletReducer -import com.tangem.tap.features.tokens.legacy.redux.TokensReducer import com.tangem.tap.features.welcome.redux.WelcomeReducer import com.tangem.tap.proxy.AppStateHolder import com.tangem.tap.proxy.redux.DaggerGraphReducer @@ -28,8 +26,6 @@ fun appReducer(action: Action, state: AppState?, appStateHolder: AppStateHolder) onboardingOtherCardsState = OnboardingOtherCardsReducer.reduce(action, state), twinCardsState = TwinCardsReducer.reduce(action, state), detailsState = DetailsReducer.reduce(action, state), - disclaimerState = DisclaimerReducer.reduce(action, state), - tokensState = TokensReducer.reduce(action, state), walletConnectState = WalletConnectReducer.reduce(action, state.walletConnectState), welcomeState = WelcomeReducer.reduce(action, state), saveWalletState = SaveWalletReducer.reduce(action, state), diff --git a/app/src/main/java/com/tangem/tap/common/redux/AppState.kt b/app/src/main/java/com/tangem/tap/common/redux/AppState.kt index bdcb0bd1c1..4fed318b36 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/AppState.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/AppState.kt @@ -10,8 +10,6 @@ import com.tangem.tap.features.details.redux.DetailsMiddleware import com.tangem.tap.features.details.redux.DetailsState import com.tangem.tap.features.details.redux.walletconnect.WalletConnectMiddleware import com.tangem.tap.features.details.redux.walletconnect.WalletConnectState -import com.tangem.tap.features.disclaimer.redux.DisclaimerMiddleware -import com.tangem.tap.features.disclaimer.redux.DisclaimerState import com.tangem.tap.features.home.redux.HomeMiddleware import com.tangem.tap.features.home.redux.HomeState import com.tangem.tap.features.onboarding.products.note.redux.OnboardingNoteMiddleware @@ -25,7 +23,6 @@ import com.tangem.tap.features.onboarding.products.wallet.redux.OnboardingWallet import com.tangem.tap.features.onboarding.products.wallet.redux.OnboardingWalletState import com.tangem.tap.features.saveWallet.redux.SaveWalletMiddleware import com.tangem.tap.features.saveWallet.redux.SaveWalletState -import com.tangem.tap.features.tokens.legacy.redux.TokensState import com.tangem.tap.features.wallet.redux.middlewares.TradeCryptoMiddleware import com.tangem.tap.features.welcome.redux.WelcomeMiddleware import com.tangem.tap.features.welcome.redux.WelcomeState @@ -43,8 +40,6 @@ data class AppState( val onboardingOtherCardsState: OnboardingOtherCardsState = OnboardingOtherCardsState(), val twinCardsState: TwinCardsState = TwinCardsState(), val detailsState: DetailsState = DetailsState(), - val disclaimerState: DisclaimerState = DisclaimerState(), - val tokensState: TokensState = TokensState(), val walletConnectState: WalletConnectState = WalletConnectState(), val welcomeState: WelcomeState = WelcomeState(), val saveWalletState: SaveWalletState = SaveWalletState(), @@ -75,7 +70,6 @@ data class AppState( OnboardingOtherCardsMiddleware.handler, TwinCardsMiddleware.handler, DetailsMiddleware().detailsMiddleware, - DisclaimerMiddleware().disclaimerMiddleware, WalletConnectMiddleware().walletConnectMiddleware, BackupMiddleware().backupMiddleware, WelcomeMiddleware().middleware, diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt index 2b9e953b46..93fc1a023b 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt @@ -2,12 +2,10 @@ package com.tangem.tap.common.redux.global import com.tangem.common.CompletionResult import com.tangem.core.analytics.models.AnalyticsParam -import com.tangem.datasource.config.ConfigManager +import com.tangem.datasource.local.config.environment.EnvironmentConfigStorage import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.redux.StateDialog -import com.tangem.tap.common.feedback.FeedbackData -import com.tangem.tap.common.feedback.LegacyFeedbackManager import com.tangem.tap.common.redux.DebugErrorAction import com.tangem.tap.common.redux.ErrorAction import com.tangem.tap.common.redux.NotificationAction @@ -69,10 +67,7 @@ sealed class GlobalAction : Action { val walletPublicKey: ByteArray, ) : GlobalAction() - data class SetConfigManager(val configManager: ConfigManager) : GlobalAction() - data class SetFeedbackManager(val feedbackManager: LegacyFeedbackManager) : GlobalAction() - - data class SendEmail(val feedbackData: FeedbackData, val scanResponse: ScanResponse?) : GlobalAction() + data class SetConfigManager(val environmentConfigStorage: EnvironmentConfigStorage) : GlobalAction() object ExchangeManager : GlobalAction() { object Init : GlobalAction() { diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMiddleware.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMiddleware.kt index 43d85d7fc5..a0c16d69f6 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMiddleware.kt @@ -4,7 +4,7 @@ import com.tangem.common.CompletionResult import com.tangem.common.core.TangemSdkError import com.tangem.common.extensions.guard import com.tangem.core.analytics.models.AnalyticsParam -import com.tangem.datasource.config.models.Config +import com.tangem.datasource.local.config.environment.EnvironmentConfig import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.common.LogConfig import com.tangem.domain.models.scan.CardDTO @@ -55,15 +55,9 @@ private fun handleAction(action: Action, appState: () -> AppState?) { is GlobalAction.RestoreAppCurrency -> { restoreAppCurrency() } - is GlobalAction.SendEmail -> { - store.state.globalState.feedbackManager?.sendEmail( - feedbackData = action.feedbackData, - scanResponse = action.scanResponse, - ) - } is GlobalAction.ExchangeManager.Init -> { val appStateSafe = appState() ?: return - val config = appStateSafe.globalState.configManager?.config ?: return + val config = appStateSafe.globalState.environmentConfigStorage?.getConfigSync() ?: return scope.launch { val scanResponseProvider: () -> ScanResponse? = { @@ -92,21 +86,24 @@ private fun handleAction(action: Action, appState: () -> AppState?) { scope.launch { exchangeManager.update() } } is GlobalAction.FetchUserCountry -> { - scope.launch { - // TODO("After adding DI") get dependencies by DI - runCatching { store.state.featureRepositoryProvider.homeRepository.getUserCountryCode() } - .onSuccess { - store.dispatchOnMain( - GlobalAction.FetchUserCountry.Success(countryCode = it.code.lowercase()), - ) - } - .onFailure { - store.dispatchOnMain( - GlobalAction.FetchUserCountry.Success( - countryCode = Locale.getDefault().country.lowercase(), - ), - ) - } + val homeFeatureToggles = store.inject(DaggerGraphState::homeFeatureToggles) + + if (!homeFeatureToggles.isMigrateUserCountryCodeEnabled) { + scope.launch { + runCatching { store.state.featureRepositoryProvider.homeRepository.getUserCountryCode() } + .onSuccess { + store.dispatchOnMain( + GlobalAction.FetchUserCountry.Success(countryCode = it.code.lowercase()), + ) + } + .onFailure { + store.dispatchOnMain( + GlobalAction.FetchUserCountry.Success( + countryCode = Locale.getDefault().country.lowercase(), + ), + ) + } + } } } } @@ -143,21 +140,24 @@ private fun restoreAppCurrency() { } } -private fun makeSellExchangeService(config: Config): ExchangeService { +private fun makeSellExchangeService(environmentConfig: EnvironmentConfig): ExchangeService { return MoonPayService( - apiKey = config.moonPayApiKey, - secretKey = config.moonPayApiSecretKey, + apiKey = environmentConfig.moonPayApiKey, + secretKey = environmentConfig.moonPayApiSecretKey, logEnabled = LogConfig.network.moonPayService, ) } -private fun makeBuyExchangeService(config: Config): ExchangeService { +private fun makeBuyExchangeService(environmentConfig: EnvironmentConfig): ExchangeService { return BuyExchangeService( - mercuryoService = makeMercuryoExchangeService(config), + mercuryoService = makeMercuryoExchangeService(environmentConfig), ) } -private fun makeMercuryoExchangeService(config: Config): MercuryoService { - val mercuryoEnvironment = MercuryoEnvironment.prod(config.mercuryoWidgetId, config.mercuryoSecret) +private fun makeMercuryoExchangeService(environmentConfig: EnvironmentConfig): MercuryoService { + val mercuryoEnvironment = MercuryoEnvironment.prod( + environmentConfig.mercuryoWidgetId, + environmentConfig.mercuryoSecret, + ) return MercuryoService(mercuryoEnvironment) } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt index 6b011082d2..223296f720 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt @@ -2,12 +2,9 @@ package com.tangem.tap.common.redux.global import com.tangem.domain.redux.domainStore import com.tangem.domain.redux.global.DomainGlobalAction -import com.tangem.tap.common.extensions.dispatchOnMain import com.tangem.tap.common.redux.AppState -import com.tangem.tap.features.home.redux.HomeAction import com.tangem.tap.features.onboarding.OnboardingManager import com.tangem.tap.proxy.AppStateHolder -import com.tangem.tap.store import com.tangem.utils.extensions.replaceBy import org.rekotlin.Action @@ -51,7 +48,7 @@ fun globalReducer(action: Action, state: AppState, appStateHolder: AppStateHolde globalState.copy(appCurrency = action.appCurrency) } is GlobalAction.SetConfigManager -> { - globalState.copy(configManager = action.configManager) + globalState.copy(environmentConfigStorage = action.environmentConfigStorage) } is GlobalAction.UpdateWalletSignedHashes -> { val card = globalState.scanResponse?.card ?: return globalState @@ -71,9 +68,6 @@ fun globalReducer(action: Action, state: AppState, appStateHolder: AppStateHolde ) globalState.copy(scanResponse = globalState.scanResponse.copy(card = newCardInstance)) } - is GlobalAction.SetFeedbackManager -> { - globalState.copy(feedbackManager = action.feedbackManager) - } is GlobalAction.ShowDialog -> { globalState.copy(dialog = action.stateDialog) } @@ -86,10 +80,7 @@ fun globalReducer(action: Action, state: AppState, appStateHolder: AppStateHolde is GlobalAction.SetIfCardVerifiedOnline -> globalState.copy(cardVerifiedOnline = action.verified) is GlobalAction.FetchUserCountry.Success -> { - store.dispatchOnMain(HomeAction.UpdateCountryCode(action.countryCode)) - globalState.copy( - userCountryCode = action.countryCode, - ) + globalState.copy(userCountryCode = action.countryCode) } else -> globalState } diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt index 420951087b..054469bc26 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt @@ -1,11 +1,10 @@ package com.tangem.tap.common.redux.global -import com.tangem.datasource.config.ConfigManager +import com.tangem.datasource.local.config.environment.EnvironmentConfigStorage import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.apptheme.model.AppThemeMode import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.redux.StateDialog -import com.tangem.tap.common.feedback.LegacyFeedbackManager import com.tangem.tap.domain.TapWalletManager import com.tangem.tap.features.onboarding.OnboardingManager import com.tangem.tap.network.exchangeServices.CurrencyExchangeManager @@ -17,12 +16,12 @@ data class GlobalState( val onboardingState: OnboardingState = OnboardingState(), val cardVerifiedOnline: Boolean = false, val tapWalletManager: TapWalletManager = TapWalletManager(), - val configManager: ConfigManager? = null, - val feedbackManager: LegacyFeedbackManager? = null, + val environmentConfigStorage: EnvironmentConfigStorage? = null, val appCurrency: AppCurrency = AppCurrency.Default, val scanCardFailsCounter: Int = 0, val dialog: StateDialog? = null, val exchangeManager: CurrencyExchangeManager = CurrencyExchangeManager.dummy(), + @Deprecated("Use GetUserCountryCodeUseCase instead") val userCountryCode: String? = null, val appThemeMode: AppThemeMode = AppThemeMode.DEFAULT, ) : StateType diff --git a/app/src/main/java/com/tangem/tap/common/redux/legacy/LegacyMiddleware.kt b/app/src/main/java/com/tangem/tap/common/redux/legacy/LegacyMiddleware.kt index 2712e8375d..1dc41c90bd 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/legacy/LegacyMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/legacy/LegacyMiddleware.kt @@ -1,15 +1,8 @@ package com.tangem.tap.common.redux.legacy -import com.tangem.blockchain.common.AmountType -import com.tangem.domain.feedback.models.BlockchainErrorInfo import com.tangem.domain.redux.LegacyAction -import com.tangem.domain.utils.convertToSdkAmount import com.tangem.tap.common.extensions.dispatchWithMain import com.tangem.tap.common.extensions.inject -import com.tangem.tap.common.extensions.stripZeroPlainString -import com.tangem.tap.common.feedback.FeedbackEmail -import com.tangem.tap.common.feedback.RateCanBeBetterEmail -import com.tangem.tap.common.feedback.SendTransactionFailedEmail import com.tangem.tap.common.redux.AppState import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.features.details.redux.DetailsAction @@ -23,7 +16,6 @@ import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.launch import org.rekotlin.Middleware internal object LegacyMiddleware { @@ -33,68 +25,13 @@ internal object LegacyMiddleware { { next -> { action -> when (action) { - is LegacyAction.SendEmailRateCanBeBetter -> { - store.state.globalState.feedbackManager?.sendEmail( - feedbackData = RateCanBeBetterEmail(), - scanResponse = action.scanResponse, - ) - } - is LegacyAction.SendEmailSupport -> { - store.state.globalState.feedbackManager?.sendEmail( - feedbackData = FeedbackEmail(), - scanResponse = action.scanResponse, - ) - } is LegacyAction.StartOnboardingProcess -> { store.dispatch( - GlobalAction.Onboarding.Start(action.scanResponse, canSkipBackup = action.canSkipBackup), - ) - } - is LegacyAction.SendEmailTransactionFailed -> { - if (store.inject(DaggerGraphState::feedbackManagerFeatureToggles).isLocalLogsEnabled) { - - val amount = action.amount?.convertToSdkAmount(action.cryptoCurrency) - store.inject(DaggerGraphState::saveBlockchainErrorUseCase).invoke( - error = BlockchainErrorInfo( - errorMessage = action.errorMessage, - blockchainId = action.cryptoCurrency.network.id.value, - derivationPath = action.cryptoCurrency.network.derivationPath.value, - destinationAddress = action.destinationAddress.orEmpty(), - tokenSymbol = if (amount?.type is AmountType.Token) { - amount.currencySymbol - } else { - "" - }, - amount = amount?.value?.stripZeroPlainString() ?: "unknown", - fee = action.fee?.convertToSdkAmount(action.cryptoCurrency) - ?.value?.stripZeroPlainString() ?: "unknown", - ), - ) - - store.state.globalState.feedbackManager?.sendEmail( - feedbackData = SendTransactionFailedEmail(action.errorMessage), + GlobalAction.Onboarding.Start( scanResponse = action.scanResponse, - ) - } else { - scope.launch { - store.inject(DaggerGraphState::walletManagersFacade) - .getOrCreateWalletManager( - userWalletId = action.userWalletId, - network = action.cryptoCurrency.network, - )?.let { walletManager -> - store.state.globalState.feedbackManager?.infoHolder?.updateOnSendError( - walletManager = walletManager, - amountToSend = action.amount?.convertToSdkAmount(action.cryptoCurrency), - feeAmount = action.fee?.convertToSdkAmount(action.cryptoCurrency), - destinationAddress = action.destinationAddress, - ) - } - store.state.globalState.feedbackManager?.sendEmail( - feedbackData = SendTransactionFailedEmail(action.errorMessage), - scanResponse = null, - ) - } - } + canSkipBackup = action.canSkipBackup, + ), + ) } is LegacyAction.PrepareDetailsScreen -> { val userWalletsListManager = store.inject(DaggerGraphState::generalUserWalletsListManager) diff --git a/app/src/main/java/com/tangem/tap/common/ui/ScanFailsDialog.kt b/app/src/main/java/com/tangem/tap/common/ui/ScanFailsDialog.kt index 410f81e1c6..6096730a8e 100644 --- a/app/src/main/java/com/tangem/tap/common/ui/ScanFailsDialog.kt +++ b/app/src/main/java/com/tangem/tap/common/ui/ScanFailsDialog.kt @@ -8,16 +8,19 @@ import androidx.core.view.isVisible import com.tangem.core.analytics.Analytics import com.tangem.core.analytics.models.AnalyticsParam import com.tangem.core.analytics.models.Basic +import com.tangem.domain.feedback.models.FeedbackEmailType import com.tangem.domain.redux.StateDialog import com.tangem.tap.common.analytics.events.ScanFailsDialogAnalytics import com.tangem.tap.common.extensions.dispatchDialogHide import com.tangem.tap.common.extensions.dispatchOpenUrl -import com.tangem.tap.common.feedback.ScanFailsEmail -import com.tangem.tap.common.redux.global.GlobalAction +import com.tangem.tap.common.extensions.inject import com.tangem.tap.features.home.LocaleRegionProvider import com.tangem.tap.features.home.RUSSIA_COUNTRY_CODE +import com.tangem.tap.proxy.redux.DaggerGraphState +import com.tangem.tap.scope import com.tangem.tap.store import com.tangem.wallet.R +import kotlinx.coroutines.launch /** [REDACTED_AUTHOR] @@ -65,7 +68,11 @@ internal object ScanFailsDialog { } customView.findViewById(R.id.request_support_button)?.setOnClickListener { Analytics.send(Basic.ButtonSupport(sourceAnalytics)) - store.dispatch(GlobalAction.SendEmail(feedbackData = ScanFailsEmail(), scanResponse = null)) + + scope.launch { + store.inject(DaggerGraphState::sendFeedbackEmailUseCase) + .invoke(type = FeedbackEmailType.ScanningProblem) + } } customView.findViewById(R.id.cancel_button)?.setOnClickListener { store.dispatchDialogHide() diff --git a/core/navigation/src/main/java/com/tangem/core/navigation/email/AndroidEmailSender.kt b/app/src/main/java/com/tangem/tap/core/navigation/email/AndroidEmailSender.kt similarity index 61% rename from core/navigation/src/main/java/com/tangem/core/navigation/email/AndroidEmailSender.kt rename to app/src/main/java/com/tangem/tap/core/navigation/email/AndroidEmailSender.kt index d6fe4b6d35..e38ae3919c 100644 --- a/core/navigation/src/main/java/com/tangem/core/navigation/email/AndroidEmailSender.kt +++ b/app/src/main/java/com/tangem/tap/core/navigation/email/AndroidEmailSender.kt @@ -1,27 +1,34 @@ -package com.tangem.core.navigation.email +package com.tangem.tap.core.navigation.email -import android.content.Context import android.content.Intent import android.net.Uri +import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ShareCompat import androidx.core.content.ContextCompat import androidx.core.content.FileProvider +import com.tangem.core.navigation.email.EmailSender +import com.tangem.tap.foregroundActivityObserver import timber.log.Timber /** * Implementation of email sender for Android * - * @property context context - * [REDACTED_AUTHOR] */ -internal class AndroidEmailSender(private val context: Context) : EmailSender { +internal class AndroidEmailSender : EmailSender { override fun send(email: EmailSender.Email, onFail: ((Exception) -> Unit)?) { - val originalIntent = createEmailShareIntent(email) + val activity = foregroundActivityObserver.foregroundActivity + + if (activity == null) { + Timber.e("Foreground activity not found") + return + } + + val originalIntent = createEmailShareIntent(activity, email) val emailFilterIntent = Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:")) - val packageManager = context.packageManager + val packageManager = activity.packageManager val originalIntentResults = packageManager.queryIntentActivities(originalIntent, 0) val emailFilterIntentResults = packageManager.queryIntentActivities(emailFilterIntent, 0) @@ -32,7 +39,7 @@ internal class AndroidEmailSender(private val context: Context) : EmailSender { } } .map { - createEmailShareIntent(email).apply { setPackage(it.activityInfo.packageName) } + createEmailShareIntent(activity, email).apply { setPackage(it.activityInfo.packageName) } } .toMutableList() @@ -41,14 +48,14 @@ internal class AndroidEmailSender(private val context: Context) : EmailSender { putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedIntents.toTypedArray()) } - ContextCompat.startActivity(context, chooserIntent, null) + ContextCompat.startActivity(activity, chooserIntent, null) } catch (ex: Exception) { Timber.e("Failed to send email: $ex") } } - private fun createEmailShareIntent(email: EmailSender.Email): Intent { - val builder = ShareCompat.IntentBuilder(context) + private fun createEmailShareIntent(activity: AppCompatActivity, email: EmailSender.Email): Intent { + val builder = ShareCompat.IntentBuilder(activity) .setType("message/rfc822") .setEmailTo(arrayOf(email.address)) .setSubject(email.subject) @@ -56,7 +63,7 @@ internal class AndroidEmailSender(private val context: Context) : EmailSender { email.attachment?.let { builder.setStream( - FileProvider.getUriForFile(context, "${context.packageName}.provider", it), + FileProvider.getUriForFile(activity, "${activity.packageName}.provider", it), ) } diff --git a/app/src/main/java/com/tangem/tap/di/FeedbackManagerFeatureTogglesModule.kt b/app/src/main/java/com/tangem/tap/di/FeedbackManagerFeatureTogglesModule.kt deleted file mode 100644 index 4202ba1af8..0000000000 --- a/app/src/main/java/com/tangem/tap/di/FeedbackManagerFeatureTogglesModule.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.tangem.tap.di - -import com.tangem.core.featuretoggle.manager.FeatureTogglesManager -import com.tangem.domain.feedback.FeedbackManagerFeatureToggles -import com.tangem.tap.common.feedback.DefaultFeedbackManagerFeatureToggles -import dagger.Module -import dagger.Provides -import dagger.hilt.InstallIn -import dagger.hilt.components.SingletonComponent -import javax.inject.Singleton - -@Module -@InstallIn(SingletonComponent::class) -internal object FeedbackManagerFeatureTogglesModule { - - @Provides - @Singleton - fun provideFeedbackManagerFeatureToggles( - featureTogglesManager: FeatureTogglesManager, - ): FeedbackManagerFeatureToggles { - return DefaultFeedbackManagerFeatureToggles(featureTogglesManager) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/di/UtilsModule.kt b/app/src/main/java/com/tangem/tap/di/UtilsModule.kt index 9c29c8598b..7fdf0263cc 100644 --- a/app/src/main/java/com/tangem/tap/di/UtilsModule.kt +++ b/app/src/main/java/com/tangem/tap/di/UtilsModule.kt @@ -5,8 +5,6 @@ import com.tangem.core.navigation.finisher.AppFinisher import com.tangem.core.navigation.settings.SettingsManager import com.tangem.core.navigation.share.ShareManager import com.tangem.core.navigation.url.UrlOpener -import com.tangem.domain.feedback.FeedbackManager -import com.tangem.tap.common.feedback.ProxyFeedbackManager import com.tangem.tap.common.finisher.AndroidAppFinisher import com.tangem.tap.common.settings.IntentSettingsManager import com.tangem.tap.common.share.IntentShareManager @@ -30,10 +28,6 @@ internal object UtilsModule { @Singleton fun provideUrlOpener(): UrlOpener = CustomTabsUrlOpener() - @Provides - @Singleton - fun provideFeedbackManager(): FeedbackManager = ProxyFeedbackManager() - @Provides @Singleton fun provideAppFinisher(@ApplicationContext context: Context): AppFinisher = AndroidAppFinisher(context) diff --git a/app/src/main/java/com/tangem/tap/di/core/navigation/email/EmailSenderModule.kt b/app/src/main/java/com/tangem/tap/di/core/navigation/email/EmailSenderModule.kt new file mode 100644 index 0000000000..b986cfe46d --- /dev/null +++ b/app/src/main/java/com/tangem/tap/di/core/navigation/email/EmailSenderModule.kt @@ -0,0 +1,18 @@ +package com.tangem.tap.di.core.navigation.email + +import com.tangem.core.navigation.email.EmailSender +import com.tangem.tap.core.navigation.email.AndroidEmailSender +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +internal object EmailSenderModule { + + @Provides + @Singleton + fun provideEmailSender(): EmailSender = AndroidEmailSender() +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/di/domain/CardDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/CardDomainModule.kt index ce9ed6e593..24c41445ab 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/CardDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/CardDomainModule.kt @@ -22,14 +22,6 @@ import javax.inject.Singleton @InstallIn(SingletonComponent::class) internal object CardDomainModule { - @Provides - @Singleton - fun provideGetBiometricsStatusUseCase( - cardSdkConfigRepository: CardSdkConfigRepository, - ): GetBiometricsStatusUseCase { - return GetBiometricsStatusUseCase(cardSdkConfigRepository = cardSdkConfigRepository) - } - @Provides @Singleton fun provideSetAccessCodeRequestPolicyUseCase( @@ -38,12 +30,6 @@ internal object CardDomainModule { return SetAccessCodeRequestPolicyUseCase(cardSdkConfigRepository = cardSdkConfigRepository) } - @Provides - @Singleton - fun provideWasWalletAlreadySignedHashesConfirmedUseCase(cardRepository: CardRepository): WasCardScannedUseCase { - return WasCardScannedUseCase(cardRepository = cardRepository) - } - @Provides @Singleton fun provideSetCardWasScannedUseCase(cardRepository: CardRepository): SetCardWasScannedUseCase { diff --git a/app/src/main/java/com/tangem/tap/di/domain/CardLegacyDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/CardLegacyDomainModule.kt index 9654238c85..12b071ad16 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/CardLegacyDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/CardLegacyDomainModule.kt @@ -1,8 +1,10 @@ package com.tangem.tap.di.domain -import com.tangem.domain.card.* +import com.tangem.core.featuretoggle.manager.FeatureTogglesManager +import com.tangem.domain.card.ScanCardProcessor import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.usecase.GenerateWalletNameUseCase +import com.tangem.tap.domain.scanCard.CardScanningFeatureToggles import com.tangem.tap.domain.scanCard.DefaultScanCardProcessor import dagger.Module import dagger.Provides @@ -14,6 +16,12 @@ import javax.inject.Singleton @InstallIn(SingletonComponent::class) internal object CardLegacyDomainModule { + @Provides + @Singleton + fun provideCardScanningFeatureToggles(featureTogglesManager: FeatureTogglesManager): CardScanningFeatureToggles { + return CardScanningFeatureToggles(featureTogglesManager) + } + @Provides @Singleton fun provideScanCardProcessor(): ScanCardProcessor = DefaultScanCardProcessor() diff --git a/app/src/main/java/com/tangem/tap/di/domain/FeedbackDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/FeedbackDomainModule.kt index 04f4f03fb8..b905aa7edc 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/FeedbackDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/FeedbackDomainModule.kt @@ -2,8 +2,8 @@ package com.tangem.tap.di.domain import android.content.Context import com.tangem.domain.feedback.GetCardInfoUseCase -import com.tangem.domain.feedback.GetFeedbackEmailUseCase import com.tangem.domain.feedback.SaveBlockchainErrorUseCase +import com.tangem.domain.feedback.SendFeedbackEmailUseCase import com.tangem.domain.feedback.repository.FeedbackRepository import dagger.Module import dagger.Provides @@ -27,8 +27,8 @@ internal object FeedbackDomainModule { fun provideGetFeedbackEmailUseCase( feedbackRepository: FeedbackRepository, @ApplicationContext context: Context, - ): GetFeedbackEmailUseCase { - return GetFeedbackEmailUseCase(feedbackRepository = feedbackRepository, resources = context.resources) + ): SendFeedbackEmailUseCase { + return SendFeedbackEmailUseCase(feedbackRepository = feedbackRepository, resources = context.resources) } @Provides diff --git a/app/src/main/java/com/tangem/tap/di/domain/MarketsDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/MarketsDomainModule.kt index 59b0f45dc5..8adbb68381 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/MarketsDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/MarketsDomainModule.kt @@ -63,4 +63,10 @@ object MarketsDomainModule { networksRepository = networksRepository, ) } + + @Provides + @Singleton + fun provideGetTokenExchangesUseCase(marketsTokenRepository: MarketsTokenRepository): GetTokenExchangesUseCase { + return GetTokenExchangesUseCase(marketsTokenRepository = marketsTokenRepository) + } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/di/domain/SettingsDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/SettingsDomainModule.kt index 1b5860c2c0..e175d51e25 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/SettingsDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/SettingsDomainModule.kt @@ -10,6 +10,8 @@ import com.tangem.domain.settings.repositories.AppRatingRepository import com.tangem.domain.settings.repositories.PermissionRepository import com.tangem.domain.settings.repositories.PromoSettingsRepository import com.tangem.domain.settings.repositories.SettingsRepository +import com.tangem.domain.settings.usercountry.FetchUserCountryUseCase +import com.tangem.domain.settings.usercountry.GetUserCountryUseCase import com.tangem.tap.domain.sdk.TangemSdkManager import com.tangem.tap.domain.settings.DefaultLegacySettingsRepository import dagger.Module @@ -212,4 +214,16 @@ internal object SettingsDomainModule { return ShouldSaveAccessCodesUseCase(settingsRepository = settingsRepository) } // endregion + + @Provides + @Singleton + fun provideFetchUserCountryCodeUseCase(settingsRepository: SettingsRepository): FetchUserCountryUseCase { + return FetchUserCountryUseCase(settingsRepository) + } + + @Provides + @Singleton + fun provideGetUserCountryCodeUseCase(settingsRepository: SettingsRepository): GetUserCountryUseCase { + return GetUserCountryUseCase(settingsRepository) + } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/di/domain/StakingDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/StakingDomainModule.kt index 6753cdf12a..be10ba1059 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/StakingDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/StakingDomainModule.kt @@ -206,4 +206,10 @@ internal object StakingDomainModule { stakingErrorResolver = stakingErrorResolver, ) } + + @Provides + @Singleton + fun provideGetStakingIntegrationIdUseCase(stakingRepository: StakingRepository): GetStakingIntegrationIdUseCase { + return GetStakingIntegrationIdUseCase(stakingRepository) + } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/di/domain/TokensDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/TokensDomainModule.kt index 4c74d58706..5245e5a7ec 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/TokensDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/TokensDomainModule.kt @@ -287,12 +287,6 @@ internal object TokensDomainModule { ) } - @Provides - @Singleton - fun provideGetCurrenciesUseCase(currenciesRepository: CurrenciesRepository): GetCryptoCurrenciesUseCase { - return GetCryptoCurrenciesUseCase(currenciesRepository = currenciesRepository) - } - @Provides @Singleton fun provideIsCryptoCurrencyCoinCouldHideUseCase( @@ -313,68 +307,6 @@ internal object TokensDomainModule { ) } - @Provides - @Singleton - fun provideHasMissedAddressesCryptoCurrenciesUseCase( - currenciesRepository: CurrenciesRepository, - ): GetMissedAddressesCryptoCurrenciesUseCase { - return GetMissedAddressesCryptoCurrenciesUseCase(currenciesRepository = currenciesRepository) - } - - @Provides - @Singleton - fun provideGetGlobalTokenListUseCase(tokensListRepository: TokensListRepository): GetGlobalTokenListUseCase { - return GetGlobalTokenListUseCase(repository = tokensListRepository) - } - - @Provides - @Singleton - fun provideCheckTokenCompatibilityUseCase( - networksCompatibilityRepository: NetworksCompatibilityRepository, - ): CheckCurrencyCompatibilityUseCase { - return CheckCurrencyCompatibilityUseCase(networksCompatibilityRepository) - } - - @Provides - @Singleton - fun provideNeedHardenedDerivationUseCase( - networksCompatibilityRepository: NetworksCompatibilityRepository, - ): RequiresHardenedDerivationOnlyUseCase { - return RequiresHardenedDerivationOnlyUseCase(networksCompatibilityRepository) - } - - @Provides - @Singleton - fun provideFindTokenByContractAddressUseCase( - tokensListRepository: TokensListRepository, - ): FindTokenByContractAddressUseCase { - return FindTokenByContractAddressUseCase(repository = tokensListRepository) - } - - @Provides - @Singleton - fun provideValidateContractAddressUseCase( - tokensListRepository: TokensListRepository, - ): ValidateContractAddressUseCase { - return ValidateContractAddressUseCase(tokensListRepository = tokensListRepository) - } - - @Provides - @Singleton - fun provideAreTokensSupportedByNetworkUseCase( - repository: NetworksCompatibilityRepository, - ): AreTokensSupportedByNetworkUseCase { - return AreTokensSupportedByNetworkUseCase(repository = repository) - } - - @Provides - @Singleton - fun provideGetNetworksSupportedByWallet( - repository: NetworksCompatibilityRepository, - ): GetNetworksSupportedByWallet { - return GetNetworksSupportedByWallet(repository = repository) - } - @Provides @Singleton fun provideGetBalanceNotEnoughForFeeWarningUseCase( diff --git a/app/src/main/java/com/tangem/tap/di/domain/TransactionDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/TransactionDomainModule.kt index e50891f228..73c0236567 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/TransactionDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/TransactionDomainModule.kt @@ -42,21 +42,6 @@ internal object TransactionDomainModule { ) } - @Provides - @Singleton - fun provideSendMultipleTransactionUseCase( - cardSdkConfigRepository: CardSdkConfigRepository, - transactionRepository: TransactionRepository, - walletManagersFacade: WalletManagersFacade, - ): SendMultipleTransactionUseCase { - return SendMultipleTransactionUseCase( - demoConfig = DemoConfig(), - cardSdkConfigRepository = cardSdkConfigRepository, - transactionRepository = transactionRepository, - walletManagersFacade = walletManagersFacade, - ) - } - @Provides @Singleton fun provideAssociateAssetUseCase( diff --git a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt index 256c8f1bf9..faaa017b70 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt @@ -4,19 +4,12 @@ import com.tangem.blockchain.common.Token import com.tangem.blockchain.common.Wallet import com.tangem.core.analytics.Analytics import com.tangem.core.analytics.models.Basic -import com.tangem.datasource.config.ConfigManager import com.tangem.domain.common.extensions.withMainContext -import com.tangem.domain.common.util.cardTypesResolver -import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.wallets.models.UserWallet import com.tangem.operations.attestation.Attestation -import com.tangem.tap.common.extensions.inject import com.tangem.tap.common.extensions.setContext import com.tangem.tap.common.redux.global.GlobalAction -import com.tangem.tap.features.disclaimer.createDisclaimer -import com.tangem.tap.features.disclaimer.redux.DisclaimerAction import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsAction -import com.tangem.tap.proxy.redux.DaggerGraphState import com.tangem.tap.store import com.tangem.tap.tangemSdkManager import com.tangem.utils.coroutines.AppCoroutineDispatcherProvider @@ -54,30 +47,13 @@ class TapWalletManager( tangemSdkManager.changeDisplayedCardIdNumbersCount(scanResponse) - val featureToggles = store.inject(DaggerGraphState::feedbackManagerFeatureToggles) - if (!featureToggles.isLocalLogsEnabled) { - store.state.globalState.feedbackManager?.infoHolder?.setCardInfo(scanResponse) - } - - updateConfigManager(scanResponse) withMainContext { // Order is important - store.dispatch(DisclaimerAction.SetDisclaimer(card.createDisclaimer())) store.dispatch(TwinCardsAction.IfTwinsPrepareState(scanResponse)) store.dispatch(GlobalAction.SaveScanResponse(scanResponse)) store.dispatch(GlobalAction.SetIfCardVerifiedOnline(!attestationFailed)) } } - - fun updateConfigManager(data: ScanResponse) { - val configManager = store.state.globalState.configManager - - if (data.cardTypesResolver.isStart2Coin()) { - configManager?.turnOff(ConfigManager.IS_TOP_UP_ENABLED) - } else { - configManager?.resetToDefault(ConfigManager.IS_TOP_UP_ENABLED) - } - } } fun Wallet.getFirstToken(): Token? = getTokens().toList().getOrNull(index = 0) \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/card/DefaultDerivationsRepository.kt b/app/src/main/java/com/tangem/tap/domain/card/DefaultDerivationsRepository.kt index 72b36175ef..0013049c04 100644 --- a/app/src/main/java/com/tangem/tap/domain/card/DefaultDerivationsRepository.kt +++ b/app/src/main/java/com/tangem/tap/domain/card/DefaultDerivationsRepository.kt @@ -12,8 +12,8 @@ import com.tangem.common.extensions.toMapKey import com.tangem.crypto.hdWallet.DerivationPath import com.tangem.data.common.currency.getNetwork import com.tangem.datasource.local.userwallet.UserWalletsStore +import com.tangem.domain.card.BackendId import com.tangem.domain.card.repository.DerivationsRepository -import com.tangem.domain.common.util.derivationStyleProvider import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.tokens.model.Network @@ -21,6 +21,7 @@ import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId import com.tangem.operations.derivation.ExtendedPublicKeysMap import com.tangem.tap.domain.sdk.TangemSdkManager +import com.tangem.tap.domain.tasks.UserWalletIdPreflightReadFilter import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.withContext import timber.log.Timber @@ -47,7 +48,7 @@ internal class DefaultDerivationsRepository( getNetwork( blockchain = Blockchain.fromNetworkId(it.value) ?: return@mapNotNull null, extraDerivationPath = null, - derivationStyleProvider = userWallet.scanResponse.derivationStyleProvider, + scanResponse = userWallet.scanResponse, ) }, ) @@ -73,17 +74,17 @@ internal class DefaultDerivationsRepository( override suspend fun hasMissedDerivations( userWalletId: UserWalletId, - networksWithDerivationPath: Map, + networksWithDerivationPath: Map, ): Boolean { val userWallet = userWalletsStore.getSyncOrNull(userWalletId) ?: error("User wallet not found") val derivations = MissedDerivationsFinder(scanResponse = userWallet.scanResponse) .findByNetworks( - networksWithDerivationPath.mapNotNull { (networkId, extraDerivationPath) -> + networksWithDerivationPath.mapNotNull { (backendId, extraDerivationPath) -> getNetwork( - blockchain = Blockchain.fromNetworkId(networkId.value) ?: return@mapNotNull null, + blockchain = Blockchain.fromNetworkId(backendId) ?: return@mapNotNull null, extraDerivationPath = extraDerivationPath, - derivationStyleProvider = userWallet.scanResponse.derivationStyleProvider, + scanResponse = userWallet.scanResponse, ) }, ) @@ -92,15 +93,20 @@ internal class DefaultDerivationsRepository( } override suspend fun derivePublicKeys(userWalletId: UserWalletId, derivations: Derivations): DerivedKeys { - tangemSdkManager.derivePublicKeys(cardId = null, derivations = derivations) - .doOnSuccess { response -> - updatePublicKeys(userWalletId = userWalletId, keys = response.entries) - .doOnSuccess { - validateDerivations(scanResponse = it.scanResponse, derivations = derivations) - return response.entries - } - .doOnFailure { throw it } - } + // todo replace it in task [REDACTED_JIRA] + val preflightReadFilter = UserWalletIdPreflightReadFilter(userWalletId) + tangemSdkManager.derivePublicKeys( + cardId = null, + derivations = derivations, + preflightReadFilter = preflightReadFilter, + ).doOnSuccess { response -> + updatePublicKeys(userWalletId = userWalletId, keys = response.entries) + .doOnSuccess { + validateDerivations(scanResponse = it.scanResponse, derivations = derivations) + return response.entries + } + .doOnFailure { throw it } + } .doOnFailure { throw it } error("This code should never be reached") diff --git a/app/src/main/java/com/tangem/tap/domain/scanCard/CardScanningFeatureToggles.kt b/app/src/main/java/com/tangem/tap/domain/scanCard/CardScanningFeatureToggles.kt new file mode 100644 index 0000000000..904cfe1673 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/domain/scanCard/CardScanningFeatureToggles.kt @@ -0,0 +1,16 @@ +package com.tangem.tap.domain.scanCard + +import com.tangem.core.featuretoggle.manager.FeatureTogglesManager + +/** + * Add custom token feature toggles + * +[REDACTED_AUTHOR] + */ +class CardScanningFeatureToggles internal constructor( + private val featureTogglesManager: FeatureTogglesManager, +) { + + val isNewCardScanningEnabled: Boolean + get() = featureTogglesManager.isFeatureEnabled(name = "NEW_CARD_SCANNING_ENABLED") +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/scanCard/DefaultScanCardProcessor.kt b/app/src/main/java/com/tangem/tap/domain/scanCard/DefaultScanCardProcessor.kt index d4b5ac160c..b8515ee5b9 100644 --- a/app/src/main/java/com/tangem/tap/domain/scanCard/DefaultScanCardProcessor.kt +++ b/app/src/main/java/com/tangem/tap/domain/scanCard/DefaultScanCardProcessor.kt @@ -12,7 +12,7 @@ import com.tangem.tap.store // TODO: Remove this object after feature toggle was removed and use ScanCardUseCase instead internal class DefaultScanCardProcessor : ScanCardProcessor { private val isNewCardScanningEnabled: Boolean - get() = store.inject(DaggerGraphState::customTokenFeatureToggles).isNewCardScanningEnabled + get() = store.inject(DaggerGraphState::cardScanningFeatureToggles).isNewCardScanningEnabled override suspend fun scan( cardId: String?, diff --git a/app/src/main/java/com/tangem/tap/domain/scanCard/LegacyScanProcessor.kt b/app/src/main/java/com/tangem/tap/domain/scanCard/LegacyScanProcessor.kt index ea7c4ac652..3475f1559f 100644 --- a/app/src/main/java/com/tangem/tap/domain/scanCard/LegacyScanProcessor.kt +++ b/app/src/main/java/com/tangem/tap/domain/scanCard/LegacyScanProcessor.kt @@ -2,7 +2,6 @@ package com.tangem.tap.domain.scanCard import com.tangem.common.CompletionResult import com.tangem.common.core.TangemError -import com.tangem.common.core.TangemSdkError import com.tangem.common.doOnFailure import com.tangem.common.doOnSuccess import com.tangem.common.routing.AppRoute @@ -18,9 +17,6 @@ import com.tangem.tap.common.analytics.paramsInterceptor.CardContextInterceptor import com.tangem.tap.common.extensions.* import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.features.disclaimer.createDisclaimer -import com.tangem.tap.features.disclaimer.redux.DisclaimerAction -import com.tangem.tap.features.disclaimer.redux.DisclaimerCallback -import com.tangem.tap.features.disclaimer.redux.DisclaimerSource import com.tangem.tap.features.onboarding.OnboardingHelper import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsAction import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsStep @@ -102,6 +98,8 @@ internal object LegacyScanProcessor { } } + // TODO: [REDACTED_JIRA] + @Suppress("UnusedPrivateMember") private suspend inline fun showDisclaimerIfNeed( scanResponse: ScanResponse, crossinline disclaimerWillShow: () -> Unit = {}, @@ -109,7 +107,6 @@ internal object LegacyScanProcessor { crossinline onFailure: suspend (error: TangemError) -> Unit, ) { val disclaimer = scanResponse.card.createDisclaimer() - store.dispatchOnMain(DisclaimerAction.SetDisclaimer(disclaimer)) if (disclaimer.isAccepted()) { nextHandler(scanResponse) @@ -120,23 +117,9 @@ internal object LegacyScanProcessor { withContext(Dispatchers.Main.immediate) { disclaimerWillShow() - store.dispatch( - DisclaimerAction.Show( - from = DisclaimerSource.Home, - callback = DisclaimerCallback( - onAccept = { - scope.launch(Dispatchers.Main.immediate) { - nextHandler(scanResponse) - } - }, - onDismiss = { - scope.launch(Dispatchers.Main.immediate) { - onFailure(TangemSdkError.UserCancelled()) - } - }, - ), - ), - ) + store.dispatchNavigationAction { + push(AppRoute.Disclaimer(isTosAccepted = false)) + } } } } @@ -149,10 +132,6 @@ internal object LegacyScanProcessor { crossinline onWalletNotCreated: suspend () -> Unit, crossinline onSuccess: suspend (ScanResponse) -> Unit, ) { - val globalState = store.state.globalState - val tapWalletManager = globalState.tapWalletManager - tapWalletManager.updateConfigManager(scanResponse) - store.dispatchOnMain(TwinCardsAction.IfTwinsPrepareState(scanResponse)) if (OnboardingHelper.isOnboardingCase(scanResponse)) { diff --git a/app/src/main/java/com/tangem/tap/domain/scanCard/UseCaseScanProcessor.kt b/app/src/main/java/com/tangem/tap/domain/scanCard/UseCaseScanProcessor.kt index 381d348980..09fe732b6d 100644 --- a/app/src/main/java/com/tangem/tap/domain/scanCard/UseCaseScanProcessor.kt +++ b/app/src/main/java/com/tangem/tap/domain/scanCard/UseCaseScanProcessor.kt @@ -59,12 +59,8 @@ internal object UseCaseScanProcessor { ), ) add(AnalyticsChain(Basic.CardWasScanned(analyticsSource))) - val pushNotificationsToggles = - store.inject(getDependency = DaggerGraphState::pushNotificationsFeatureToggles) - if (pushNotificationsToggles.isPushNotificationsEnabled) { - add(DisclaimerChain(store, disclaimerWillShow)) - } - add(CheckForOnboardingChain(store, store.state.globalState.tapWalletManager)) + add(DisclaimerChain(store, disclaimerWillShow)) + add(CheckForOnboardingChain(store)) } scanCardUseCase(cardId, afterScanChains = chains).fold( diff --git a/app/src/main/java/com/tangem/tap/domain/scanCard/chains/CheckForOnboardingChain.kt b/app/src/main/java/com/tangem/tap/domain/scanCard/chains/CheckForOnboardingChain.kt index 72d0b6ee59..f5606560c0 100644 --- a/app/src/main/java/com/tangem/tap/domain/scanCard/chains/CheckForOnboardingChain.kt +++ b/app/src/main/java/com/tangem/tap/domain/scanCard/chains/CheckForOnboardingChain.kt @@ -16,7 +16,6 @@ import com.tangem.tap.common.extensions.inject import com.tangem.tap.common.extensions.setContext import com.tangem.tap.common.redux.AppState import com.tangem.tap.common.redux.global.GlobalAction -import com.tangem.tap.domain.TapWalletManager import com.tangem.tap.features.onboarding.OnboardingHelper import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsAction import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsStep @@ -32,17 +31,14 @@ import org.rekotlin.Store * - [ScanChainException.OnboardingNeeded] if onboarding required. * * @param store the [Store] that holds the state of the app. - * @param tapWalletManager manager responsible for handling operations related to the Wallet. * * @see Chain for more information about the Chain interface. */ class CheckForOnboardingChain( private val store: Store, - private val tapWalletManager: TapWalletManager, ) : ResultChain() { override suspend fun launch(previousChainResult: ScanResponse): ScanChainResult { - tapWalletManager.updateConfigManager(previousChainResult) store.dispatchOnMain(TwinCardsAction.IfTwinsPrepareState(previousChainResult)) return when { diff --git a/app/src/main/java/com/tangem/tap/domain/scanCard/chains/DisclaimerChain.kt b/app/src/main/java/com/tangem/tap/domain/scanCard/chains/DisclaimerChain.kt index 8aa003b952..7bd4be874c 100644 --- a/app/src/main/java/com/tangem/tap/domain/scanCard/chains/DisclaimerChain.kt +++ b/app/src/main/java/com/tangem/tap/domain/scanCard/chains/DisclaimerChain.kt @@ -1,21 +1,15 @@ package com.tangem.tap.domain.scanCard.chains -import arrow.core.left import arrow.core.right +import com.tangem.common.routing.AppRoute import com.tangem.domain.card.ScanCardException import com.tangem.domain.core.chain.Chain import com.tangem.domain.core.chain.ResultChain import com.tangem.domain.models.scan.ScanResponse -import com.tangem.tap.common.extensions.dispatchOnMain +import com.tangem.tap.common.extensions.dispatchNavigationAction import com.tangem.tap.common.redux.AppState -import com.tangem.tap.features.disclaimer.Disclaimer import com.tangem.tap.features.disclaimer.createDisclaimer -import com.tangem.tap.features.disclaimer.redux.DisclaimerAction -import com.tangem.tap.features.disclaimer.redux.DisclaimerCallback -import com.tangem.tap.features.disclaimer.redux.DisclaimerSource -import kotlinx.coroutines.suspendCancellableCoroutine import org.rekotlin.Store -import kotlin.coroutines.resume /** * Handles disclaimer display after the card scanning operation. @@ -40,31 +34,13 @@ internal class DisclaimerChain( previousChainResult.right() } else { disclaimerWillShow() - showDisclaimer(disclaimer, previousChainResult) - } - } - private suspend fun showDisclaimer(disclaimer: Disclaimer, response: ScanResponse): ScanChainResult { - store.dispatchOnMain(DisclaimerAction.SetDisclaimer(disclaimer)) + // TODO: [REDACTED_JIRA] + store.dispatchNavigationAction { + push(route = AppRoute.Disclaimer(isTosAccepted = false)) + } - return suspendCancellableCoroutine { continuation -> - store.dispatchOnMain( - DisclaimerAction.Show( - from = DisclaimerSource.Home, - callback = DisclaimerCallback( - onAccept = { - if (continuation.isActive) { - continuation.resume(response.right()) - } - }, - onDismiss = { - if (continuation.isActive) { - continuation.resume(ScanChainException.DisclaimerWasCanceled.left()) - } - }, - ), - ), - ) + previousChainResult.right() } } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/sdk/TangemSdkManager.kt b/app/src/main/java/com/tangem/tap/domain/sdk/TangemSdkManager.kt index 2dbfaec5b7..5ee23082e0 100644 --- a/app/src/main/java/com/tangem/tap/domain/sdk/TangemSdkManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/sdk/TangemSdkManager.kt @@ -17,6 +17,7 @@ import com.tangem.domain.models.scan.CardDTO import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.wallets.models.UserWalletId import com.tangem.operations.derivation.DerivationTaskResponse +import com.tangem.operations.preflightread.PreflightReadFilter import com.tangem.operations.wallet.CreateWalletResponse import com.tangem.tap.domain.tasks.product.CreateProductWalletTaskResponse @@ -59,6 +60,7 @@ interface TangemSdkManager { suspend fun derivePublicKeys( cardId: String?, derivations: Map>, + preflightReadFilter: PreflightReadFilter?, ): CompletionResult suspend fun deriveExtendedPublicKey( @@ -99,6 +101,7 @@ interface TangemSdkManager { ) suspend fun runTaskAsync( runnable: CardSessionRunnable, + preflightReadFilter: PreflightReadFilter?, cardId: String? = null, initialMessage: Message? = null, accessCode: String? = null, diff --git a/app/src/main/java/com/tangem/tap/domain/sdk/impl/DefaultTangemSdkManager.kt b/app/src/main/java/com/tangem/tap/domain/sdk/impl/DefaultTangemSdkManager.kt index 835a2fee69..8f9e869f0d 100644 --- a/app/src/main/java/com/tangem/tap/domain/sdk/impl/DefaultTangemSdkManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/sdk/impl/DefaultTangemSdkManager.kt @@ -30,6 +30,7 @@ import com.tangem.operations.derivation.DerivationTaskResponse import com.tangem.operations.derivation.DeriveMultipleWalletPublicKeysTask import com.tangem.operations.derivation.DeriveWalletPublicKeyTask import com.tangem.operations.pins.SetUserCodeCommand +import com.tangem.operations.preflightread.PreflightReadFilter import com.tangem.operations.usersetttings.SetUserCodeRecoveryAllowedTask import com.tangem.operations.wallet.CreateWalletResponse import com.tangem.tap.derivationsFinder @@ -146,6 +147,7 @@ class DefaultTangemSdkManager( cardId = scanResponse.card.cardId, initialMessage = Message(resources.getString(R.string.initial_message_create_wallet_body)), iconScanRes = if (scanResponse.cardTypesResolver.isRing()) R.drawable.img_hand_scan_ring else null, + preflightReadFilter = null, ) } @@ -161,15 +163,16 @@ class DefaultTangemSdkManager( return CompletionResult.Failure(e) } return runTaskAsync( - CreateProductWalletTask( + runnable = CreateProductWalletTask( cardTypesResolver = scanResponse.cardTypesResolver, derivationStyleProvider = scanResponse.derivationStyleProvider, mnemonic = defaultMnemonic, passphrase = passphrase, shouldReset = shouldReset, ), - scanResponse.card.cardId, - Message(resources.getString(R.string.initial_message_create_wallet_body)), + cardId = scanResponse.card.cardId, + initialMessage = Message(resources.getString(R.string.initial_message_create_wallet_body)), + preflightReadFilter = null, ) } @@ -184,8 +187,13 @@ class DefaultTangemSdkManager( override suspend fun derivePublicKeys( cardId: String?, derivations: Map>, + preflightReadFilter: PreflightReadFilter?, ): CompletionResult { - return runTaskAsyncReturnOnMain(DeriveMultipleWalletPublicKeysTask(derivations), cardId) + return runTaskAsyncReturnOnMain( + runnable = DeriveMultipleWalletPublicKeysTask(derivations), + cardId = cardId, + preflightReadFilter = preflightReadFilter, + ) } override suspend fun deriveExtendedPublicKey( @@ -291,13 +299,21 @@ class DefaultTangemSdkManager( override suspend fun runTaskAsync( runnable: CardSessionRunnable, + preflightReadFilter: PreflightReadFilter?, cardId: String?, initialMessage: Message?, accessCode: String?, @DrawableRes iconScanRes: Int?, ): CompletionResult = withContext(Dispatchers.Main) { suspendCancellableCoroutine { continuation -> - tangemSdk.startSessionWithRunnable(runnable, cardId, initialMessage, accessCode, iconScanRes) { result -> + tangemSdk.startSessionWithRunnable( + runnable = runnable, + cardId = cardId, + initialMessage = initialMessage, + accessCode = accessCode, + preflightReadFilter = preflightReadFilter, + iconScanRes = iconScanRes, + ) { result -> if (continuation.isActive) continuation.resume(result) } } @@ -307,8 +323,14 @@ class DefaultTangemSdkManager( runnable: CardSessionRunnable, cardId: String? = null, initialMessage: Message? = null, + preflightReadFilter: PreflightReadFilter? = null, ): CompletionResult { - val result = runTaskAsync(runnable, cardId, initialMessage) + val result = runTaskAsync( + runnable = runnable, + cardId = cardId, + initialMessage = initialMessage, + preflightReadFilter = preflightReadFilter, + ) return withContext(Dispatchers.Main) { result } } @@ -360,6 +382,7 @@ class DefaultTangemSdkManager( runnable = CreateFirstTwinWalletTask(cardId), cardId = cardId, initialMessage = initialMessage, + preflightReadFilter = null, ) } @@ -378,7 +401,7 @@ class DefaultTangemSdkManager( preparingMessage = preparingMessage, creatingWalletMessage = creatingWalletMessage, ) - return runTaskAsync(task, null, initialMessage) + return runTaskAsync(runnable = task, cardId = null, initialMessage = initialMessage, preflightReadFilter = null) } override suspend fun finalizeTwin( @@ -391,6 +414,7 @@ class DefaultTangemSdkManager( runnable = FinalizeTwinTask(secondCardPublicKey, issuerKeyPair), cardId = cardId, initialMessage = initialMessage, + preflightReadFilter = null, ) } diff --git a/app/src/main/java/com/tangem/tap/domain/sdk/impl/MockTangemSdkManager.kt b/app/src/main/java/com/tangem/tap/domain/sdk/impl/MockTangemSdkManager.kt index 0dffc198a7..bddbaad9d6 100644 --- a/app/src/main/java/com/tangem/tap/domain/sdk/impl/MockTangemSdkManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/sdk/impl/MockTangemSdkManager.kt @@ -18,6 +18,7 @@ import com.tangem.domain.models.scan.CardDTO import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.wallets.models.UserWalletId import com.tangem.operations.derivation.DerivationTaskResponse +import com.tangem.operations.preflightread.PreflightReadFilter import com.tangem.operations.wallet.CreateWalletResponse import com.tangem.tap.domain.sdk.TangemSdkManager import com.tangem.tap.domain.sdk.mocks.MockProvider @@ -72,6 +73,7 @@ class MockTangemSdkManager( override suspend fun derivePublicKeys( cardId: String?, derivations: Map>, + preflightReadFilter: PreflightReadFilter?, ): CompletionResult { return MockProvider.getDerivationTaskResponse() } @@ -135,6 +137,7 @@ class MockTangemSdkManager( override suspend fun runTaskAsync( runnable: CardSessionRunnable, + preflightReadFilter: PreflightReadFilter?, cardId: String?, initialMessage: Message?, accessCode: String?, diff --git a/app/src/main/java/com/tangem/tap/domain/tasks/product/ResetBackupCardTask.kt b/app/src/main/java/com/tangem/tap/domain/tasks/product/ResetBackupCardTask.kt index 288ca22a9d..096aa23b39 100644 --- a/app/src/main/java/com/tangem/tap/domain/tasks/product/ResetBackupCardTask.kt +++ b/app/src/main/java/com/tangem/tap/domain/tasks/product/ResetBackupCardTask.kt @@ -17,6 +17,7 @@ import com.tangem.tap.domain.tasks.UserWalletIdPreflightReadFilter * [REDACTED_AUTHOR] */ +// TODO remove it after test after resolve [REDACTED_JIRA] internal class ResetBackupCardTask( private val userWalletId: UserWalletId, ) : CardSessionRunnable { diff --git a/app/src/main/java/com/tangem/tap/domain/walletconnect/BnbHelper.kt b/app/src/main/java/com/tangem/tap/domain/walletconnect/BnbHelper.kt index 2b3094d9f6..0e6ccce36b 100644 --- a/app/src/main/java/com/tangem/tap/domain/walletconnect/BnbHelper.kt +++ b/app/src/main/java/com/tangem/tap/domain/walletconnect/BnbHelper.kt @@ -4,12 +4,12 @@ import com.github.salomonbrys.kotson.registerTypeAdapter import com.google.gson.GsonBuilder import com.tangem.blockchain.common.Blockchain import com.tangem.common.extensions.calculateSha256 -import com.tangem.tap.common.extensions.stripZeroPlainString import com.tangem.tap.domain.walletconnect2.domain.models.binance.WcBinanceTradeOrder import com.tangem.tap.domain.walletconnect2.domain.models.binance.WcBinanceTransferOrder import com.tangem.tap.domain.walletconnect2.domain.models.binance.tradeOrderSerializer import com.tangem.tap.features.details.redux.walletconnect.BinanceMessageData import com.tangem.tap.features.details.redux.walletconnect.TradeData +import com.tangem.utils.extensions.stripZeroPlainString import timber.log.Timber internal object BnbHelper { diff --git a/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectSdkHelper.kt b/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectSdkHelper.kt index 8c78ffa3a5..0ee7f0e2ea 100644 --- a/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectSdkHelper.kt +++ b/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectSdkHelper.kt @@ -239,16 +239,22 @@ class WalletConnectSdkHelper { private suspend fun signTransaction(data: WcTransactionData, cardId: String?): String? { val dataToSign = EthereumUtils.buildTransactionToSign( transactionData = data.transaction, - nonce = null, blockchain = data.walletManager.wallet.blockchain, - ) ?: return null + ) val command = SignHashCommand( hash = dataToSign.hash, walletPublicKey = data.walletManager.wallet.publicKey.seedKey, derivationPath = data.walletManager.wallet.publicKey.derivationPath, ) - return when (val result = tangemSdkManager.runTaskAsync(command, initialMessage = Message(), cardId = cardId)) { + return when ( + val result = tangemSdkManager.runTaskAsync( + runnable = command, + initialMessage = Message(), + cardId = cardId, + preflightReadFilter = null, + ) + ) { is CompletionResult.Success -> { val hash = EthereumUtils.prepareTransactionToSend( signature = result.data.signature, @@ -291,7 +297,14 @@ class WalletConnectSdkHelper { walletPublicKey = wallet.publicKey.seedKey, derivationPath = wallet.publicKey.derivationPath, ) - return when (val result = tangemSdkManager.runTaskAsync(command, initialMessage = Message(), cardId = cardId)) { + return when ( + val result = tangemSdkManager.runTaskAsync( + runnable = command, + initialMessage = Message(), + cardId = cardId, + preflightReadFilter = null, + ) + ) { is CompletionResult.Success -> { val key = wallet.publicKey.blockchainKey.toDecompressedPublicKey() getBnbResultString( @@ -385,7 +398,13 @@ class WalletConnectSdkHelper { walletPublicKey = wallet.publicKey.seedKey, derivationPath = wallet.publicKey.derivationPath, ) - return when (val result = tangemSdkManager.runTaskAsync(command, cardId)) { + return when ( + val result = tangemSdkManager.runTaskAsync( + runnable = command, + cardId = cardId, + preflightReadFilter = null, + ) + ) { is CompletionResult.Success -> { val signedHash = result.data.signature @@ -420,7 +439,13 @@ class WalletConnectSdkHelper { walletPublicKey = wallet.publicKey.seedKey, derivationPath = wallet.publicKey.derivationPath, ) - return when (val result = tangemSdkManager.runTaskAsync(command, cardId)) { + return when ( + val result = tangemSdkManager.runTaskAsync( + runnable = command, + cardId = cardId, + preflightReadFilter = null, + ) + ) { is CompletionResult.Success -> { val signedHash = result.data.signature diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/api/featuretoggles/CustomTokenFeatureToggles.kt b/app/src/main/java/com/tangem/tap/features/customtoken/api/featuretoggles/CustomTokenFeatureToggles.kt deleted file mode 100644 index a6894e04b1..0000000000 --- a/app/src/main/java/com/tangem/tap/features/customtoken/api/featuretoggles/CustomTokenFeatureToggles.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.tangem.tap.features.customtoken.api.featuretoggles - -/** - * Add custom token feature toggles - * -[REDACTED_AUTHOR] - */ -interface CustomTokenFeatureToggles { - - val isNewCardScanningEnabled: Boolean -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/data/DefaultCustomTokenRepository.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/data/DefaultCustomTokenRepository.kt deleted file mode 100644 index e9b45a2623..0000000000 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/data/DefaultCustomTokenRepository.kt +++ /dev/null @@ -1,61 +0,0 @@ -package com.tangem.tap.features.customtoken.impl.data - -import com.tangem.blockchain.common.Blockchain -import com.tangem.blockchainsdk.utils.toNetworkId -import com.tangem.datasource.api.common.response.getOrThrow -import com.tangem.datasource.api.tangemTech.TangemTechApi -import com.tangem.domain.common.extensions.supportedBlockchains -import com.tangem.domain.common.util.cardTypesResolver -import com.tangem.tap.features.customtoken.impl.data.converters.FoundTokenConverter -import com.tangem.tap.features.customtoken.impl.domain.CustomTokenRepository -import com.tangem.tap.features.customtoken.impl.domain.models.FoundToken -import com.tangem.tap.proxy.AppStateHolder -import com.tangem.utils.coroutines.CoroutineDispatcherProvider -import kotlinx.coroutines.withContext - -/** - * Default implementation of custom token repository - * - * @property tangemTechApi TangemTech API - * @property dispatchers coroutine dispatchers provider - * @property reduxStateHolder redux state holder - * -[REDACTED_AUTHOR] - */ -class DefaultCustomTokenRepository( - private val tangemTechApi: TangemTechApi, - private val dispatchers: CoroutineDispatcherProvider, - private val reduxStateHolder: AppStateHolder, -) : CustomTokenRepository { - - override suspend fun findToken(address: String, networkId: String?): FoundToken { - val scanResponse = requireNotNull(reduxStateHolder.scanResponse) - val supportedTokenNetworkIds = requireNotNull(scanResponse.card) - .supportedBlockchains(scanResponse.cardTypesResolver) - .filter(Blockchain::canHandleTokens) - .map(Blockchain::toNetworkId) - - return withContext(dispatchers.io) { - val foundCoin = tangemTechApi.getCoins( - contractAddress = address, - networkIds = networkId ?: supportedTokenNetworkIds.joinToString(separator = ","), - ) - .getOrThrow() - .coins.firstNotNullOfOrNull { coin -> - val networksWithTheSameAddress = coin.networks.filter { network -> - (network.contractAddress != null || network.decimalCount != null) && - network.contractAddress?.equals(address, ignoreCase = true) == true && - supportedTokenNetworkIds.contains(network.networkId) - } - - if (networksWithTheSameAddress.isNotEmpty()) { - coin.copy(networks = networksWithTheSameAddress) - } else { - null - } - } - - foundCoin?.let(FoundTokenConverter::convert) ?: error("Token not found") - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/data/converters/FoundTokenConverter.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/data/converters/FoundTokenConverter.kt deleted file mode 100644 index 33271e9fb6..0000000000 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/data/converters/FoundTokenConverter.kt +++ /dev/null @@ -1,29 +0,0 @@ -package com.tangem.tap.features.customtoken.impl.data.converters - -import com.tangem.datasource.api.tangemTech.models.CoinsResponse -import com.tangem.tap.features.customtoken.impl.domain.models.FoundToken -import com.tangem.utils.converter.Converter - -/** - * Converter between data model [CoinsResponse.Coin] and domain model [FoundToken] - * -[REDACTED_AUTHOR] - */ -object FoundTokenConverter : Converter { - - override fun convert(value: CoinsResponse.Coin): FoundToken { - return FoundToken( - id = value.id, - name = value.name, - symbol = value.symbol, - isActive = value.active, - network = value.networks.firstOrNull()?.let { network -> - FoundToken.Network( - id = network.networkId, - contractAddress = requireNotNull(network.contractAddress), - decimalCount = requireNotNull(network.decimalCount).toString(), - ) - } ?: error("Found token networks is empty"), - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/di/CustomTokenFeatureTogglesModule.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/di/CustomTokenFeatureTogglesModule.kt deleted file mode 100644 index 5648aa592d..0000000000 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/di/CustomTokenFeatureTogglesModule.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.tangem.tap.features.customtoken.impl.di - -import com.tangem.core.featuretoggle.manager.FeatureTogglesManager -import com.tangem.tap.features.customtoken.api.featuretoggles.CustomTokenFeatureToggles -import com.tangem.tap.features.customtoken.impl.featuretoggles.DefaultCustomTokenFeatureToggles -import dagger.Module -import dagger.Provides -import dagger.hilt.InstallIn -import dagger.hilt.components.SingletonComponent -import javax.inject.Singleton - -/** -[REDACTED_AUTHOR] - */ -@Module -@InstallIn(SingletonComponent::class) -internal object CustomTokenFeatureTogglesModule { - - @Provides - @Singleton - fun providesCustomTokenFeatureToggles(featureTogglesManager: FeatureTogglesManager): CustomTokenFeatureToggles { - return DefaultCustomTokenFeatureToggles(featureTogglesManager) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/di/CustomTokenInteractorModule.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/di/CustomTokenInteractorModule.kt deleted file mode 100644 index 61dc90c2dc..0000000000 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/di/CustomTokenInteractorModule.kt +++ /dev/null @@ -1,43 +0,0 @@ -package com.tangem.tap.features.customtoken.impl.di - -import com.tangem.datasource.api.tangemTech.TangemTechApi -import com.tangem.domain.card.DerivePublicKeysUseCase -import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase -import com.tangem.tap.features.customtoken.impl.data.DefaultCustomTokenRepository -import com.tangem.tap.features.customtoken.impl.domain.CustomTokenInteractor -import com.tangem.tap.features.customtoken.impl.domain.DefaultCustomTokenInteractor -import com.tangem.tap.proxy.AppStateHolder -import com.tangem.utils.coroutines.AppCoroutineDispatcherProvider -import dagger.Module -import dagger.Provides -import dagger.hilt.InstallIn -import dagger.hilt.android.components.ViewModelComponent -import dagger.hilt.android.scopes.ViewModelScoped - -/** -[REDACTED_AUTHOR] - */ -@Module -@InstallIn(ViewModelComponent::class) -internal object CustomTokenInteractorModule { - - @Provides - @ViewModelScoped - fun provideCustomTokenInteractor( - tangemTechApi: TangemTechApi, - appCoroutineDispatcherProvider: AppCoroutineDispatcherProvider, - reduxStateHolder: AppStateHolder, - getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase, - derivePublicKeysUseCase: DerivePublicKeysUseCase, - ): CustomTokenInteractor { - return DefaultCustomTokenInteractor( - featureRepository = DefaultCustomTokenRepository( - tangemTechApi = tangemTechApi, - dispatchers = appCoroutineDispatcherProvider, - reduxStateHolder = reduxStateHolder, - ), - getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase, - derivePublicKeysUseCase = derivePublicKeysUseCase, - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/di/CustomTokenRouterModule.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/di/CustomTokenRouterModule.kt deleted file mode 100644 index 0c8dec0948..0000000000 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/di/CustomTokenRouterModule.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.tangem.tap.features.customtoken.impl.di - -import com.tangem.tap.features.customtoken.impl.presentation.routers.CustomTokenRouter -import com.tangem.tap.features.customtoken.impl.presentation.routers.DefaultCustomTokenRouter -import dagger.Module -import dagger.Provides -import dagger.hilt.InstallIn -import dagger.hilt.android.components.ViewModelComponent -import dagger.hilt.android.scopes.ViewModelScoped - -/** -[REDACTED_AUTHOR] - */ -@Module -@InstallIn(ViewModelComponent::class) -internal object CustomTokenRouterModule { - - @Provides - @ViewModelScoped - fun provideAddCustomTokenRouter(): CustomTokenRouter = DefaultCustomTokenRouter() -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/domain/CustomTokenInteractor.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/domain/CustomTokenInteractor.kt deleted file mode 100644 index 22bea5bf11..0000000000 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/domain/CustomTokenInteractor.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.tangem.tap.features.customtoken.impl.domain - -import com.tangem.blockchain.common.Blockchain -import com.tangem.common.core.TangemError -import com.tangem.domain.features.addCustomToken.CustomCurrency -import com.tangem.tap.features.customtoken.impl.domain.models.FoundToken - -/** - * Custom token interactor - * -[REDACTED_AUTHOR] - */ -interface CustomTokenInteractor { - - /** Find token by [address] and [blockchain] */ - suspend fun findToken(address: String, blockchain: Blockchain): FoundToken - - /** Save token [customCurrency] */ - @Throws(TangemError::class) - suspend fun saveToken(customCurrency: CustomCurrency): Result -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/domain/CustomTokenRepository.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/domain/CustomTokenRepository.kt deleted file mode 100644 index cb1959d157..0000000000 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/domain/CustomTokenRepository.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.tangem.tap.features.customtoken.impl.domain - -import com.tangem.tap.features.customtoken.impl.domain.models.FoundToken - -/** - * Custom token repository - * -[REDACTED_AUTHOR] - */ -interface CustomTokenRepository { - - /** - * Find token by [address] and [networkId] - * - * @throws com.tangem.datasource.api.common.response.ApiResponseError - * */ - suspend fun findToken(address: String, networkId: String?): FoundToken -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/domain/DefaultCustomTokenInteractor.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/domain/DefaultCustomTokenInteractor.kt deleted file mode 100644 index bd9cc89301..0000000000 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/domain/DefaultCustomTokenInteractor.kt +++ /dev/null @@ -1,84 +0,0 @@ -package com.tangem.tap.features.customtoken.impl.domain - -import arrow.core.getOrElse -import arrow.core.raise.result -import com.tangem.blockchain.common.Blockchain -import com.tangem.blockchainsdk.utils.toNetworkId -import com.tangem.data.common.currency.CryptoCurrencyFactory -import com.tangem.domain.card.DerivePublicKeysUseCase -import com.tangem.domain.common.util.derivationStyleProvider -import com.tangem.domain.features.addCustomToken.CustomCurrency -import com.tangem.domain.models.scan.ScanResponse -import com.tangem.domain.tokens.AddCryptoCurrenciesUseCase -import com.tangem.domain.tokens.model.CryptoCurrency -import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase -import com.tangem.tap.common.extensions.inject -import com.tangem.tap.domain.model.Currency -import com.tangem.tap.features.customtoken.impl.domain.models.FoundToken -import com.tangem.tap.proxy.redux.DaggerGraphState -import com.tangem.tap.store - -/** - * Default implementation of custom token interactor - * - * @property featureRepository feature repository - * -[REDACTED_AUTHOR] - */ -class DefaultCustomTokenInteractor( - private val featureRepository: CustomTokenRepository, - private val getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase, - private val derivePublicKeysUseCase: DerivePublicKeysUseCase, -) : CustomTokenInteractor { - - // TODO: Move to DI - private val addCryptoCurrenciesUseCase by lazy(LazyThreadSafetyMode.NONE) { - val currenciesRepository = store.inject(DaggerGraphState::currenciesRepository) - val networksRepository = store.inject(DaggerGraphState::networksRepository) - - AddCryptoCurrenciesUseCase(currenciesRepository, networksRepository) - } - - override suspend fun findToken(address: String, blockchain: Blockchain): FoundToken { - return featureRepository.findToken( - address = address, - networkId = if (blockchain != Blockchain.Unknown) blockchain.toNetworkId() else null, - ) - } - - override suspend fun saveToken(customCurrency: CustomCurrency): Result { - return result { - val userWallet = getSelectedWalletSyncUseCase().getOrElse { - error("Failed to get selected wallet: $it") - } - - val currency = Currency.fromCustomCurrency(customCurrency) - val currencies = listOfNotNull(element = currency.toCryptoCurrency(userWallet.scanResponse)) - - derivePublicKeysUseCase(userWalletId = userWallet.walletId, currencies = currencies).bind() - addCryptoCurrenciesUseCase(userWalletId = userWallet.walletId, currencies = currencies).bind() - } - } - - private fun Currency.toCryptoCurrency(scanResponse: ScanResponse): CryptoCurrency? { - val cryptoCurrencyFactory = CryptoCurrencyFactory() - - return when (this) { - is Currency.Blockchain -> { - cryptoCurrencyFactory.createCoin( - blockchain = blockchain, - extraDerivationPath = derivationPath, - derivationStyleProvider = scanResponse.derivationStyleProvider, - ) - } - is Currency.Token -> { - cryptoCurrencyFactory.createToken( - sdkToken = token, - blockchain = blockchain, - extraDerivationPath = derivationPath, - derivationStyleProvider = scanResponse.derivationStyleProvider, - ) - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/domain/models/FoundToken.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/domain/models/FoundToken.kt deleted file mode 100644 index 5b39f2dd52..0000000000 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/domain/models/FoundToken.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.tangem.tap.features.customtoken.impl.domain.models - -/** - * Found token model - * - * @property id id - * @property name name - * @property symbol symbol - * @property isActive flag that determines status of token - * @property network network - * -[REDACTED_AUTHOR] - */ -data class FoundToken( - val id: String, - val name: String, - val symbol: String, - val isActive: Boolean, - val network: Network, -) { - - /** - * Found token network - * - * @property id id - * @property contractAddress address - * @property decimalCount decimal count - */ - data class Network(val id: String, val contractAddress: String, val decimalCount: String) -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/featuretoggles/DefaultCustomTokenFeatureToggles.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/featuretoggles/DefaultCustomTokenFeatureToggles.kt deleted file mode 100644 index cd06665b00..0000000000 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/featuretoggles/DefaultCustomTokenFeatureToggles.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.tangem.tap.features.customtoken.impl.featuretoggles - -import com.tangem.core.featuretoggle.manager.FeatureTogglesManager -import com.tangem.tap.features.customtoken.api.featuretoggles.CustomTokenFeatureToggles - -/** - * Default implementation of CustomToken feature toggles - * - * @property featureTogglesManager manager for getting information about the availability of feature toggles - * -[REDACTED_AUTHOR] - */ -internal class DefaultCustomTokenFeatureToggles( - private val featureTogglesManager: FeatureTogglesManager, -) : CustomTokenFeatureToggles { - - override val isNewCardScanningEnabled: Boolean - get() = featureTogglesManager.isFeatureEnabled(name = "NEW_CARD_SCANNING_ENABLED") -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/AddCustomTokenFragment.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/AddCustomTokenFragment.kt deleted file mode 100644 index 443a8af290..0000000000 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/AddCustomTokenFragment.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.tangem.tap.features.customtoken.impl.presentation - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.systemBarsPadding -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalLifecycleOwner -import androidx.hilt.navigation.compose.hiltViewModel -import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.tangem.core.ui.UiDependencies -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.screen.ComposeFragment -import com.tangem.tap.features.customtoken.impl.presentation.ui.AddCustomTokenScreen -import com.tangem.tap.features.customtoken.impl.presentation.viewmodels.AddCustomTokenViewModel -import dagger.hilt.android.AndroidEntryPoint -import javax.inject.Inject - -/** - * Add custom token screen - * -[REDACTED_AUTHOR] - */ -@AndroidEntryPoint -internal class AddCustomTokenFragment : ComposeFragment() { - - @Inject - override lateinit var uiDependencies: UiDependencies - - @Composable - override fun ScreenContent(modifier: Modifier) { - val viewModel = hiltViewModel().apply { - LocalLifecycleOwner.current.lifecycle.addObserver(this) - } - val state by viewModel.uiState.collectAsStateWithLifecycle() - - AddCustomTokenScreen( - modifier = Modifier - .background(TangemTheme.colors.background.primary) - .systemBarsPadding(), - stateHolder = state, - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/models/AddCustomTokenViewsModels.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/models/AddCustomTokenViewsModels.kt deleted file mode 100644 index 6ba979beab..0000000000 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/models/AddCustomTokenViewsModels.kt +++ /dev/null @@ -1,324 +0,0 @@ -package com.tangem.tap.features.customtoken.impl.presentation.models - -import androidx.compose.foundation.text.KeyboardOptions -import com.tangem.blockchain.common.Blockchain -import com.tangem.tap.features.details.ui.cardsettings.TextReference -import com.tangem.wallet.R - -/** - * Toolbar model of add custom token screen - * - * @property title title - * @property onBackButtonClick lambda be invoked when back button is been pressed - */ -internal data class AddCustomTokensToolbar(val title: TextReference, val onBackButtonClick: () -> Unit) - -/** - * Model of block with fields for testing - * - * @property chooseTokenButtonText choose token button text - * @property clearButtonText clear button text - * @property resetButtonText reset button text - * @property onClearAddressButtonClick lambda be invoked when clear address button is been pressed - * @property onResetButtonClick lambda be invoked when reset form fields button is been pressed - */ -internal data class AddCustomTokenTestBlock( - val chooseTokenButtonText: String, - val clearButtonText: String, - val resetButtonText: String, - val onClearAddressButtonClick: () -> Unit, - val onResetButtonClick: () -> Unit, -) - -/** - * Bottom sheet model for choose custom token - * - * @property categoriesBlocks tokens categories - * @property onTestTokenClick lambda be invoked when token is been pressed - */ -internal data class AddCustomTokenChooseTokenBottomSheet( - val categoriesBlocks: List, - val onTestTokenClick: (String) -> Unit, -) { - - /** - * Tokens category model - * - * @property name category name - * @property items category items - */ - data class TokensCategoryBlock(val name: String, val items: List) - - /** - * Test token model - * - * @property name token name - * @property address token address - */ - data class TestTokenItem(val name: String, val address: String) -} - -/** - * Form with fields model of add custom token screen - * - * @property contractAddressInputField input field to enter the contract address - * @property networkSelectorField selector field to select the token network - * @property tokenNameInputField input field to enter the token name - * @property tokenSymbolInputField input field to enter the token symbol - * @property decimalsInputField input field to enter the token decimals - * @property derivationPathSelectorField selector field to select the derivation path - * @property derivationPathInputField input field for a custom derivation path - * @property showTokenFields if token fields should be shown - */ -internal data class AddCustomTokenForm( - val contractAddressInputField: AddCustomTokenInputField.ContactAddress, - val networkSelectorField: AddCustomTokenSelectorField.Network, - val tokenNameInputField: AddCustomTokenInputField.TokenName, - val tokenSymbolInputField: AddCustomTokenInputField.TokenSymbol, - val decimalsInputField: AddCustomTokenInputField.Decimals, - val derivationPathSelectorField: AddCustomTokenSelectorField.DerivationPath?, - val derivationPathInputField: AddCustomTokenInputField.DerivationPath?, - val showTokenFields: Boolean = false, -) - -/** Base input field model of add custom token screen */ -internal sealed interface AddCustomTokenInputField { - - /** Current value */ - val value: String - - /** Lambda be invoked when value is been changed */ - val onValueChange: (String) -> Unit - - /** Keyboard options */ - val keyboardOptions: KeyboardOptions - - /** Label */ - val label: TextReference - - /** Placeholder (hint) */ - val placeholder: TextReference - - /** - * Input field model to enter the contract address - * - * @property value current value - * @property onValueChange lambda be invoked when value is been changed - * @property keyboardOptions keyboard options - * @property label label - * @property placeholder placeholder (hint) - * @property isLoading flag that determine the processing of current value - * @property isError flag that determine if current value has error - * @property error error description - */ - data class ContactAddress( - override val value: String, - override val onValueChange: (String) -> Unit, - override val keyboardOptions: KeyboardOptions, - override val label: TextReference, - override val placeholder: TextReference, - val isLoading: Boolean, - val isError: Boolean, - val error: TextReference? = null, - ) : AddCustomTokenInputField - - /** - * Input field model to enter the token name - * - * @property value current value - * @property onValueChange lambda be invoked when value is been changed - * @property keyboardOptions keyboard options - * @property label label - * @property placeholder placeholder (hint) - * @property isEnabled input availability - */ - data class TokenName( - override val value: String, - override val onValueChange: (String) -> Unit, - override val keyboardOptions: KeyboardOptions, - override val label: TextReference, - override val placeholder: TextReference, - val isEnabled: Boolean, - ) : AddCustomTokenInputField - - /** - * Input field model to enter the token symbol - * - * @property value current value - * @property onValueChange lambda be invoked when value is been changed - * @property keyboardOptions keyboard options - * @property label label - * @property placeholder placeholder (hint) - * @property isEnabled input availability - */ - data class TokenSymbol( - override val value: String, - override val onValueChange: (String) -> Unit, - override val keyboardOptions: KeyboardOptions, - override val label: TextReference, - override val placeholder: TextReference, - val isEnabled: Boolean, - ) : AddCustomTokenInputField - - /** - * Input field model to enter the token decimals - * - * @property value current value - * @property onValueChange lambda be invoked when value is been changed - * @property keyboardOptions keyboard options - * @property label label - * @property placeholder placeholder (hint) - * @property isEnabled input availability - */ - data class Decimals( - override val value: String, - override val onValueChange: (String) -> Unit, - override val keyboardOptions: KeyboardOptions, - override val label: TextReference, - override val placeholder: TextReference, - val isEnabled: Boolean, - ) : AddCustomTokenInputField - - /** - * Input field model to enter a custom derivation path - * - * @property value current value - * @property onValueChange lambda be invoked when value is been changed - * @property keyboardOptions keyboard options - * @property label label - * @property placeholder placeholder (hint) - * @property showField whether the field should be shown - */ - data class DerivationPath( - override val value: String, - override val onValueChange: (String) -> Unit, - override val keyboardOptions: KeyboardOptions, - override val label: TextReference, - override val placeholder: TextReference, - val showField: Boolean = false, - ) : AddCustomTokenInputField -} - -/** Base selector field model of add custom token screen */ -internal sealed interface AddCustomTokenSelectorField { - - /** Label */ - val label: TextReference - - /** Selected menu item */ - val selectedItem: SelectorItem - - /** Menu items */ - val items: List - - /** Lambda be invoked when menu item is been selected */ - val onMenuItemClick: (Int) -> Unit - - /** - * Network selector model - * - * @property label label - * @property selectedItem selected menu item - * @property items menu items - * @property onMenuItemClick lambda be invoked when menu item is been selected - */ - data class Network( - override val label: TextReference, - override val selectedItem: SelectorItem.Title, - override val items: List, - override val onMenuItemClick: (Int) -> Unit, - ) : AddCustomTokenSelectorField - - /** - * Derivation path selector model - * - * @property label label - * @property selectedItem selected menu item - * @property items menu items - * @property onMenuItemClick lambda be invoked when menu item is been selected - * @property isEnabled selection availability - */ - data class DerivationPath( - override val label: TextReference, - override val selectedItem: SelectorItem.TitleWithSubtitle, - override val items: List, - override val onMenuItemClick: (Int) -> Unit, - val isEnabled: Boolean, - ) : AddCustomTokenSelectorField - - /** Base menu item model */ - sealed interface SelectorItem { - - /** Title */ - val title: TextReference - - /** Blockchain */ - val blockchain: Blockchain - - /** - * Menu item with title - * - * @property title title text - * @property blockchain blockchain - */ - data class Title(override val title: TextReference, override val blockchain: Blockchain) : SelectorItem - - /** - * Menu item with title ans subtitle - * - * @property title title text - * @property blockchain blockchain - * @property subtitle subtitle text - */ - data class TitleWithSubtitle( - override val title: TextReference, - override val blockchain: Blockchain, - val subtitle: TextReference, - val type: DerivationPathSelectorType = DerivationPathSelectorType.BLOCKCHAIN, - ) : SelectorItem - } -} - -enum class DerivationPathSelectorType { - DEFAULT, CUSTOM, BLOCKCHAIN -} - -/** - * Warning model of add custom token screen - * - * @property description warning description - */ -internal sealed class AddCustomTokenWarning(val description: TextReference) { - - /** Potential scam warning */ - data object PotentialScamToken : AddCustomTokenWarning( - description = TextReference.Res(R.string.custom_token_validation_error_not_found), - ) - - /** Token already added warning */ - data object TokenAlreadyAdded : AddCustomTokenWarning( - description = TextReference.Res(R.string.custom_token_validation_error_already_added), - ) - - /** Unsupported token warning */ - data class UnsupportedToken(val networkName: String) : AddCustomTokenWarning( - description = TextReference.Res(R.string.alert_manage_tokens_unsupported_message, networkName), - ) - - data object WrongDerivationPath : AddCustomTokenWarning( - description = TextReference.Res(R.string.custom_token_invalid_derivation_path), - ) -} - -/** - * Floating button of add custom token screen - * - * @property isEnabled button availability - * @property showProgress whether circle progress indication is enabled - * @property onClick lambda be invoked when button is been pressed - */ -internal data class AddCustomTokenFloatingButton( - val isEnabled: Boolean, - val showProgress: Boolean, - val onClick: () -> Unit, -) \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/models/CustomTokenType.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/models/CustomTokenType.kt deleted file mode 100644 index b36fe58ce3..0000000000 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/models/CustomTokenType.kt +++ /dev/null @@ -1,4 +0,0 @@ -package com.tangem.tap.features.customtoken.impl.presentation.models - -/** Custom token type */ -enum class CustomTokenType { TOKEN, BLOCKCHAIN } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/models/SupportBlockchainType.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/models/SupportBlockchainType.kt deleted file mode 100644 index 27215046bd..0000000000 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/models/SupportBlockchainType.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.tangem.tap.features.customtoken.impl.presentation.models - -internal enum class SupportBlockchainType { - - SUPPORTED, UNSUPPORTED, UNABLE_TO_DETERMINE -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/routers/CustomTokenRouter.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/routers/CustomTokenRouter.kt deleted file mode 100644 index 1c016c4993..0000000000 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/routers/CustomTokenRouter.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.tangem.tap.features.customtoken.impl.presentation.routers - -import com.tangem.blockchain.common.Blockchain - -/** - * Custom token feature router - * -[REDACTED_AUTHOR] - */ -internal interface CustomTokenRouter { - - /** Return to last screen */ - fun popBackStack() - - /** Open wallet (main) screen */ - fun openWalletScreen() - - /** Open alert if solana network is unsupported - * - * @param blockchain blockchain to show alert - */ - fun openUnsupportedNetworkAlert(blockchain: Blockchain) - - fun showGenericErrorAlertAndPopBack() -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/routers/DefaultCustomTokenRouter.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/routers/DefaultCustomTokenRouter.kt deleted file mode 100644 index 348c3492ce..0000000000 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/routers/DefaultCustomTokenRouter.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.tangem.tap.features.customtoken.impl.presentation.routers - -import com.tangem.blockchain.common.Blockchain -import com.tangem.common.routing.AppRoute -import com.tangem.common.routing.AppRouter -import com.tangem.common.routing.utils.popTo -import com.tangem.tap.common.extensions.dispatchDialogShow -import com.tangem.tap.common.extensions.dispatchNavigationAction -import com.tangem.tap.common.redux.AppDialog -import com.tangem.tap.store -import com.tangem.wallet.R - -/** Default implementation of custom token feature router */ -internal class DefaultCustomTokenRouter : CustomTokenRouter { - - override fun popBackStack() { - store.dispatchNavigationAction(AppRouter::pop) - } - - override fun openWalletScreen() { - store.dispatchNavigationAction { popTo() } - } - - override fun openUnsupportedNetworkAlert(blockchain: Blockchain) { - val alert = AppDialog.SimpleOkDialogRes( - headerId = R.string.common_warning, - messageId = R.string.alert_manage_tokens_unsupported_curve_message, - args = listOf(blockchain.getNetworkName()), - ) - store.dispatchDialogShow(alert) - } - - override fun showGenericErrorAlertAndPopBack() { - val alert = AppDialog.SimpleOkDialogRes( - headerId = R.string.common_error, - messageId = R.string.common_unknown_error, - onOk = { store.dispatchNavigationAction(AppRouter::pop) }, - ) - store.dispatchDialogShow(alert) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/states/AddCustomTokenStateHolder.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/states/AddCustomTokenStateHolder.kt deleted file mode 100644 index 32eba291ef..0000000000 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/states/AddCustomTokenStateHolder.kt +++ /dev/null @@ -1,91 +0,0 @@ -package com.tangem.tap.features.customtoken.impl.presentation.states - -import com.tangem.tap.features.customtoken.impl.presentation.models.AddCustomTokenChooseTokenBottomSheet -import com.tangem.tap.features.customtoken.impl.presentation.models.AddCustomTokenFloatingButton -import com.tangem.tap.features.customtoken.impl.presentation.models.AddCustomTokenForm -import com.tangem.tap.features.customtoken.impl.presentation.models.AddCustomTokenTestBlock -import com.tangem.tap.features.customtoken.impl.presentation.models.AddCustomTokenWarning -import com.tangem.tap.features.customtoken.impl.presentation.models.AddCustomTokensToolbar - -/** - * State holder of add custom token screen - * -[REDACTED_AUTHOR] - */ -internal sealed interface AddCustomTokenStateHolder { - - /** Lambda be invoked when system back action is been called */ - val onBackButtonClick: () -> Unit - - /** Toolbar model */ - val toolbar: AddCustomTokensToolbar - - /** Form model */ - val form: AddCustomTokenForm - - /** Warnings */ - val warnings: Set - - /** Floating button model */ - val floatingButton: AddCustomTokenFloatingButton - - /** - * Util function that allow to make a copy - * - * @param onBackButtonClick lambda be invoked when system back action is been called - * @param toolbar toolbar model - * @param form form model - * @param warnings warnings - * @param floatingButton floating button model - */ - fun copySealed( - onBackButtonClick: () -> Unit = this.onBackButtonClick, - toolbar: AddCustomTokensToolbar = this.toolbar, - form: AddCustomTokenForm = this.form, - warnings: Set = this.warnings, - floatingButton: AddCustomTokenFloatingButton = this.floatingButton, - ): AddCustomTokenStateHolder { - return when (this) { - is Content -> copy(onBackButtonClick, toolbar, form, warnings, floatingButton) - is TestContent -> copy(onBackButtonClick, toolbar, form, warnings, floatingButton) - } - } - - /** - * Content state - * - * @property onBackButtonClick lambda be invoked when system back action is been called - * @property toolbar toolbar model - * @property form form model - * @property warnings warnings - * @property floatingButton floating button model - */ - data class Content( - override val onBackButtonClick: () -> Unit, - override val toolbar: AddCustomTokensToolbar, - override val form: AddCustomTokenForm, - override val warnings: Set, - override val floatingButton: AddCustomTokenFloatingButton, - ) : AddCustomTokenStateHolder - - /** - * Content state with fields for testing - * - * @property onBackButtonClick lambda be invoked when system back action is been called - * @property toolbar toolbar model - * @property form form model - * @property warnings warnings - * @property floatingButton floating button model - * @property testBlock test block model - * @property bottomSheet bottom sheet model - */ - data class TestContent( - override val onBackButtonClick: () -> Unit, - override val toolbar: AddCustomTokensToolbar, - override val form: AddCustomTokenForm, - override val warnings: Set, - override val floatingButton: AddCustomTokenFloatingButton, - val testBlock: AddCustomTokenTestBlock, - val bottomSheet: AddCustomTokenChooseTokenBottomSheet, - ) : AddCustomTokenStateHolder -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/ui/AddCustomTokenContent.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/ui/AddCustomTokenContent.kt deleted file mode 100644 index afff4bf8e5..0000000000 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/ui/AddCustomTokenContent.kt +++ /dev/null @@ -1,77 +0,0 @@ -package com.tangem.tap.features.customtoken.impl.presentation.ui - -import androidx.activity.compose.BackHandler -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.verticalScroll -import androidx.compose.material.FabPosition -import androidx.compose.material.Scaffold -import androidx.compose.runtime.* -import androidx.compose.ui.Modifier -import androidx.compose.ui.layout.onSizeChanged -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.tap.features.customtoken.impl.presentation.states.AddCustomTokenStateHolder -import com.tangem.tap.features.customtoken.impl.presentation.ui.components.AddCustomTokenFloatingButton -import com.tangem.tap.features.customtoken.impl.presentation.ui.components.AddCustomTokenForm -import com.tangem.tap.features.customtoken.impl.presentation.ui.components.AddCustomTokenToolbar -import com.tangem.tap.features.customtoken.impl.presentation.ui.components.AddCustomTokenWarnings - -/** - * Add custom token content - * - * @param state screen state - * -[REDACTED_AUTHOR] - */ -@Composable -internal fun AddCustomTokenContent(state: AddCustomTokenStateHolder.Content, modifier: Modifier = Modifier) { - BackHandler(onBack = state.onBackButtonClick) - - var floatingButtonHeight by remember { mutableStateOf(0.dp) } - Scaffold( - modifier = modifier, - topBar = { - AddCustomTokenToolbar( - title = state.toolbar.title, - onBackButtonClick = state.toolbar.onBackButtonClick, - ) - }, - floatingActionButton = { - val density = LocalDensity.current - val verticalPadding = TangemTheme.dimens.spacing32 - AddCustomTokenFloatingButton( - model = state.floatingButton, - modifier = Modifier.onSizeChanged { - floatingButtonHeight = with(density) { it.height.toDp() + verticalPadding } - }, - ) - }, - floatingActionButtonPosition = FabPosition.Center, - ) { - Column( - modifier = Modifier - .verticalScroll(rememberScrollState()) - .padding(paddingValues = it) - .padding(bottom = floatingButtonHeight) - .fillMaxSize(), - ) { - AddCustomTokenForm(model = state.form) - - AddCustomTokenWarnings(warnings = state.warnings) - } - } -} - -@Preview -@Composable -private fun Preview_AddCustomTokenContent() { - TangemThemePreview { - AddCustomTokenContent(state = AddCustomTokenPreviewData.createContent()) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/ui/AddCustomTokenPreviewData.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/ui/AddCustomTokenPreviewData.kt deleted file mode 100644 index ba7d22727c..0000000000 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/ui/AddCustomTokenPreviewData.kt +++ /dev/null @@ -1,126 +0,0 @@ -package com.tangem.tap.features.customtoken.impl.presentation.ui - -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.ui.text.input.ImeAction -import androidx.compose.ui.text.input.KeyboardType -import com.tangem.blockchain.common.Blockchain -import com.tangem.tap.features.customtoken.impl.presentation.models.* -import com.tangem.tap.features.customtoken.impl.presentation.states.AddCustomTokenStateHolder -import com.tangem.tap.features.details.ui.cardsettings.TextReference -import com.tangem.wallet.R - -/** -[REDACTED_AUTHOR] - */ -internal object AddCustomTokenPreviewData { - - fun createWarnings(): Set { - return setOf( - AddCustomTokenWarning.PotentialScamToken, - AddCustomTokenWarning.TokenAlreadyAdded, - AddCustomTokenWarning.UnsupportedToken(networkName = "Solana"), - ) - } - - fun createDefaultForm(): AddCustomTokenForm { - return AddCustomTokenForm( - contractAddressInputField = AddCustomTokenInputField.ContactAddress( - value = "", - onValueChange = {}, - keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next), - label = TextReference.Res(R.string.custom_token_contract_address_input_title), - placeholder = TextReference.Str(value = "0x0000000000000000000000000000000000000000"), - isLoading = false, - isError = false, - error = null, - ), - networkSelectorField = AddCustomTokenSelectorField.Network( - label = TextReference.Res(R.string.custom_token_network_input_title), - selectedItem = AddCustomTokenSelectorField.SelectorItem.Title( - title = TextReference.Res(R.string.custom_token_network_input_not_selected), - blockchain = Blockchain.Unknown, - ), - items = emptyList(), - onMenuItemClick = {}, - ), - tokenNameInputField = AddCustomTokenInputField.TokenName( - value = "", - onValueChange = {}, - keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next), - label = TextReference.Res(R.string.custom_token_name_input_title), - placeholder = TextReference.Res(id = R.string.custom_token_name_input_placeholder), - isEnabled = false, - ), - tokenSymbolInputField = AddCustomTokenInputField.TokenSymbol( - value = "", - onValueChange = {}, - keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next), - label = TextReference.Res(R.string.custom_token_token_symbol_input_title_old), - placeholder = TextReference.Res(id = R.string.custom_token_token_symbol_input_placeholder), - isEnabled = false, - ), - decimalsInputField = AddCustomTokenInputField.Decimals( - value = "", - onValueChange = {}, - keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Next), - label = TextReference.Res(R.string.custom_token_decimals_input_title), - placeholder = TextReference.Str(value = "8"), - isEnabled = false, - ), - derivationPathSelectorField = AddCustomTokenSelectorField.DerivationPath( - label = TextReference.Res(R.string.custom_token_derivation_path_input_title), - selectedItem = AddCustomTokenSelectorField.SelectorItem.TitleWithSubtitle( - title = TextReference.Res(R.string.custom_token_derivation_path_default), - subtitle = TextReference.Res(R.string.custom_token_derivation_path_default), - blockchain = Blockchain.Unknown, - ), - items = emptyList(), - onMenuItemClick = {}, - isEnabled = true, - ), - derivationPathInputField = null, - ) - } - - fun createTestContent(): AddCustomTokenStateHolder.TestContent { - return AddCustomTokenStateHolder.TestContent( - onBackButtonClick = {}, - toolbar = AddCustomTokensToolbar( - title = TextReference.Res(R.string.add_custom_token_title), - onBackButtonClick = {}, - ), - form = createDefaultForm(), - warnings = createWarnings(), - floatingButton = AddCustomTokenFloatingButton( - isEnabled = false, - showProgress = false, - onClick = {}, - ), - testBlock = AddCustomTokenTestBlock( - chooseTokenButtonText = "Choose token", - clearButtonText = "Clear address", - resetButtonText = "Reset", - onClearAddressButtonClick = {}, - onResetButtonClick = {}, - ), - bottomSheet = AddCustomTokenChooseTokenBottomSheet(categoriesBlocks = emptyList(), onTestTokenClick = {}), - ) - } - - fun createContent(): AddCustomTokenStateHolder.Content { - return AddCustomTokenStateHolder.Content( - onBackButtonClick = {}, - toolbar = AddCustomTokensToolbar( - title = TextReference.Res(R.string.add_custom_token_title), - onBackButtonClick = {}, - ), - form = createDefaultForm(), - warnings = createWarnings(), - floatingButton = AddCustomTokenFloatingButton( - isEnabled = false, - showProgress = false, - onClick = {}, - ), - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/ui/AddCustomTokenScreen.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/ui/AddCustomTokenScreen.kt deleted file mode 100644 index d2e3729321..0000000000 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/ui/AddCustomTokenScreen.kt +++ /dev/null @@ -1,43 +0,0 @@ -package com.tangem.tap.features.customtoken.impl.presentation.ui - -import android.content.res.Configuration -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.tooling.preview.PreviewParameter -import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.tap.features.customtoken.impl.presentation.states.AddCustomTokenStateHolder - -/** - * Add custom token screen - * - * @param stateHolder state holder - * -[REDACTED_AUTHOR] - */ -@Composable -internal fun AddCustomTokenScreen(stateHolder: AddCustomTokenStateHolder, modifier: Modifier = Modifier) { - when (stateHolder) { - is AddCustomTokenStateHolder.Content -> AddCustomTokenContent(stateHolder, modifier) - is AddCustomTokenStateHolder.TestContent -> AddCustomTokenTestContent(stateHolder, modifier) - } -} - -@Preview(showSystemUi = true) -@Preview(showSystemUi = true, uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun Preview_AddCustomTokenScreen( - @PreviewParameter(AddCustomTokenScreenProvider::class) stateHolder: AddCustomTokenStateHolder, -) { - TangemThemePreview { - AddCustomTokenScreen(stateHolder) - } -} - -private class AddCustomTokenScreenProvider : CollectionPreviewParameterProvider( - collection = listOf( - AddCustomTokenPreviewData.createContent(), - AddCustomTokenPreviewData.createTestContent(), - ), -) \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/ui/AddCustomTokenTestContent.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/ui/AddCustomTokenTestContent.kt deleted file mode 100644 index f5b7759a82..0000000000 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/ui/AddCustomTokenTestContent.kt +++ /dev/null @@ -1,249 +0,0 @@ -package com.tangem.tap.features.customtoken.impl.presentation.ui - -import androidx.activity.compose.BackHandler -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.verticalScroll -import androidx.compose.material.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.ExperimentalComposeUiApi -import androidx.compose.ui.Modifier -import androidx.compose.ui.layout.onSizeChanged -import androidx.compose.ui.platform.LocalConfiguration -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.platform.LocalSoftwareKeyboardController -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import com.tangem.core.ui.components.PrimaryButton -import com.tangem.core.ui.components.SpacerH8 -import com.tangem.core.ui.components.atoms.Hand -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.tap.features.customtoken.impl.presentation.models.AddCustomTokenChooseTokenBottomSheet -import com.tangem.tap.features.customtoken.impl.presentation.models.AddCustomTokenChooseTokenBottomSheet.TestTokenItem -import com.tangem.tap.features.customtoken.impl.presentation.models.AddCustomTokenTestBlock -import com.tangem.tap.features.customtoken.impl.presentation.states.AddCustomTokenStateHolder -import com.tangem.tap.features.customtoken.impl.presentation.ui.components.AddCustomTokenFloatingButton -import com.tangem.tap.features.customtoken.impl.presentation.ui.components.AddCustomTokenForm -import com.tangem.tap.features.customtoken.impl.presentation.ui.components.AddCustomTokenToolbar -import com.tangem.tap.features.customtoken.impl.presentation.ui.components.AddCustomTokenWarnings -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.launch - -/** - * Add custom token content for testing - * - * @param state screen state - * -[REDACTED_AUTHOR] - */ -@OptIn(ExperimentalMaterialApi::class) -@Composable -internal fun AddCustomTokenTestContent(state: AddCustomTokenStateHolder.TestContent, modifier: Modifier = Modifier) { - val coroutineScope = rememberCoroutineScope() - val bottomSheetScaffoldState = rememberBottomSheetScaffoldState( - bottomSheetState = BottomSheetState(initialValue = BottomSheetValue.Collapsed, LocalDensity.current), - ) - - BackHandler( - onBack = { - onBackButtonClicked( - coroutineScope = coroutineScope, - bottomSheetScaffoldState = bottomSheetScaffoldState, - defaultAction = state.onBackButtonClick, - ) - }, - ) - - var floatingButtonHeight by remember { mutableStateOf(0.dp) } - BottomSheetScaffold( - modifier = modifier, - sheetContent = { - SheetContent( - coroutineScope = coroutineScope, - bottomSheetScaffoldState = bottomSheetScaffoldState, - model = state.bottomSheet, - ) - }, - scaffoldState = bottomSheetScaffoldState, - topBar = { - AddCustomTokenToolbar( - title = state.toolbar.title, - onBackButtonClick = { - onBackButtonClicked( - coroutineScope, - bottomSheetScaffoldState, - defaultAction = state.toolbar.onBackButtonClick, - ) - }, - ) - }, - floatingActionButton = { - val density = LocalDensity.current - val verticalPadding = TangemTheme.dimens.spacing32 - AddCustomTokenFloatingButton( - model = state.floatingButton, - modifier = Modifier.onSizeChanged { - floatingButtonHeight = with(density) { it.height.toDp() + verticalPadding } - }, - ) - }, - floatingActionButtonPosition = FabPosition.Center, - sheetBackgroundColor = TangemTheme.colors.background.secondary, - sheetPeekHeight = TangemTheme.dimens.size0, - backgroundColor = TangemTheme.colors.background.primary, - ) { - Column( - modifier = Modifier - .verticalScroll(rememberScrollState()) - .padding(paddingValues = it) - .padding(bottom = floatingButtonHeight) - .fillMaxSize(), - ) { - TestBlock( - state.testBlock, - coroutineScope, - bottomSheetScaffoldState, - ) - - AddCustomTokenForm(model = state.form) - - AddCustomTokenWarnings(warnings = state.warnings) - } - } -} - -@OptIn(ExperimentalMaterialApi::class) -private fun onBackButtonClicked( - coroutineScope: CoroutineScope, - bottomSheetScaffoldState: BottomSheetScaffoldState, - defaultAction: () -> Unit, -) { - coroutineScope.launch { - if (bottomSheetScaffoldState.bottomSheetState.isExpanded) { - bottomSheetScaffoldState.bottomSheetState.collapse() - } else { - defaultAction() - } - } -} - -@OptIn(ExperimentalMaterialApi::class) -@Composable -private fun SheetContent( - model: AddCustomTokenChooseTokenBottomSheet, - coroutineScope: CoroutineScope, - bottomSheetScaffoldState: BottomSheetScaffoldState, -) { - Column( - modifier = Modifier - .fillMaxWidth() - .height(LocalConfiguration.current.screenHeightDp.dp - TangemTheme.dimens.spacing16), - ) { - Hand() - - Column( - modifier = Modifier - .fillMaxWidth() - .verticalScroll(rememberScrollState()), - ) { - model.categoriesBlocks.forEachIndexed { index, categoryBlock -> - key(categoryBlock) { - Column { - TokensList( - title = categoryBlock.name, - tokens = categoryBlock.items, - onTestTokenClick = { address -> - model.onTestTokenClick(address) - coroutineScope.launch { bottomSheetScaffoldState.bottomSheetState.collapse() } - }, - ) - - if (model.categoriesBlocks.lastIndex != index) { - Divider() - SpacerH8() - } - } - } - } - } - } -} - -@Composable -private fun TokensList(title: String, tokens: List, onTestTokenClick: (String) -> Unit) { - Text( - text = title, - modifier = Modifier.padding( - horizontal = TangemTheme.dimens.spacing24, - vertical = TangemTheme.dimens.spacing8, - ), - maxLines = 1, - style = TangemTheme.typography.h3, - ) - - tokens.forEach { token -> - key(token) { - PrimaryButton( - text = token.name, - onClick = { onTestTokenClick(token.address) }, - modifier = Modifier - .padding(horizontal = TangemTheme.dimens.spacing16) - .padding(bottom = TangemTheme.dimens.spacing8) - .fillMaxWidth(), - ) - } - } -} - -@OptIn(ExperimentalMaterialApi::class, ExperimentalComposeUiApi::class) -@Composable -private fun TestBlock( - model: AddCustomTokenTestBlock, - coroutineScope: CoroutineScope, - bottomSheetScaffoldState: BottomSheetScaffoldState, -) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = TangemTheme.dimens.spacing16) - .padding(top = TangemTheme.dimens.spacing16), - verticalArrangement = Arrangement.spacedBy(space = TangemTheme.dimens.spacing8), - ) { - val softwareKeyboardController = LocalSoftwareKeyboardController.current - PrimaryButton( - text = model.chooseTokenButtonText, - onClick = { - softwareKeyboardController?.hide() - coroutineScope.launch { bottomSheetScaffoldState.bottomSheetState.expand() } - }, - modifier = Modifier.fillMaxWidth(), - ) - - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8), - verticalAlignment = Alignment.CenterVertically, - ) { - PrimaryButton( - text = model.clearButtonText, - onClick = model.onClearAddressButtonClick, - modifier = Modifier.weight(1f), - ) - PrimaryButton( - text = model.resetButtonText, - onClick = model.onResetButtonClick, - modifier = Modifier.weight(1f), - ) - } - } -} - -@Preview -@Composable -private fun Preview_AddCustomTokenTestContent() { - TangemThemePreview { - AddCustomTokenTestContent(state = AddCustomTokenPreviewData.createTestContent()) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/ui/components/AddCustomTokenFloatingButton.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/ui/components/AddCustomTokenFloatingButton.kt deleted file mode 100644 index 3cc1d4847a..0000000000 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/ui/components/AddCustomTokenFloatingButton.kt +++ /dev/null @@ -1,56 +0,0 @@ -package com.tangem.tap.features.customtoken.impl.presentation.ui.components - -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.imePadding -import androidx.compose.foundation.layout.padding -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.tooling.preview.PreviewParameter -import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider -import com.tangem.core.ui.components.PrimaryButtonIconStart -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.tap.features.customtoken.impl.presentation.models.AddCustomTokenFloatingButton -import com.tangem.wallet.R - -/** - * Add custom token floating button. Attached above the keyboard. - * - * @param model button model - * @param modifier modifier - * -[REDACTED_AUTHOR] - */ -@Composable -internal fun AddCustomTokenFloatingButton(model: AddCustomTokenFloatingButton, modifier: Modifier = Modifier) { - PrimaryButtonIconStart( - modifier = modifier - .imePadding() - .padding(horizontal = TangemTheme.dimens.spacing16) - .fillMaxWidth(), - text = stringResource(id = R.string.custom_token_add_token), - iconResId = R.drawable.ic_plus_24, - enabled = model.isEnabled, - showProgress = model.showProgress, - onClick = model.onClick, - ) -} - -@Preview -@Composable -private fun Preview_AddCustomTokenFloatingButton( - @PreviewParameter(AddCustomTokenFloatingButtonProvider::class) model: AddCustomTokenFloatingButton, -) { - TangemThemePreview { - AddCustomTokenFloatingButton(model) - } -} - -private class AddCustomTokenFloatingButtonProvider : CollectionPreviewParameterProvider( - listOf( - AddCustomTokenFloatingButton(isEnabled = true, showProgress = false, onClick = {}), - AddCustomTokenFloatingButton(isEnabled = false, showProgress = false, onClick = {}), - ), -) \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/ui/components/AddCustomTokenForm.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/ui/components/AddCustomTokenForm.kt deleted file mode 100644 index 58da365d81..0000000000 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/ui/components/AddCustomTokenForm.kt +++ /dev/null @@ -1,212 +0,0 @@ -package com.tangem.tap.features.customtoken.impl.presentation.ui.components - -import androidx.compose.animation.* -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.tooling.preview.PreviewParameter -import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.tap.common.compose.TangemTextFieldsDefault -import com.tangem.tap.features.customtoken.impl.presentation.models.AddCustomTokenForm -import com.tangem.tap.features.customtoken.impl.presentation.models.AddCustomTokenInputField -import com.tangem.tap.features.customtoken.impl.presentation.models.AddCustomTokenSelectorField -import com.tangem.tap.features.customtoken.impl.presentation.ui.AddCustomTokenPreviewData -import com.tangem.tap.features.details.ui.cardsettings.resolveReference - -/** - * Add custom token form - * - * @param model component model - * -[REDACTED_AUTHOR] - */ -@Composable -internal fun AddCustomTokenForm(model: AddCustomTokenForm) { - Card( - modifier = Modifier - .fillMaxWidth() - .padding(TangemTheme.dimens.spacing16), - shape = RoundedCornerShape(TangemTheme.dimens.radius8), - backgroundColor = TangemTheme.colors.background.primary, - elevation = TangemTheme.dimens.elevation4, - ) { - Column( - modifier = Modifier.padding(TangemTheme.dimens.spacing16), - verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8), - ) { - if (model.showTokenFields) InputField(model = model.contractAddressInputField) - SelectorField(model = model.networkSelectorField) - if (model.showTokenFields) InputField(model = model.tokenNameInputField) - if (model.showTokenFields) InputField(model = model.tokenSymbolInputField) - if (model.showTokenFields) InputField(model = model.decimalsInputField) - model.derivationPathSelectorField?.let { SelectorField(model = it) } - if (model.derivationPathInputField?.showField == true) InputField(model = model.derivationPathInputField) - } - } -} - -@Composable -private fun InputField(model: AddCustomTokenInputField) { - Column { - val isError = (model as? AddCustomTokenInputField.ContactAddress)?.isError ?: false - - TextField(model, isError) - - (model as? AddCustomTokenInputField.ContactAddress)?.error?.resolveReference()?.let { - AnimatedVisibility( - visible = isError, - enter = fadeIn() + slideInVertically(), - exit = slideOutVertically() + fadeOut(), - ) { - Text( - text = it, - color = MaterialTheme.colors.error, - style = TangemTheme.typography.body2, - ) - } - } - } -} - -@Composable -private fun TextField(model: AddCustomTokenInputField, isError: Boolean) { - Box { - val isEnabled = when (model) { - is AddCustomTokenInputField.ContactAddress -> true - is AddCustomTokenInputField.Decimals -> model.isEnabled - is AddCustomTokenInputField.TokenName -> model.isEnabled - is AddCustomTokenInputField.TokenSymbol -> model.isEnabled - is AddCustomTokenInputField.DerivationPath -> true - } - - OutlinedTextField( - modifier = Modifier.fillMaxWidth(), - value = model.value, - onValueChange = model.onValueChange, - keyboardOptions = model.keyboardOptions, - label = { - Text( - text = model.label.resolveReference(), - style = TangemTheme.typography.caption2, - color = TangemTextFieldsDefault.defaultTextFieldColors.labelColor( - enabled = isEnabled, - error = isError, - interactionSource = remember { MutableInteractionSource() }, - ).value, - ) - }, - placeholder = { - Text( - text = model.placeholder.resolveReference(), - style = TangemTheme.typography.body1, - color = TangemTextFieldsDefault.defaultTextFieldColors - .placeholderColor(enabled = isEnabled) - .value, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - }, - singleLine = true, - enabled = isEnabled, - isError = isError, - colors = TangemTextFieldsDefault.defaultTextFieldColors, - ) - - AnimatedVisibility( - visible = (model as? AddCustomTokenInputField.ContactAddress)?.isLoading ?: false, - modifier = Modifier - .fillMaxWidth() - .align(Alignment.BottomCenter) - .padding(horizontal = TangemTheme.dimens.spacing6) - .padding(bottom = TangemTheme.dimens.spacing6), - ) { - LinearProgressIndicator(color = TangemTheme.colors.icon.primary1) - } - } -} - -/** - * Be careful with this function – ExposedDropdownMenuBox can crash the app if it is open and user clicks system back - * button. It was fixed in compose-material 1.6.4. - */ -@OptIn(ExperimentalMaterialApi::class) -@Composable -private fun SelectorField(model: AddCustomTokenSelectorField) { - var isExpanded by remember { mutableStateOf(value = false) } - - ExposedDropdownMenuBox( - expanded = isExpanded, - onExpandedChange = { isExpanded = !isExpanded }, - ) { - val isEnabled = (model as? AddCustomTokenSelectorField.DerivationPath)?.isEnabled ?: true - OutlinedTextField( - value = when (val item = model.selectedItem) { - is AddCustomTokenSelectorField.SelectorItem.Title -> item.title - is AddCustomTokenSelectorField.SelectorItem.TitleWithSubtitle -> item.subtitle - }.resolveReference(), - modifier = Modifier.fillMaxWidth(), - onValueChange = {}, - readOnly = true, - enabled = isEnabled, - label = { Text(text = model.label.resolveReference()) }, - trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = isExpanded) }, - colors = TangemTextFieldsDefault.defaultTextFieldColors, - ) - - ExposedDropdownMenu( - expanded = isExpanded && isEnabled, - onDismissRequest = { isExpanded = false }, - ) { - model.items.forEachIndexed { index, item -> - DropdownMenuItem( - onClick = { - model.onMenuItemClick(index) - isExpanded = false - }, - ) { - Column { - Text(text = item.title.resolveReference()) - - val subtitle = (item as? AddCustomTokenSelectorField.SelectorItem.TitleWithSubtitle) - ?.subtitle?.resolveReference() - - if (!subtitle.isNullOrBlank()) { - Text( - text = subtitle, - color = TangemTheme.colors.text.secondary, - maxLines = 1, - style = TangemTheme.typography.caption2, - ) - } - } - } - } - } - } -} - -@Preview -@Composable -private fun Preview_AddCustomTokenForm(@PreviewParameter(AddCustomTokenFormProvider::class) model: AddCustomTokenForm) { - TangemThemePreview { - AddCustomTokenForm(model) - } -} - -private class AddCustomTokenFormProvider : CollectionPreviewParameterProvider( - collection = listOf( - AddCustomTokenPreviewData.createDefaultForm(), - AddCustomTokenPreviewData.createDefaultForm().copy(derivationPathSelectorField = null), - AddCustomTokenPreviewData.createDefaultForm().let { form -> - form.copy(contractAddressInputField = form.contractAddressInputField.copy(isLoading = true)) - }, - ), -) \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/ui/components/AddCustomTokenToolbar.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/ui/components/AddCustomTokenToolbar.kt deleted file mode 100644 index 030f130a1a..0000000000 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/ui/components/AddCustomTokenToolbar.kt +++ /dev/null @@ -1,61 +0,0 @@ -package com.tangem.tap.features.customtoken.impl.presentation.ui.components - -import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.width -import androidx.compose.material.* -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.tooling.preview.Preview -import com.tangem.core.ui.R -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.tap.features.details.ui.cardsettings.TextReference -import com.tangem.tap.features.details.ui.cardsettings.resolveReference - -/** - * Add custom token toolbar - * - * @param title title - * @param onBackButtonClick lambda be invoked when BackButton is been pressed - * -[REDACTED_AUTHOR] - */ -@Composable -internal fun AddCustomTokenToolbar(title: TextReference, onBackButtonClick: () -> Unit) { - val toolbarElevation = if (isSystemInDarkTheme()) { - TangemTheme.dimens.elevation0 - } else { - AppBarDefaults.TopAppBarElevation - } - TopAppBar( - backgroundColor = TangemTheme.colors.background.primary, - elevation = toolbarElevation, - ) { - IconButton(onClick = onBackButtonClick) { - Icon( - painter = painterResource(id = R.drawable.ic_back_24), - contentDescription = null, - tint = TangemTheme.colors.icon.secondary, - ) - } - - Spacer(modifier = Modifier.width(TangemTheme.dimens.spacing26)) - - Text( - text = title.resolveReference(), - color = TangemTheme.colors.text.primary1, - maxLines = 1, - style = TangemTheme.typography.h3, - ) - } -} - -@Preview -@Composable -internal fun Preview_AddCustomTokenToolbar() { - TangemThemePreview { - AddCustomTokenToolbar(title = TextReference.Res(R.string.add_custom_token_title), onBackButtonClick = {}) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/ui/components/AddCustomTokenWarnings.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/ui/components/AddCustomTokenWarnings.kt deleted file mode 100644 index a323a8a982..0000000000 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/ui/components/AddCustomTokenWarnings.kt +++ /dev/null @@ -1,82 +0,0 @@ -package com.tangem.tap.features.customtoken.impl.presentation.ui.components - -import android.content.res.Configuration -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.material.Card -import androidx.compose.material.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.key -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.sp -import com.tangem.core.ui.res.TangemColorPalette -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.core.ui.res.TangemTheme -import com.tangem.tap.features.customtoken.impl.presentation.models.AddCustomTokenWarning -import com.tangem.tap.features.customtoken.impl.presentation.ui.AddCustomTokenPreviewData -import com.tangem.tap.features.details.ui.cardsettings.resolveReference -import com.tangem.wallet.R - -/** - * Add custom token warnings - * - * @param warnings warnings descriptions set - * -[REDACTED_AUTHOR] - */ -@Composable -internal fun AddCustomTokenWarnings(warnings: Set) { - Column( - modifier = Modifier - .padding(horizontal = TangemTheme.dimens.spacing16) - .fillMaxWidth(), - verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8), - ) { - warnings.forEach { warning -> - key(warning) { AddCustomTokenWarning(warning) } - } - } -} - -@Composable -private fun AddCustomTokenWarning(warning: AddCustomTokenWarning) { - Card( - modifier = Modifier.fillMaxSize(), - shape = TangemTheme.shapes.roundedCornersSmall2, - backgroundColor = TangemColorPalette.Tangerine, - contentColor = TangemColorPalette.White, - elevation = TangemTheme.dimens.elevation4, - ) { - // FIXME("Incorrect typography. Replace with typography from design system") - Column( - modifier = Modifier.padding(all = TangemTheme.dimens.spacing16), - verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8), - ) { - Text( - text = stringResource(id = R.string.common_warning), - maxLines = 1, - style = TangemTheme.typography.body2.copy(fontWeight = FontWeight.Bold), - ) - Text( - text = warning.description.resolveReference(), - fontSize = 13.sp, - lineHeight = 18.sp, - ) - } - } -} - -@Preview -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun Preview_AddCustomTokenWarnings() { - TangemThemePreview { - AddCustomTokenWarnings(warnings = AddCustomTokenPreviewData.createWarnings()) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/validators/ContractAddressValidator.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/validators/ContractAddressValidator.kt deleted file mode 100644 index 966af2bd6a..0000000000 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/validators/ContractAddressValidator.kt +++ /dev/null @@ -1,42 +0,0 @@ -package com.tangem.tap.features.customtoken.impl.presentation.validators - -import com.tangem.blockchain.common.Blockchain -import com.tangem.blockchain.common.address.AddressService -import com.tangem.common.card.EllipticCurve -import com.tangem.domain.tokens.error.AddCustomTokenError - -/** - * Validator of contract address - * -[REDACTED_AUTHOR] - */ -object ContractAddressValidator { - - /** Validate a [address] using [blockchain] */ - fun validate(address: String, blockchain: Blockchain): ContractAddressValidatorResult { - return when { - address.isEmpty() -> ContractAddressValidatorResult.Error(type = AddCustomTokenError.FIELD_IS_EMPTY) - validateAddress(blockchain, address) -> ContractAddressValidatorResult.Success - else -> ContractAddressValidatorResult.Error(type = AddCustomTokenError.INVALID_CONTRACT_ADDRESS) - } - } - - private fun validateAddress(blockchain: Blockchain, address: String): Boolean { - return when (blockchain) { - Blockchain.Unknown, - Blockchain.Binance, - Blockchain.BinanceTestnet, - -> SuccessAddressValidator.validate(address) - Blockchain.Cardano -> blockchain.validateContractAddress(address) - else -> blockchain.validateAddress(address) - } - } - - private object SuccessAddressValidator : AddressService() { - override fun makeAddress(walletPublicKey: ByteArray, curve: EllipticCurve?): String { - throw UnsupportedOperationException() - } - - override fun validate(address: String): Boolean = true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/validators/ContractAddressValidatorResult.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/validators/ContractAddressValidatorResult.kt deleted file mode 100644 index daf1b4d159..0000000000 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/validators/ContractAddressValidatorResult.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.tangem.tap.features.customtoken.impl.presentation.validators - -import com.tangem.domain.tokens.error.AddCustomTokenError - -/** - * Result of validation contract address - * -[REDACTED_AUTHOR] - */ -sealed interface ContractAddressValidatorResult { - - /** Success */ - object Success : ContractAddressValidatorResult - - /** - * Error - * - * @property type type of error - */ - data class Error(val type: AddCustomTokenError) : ContractAddressValidatorResult -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/viewmodels/AddCustomTokenAnalyticsSender.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/viewmodels/AddCustomTokenAnalyticsSender.kt deleted file mode 100644 index 55886b316a..0000000000 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/viewmodels/AddCustomTokenAnalyticsSender.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.tangem.tap.features.customtoken.impl.presentation.viewmodels - -import com.tangem.core.analytics.api.AnalyticsEventHandler -import com.tangem.domain.features.addCustomToken.CustomCurrency -import com.tangem.tap.common.analytics.events.ManageTokens - -/** Analytics sender for tokens list screen */ -class AddCustomTokenAnalyticsSender(private val analyticsEventHandler: AnalyticsEventHandler) { - - fun sendWhenScreenOpened() { - analyticsEventHandler.send(ManageTokens.CustomToken.ScreenOpened) - } - - fun sendWhenAddTokenButtonClicked(customCurrency: CustomCurrency) { - analyticsEventHandler.send(ManageTokens.CustomToken.TokenWasAdded(customCurrency)) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/viewmodels/AddCustomTokenViewModel.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/viewmodels/AddCustomTokenViewModel.kt deleted file mode 100644 index 0fadd8ea5b..0000000000 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/viewmodels/AddCustomTokenViewModel.kt +++ /dev/null @@ -1,1048 +0,0 @@ -package com.tangem.tap.features.customtoken.impl.presentation.viewmodels - -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.ui.text.input.ImeAction -import androidx.compose.ui.text.input.KeyboardType -import androidx.lifecycle.DefaultLifecycleObserver -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import com.tangem.blockchain.blockchains.cardano.CardanoTokenAddressConverter -import com.tangem.blockchain.blockchains.hedera.HederaTokenAddressConverter -import com.tangem.blockchain.common.Blockchain -import com.tangem.blockchain.common.Token -import com.tangem.blockchain.common.derivation.DerivationStyle -import com.tangem.blockchainsdk.utils.fromNetworkId -import com.tangem.blockchainsdk.utils.isSupportedInApp -import com.tangem.blockchainsdk.utils.toNetworkId -import com.tangem.core.analytics.api.AnalyticsEventHandler -import com.tangem.crypto.hdWallet.DerivationPath -import com.tangem.domain.common.DerivationStyleProvider -import com.tangem.domain.common.extensions.canHandleBlockchain -import com.tangem.domain.common.extensions.canHandleToken -import com.tangem.domain.common.extensions.supportedBlockchains -import com.tangem.domain.common.util.cardTypesResolver -import com.tangem.domain.common.util.derivationStyleProvider -import com.tangem.domain.features.addCustomToken.CustomCurrency -import com.tangem.domain.tokens.GetCryptoCurrenciesUseCase -import com.tangem.domain.tokens.error.AddCustomTokenError -import com.tangem.domain.tokens.model.CryptoCurrency -import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase -import com.tangem.tap.features.customtoken.impl.domain.CustomTokenInteractor -import com.tangem.tap.features.customtoken.impl.domain.models.FoundToken -import com.tangem.tap.features.customtoken.impl.presentation.models.* -import com.tangem.tap.features.customtoken.impl.presentation.models.AddCustomTokenChooseTokenBottomSheet.TestTokenItem -import com.tangem.tap.features.customtoken.impl.presentation.models.AddCustomTokenChooseTokenBottomSheet.TokensCategoryBlock -import com.tangem.tap.features.customtoken.impl.presentation.models.AddCustomTokenSelectorField.SelectorItem -import com.tangem.tap.features.customtoken.impl.presentation.routers.CustomTokenRouter -import com.tangem.tap.features.customtoken.impl.presentation.states.AddCustomTokenStateHolder -import com.tangem.tap.features.customtoken.impl.presentation.validators.ContractAddressValidator -import com.tangem.tap.features.customtoken.impl.presentation.validators.ContractAddressValidatorResult -import com.tangem.tap.features.details.ui.cardsettings.TextReference -import com.tangem.utils.coroutines.AppCoroutineDispatcherProvider -import com.tangem.utils.coroutines.runCatching -import com.tangem.wallet.BuildConfig -import com.tangem.wallet.R -import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.collections.immutable.persistentListOf -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.update -import kotlinx.coroutines.flow.updateAndGet -import kotlinx.coroutines.launch -import timber.log.Timber -import javax.inject.Inject - -/** - * ViewModel for add custom token screen - * - * @param analyticsEventHandler analytics event handler - * @param featureRouter feature router - * @property featureInteractor feature interactor - * @property getSelectedWalletSyncUseCase use case that returns selected wallet - * @property dispatchers coroutine dispatchers provider - * -[REDACTED_AUTHOR] - */ -@Suppress("LargeClass", "LongParameterList") -@HiltViewModel -internal class AddCustomTokenViewModel @Inject constructor( - analyticsEventHandler: AnalyticsEventHandler, - featureRouter: CustomTokenRouter, - getCurrenciesUseCase: GetCryptoCurrenciesUseCase, - private val featureInteractor: CustomTokenInteractor, - private val dispatchers: AppCoroutineDispatcherProvider, - private val getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase, -) : ViewModel(), DefaultLifecycleObserver { - - private val analyticsSender = AddCustomTokenAnalyticsSender(analyticsEventHandler) - private val actionsHandler = ActionsHandler(featureRouter) - private val testActionsHandler = TestActionsHandler() - private val formStateBuilder = FormStateBuilder() - private val hederaAddressConverter = HederaTokenAddressConverter() - private val cardanoTokenAddressConverter = CardanoTokenAddressConverter() - - private var currentCryptoCurrencies: List = emptyList() - - /** Screen state */ - val uiState: MutableStateFlow = MutableStateFlow(value = getInitialUiState()) - - private var foundToken: FoundToken? = null - - init { - viewModelScope.launch(dispatchers.main) { - currentCryptoCurrencies = getSelectedWalletSyncUseCase().fold( - ifLeft = { emptyList() }, - ifRight = { selectedWallet -> - getCurrenciesUseCase.getSync(selectedWallet.walletId).fold( - ifLeft = { emptyList() }, - ifRight = { it }, - ) - }, - ) - } - } - - override fun onCreate(owner: LifecycleOwner) { - analyticsSender.sendWhenScreenOpened() - } - - private fun getInitialUiState(): AddCustomTokenStateHolder { - return if (BuildConfig.TEST_ACTION_ENABLED) { - AddCustomTokenStateHolder.TestContent( - onBackButtonClick = actionsHandler::onBackButtonClick, - toolbar = createToolbar(), - form = formStateBuilder.createForm(), - warnings = emptySet(), - floatingButton = createFloatingButton(), - testBlock = AddCustomTokenTestBlock( - chooseTokenButtonText = "Choose token", - clearButtonText = "Clear address", - resetButtonText = "Reset", - onClearAddressButtonClick = testActionsHandler::onClearAddressButtonClick, - onResetButtonClick = testActionsHandler::onResetButtonClick, - ), - bottomSheet = AddCustomTokenChooseTokenBottomSheet( - categoriesBlocks = listOf( - TokensCategoryBlock(name = "Common", items = COMMON_TOKENS), - TokensCategoryBlock(name = "Solana", items = SOLANA_TOKENS), - ), - onTestTokenClick = actionsHandler::onContactAddressValueChange, - ), - ) - } else { - AddCustomTokenStateHolder.Content( - onBackButtonClick = actionsHandler::onBackButtonClick, - toolbar = createToolbar(), - form = formStateBuilder.createForm(), - warnings = emptySet(), - floatingButton = createFloatingButton(), - ) - } - } - - private fun createToolbar(): AddCustomTokensToolbar { - return AddCustomTokensToolbar( - title = TextReference.Res(R.string.add_custom_token_title), - onBackButtonClick = actionsHandler::onBackButtonClick, - ) - } - - private fun createFloatingButton(): AddCustomTokenFloatingButton { - return AddCustomTokenFloatingButton( - isEnabled = true, - showProgress = false, - onClick = actionsHandler::onAddCustomTokenClick, - ) - } - - private inner class FormStateBuilder { - - fun createForm(): AddCustomTokenForm { - return AddCustomTokenForm( - contractAddressInputField = createContractAddressInputField(), - networkSelectorField = createNetworkSelectorField(), - tokenNameInputField = createTokenNameInputField(), - tokenSymbolInputField = createTokenSymbolInputField(), - decimalsInputField = createDecimalsInputField(), - derivationPathSelectorField = createDerivationPathsSelectorField(), - derivationPathInputField = createDerivationPathInputField(), - ) - } - - fun createDerivationPathSelectorAdditionalItem( - blockchain: Blockchain, - type: DerivationPathSelectorType = DerivationPathSelectorType.BLOCKCHAIN, - derivationPath: String, - ): SelectorItem.TitleWithSubtitle { - return when (type) { - DerivationPathSelectorType.DEFAULT -> SelectorItem.TitleWithSubtitle( - title = TextReference.Res(R.string.custom_token_derivation_path_default), - subtitle = TextReference.Res(R.string.custom_token_derivation_path_default), - blockchain = Blockchain.Unknown, - type = DerivationPathSelectorType.DEFAULT, - ) - DerivationPathSelectorType.CUSTOM -> SelectorItem.TitleWithSubtitle( - title = TextReference.Res(R.string.custom_token_custom_derivation), - subtitle = TextReference.Res(R.string.custom_token_custom_derivation), - blockchain = Blockchain.Unknown, - type = DerivationPathSelectorType.CUSTOM, - ) - DerivationPathSelectorType.BLOCKCHAIN -> SelectorItem.TitleWithSubtitle( - title = TextReference.Str(derivationPath), - subtitle = TextReference.Str(blockchain.getNetworkName()), - blockchain = blockchain, - ) - } - } - - fun createNetworkSelectorItem(blockchain: Blockchain): SelectorItem.Title { - return if (blockchain == Blockchain.Unknown) { - SelectorItem.Title( - title = TextReference.Res(R.string.custom_token_network_input_not_selected), - blockchain = Blockchain.Unknown, - ) - } else { - SelectorItem.Title( - title = TextReference.Str(blockchain.getNetworkName()), - blockchain = blockchain, - ) - } - } - - private fun createContractAddressInputField(): AddCustomTokenInputField.ContactAddress { - return AddCustomTokenInputField.ContactAddress( - value = "", - onValueChange = actionsHandler::onContactAddressValueChange, - keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next), - label = TextReference.Res(R.string.custom_token_contract_address_input_title), - placeholder = TextReference.Str(value = CONTRACT_ADDRESS_PLACEHOLDER), - isLoading = false, - isError = false, - error = null, - ) - } - - private fun createNetworkSelectorField(): AddCustomTokenSelectorField.Network { - val selectorItems = getNetworkSelectorItems() - return AddCustomTokenSelectorField.Network( - label = TextReference.Res(R.string.custom_token_network_input_title), - selectedItem = requireNotNull(selectorItems.firstOrNull()), - items = selectorItems, - onMenuItemClick = actionsHandler::onNetworkSelectorItemClick, - ) - } - - private fun getNetworkSelectorItems(): List { - val defaultNetwork = createNetworkSelectorItem(blockchain = Blockchain.Unknown) - val scanResponse = getSelectedWalletSyncUseCase().fold( - ifLeft = { null }, - ifRight = { it.scanResponse }, - ) - val derivationStyle = scanResponse?.derivationStyleProvider?.getDerivationStyle() - return listOf(defaultNetwork) + Blockchain.entries - .filter { blockchain -> - scanResponse?.card?.supportedBlockchains(scanResponse.cardTypesResolver) - ?.contains(blockchain) == true && isDerivationPathNotEmpty(derivationStyle, blockchain) - } - .sortedBy(Blockchain::fullName) - .map(::createNetworkSelectorItem) - } - - private fun isDerivationPathNotEmpty(derivationStyle: DerivationStyle?, blockchain: Blockchain): Boolean { - // derivationStyle is null for cards without HD wallets, always return true - return if (derivationStyle != null) { - blockchain.derivationPath(derivationStyle)?.rawPath?.isNotEmpty() == true - } else { - true - } - } - - private fun createTokenNameInputField(): AddCustomTokenInputField.TokenName { - return AddCustomTokenInputField.TokenName( - value = "", - onValueChange = actionsHandler::onTokenNameValueChange, - keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next), - label = TextReference.Res(R.string.custom_token_name_input_title), - placeholder = TextReference.Res(id = R.string.custom_token_name_input_placeholder), - isEnabled = false, - ) - } - - private fun createTokenSymbolInputField(): AddCustomTokenInputField.TokenSymbol { - return AddCustomTokenInputField.TokenSymbol( - value = "", - onValueChange = actionsHandler::onTokenSymbolValueChange, - keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next), - label = TextReference.Res(R.string.custom_token_token_symbol_input_title_old), - placeholder = TextReference.Res(id = R.string.custom_token_token_symbol_input_placeholder), - isEnabled = false, - ) - } - - private fun createDecimalsInputField(): AddCustomTokenInputField.Decimals { - return AddCustomTokenInputField.Decimals( - value = "", - onValueChange = actionsHandler::onDecimalsValueChange, - keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Next), - label = TextReference.Res(R.string.custom_token_decimals_input_title), - placeholder = TextReference.Str(value = DECIMALS_PLACEHOLDER), - isEnabled = false, - ) - } - - private fun createDerivationPathsSelectorField(): AddCustomTokenSelectorField.DerivationPath? { - return getSelectedWalletSyncUseCase().fold( - ifLeft = { null }, - ifRight = { - if (!it.scanResponse.card.settings.isHDWalletAllowed) return null - - val selectorItems = getDerivationPathsSelectorItems(it.scanResponse.derivationStyleProvider) - AddCustomTokenSelectorField.DerivationPath( - label = TextReference.Res(R.string.custom_token_derivation_path_input_title), - selectedItem = requireNotNull(selectorItems.firstOrNull()), - items = selectorItems, - onMenuItemClick = actionsHandler::onDerivationPathSelectorItemClick, - isEnabled = true, - ) - }, - ) - } - - private fun getDerivationPathsSelectorItems( - derivationStyleProvider: DerivationStyleProvider?, - ): List { - val derivationStyle = derivationStyleProvider?.getDerivationStyle() - return listOf( - createDerivationPathSelectorAdditionalItem( - blockchain = Blockchain.Unknown, - type = DerivationPathSelectorType.DEFAULT, - derivationPath = "", - ), - createDerivationPathSelectorAdditionalItem( - blockchain = Blockchain.Unknown, - type = DerivationPathSelectorType.CUSTOM, - derivationPath = "", - ), - ) + Blockchain.entries - .filter { blockchain -> - blockchain.isSupportedInApp() && !blockchain.isTestnet() - } - .sortedBy(Blockchain::fullName) - .mapNotNull { - val derivationPath = if (derivationStyle != null) { - it.derivationPath(derivationStyle)?.rawPath - } else { - // derivationStyle is null for cards without HDWallet, use DerivationStyle.V1 - it.derivationPath(DerivationStyle.V1)?.rawPath - } - if (derivationPath?.isNotEmpty() == true) { - createDerivationPathSelectorAdditionalItem( - blockchain = it, - derivationPath = derivationPath, - ) - } else { - null - } - } - } - - private fun createDerivationPathInputField(): AddCustomTokenInputField.DerivationPath? { - return getSelectedWalletSyncUseCase().fold( - ifLeft = { null }, - ifRight = { - if (!it.scanResponse.card.settings.isHDWalletAllowed) return null - - AddCustomTokenInputField.DerivationPath( - value = "", - onValueChange = actionsHandler::onDerivationPathValueChange, - keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), - label = TextReference.Res(R.string.custom_token_custom_derivation), - placeholder = TextReference.Str(value = DERIVATION_PATH_PLACEHOLDER), - ) - }, - ) - } - } - - private fun updateForm(address: String, selectedNetwork: Blockchain) { - viewModelScope.launch(dispatchers.main) { - runCatching(dispatchers.io) { - val tokenAddress = convertTokenAddress(selectedNetwork, address) - ?: error("TokenAddress is invalid") - - featureInteractor.findToken(address = tokenAddress, blockchain = selectedNetwork) - } - .onSuccess { token -> - foundToken = token - uiState.update { state -> - state.copySealed( - form = state.form.copy( - contractAddressInputField = state.form.contractAddressInputField.copy( - isLoading = false, - ), - networkSelectorField = state.form.networkSelectorField.copy( - selectedItem = formStateBuilder.createNetworkSelectorItem( - blockchain = Blockchain.fromNetworkId(token.network.id) - ?: Blockchain.Unknown, - ), - ), - tokenNameInputField = state.form.tokenNameInputField.copy( - value = token.name, - isEnabled = false, - ), - tokenSymbolInputField = state.form.tokenSymbolInputField.copy( - value = token.symbol, - isEnabled = false, - ), - decimalsInputField = state.form.decimalsInputField.copy( - value = token.network.decimalCount, - isEnabled = false, - ), - ), - ) - } - } - .onFailure { - foundToken = null - uiState.update { state -> - state.copySealed( - form = state.form.copy( - contractAddressInputField = state.form.contractAddressInputField.copy( - isLoading = false, - ), - tokenNameInputField = state.form.tokenNameInputField.copy(isEnabled = true), - tokenSymbolInputField = state.form.tokenSymbolInputField.copy(isEnabled = true), - decimalsInputField = state.form.decimalsInputField.copy(isEnabled = true), - ), - ) - } - Timber.e(it) - } - - updateWarnings() - updateFloatingButton() - } - } - - private fun isDerivationPathSelected(): Boolean { - val blockchain = uiState.value.form.derivationPathSelectorField?.selectedItem?.blockchain - val selectorType = uiState.value.form.derivationPathSelectorField?.selectedItem?.type - - return blockchain != null && blockchain != Blockchain.Unknown || - selectorType == DerivationPathSelectorType.CUSTOM && - !uiState.value.warnings.contains(AddCustomTokenWarning.WrongDerivationPath) - } - - private fun updateWarnings() { - uiState.update { state -> - state.copySealed( - warnings = buildSet { - when (getCustomTokenType()) { - CustomTokenType.TOKEN -> { - addAll(getTokenWarningSet()) - } - - CustomTokenType.BLOCKCHAIN -> { - if (isCustomTokenAlreadyAdded()) add(AddCustomTokenWarning.TokenAlreadyAdded) - if (isDerivationPathSelected()) add(AddCustomTokenWarning.PotentialScamToken) - } - } - }, - ) - } - } - - private fun getCustomTokenType(): CustomTokenType { - return if (isAnyTokenFieldsFilled() || isAllTokenFieldsFilled()) { - CustomTokenType.TOKEN - } else { - CustomTokenType.BLOCKCHAIN - } - } - - private fun isAnyTokenFieldsFilled(): Boolean { - return with(uiState.value.form) { - contractAddressInputField.value.isNotEmpty() || tokenNameInputField.value.isNotEmpty() || - tokenSymbolInputField.value.isNotEmpty() || decimalsInputField.value.isNotEmpty() - } - } - - private fun isAllTokenFieldsFilled(): Boolean { - return with(uiState.value.form) { - contractAddressInputField.value.isNotEmpty() && tokenNameInputField.value.isNotEmpty() && - tokenSymbolInputField.value.isNotEmpty() && decimalsInputField.value.isNotEmpty() - } - } - - private fun getTokenWarningSet(): Set { - val networkSelectorValue = uiState.value.form.networkSelectorField.selectedItem.blockchain - - val isContractAddressFieldEmpty = ContractAddressValidator.validate( - address = uiState.value.form.contractAddressInputField.value, - blockchain = networkSelectorValue, - ).let { - it is ContractAddressValidatorResult.Error && it.type == AddCustomTokenError.FIELD_IS_EMPTY - } - - val isSupportedToken = if (!isNetworkSelected()) { - true - } else { - getSelectedWalletSyncUseCase().fold( - ifLeft = { false }, - ifRight = { - it.scanResponse.card.canHandleToken( - blockchain = networkSelectorValue, - cardTypesResolver = it.scanResponse.cardTypesResolver, - ) - }, - ) - } - - return buildSet { - if (!isSupportedToken && !isContractAddressFieldEmpty) { - add(AddCustomTokenWarning.UnsupportedToken(networkSelectorValue.getNetworkName())) - } - if (isCustomTokenAlreadyAdded()) { - add(AddCustomTokenWarning.TokenAlreadyAdded) - } - if (foundToken == null && isAnyTokenFieldsFilled() || foundToken?.isActive == false) { - add(AddCustomTokenWarning.PotentialScamToken) - } - } - } - - private fun isNetworkSelected(): Boolean { - return uiState.value.form.networkSelectorField.selectedItem.blockchain != Blockchain.Unknown - } - - private fun updateFloatingButton() { - uiState.update { state -> - updateStateWithDerivationError(state) - } - if (isCustomTokenAlreadyAdded()) { - uiState.update { state -> - state.copySealed( - warnings = state.warnings + AddCustomTokenWarning.TokenAlreadyAdded, - floatingButton = state.floatingButton.copy(isEnabled = false), - ) - } - return - } - - uiState.update { state -> - val isCorrectDerivationInput = !state.warnings.contains(AddCustomTokenWarning.WrongDerivationPath) - val updatedState = when { - isAllTokenFieldsFilled() && isNetworkSelected() -> { - val networkSelectorValue = state.form.networkSelectorField.selectedItem.blockchain - val error = ContractAddressValidator.validate( - address = state.form.contractAddressInputField.value, - blockchain = networkSelectorValue, - ) - - val isSupportedToken = getSelectedWalletSyncUseCase().fold( - ifLeft = { false }, - ifRight = { - it.scanResponse.card.canHandleToken( - blockchain = networkSelectorValue, - cardTypesResolver = it.scanResponse.cardTypesResolver, - ) - }, - ) - - state.copySealed( - floatingButton = state.floatingButton.copy( - isEnabled = error is ContractAddressValidatorResult.Success && - isSupportedToken && isCorrectDerivationInput, - ), - ) - } - isAnyTokenFieldsFilled() -> { - state.copySealed(floatingButton = state.floatingButton.copy(isEnabled = false)) - } - else -> { - state.copySealed( - floatingButton = state.floatingButton.copy( - isEnabled = if (isNetworkSelected()) { - !isBlockchainAlreadyAdded() && isCorrectDerivationInput - } else { - false - }, - ), - ) - } - } - - updatedState.copySealed( - warnings = updatedState.warnings - AddCustomTokenWarning.TokenAlreadyAdded, - ) - } - } - - private fun updateStateWithDerivationError(uiState: AddCustomTokenStateHolder): AddCustomTokenStateHolder { - val updatedWarnings = if (isWrongDerivationPathEntered( - derivationPathSelectorType = uiState.form.derivationPathSelectorField?.selectedItem?.type, - derivationPath = getDerivationPath(), - ) - ) { - uiState.warnings + AddCustomTokenWarning.WrongDerivationPath - } else { - uiState.warnings - AddCustomTokenWarning.WrongDerivationPath - } - return uiState.copySealed( - warnings = updatedWarnings, - ) - } - - private fun isWrongDerivationPathEntered( - derivationPathSelectorType: DerivationPathSelectorType?, - derivationPath: DerivationPath?, - ): Boolean { - return derivationPathSelectorType == DerivationPathSelectorType.CUSTOM && derivationPath == null - } - - private fun isCustomTokenAlreadyAdded(): Boolean { - return when (getCustomTokenType()) { - CustomTokenType.TOKEN -> isTokenAlreadyAdded() - CustomTokenType.BLOCKCHAIN -> isBlockchainAlreadyAdded() - } - } - - private fun isTokenAlreadyAdded(): Boolean { - val networkSelectorValue = uiState.value.form.networkSelectorField.selectedItem.blockchain - val networkId = Blockchain.fromNetworkId(networkSelectorValue.toNetworkId())?.id - val contractAddress = convertTokenAddress( - blockchain = networkSelectorValue, - address = uiState.value.form.contractAddressInputField.value, - ) ?: return false // invalid address can't be "already added" - - return currentCryptoCurrencies - .filterIsInstance() - .any { token -> - val sameId = if (!token.isCustom) { - // todo after move foundToken to CryptoCurrency model, use only id - foundToken?.id == token.id.rawCurrencyId - } else { - true - } - - val sameAddress = contractAddress.equals(token.contractAddress, ignoreCase = true) - val sameBlockchain = networkId == token.network.id.value - val isSameDerivationPath = getDerivationPath()?.rawPath == token.network.derivationPath.value - - sameId && sameAddress && sameBlockchain && isSameDerivationPath - } - } - - private fun isBlockchainAlreadyAdded(): Boolean { - return currentCryptoCurrencies - .filterIsInstance() - .any { coin -> - coin.network.id.value == uiState.value.form.networkSelectorField.selectedItem.blockchain.id && - coin.network.derivationPath.value == getDerivationPath()?.rawPath - } - } - - private fun handleContractAddressErrorValidation(type: AddCustomTokenError) { - when { - isNetworkSelected() && type == AddCustomTokenError.INVALID_CONTRACT_ADDRESS -> { - val isAnotherTokenFieldsFilled = isAnyTokenFieldsFilled() - uiState.update { state -> - state.copySealed( - form = state.form.copy( - contractAddressInputField = state.form.contractAddressInputField.copy( - isError = true, - error = TextReference.Res( - id = R.string.custom_token_creation_error_invalid_contract_address, - ), - ), - tokenNameInputField = state.form.tokenNameInputField.copy( - isEnabled = isAnotherTokenFieldsFilled, - ), - tokenSymbolInputField = state.form.tokenSymbolInputField.copy( - isEnabled = isAnotherTokenFieldsFilled, - ), - decimalsInputField = state.form.decimalsInputField.copy( - isEnabled = isAnotherTokenFieldsFilled, - ), - ), - ) - } - } - - !isNetworkSelected() || type == AddCustomTokenError.FIELD_IS_EMPTY -> { - uiState.update { state -> - state.copySealed( - form = state.form.copy( - contractAddressInputField = state.form.contractAddressInputField.copy(isError = false), - tokenNameInputField = state.form.tokenNameInputField.copy(value = "", isEnabled = false), - tokenSymbolInputField = state.form.tokenSymbolInputField.copy( - value = "", - isEnabled = false, - ), - decimalsInputField = state.form.decimalsInputField.copy(value = "", isEnabled = false), - ), - ) - } - } - - else -> Unit - } - } - - private fun getDerivationPath(): DerivationPath? { - return when (uiState.value.form.derivationPathSelectorField?.selectedItem?.type) { - DerivationPathSelectorType.CUSTOM -> - createDerivationPathOrNull(uiState.value.form.derivationPathInputField?.value ?: "") - else -> - getDerivationPathForBlockchain(uiState.value.form.derivationPathSelectorField?.selectedItem?.blockchain) - } - } - - private fun createDerivationPathOrNull(rawPath: String): DerivationPath? { - return try { - DerivationPath(rawPath) - } catch (error: Throwable) { - null - } - } - - private fun getDerivationPathForBlockchain(blockchain: Blockchain?): DerivationPath? { - if (blockchain == null) return null - - val derivationStyle = getSelectedWalletSyncUseCase().fold( - ifLeft = { null }, - ifRight = { - it.scanResponse.derivationStyleProvider.getDerivationStyle() - }, - ) - - val derivationNetwork = if (blockchain == Blockchain.Unknown) { - uiState.value.form.networkSelectorField.selectedItem.blockchain - } else { - blockchain - } - return derivationNetwork.derivationPath(derivationStyle) - } - - private fun getSupportBlockchainType(blockchain: Blockchain): SupportBlockchainType { - return getSelectedWalletSyncUseCase().fold( - ifLeft = { SupportBlockchainType.UNABLE_TO_DETERMINE }, - ifRight = { - val canHandleBlockchain = it.scanResponse.card.canHandleBlockchain( - blockchain = blockchain, - cardTypesResolver = it.scanResponse.cardTypesResolver, - ) - if (canHandleBlockchain) { - SupportBlockchainType.SUPPORTED - } else { - SupportBlockchainType.UNSUPPORTED - } - }, - ) - } - - private inner class ActionsHandler(private val featureRouter: CustomTokenRouter) { - - fun onBackButtonClick() { - viewModelScope.launch(dispatchers.main) { - // need delay before close, cause crashed in compose PopUpMenu as - delay(timeMillis = 100) - featureRouter.popBackStack() - } - } - - fun onContactAddressValueChange(enteredValue: String) { - uiState.update { state -> - state.copySealed( - form = state.form.copy( - contractAddressInputField = state.form.contractAddressInputField.copy(value = enteredValue), - ), - ) - } - - val selectedNetwork = uiState.value.form.networkSelectorField.selectedItem.blockchain - val validatorResult = ContractAddressValidator.validate( - address = enteredValue, - blockchain = selectedNetwork, - ) - - when (validatorResult) { - is ContractAddressValidatorResult.Success -> { - uiState.update { state -> - state.copySealed( - form = state.form.copy( - contractAddressInputField = state.form.contractAddressInputField.copy( - isError = false, - isLoading = true, - ), - ), - ) - } - updateForm(address = enteredValue, selectedNetwork = selectedNetwork) - } - - is ContractAddressValidatorResult.Error -> { - handleContractAddressErrorValidation(type = validatorResult.type) - updateWarnings() - updateFloatingButton() - } - } - } - - fun onNetworkSelectorItemClick(index: Int) { - val state = uiState.updateAndGet { state -> - val selectedItem = requireNotNull(state.form.networkSelectorField.items.getOrNull(index)) - state.copySealed( - form = state.form.copy( - networkSelectorField = state.form.networkSelectorField.copy( - selectedItem = selectedItem, - ), - showTokenFields = selectedItem.blockchain.canHandleTokens() && - // workaround cause in Terra we support only 1 token - selectedItem.blockchain != Blockchain.TerraV1, - ), - ) - } - - onContactAddressValueChange(state.form.contractAddressInputField.value) - } - - fun onTokenNameValueChange(enteredValue: String) { - uiState.update { state -> - state.copySealed( - form = state.form.copy( - tokenNameInputField = state.form.tokenNameInputField.copy(value = enteredValue), - ), - ) - } - - updateFloatingButton() - } - - fun onTokenSymbolValueChange(enteredValue: String) { - uiState.update { state -> - state.copySealed( - form = state.form.copy( - tokenSymbolInputField = state.form.tokenSymbolInputField.copy(value = enteredValue), - ), - ) - } - updateFloatingButton() - } - - fun onDecimalsValueChange(enteredValue: String) { - uiState.update { state -> - state.copySealed( - form = state.form.copy( - decimalsInputField = state.form.decimalsInputField.copy(value = enteredValue), - ), - ) - } - updateFloatingButton() - } - - fun onDerivationPathSelectorItemClick(index: Int) { - uiState.update { state -> - val derivationSelector = requireNotNull(state.form.derivationPathSelectorField) - val selected = requireNotNull(derivationSelector.items.getOrNull(index)) - val derivationInputField = requireNotNull(state.form.derivationPathInputField) - - state.copySealed( - form = state.form.copy( - derivationPathSelectorField = derivationSelector.copy( - selectedItem = selected, - ), - derivationPathInputField = derivationInputField.copy( - showField = selected.type == DerivationPathSelectorType.CUSTOM, - ), - ), - ) - } - - updateFloatingButton() - } - - fun onDerivationPathValueChange(enteredValue: String) { - uiState.update { state -> - state.copySealed( - form = state.form.copy( - derivationPathInputField = state.form.derivationPathInputField?.copy(value = enteredValue), - ), - ) - } - updateFloatingButton() - } - - fun onAddCustomTokenClick() { - if (!isNetworkSelected()) return - val blockchain = uiState.value.form.networkSelectorField.selectedItem.blockchain - when (getSupportBlockchainType(blockchain)) { - SupportBlockchainType.SUPPORTED -> { - /* no-op */ - } - SupportBlockchainType.UNSUPPORTED -> { - featureRouter.openUnsupportedNetworkAlert(blockchain) - return - } - SupportBlockchainType.UNABLE_TO_DETERMINE -> { - featureRouter.showGenericErrorAlertAndPopBack() - return - } - } - - val currency = when (getCustomTokenType()) { - CustomTokenType.TOKEN -> { - val contractAddress = convertTokenAddress( - blockchain = blockchain, - address = foundToken?.network?.contractAddress ?: uiState.value.form.contractAddressInputField - .value, - ) ?: error("Contract address is invalid") // impossible to add a token with invalid address - - CustomCurrency.CustomToken( - token = Token( - name = uiState.value.form.tokenNameInputField.value, - symbol = uiState.value.form.tokenSymbolInputField.value, - contractAddress = contractAddress, - decimals = requireNotNull(uiState.value.form.decimalsInputField.value.toIntOrNull()), - id = foundToken?.id, - ), - network = blockchain, - derivationPath = getDerivationPath(), - ) - } - CustomTokenType.BLOCKCHAIN -> { - CustomCurrency.CustomBlockchain( - network = blockchain, - derivationPath = getDerivationPath(), - ) - } - } - - analyticsSender.sendWhenAddTokenButtonClicked(currency) - - viewModelScope.launch { - uiState.update { state -> - state.copySealed( - floatingButton = state.floatingButton.copy( - isEnabled = false, - showProgress = true, - ), - ) - } - - val result = featureInteractor.saveToken(currency) - - uiState.update { state -> - state.copySealed( - floatingButton = state.floatingButton.copy( - isEnabled = true, - showProgress = false, - ), - ) - } - - result - .onSuccess { featureRouter.openWalletScreen() } - .onFailure { Timber.e(it, "Unable to save custom token") } - } - } - } - - /** Convert [address] to single address for specific [blockchain] or return null if invalid */ - private fun convertTokenAddress(blockchain: Blockchain, address: String): String? { - return runCatching { - when (blockchain) { - Blockchain.Hedera, Blockchain.HederaTestnet -> hederaAddressConverter.convertToTokenId(address) - Blockchain.Cardano -> { - // TODO: [REDACTED_JIRA] - cardanoTokenAddressConverter.convertToFingerprint( - address = address, - symbol = uiState.value.form.tokenSymbolInputField.value, - ) - } - else -> address - } - } - .getOrNull() - } - - private inner class TestActionsHandler { - - fun onClearAddressButtonClick() { - uiState.update { state -> - state.copySealed( - form = state.form.copy( - contractAddressInputField = state.form.contractAddressInputField.copy( - value = "", - isLoading = false, - isError = false, - error = null, - ), - ), - ) - } - } - - fun onResetButtonClick() { - uiState.update { state -> - with(state.form) { - state.copySealed( - form = state.form.copy( - contractAddressInputField = contractAddressInputField.copy( - value = "", - isLoading = false, - isError = false, - error = null, - ), - networkSelectorField = networkSelectorField.copy( - selectedItem = formStateBuilder.createNetworkSelectorItem( - blockchain = Blockchain.Unknown, - ), - ), - tokenNameInputField = tokenNameInputField.copy(value = "", isEnabled = false), - tokenSymbolInputField = tokenSymbolInputField.copy(value = "", isEnabled = false), - decimalsInputField = decimalsInputField.copy(value = "", isEnabled = false), - derivationPathSelectorField = derivationPathSelectorField?.copy( - isEnabled = true, - selectedItem = formStateBuilder.createDerivationPathSelectorAdditionalItem( - blockchain = Blockchain.Unknown, - type = DerivationPathSelectorType.DEFAULT, - derivationPath = "", - ), - ), - ), - ) - } - } - } - } - - private companion object { - val COMMON_TOKENS = persistentListOf( - TestTokenItem(name = "USDC on ETH", address = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"), - TestTokenItem(name = "BUSD on ETH", address = "0x4fabb145d64652a948d72533023f6e7a623c7c53"), - TestTokenItem(name = "ETH on AVALANCHE", address = "0xf20d962a6c8f70c731bd838a3a388d7d48fa6e15"), - TestTokenItem(name = "USDC on ETH (invalid - cut address)", address = "0xa0b86991c6218b36c1d1"), - TestTokenItem(name = "Custom EVM", address = "0x1111111111111111112111111111111111111113"), - TestTokenItem( - name = "Supported by several networks", - address = "0xa1faa113cbe53436df28ff0aee54275c13b40975", - ), - TestTokenItem(name = "Invalid", address = "!@#_ _-%%^&&*((){P P2iOWsdfFQLA"), - ) - - val SOLANA_TOKENS = persistentListOf( - TestTokenItem(name = "USDT (full)", address = "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB"), - TestTokenItem( - name = "USDT (valid - 2/3 of address)", - address = "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8Ben", - ), - TestTokenItem(name = "USDT (invalid - 1/3 of address)", address = "Es9vMFrzaCERmJ"), - TestTokenItem(name = "ETH (full)", address = "2FPyTwcZLUg1MDrwsyoP4D6s1tM7hAkHYRjkNb5w6Pxk"), - ) - const val DERIVATION_PATH_PLACEHOLDER = "m/44'/0'/0'/0/0" - const val DECIMALS_PLACEHOLDER = "8" - const val CONTRACT_ADDRESS_PLACEHOLDER = "0x0000000000000000000000000000000000000000" - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt index 10bb1b383d..53844799aa 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt @@ -1,7 +1,6 @@ package com.tangem.tap.features.details.redux import androidx.lifecycle.LifecycleCoroutineScope -import com.tangem.core.ui.extensions.TextReference import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.apptheme.model.AppThemeMode import com.tangem.domain.models.scan.ScanResponse @@ -14,15 +13,6 @@ sealed class DetailsAction : Action { val shouldSaveUserWallets: Boolean, ) : DetailsAction() - data object ScanAndSaveUserWallet : DetailsAction() { - - data object Success : DetailsAction() - - data class Error(val error: TextReference?) : DetailsAction() - } - - data object DismissError : DetailsAction() - sealed class AppSettings : DetailsAction() { data class SwitchPrivacySetting( val enable: Boolean, diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt index 40f3d03a11..713ffe5c9a 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt @@ -2,36 +2,24 @@ package com.tangem.tap.features.details.redux import androidx.lifecycle.LifecycleCoroutineScope import com.tangem.common.CompletionResult -import com.tangem.common.core.TangemError -import com.tangem.common.core.TangemSdkError import com.tangem.common.doOnFailure import com.tangem.common.doOnSuccess import com.tangem.common.routing.AppRoute -import com.tangem.common.routing.AppRouter -import com.tangem.common.routing.utils.popTo import com.tangem.core.analytics.Analytics -import com.tangem.core.ui.extensions.TextReference -import com.tangem.core.ui.extensions.resourceReference -import com.tangem.core.ui.extensions.stringReference import com.tangem.domain.apptheme.model.AppThemeMode import com.tangem.domain.models.scan.ScanResponse -import com.tangem.domain.wallets.builder.UserWalletBuilder -import com.tangem.domain.wallets.legacy.UserWalletsListError -import com.tangem.domain.wallets.models.UserWallet import com.tangem.tap.* import com.tangem.tap.common.analytics.events.AnalyticsParam import com.tangem.tap.common.analytics.events.Settings import com.tangem.tap.common.extensions.dispatchNavigationAction import com.tangem.tap.common.extensions.dispatchWithMain import com.tangem.tap.common.extensions.inject -import com.tangem.tap.common.extensions.onUserWalletSelected import com.tangem.tap.common.redux.AppState import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.features.demo.DemoHelper import com.tangem.tap.proxy.redux.DaggerGraphState import com.tangem.utils.coroutines.JobHolder import com.tangem.utils.coroutines.saveIn -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flow @@ -41,7 +29,6 @@ import kotlinx.coroutines.launch import org.rekotlin.Action import org.rekotlin.Middleware import timber.log.Timber -import com.tangem.core.analytics.models.AnalyticsParam as CoreAnalyticsParam class DetailsMiddleware { private val appSettingsMiddleware = AppSettingsMiddleware() @@ -62,7 +49,6 @@ class DetailsMiddleware { private fun handleAction(state: DetailsState, action: Action) { when (action) { is DetailsAction.AppSettings -> appSettingsMiddleware.handle(state, action) - is DetailsAction.ScanAndSaveUserWallet -> scanAndSaveUserWallet() } } @@ -278,95 +264,4 @@ class DetailsMiddleware { } } } - - private fun scanAndSaveUserWallet() = scope.launch(Dispatchers.IO) { - val cardSdkConfigRepository = store.inject(DaggerGraphState::cardSdkConfigRepository) - - val prevUseBiometricsForAccessCode = cardSdkConfigRepository.isBiometricsRequestPolicy() - - // Update access code policy for access code saving when a card was scanned - val shouldSaveAccessCodes = store.inject(DaggerGraphState::settingsRepository).shouldSaveAccessCodes() - cardSdkConfigRepository.setAccessCodeRequestPolicy(isBiometricsRequestPolicy = shouldSaveAccessCodes) - - store.inject(DaggerGraphState::scanCardProcessor).scan( - analyticsSource = CoreAnalyticsParam.ScreensSources.Settings, - onWalletNotCreated = { - // No need to rollback policy, continue with the policy set before the card scan - store.dispatchWithMain(DetailsAction.ScanAndSaveUserWallet.Success) - }, - disclaimerWillShow = { - store.dispatchNavigationAction(AppRouter::pop) - }, - onSuccess = { scanResponse -> - createUserWallet(scanResponse) - .doOnSuccess { - saveUserWalletAndPopBackToWalletScreen( - userWallet = it, - prevUseBiometricsForAccessCode = prevUseBiometricsForAccessCode, - ) - } - .doOnFailure { error -> - Timber.e(error, "Unable to create user wallet") - handleError(error = error, prevUseBiometricsForAccessCode = prevUseBiometricsForAccessCode) - } - }, - onFailure = { error -> - Timber.e(error, "Unable to scan card") - handleError(error = error, prevUseBiometricsForAccessCode = prevUseBiometricsForAccessCode) - }, - ) - } - - private suspend fun createUserWallet(scanResponse: ScanResponse): CompletionResult { - val walletNameGenerateUseCase = store.inject(DaggerGraphState::generateWalletNameUseCase) - val userWallet = UserWalletBuilder(scanResponse, walletNameGenerateUseCase).build() - - return if (userWallet != null) { - CompletionResult.Success(userWallet) - } else { - CompletionResult.Failure(TangemSdkError.WalletIsNotCreated()) - } - } - - private suspend fun saveUserWalletAndPopBackToWalletScreen( - userWallet: UserWallet, - prevUseBiometricsForAccessCode: Boolean, - ) { - val userWalletsListManager = store.inject(DaggerGraphState::generalUserWalletsListManager) - - userWalletsListManager.save(userWallet) - .doOnSuccess { - store.onUserWalletSelected(userWallet) - - store.dispatchWithMain(DetailsAction.ScanAndSaveUserWallet.Success) - store.dispatchNavigationAction { popTo() } - } - .doOnFailure { error -> - if (error is UserWalletsListError.WalletAlreadySaved) { - userWalletsListManager.select(userWallet.walletId) - store.onUserWalletSelected(userWallet) - - store.dispatchWithMain(DetailsAction.ScanAndSaveUserWallet.Success) - store.dispatchNavigationAction { popTo() } - } else { - Timber.e(error, "Unable to create user wallet") - handleError(error, prevUseBiometricsForAccessCode) - } - } - } - - private suspend fun handleError(error: TangemError, prevUseBiometricsForAccessCode: Boolean) { - val cardSdkConfigRepository = store.inject(DaggerGraphState::cardSdkConfigRepository) - - // Rollback policy if card saving was failed - cardSdkConfigRepository.setAccessCodeRequestPolicy(prevUseBiometricsForAccessCode) - - store.dispatchWithMain(DetailsAction.ScanAndSaveUserWallet.Error(error.toTextReference())) - } - - private fun TangemError.toTextReference(): TextReference? { - if (silent) return null - - return messageResId?.let(::resourceReference) ?: stringReference(customMessage) - } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt index dbb450b426..bfe8750b2a 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt @@ -1,7 +1,6 @@ package com.tangem.tap.features.details.redux import com.tangem.domain.apptheme.model.AppThemeMode -import com.tangem.domain.models.scan.CardDTO import com.tangem.tap.common.extensions.inject import com.tangem.tap.common.redux.AppState import com.tangem.tap.proxy.redux.DaggerGraphState @@ -21,7 +20,7 @@ private fun internalReduce(action: Action, state: AppState): DetailsState { val detailsState = state.detailsState return when (action) { is DetailsAction.PrepareScreen -> { - handlePrepareScreen(action, state) + handlePrepareScreen(action) } is DetailsAction.AppSettings -> { handlePrivacyAction(action, detailsState) @@ -31,26 +30,12 @@ private fun internalReduce(action: Action, state: AppState): DetailsState { selectedAppCurrency = action.currency, ), ) - is DetailsAction.ScanAndSaveUserWallet -> detailsState.copy( - isScanningInProgress = true, - ) - is DetailsAction.ScanAndSaveUserWallet.Error -> detailsState.copy( - isScanningInProgress = false, - error = action.error, - ) - is DetailsAction.ScanAndSaveUserWallet.Success -> detailsState.copy( - isScanningInProgress = false, - ) - is DetailsAction.DismissError -> detailsState.copy( - error = null, - ) } } -private fun handlePrepareScreen(action: DetailsAction.PrepareScreen, state: AppState): DetailsState { +private fun handlePrepareScreen(action: DetailsAction.PrepareScreen): DetailsState { return DetailsState( scanResponse = action.scanResponse, - createBackupAllowed = action.scanResponse.card.backupStatus == CardDTO.BackupStatus.NoBackup, appSettingsState = AppSettingsState( isBiometricsAvailable = runBlocking { tangemSdkManager.checkCanUseBiometry() diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsState.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsState.kt index c35d0c8d83..bc7f17a7b6 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsState.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsState.kt @@ -1,27 +1,16 @@ package com.tangem.tap.features.details.redux -import com.tangem.core.ui.extensions.TextReference import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.apptheme.model.AppThemeMode import com.tangem.domain.models.scan.ScanResponse import org.rekotlin.StateType data class DetailsState( + @Deprecated("Delete after onboarding refactoring") val scanResponse: ScanResponse? = null, - val privacyPolicyUrl: String? = null, - val createBackupAllowed: Boolean = false, - val isScanningInProgress: Boolean = false, - val error: TextReference? = null, val appSettingsState: AppSettingsState = AppSettingsState(), ) : StateType -sealed class ResetCardDialog { - data object StartResetDialog : ResetCardDialog() - data object ContinueResetDialog : ResetCardDialog() - data object InterruptedResetDialog : ResetCardDialog() - data object CompletedResetDialog : ResetCardDialog() -} - data class AppSettingsState( val saveWallets: Boolean = false, val saveAccessCodes: Boolean = false, diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsViewModel.kt b/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsViewModel.kt index 34a693dbb4..55d16d7d80 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsViewModel.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsViewModel.kt @@ -11,7 +11,6 @@ import com.tangem.domain.balancehiding.repositories.BalanceHidingRepository import com.tangem.domain.settings.CanUseBiometryUseCase import com.tangem.domain.settings.repositories.SettingsRepository import com.tangem.domain.wallets.repository.WalletsRepository -import com.tangem.features.details.DetailsFeatureToggles import com.tangem.tap.common.analytics.events.AnalyticsParam import com.tangem.tap.common.analytics.events.Settings import com.tangem.tap.common.extensions.dispatchNavigationAction @@ -45,7 +44,6 @@ internal class AppSettingsViewModel @Inject constructor( private val appThemeModeRepository: AppThemeModeRepository, private val settingsRepository: SettingsRepository, private val appSettingsItemsAnalyticsSender: AppSettingsItemsAnalyticsSender, - private val detailsFeatureToggles: DetailsFeatureToggles, ) : ViewModel(), StoreSubscriber, DefaultLifecycleObserver { @@ -62,9 +60,7 @@ internal class AppSettingsViewModel @Inject constructor( init { bootstrapAppCurrencyUpdates() - if (detailsFeatureToggles.isRedesignEnabled) { - bootstrapBiometricsUpdates() - } + bootstrapBiometricsUpdates() subscribeToStoreChanges() sendItemsAnalytics() diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsFragment.kt b/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsFragment.kt deleted file mode 100644 index 5b41307402..0000000000 --- a/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsFragment.kt +++ /dev/null @@ -1,71 +0,0 @@ -package com.tangem.tap.features.details.ui.details - -import android.os.Bundle -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import com.tangem.common.routing.AppRouter -import com.tangem.core.analytics.Analytics -import com.tangem.core.ui.UiDependencies -import com.tangem.core.ui.screen.ComposeFragment -import com.tangem.domain.wallets.legacy.UserWalletsListManager -import com.tangem.domain.wallets.repository.WalletsRepository -import com.tangem.tap.common.analytics.events.Settings -import com.tangem.tap.common.extensions.dispatchNavigationAction -import com.tangem.tap.features.details.redux.DetailsState -import com.tangem.tap.store -import dagger.hilt.android.AndroidEntryPoint -import org.rekotlin.StoreSubscriber -import javax.inject.Inject - -@AndroidEntryPoint -internal class DetailsFragment : ComposeFragment(), StoreSubscriber { - - @Inject - override lateinit var uiDependencies: UiDependencies - - @Inject - lateinit var walletsRepository: WalletsRepository - - @Inject - lateinit var userWalletsListManager: UserWalletsListManager - - private lateinit var detailsViewModel: DetailsViewModel - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - detailsViewModel = DetailsViewModel( - store = store, - walletsRepository = walletsRepository, - userWalletsListManager = userWalletsListManager, - ) - Analytics.send(Settings.ScreenOpened()) - } - - @Composable - override fun ScreenContent(modifier: Modifier) { - DetailsScreen( - modifier = modifier, - state = detailsViewModel.detailsScreenState.value, - onBackClick = { store.dispatchNavigationAction(AppRouter::pop) }, - ) - } - - override fun onStart() { - super.onStart() - store.subscribe(this) { state -> - state.skipRepeats { oldState, newState -> - oldState.detailsState == newState.detailsState - }.select { it.detailsState } - } - } - - override fun onStop() { - super.onStop() - store.unsubscribe(this) - } - - override fun newState(state: DetailsState) { - if (activity == null || view == null) return - detailsViewModel.detailsScreenState.value = detailsViewModel.updateState(state) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsScreen.kt b/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsScreen.kt deleted file mode 100644 index f31718287c..0000000000 --- a/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsScreen.kt +++ /dev/null @@ -1,288 +0,0 @@ -package com.tangem.tap.features.details.ui.details - -import android.content.res.Configuration -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyRow -import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.verticalScroll -import androidx.compose.material.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.tooling.preview.PreviewParameter -import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider -import com.tangem.core.ui.components.SpacerH -import com.tangem.core.ui.components.SpacerHMax -import com.tangem.core.ui.event.EventEffect -import com.tangem.core.ui.event.StateEvent -import com.tangem.core.ui.event.consumedEvent -import com.tangem.core.ui.extensions.TextReference -import com.tangem.core.ui.extensions.resolveReference -import com.tangem.core.ui.res.TangemColorPalette -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.core.ui.res.TangemTheme -import com.tangem.tap.features.details.ui.common.ScreenTitle -import com.tangem.tap.features.details.ui.common.SettingsScreensScaffold -import com.tangem.wallet.R -import kotlinx.collections.immutable.toImmutableList - -@Composable -internal fun DetailsScreen(state: DetailsScreenState, onBackClick: () -> Unit, modifier: Modifier = Modifier) { - val snackbarHostState = remember { SnackbarHostState() } - - SettingsScreensScaffold( - modifier = modifier, - snackbarHostState = snackbarHostState, - content = { Content(state = state) }, - onBackClick = onBackClick, - ) - - ShowSnackbarIfNeeded( - snackbarHostState = snackbarHostState, - messageEvent = state.showSnackbar, - ) -} - -@Composable -private fun Content(state: DetailsScreenState, modifier: Modifier = Modifier) { - Box(modifier = modifier) { - Column( - modifier = Modifier - .fillMaxSize() - .verticalScroll(rememberScrollState()), - ) { - ScreenTitle(titleRes = R.string.details_title) - SpacerH(height = TangemTheme.dimens.spacing36) - SettingsItems( - items = state.elements, - ) - SpacerHMax() - TangemSocialAccounts( - links = state.tangemLinks, - onSocialNetworkClick = state.onSocialNetworkClick, - ) - SpacerH(height = TangemTheme.dimens.spacing12) - TangemAppVersion( - appNameRes = state.appNameRes, - version = state.tangemVersion, - ) - SpacerH(height = TangemTheme.dimens.spacing16) - } - } -} - -@Composable -private fun SettingsItems(items: List) { - items.forEach { item -> - if (item.isLarge) { - LargeDetailsItem(item) - } else { - DetailsItem(item) - } - } -} - -@Composable -private fun LargeDetailsItem(item: SettingsItem) { - Row( - modifier = Modifier - .clickable(onClick = item.onClick) - .padding(horizontal = TangemTheme.dimens.spacing20) - .heightIn(min = TangemTheme.dimens.size84) - .fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing20), - verticalAlignment = Alignment.CenterVertically, - ) { - if (item.showProgress) { - CircularProgressIndicator( - modifier = Modifier.size(TangemTheme.dimens.size24), - color = TangemTheme.colors.icon.informative, - ) - } else { - Icon( - modifier = Modifier.size(TangemTheme.dimens.size24), - painter = painterResource(id = item.iconResId), - contentDescription = item.title.resolveReference(), - tint = TangemColorPalette.Azure, - ) - } - Column( - modifier = Modifier.heightIn(min = TangemTheme.dimens.size56), - horizontalAlignment = Alignment.Start, - verticalArrangement = Arrangement.spacedBy( - space = TangemTheme.dimens.spacing4, - alignment = Alignment.CenterVertically, - ), - ) { - Text( - text = item.title.resolveReference(), - style = TangemTheme.typography.h3, - color = TangemTheme.colors.text.primary1, - ) - - if (item.subtitle != null) { - Text( - text = item.subtitle.resolveReference(), - style = TangemTheme.typography.body1, - color = TangemTheme.colors.text.secondary, - ) - } - } - } -} - -@Composable -private fun DetailsItem(item: SettingsItem) { - Row( - modifier = Modifier - .clickable(enabled = !item.showProgress, onClick = item.onClick) - .padding(horizontal = TangemTheme.dimens.spacing20) - .heightIn(min = TangemTheme.dimens.size56) - .fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing20), - verticalAlignment = Alignment.CenterVertically, - ) { - if (item.showProgress) { - CircularProgressIndicator( - modifier = Modifier.size(TangemTheme.dimens.size24), - color = TangemTheme.colors.icon.informative, - ) - } else { - Icon( - modifier = Modifier.size(TangemTheme.dimens.size24), - painter = painterResource(id = item.iconResId), - contentDescription = item.title.resolveReference(), - tint = TangemTheme.colors.icon.secondary, - ) - } - - Column( - horizontalAlignment = Alignment.Start, - verticalArrangement = Arrangement.SpaceAround, - ) { - Text( - text = item.title.resolveReference(), - style = TangemTheme.typography.subtitle1, - color = TangemTheme.colors.text.primary1, - ) - - if (item.subtitle != null) { - Text( - text = item.subtitle.resolveReference(), - style = TangemTheme.typography.body2, - color = TangemTheme.colors.text.secondary, - ) - } - } - } -} - -@Composable -private fun TangemSocialAccounts(links: List, onSocialNetworkClick: (SocialNetworkLink) -> Unit) { - LazyRow( - verticalAlignment = Alignment.CenterVertically, - contentPadding = PaddingValues(horizontal = TangemTheme.dimens.spacing8), - ) { - items(links) { - val onClick = remember(it) { - { onSocialNetworkClick(it) } - } - - IconButton( - modifier = Modifier - .padding(horizontal = TangemTheme.dimens.spacing4) - .size(TangemTheme.dimens.size32), - onClick = onClick, - ) { - Icon( - modifier = Modifier.size(TangemTheme.dimens.size24), - painter = painterResource(id = it.network.iconRes), - tint = TangemTheme.colors.icon.informative, - contentDescription = null, - ) - } - } - } -} - -@Composable -private fun ShowSnackbarIfNeeded(snackbarHostState: SnackbarHostState, messageEvent: StateEvent) { - var message: TextReference? by remember { mutableStateOf(value = null) } - val resolvedMessage by rememberUpdatedState(newValue = message?.resolveReference()) - - LaunchedEffect(resolvedMessage) { - resolvedMessage?.let { - snackbarHostState.showSnackbar(it) - } - } - - EventEffect(messageEvent) { - message = it - } -} - -@Composable -private fun TangemAppVersion(appNameRes: Int, version: String, modifier: Modifier = Modifier) { - Text( - modifier = modifier.padding(horizontal = TangemTheme.dimens.spacing16), - text = "${stringResource(id = appNameRes)} $version", - style = TangemTheme.typography.caption2, - color = TangemTheme.colors.text.tertiary, - ) -} - -// region Preview -@Preview(showBackground = true, widthDp = 360, heightDp = 900) -@Preview(showBackground = true, widthDp = 360, heightDp = 900, uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun DetailsScreenPreview(@PreviewParameter(DetailsScreenStateProvider::class) param: DetailsScreenState) { - TangemThemePreview { - DetailsScreen(param, onBackClick = {}) - } -} - -private class DetailsScreenStateProvider : CollectionPreviewParameterProvider( - collection = buildList { - DetailsScreenState( - elements = buildList { - SettingsItem.WalletConnect({}).let(::add) - SettingsItem.AddWallet(showProgress = false, {}).let(::add) - SettingsItem.LinkMoreCards({}).let(::add) - SettingsItem.CardSettings({}).let(::add) - SettingsItem.AppSettings({}).let(::add) - // removed chat in task [REDACTED_TASK_KEY] - // SettingsItem.Chat({}).let(::add) - SettingsItem.SendFeedback({}).let(::add) - SettingsItem.ReferralProgram({}).let(::add) - SettingsItem.TermsOfService({}).let(::add) - }.toImmutableList(), - tangemLinks = TangemSocialAccounts.accountsEn, - tangemVersion = "Tangem 2.14.12 (343)", - showSnackbar = consumedEvent(), - onSocialNetworkClick = {}, - ).let(::add) - - DetailsScreenState( - elements = buildList { - SettingsItem.WalletConnect({}).let(::add) - SettingsItem.AddWallet(showProgress = true, {}).let(::add) - SettingsItem.CardSettings({}).let(::add) - SettingsItem.AppSettings({}).let(::add) - // removed chat in task [REDACTED_TASK_KEY] - // SettingsItem.Chat({}).let(::add) - SettingsItem.SendFeedback({}).let(::add) - SettingsItem.TermsOfService({}).let(::add) - }.toImmutableList(), - tangemLinks = TangemSocialAccounts.accountsRu, - tangemVersion = "Tangem 2.14.12 (343)", - showSnackbar = consumedEvent(), - onSocialNetworkClick = {}, - ).let(::add) - }, -) -// endregion Preview \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsScreenState.kt b/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsScreenState.kt deleted file mode 100644 index acafefe8e7..0000000000 --- a/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsScreenState.kt +++ /dev/null @@ -1,162 +0,0 @@ -package com.tangem.tap.features.details.ui.details - -import androidx.annotation.DrawableRes -import androidx.compose.runtime.Immutable -import com.tangem.core.ui.event.StateEvent -import com.tangem.core.ui.extensions.TextReference -import com.tangem.core.ui.extensions.resourceReference -import com.tangem.wallet.R -import kotlinx.collections.immutable.ImmutableList -import kotlinx.collections.immutable.persistentListOf - -@Immutable -internal data class DetailsScreenState( - val elements: ImmutableList, - val tangemLinks: ImmutableList, - val tangemVersion: String, - val showSnackbar: StateEvent, - val onSocialNetworkClick: (SocialNetworkLink) -> Unit, -) { - val appNameRes: Int = R.string.tangem_app_name -} - -@Immutable -internal sealed class SettingsItem( - @DrawableRes val iconResId: Int, - val title: TextReference, - val subtitle: TextReference? = null, - val isLarge: Boolean = false, -) { - - abstract val onClick: () -> Unit - - open val showProgress: Boolean = false - - data class WalletConnect( - override val onClick: () -> Unit, - ) : SettingsItem( - iconResId = R.drawable.ic_wallet_connect_24, - title = resourceReference(R.string.wallet_connect_title), - subtitle = resourceReference(R.string.wallet_connect_subtitle), - isLarge = true, - ) - - data class AddWallet( - override val showProgress: Boolean, - override val onClick: () -> Unit, - ) : SettingsItem( - iconResId = R.drawable.ic_plus_24, - title = resourceReference(R.string.user_wallet_list_add_button), - ) - - data class ScanWallet( - override val showProgress: Boolean, - override val onClick: () -> Unit, - ) : SettingsItem( - iconResId = R.drawable.ic_plus_24, - title = resourceReference(R.string.scan_card_settings_button), - ) - - data class LinkMoreCards( - override val onClick: () -> Unit, - ) : SettingsItem( - iconResId = R.drawable.ic_more_cards_24, - title = resourceReference(R.string.details_row_title_create_backup), - ) - - data class CardSettings( - override val onClick: () -> Unit, - ) : SettingsItem( - iconResId = R.drawable.ic_card_settings_24, - title = resourceReference(R.string.card_settings_title), - ) - - data class AppSettings( - override val onClick: () -> Unit, - ) : SettingsItem( - iconResId = R.drawable.ic_settings, - title = resourceReference(R.string.app_settings_title), - ) - - data class Chat( - override val onClick: () -> Unit, - ) : SettingsItem( - iconResId = R.drawable.ic_chat_24, - title = resourceReference(R.string.details_chat), - ) - - data class SendFeedback( - override val onClick: () -> Unit, - ) : SettingsItem( - iconResId = R.drawable.ic_comment_24, - title = resourceReference(R.string.details_row_title_contact_to_support), - ) - - data class ReferralProgram( - override val onClick: () -> Unit, - ) : SettingsItem( - iconResId = R.drawable.ic_add_friends_24, - title = resourceReference(R.string.details_referral_title), - ) - - data class TermsOfService( - override val onClick: () -> Unit, - ) : SettingsItem( - iconResId = R.drawable.ic_text_24, - title = resourceReference(R.string.disclaimer_title), - ) - - data class TesterMenu( - override val onClick: () -> Unit, - ) : SettingsItem( - iconResId = R.drawable.ic_alert_24, - title = resourceReference(R.string.tester_menu), - ) -} - -@Immutable -internal data class SocialNetworkLink( - val network: SocialNetwork, - val url: String, -) - -internal sealed class EventError { - object Empty : EventError() -} - -sealed class SocialNetwork(val id: String, val iconRes: Int) { - object Twitter : SocialNetwork("Twitter", R.drawable.ic_twitter_24) - object Telegram : SocialNetwork("Telegram", R.drawable.ic_telegram_24) - object Discord : SocialNetwork("Discord", R.drawable.ic_discord_24) - object Reddit : SocialNetwork("Reddit", R.drawable.ic_reddit_24) - object Instagram : SocialNetwork("Instagram", R.drawable.ic_instagram_24) - object GitHub : SocialNetwork("GitHub", R.drawable.ic_github_24) - object Facebook : SocialNetwork("Facebook", R.drawable.ic_facebook_24) - object LinkedIn : SocialNetwork("LinkedIn", R.drawable.ic_linkedin_24) - object YouTube : SocialNetwork("YouTube", R.drawable.ic_youtube_24) -} - -internal object TangemSocialAccounts { - val accountsEn: ImmutableList = persistentListOf( - SocialNetworkLink(SocialNetwork.Twitter, "https://x.com/tangem"), - SocialNetworkLink(SocialNetwork.Telegram, "https://t.me/tangem_chat"), - SocialNetworkLink(SocialNetwork.Discord, "https://discord.gg/tangem"), - SocialNetworkLink(SocialNetwork.Reddit, "https://www.reddit.com/r/Tangem/"), - SocialNetworkLink(SocialNetwork.Instagram, "https://www.instagram.com/tangemwallet"), - SocialNetworkLink(SocialNetwork.GitHub, "https://github.com/tangem"), - SocialNetworkLink(SocialNetwork.Facebook, "https://www.facebook.com/tangemwallet"), - SocialNetworkLink(SocialNetwork.LinkedIn, "https://www.linkedin.com/company/tangem"), - SocialNetworkLink(SocialNetwork.YouTube, "https://youtube.com/@tangem_official"), - ) - val accountsRu: ImmutableList = persistentListOf( - SocialNetworkLink(SocialNetwork.Twitter, "https://x.com/tangem"), - SocialNetworkLink(SocialNetwork.Telegram, "https://t.me/tangem_chat_ru"), - SocialNetworkLink(SocialNetwork.Discord, "https://discord.gg/tangem"), - SocialNetworkLink(SocialNetwork.Reddit, "https://www.reddit.com/r/Tangem/"), - SocialNetworkLink(SocialNetwork.Instagram, "https://www.instagram.com/tangemwallet"), - SocialNetworkLink(SocialNetwork.GitHub, "https://github.com/tangem"), - SocialNetworkLink(SocialNetwork.Facebook, "https://www.facebook.com/tangemwallet"), - SocialNetworkLink(SocialNetwork.LinkedIn, "https://www.linkedin.com/company/tangem"), - SocialNetworkLink(SocialNetwork.YouTube, "https://youtube.com/@tangem_official"), - ) -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsViewModel.kt b/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsViewModel.kt deleted file mode 100644 index d2c84a43db..0000000000 --- a/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsViewModel.kt +++ /dev/null @@ -1,215 +0,0 @@ -package com.tangem.tap.features.details.ui.details - -import androidx.compose.runtime.MutableState -import androidx.compose.runtime.mutableStateOf -import com.tangem.common.extensions.guard -import com.tangem.common.routing.AppRoute -import com.tangem.core.analytics.Analytics -import com.tangem.core.analytics.models.AnalyticsParam -import com.tangem.core.analytics.models.Basic - -import com.tangem.core.ui.event.StateEvent -import com.tangem.core.ui.event.consumedEvent -import com.tangem.core.ui.event.triggeredEvent -import com.tangem.core.ui.extensions.TextReference -import com.tangem.domain.common.util.cardTypesResolver -import com.tangem.domain.wallets.legacy.UserWalletsListManager -import com.tangem.domain.wallets.repository.WalletsRepository -import com.tangem.tap.common.analytics.events.Settings -import com.tangem.tap.common.extensions.* -import com.tangem.tap.common.feedback.FeedbackEmail -import com.tangem.tap.common.redux.AppState -import com.tangem.tap.common.redux.global.GlobalAction -import com.tangem.tap.features.details.redux.DetailsAction -import com.tangem.tap.features.details.redux.DetailsState -import com.tangem.tap.features.disclaimer.redux.DisclaimerAction -import com.tangem.tap.features.disclaimer.redux.DisclaimerSource -import com.tangem.tap.features.home.LocaleRegionProvider -import com.tangem.tap.features.home.RUSSIA_COUNTRY_CODE -import com.tangem.tap.scope -import com.tangem.wallet.BuildConfig -import kotlinx.collections.immutable.ImmutableList -import kotlinx.collections.immutable.persistentListOf -import kotlinx.collections.immutable.toImmutableList -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.flowOn -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import org.rekotlin.Store -import timber.log.Timber - -internal class DetailsViewModel( - private val store: Store, - private val walletsRepository: WalletsRepository, - private val userWalletsListManager: UserWalletsListManager, -) { - - var detailsScreenState: MutableState = mutableStateOf(updateState(store.state.detailsState)) - private set - - init { - bootstrapScreenState() - } - - fun updateState(state: DetailsState): DetailsScreenState { - return DetailsScreenState( - elements = createSettingsItems(state), - tangemLinks = getSocialLinks(), - tangemVersion = getTangemAppVersion(), - showSnackbar = triggerErrorSnackbarIfNeeded(state.error), - onSocialNetworkClick = ::handleSocialNetworkClick, - ) - } - - private fun createSettingsItems(state: DetailsState): ImmutableList { - val scanResponse = state.scanResponse ?: return persistentListOf() - val cardTypesResolver = scanResponse.cardTypesResolver - - return buildList { - SettingsItem.WalletConnect(::navigateToWalletConnect) - .takeIf { cardTypesResolver.isMultiwalletAllowed() } - ?.let(::add) - - SettingsItem.AddWallet(showProgress = state.isScanningInProgress, ::scanAndSaveUserWallet) - .takeIf { state.appSettingsState.saveWallets } - ?.let(::add) - - SettingsItem.ScanWallet(showProgress = state.isScanningInProgress, ::scanAndSaveUserWallet) - .takeUnless { state.appSettingsState.saveWallets } - ?.let(::add) - - SettingsItem.LinkMoreCards(::linkMoreCards) - .takeIf { state.createBackupAllowed } - ?.let(::add) - - SettingsItem.CardSettings(::navigateToCardSettings) - .let(::add) - - SettingsItem.AppSettings(::navigateToAppSettings) - .let(::add) - - SettingsItem.SendFeedback(::sendFeedback) - .let(::add) - - SettingsItem.ReferralProgram(::navigateToReferralProgram) - .takeIf { cardTypesResolver.isTangemWallet() } - ?.let(::add) - - SettingsItem.TermsOfService(::navigateToToS) - .let(::add) - - SettingsItem.TesterMenu(::navigateToTesterMenu) - .takeIf { BuildConfig.TESTER_MENU_ENABLED } - ?.let(::add) - }.toImmutableList() - } - - private fun triggerErrorSnackbarIfNeeded(text: TextReference?): StateEvent { - return if (text == null) { - consumedEvent() - } else { - triggeredEvent(text) { - store.dispatch(DetailsAction.DismissError) - } - } - } - - private fun getTangemAppVersion(): String { - val versionCode: Int = BuildConfig.VERSION_CODE - val versionName: String = BuildConfig.VERSION_NAME - return "$versionName ($versionCode)" - } - - private fun navigateToTesterMenu() { - store.dispatchNavigationAction { - push(AppRoute.TesterMenu) - } - } - - private fun navigateToToS() { - store.dispatchOnMain(DisclaimerAction.Show(DisclaimerSource.Details)) - } - - private fun navigateToReferralProgram() { - val userWallet = userWalletsListManager.selectedUserWalletSync - ?: error("Selected wallet must be not null") - - store.dispatchNavigationAction { push(AppRoute.ReferralProgram(userWallet.walletId)) } - } - - private fun sendFeedback() { - Analytics.send(Basic.ButtonSupport(AnalyticsParam.ScreensSources.Settings)) - store.dispatchOnMain( - GlobalAction.SendEmail( - feedbackData = FeedbackEmail(), - scanResponse = userWalletsListManager.selectedUserWalletSync?.scanResponse - ?: error("ScanResponse must be not null"), - ), - ) - } - - private fun navigateToAppSettings() { - Analytics.send(Settings.ButtonAppSettings()) - store.dispatchNavigationAction { push(AppRoute.AppSettings) } - } - - private fun navigateToCardSettings() { - val userWalletId = userWalletsListManager.selectedUserWalletSync?.walletId - ?: error("UserWalletId must be not null") - Analytics.send(Settings.ButtonCardSettings()) - store.dispatchNavigationAction { push(AppRoute.CardSettings(userWalletId)) } - } - - private fun linkMoreCards() { - Analytics.send(Settings.ButtonCreateBackup()) - - val selectedUserWallet = userWalletsListManager.selectedUserWalletSync.guard { - Timber.e("Unable to backup wallet, no user wallet selected") - return - } - val scanResponse = selectedUserWallet.scanResponse - Analytics.addContext(scanResponse) - store.dispatch(GlobalAction.Onboarding.Start(scanResponse, canSkipBackup = false)) - store.dispatchNavigationAction { push(AppRoute.OnboardingWallet()) } - } - - private fun scanAndSaveUserWallet() { - Analytics.send(Settings.ScanNewCard) - store.dispatchOnMain(DetailsAction.ScanAndSaveUserWallet) - } - - private fun navigateToWalletConnect() { - Analytics.send(Settings.ButtonWalletConnect()) - store.dispatchNavigationAction { push(AppRoute.WalletConnectSessions) } - } - - private fun handleSocialNetworkClick(link: SocialNetworkLink) { - Analytics.send(Settings.ButtonSocialNetwork(link.network)) - store.dispatchOpenUrl(link.url) - } - - private fun getSocialLinks(): ImmutableList { - val locale = LocaleRegionProvider().getRegion() - return if (locale.lowercase() == RUSSIA_COUNTRY_CODE) { - TangemSocialAccounts.accountsRu - } else { - TangemSocialAccounts.accountsEn - } - } - - private fun bootstrapScreenState() { - userWalletsListManager.selectedUserWallet - .distinctUntilChanged() - .onEach { selectedUserWallet -> - store.dispatchWithMain( - DetailsAction.PrepareScreen( - scanResponse = selectedUserWallet.scanResponse, - shouldSaveUserWallets = walletsRepository.shouldSaveUserWalletsSync(), - ), - ) - } - .flowOn(Dispatchers.IO) - .launchIn(scope) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/ResetCardDialog.kt b/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/ResetCardDialog.kt new file mode 100644 index 0000000000..c6efa99d33 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/ResetCardDialog.kt @@ -0,0 +1,8 @@ +package com.tangem.tap.features.details.ui.resetcard + +internal sealed class ResetCardDialog { + data object StartResetDialog : ResetCardDialog() + data object ContinueResetDialog : ResetCardDialog() + data object InterruptedResetDialog : ResetCardDialog() + data object CompletedResetDialog : ResetCardDialog() +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/ResetCardViewModel.kt b/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/ResetCardViewModel.kt index fefbdf122e..ebcdf702a9 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/ResetCardViewModel.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/ResetCardViewModel.kt @@ -22,7 +22,6 @@ import com.tangem.domain.wallets.usecase.GetUserWalletUseCase import com.tangem.tap.common.analytics.events.Settings import com.tangem.tap.common.extensions.dispatchNavigationAction import com.tangem.tap.common.extensions.onUserWalletSelected -import com.tangem.tap.features.details.redux.ResetCardDialog import com.tangem.tap.features.details.ui.cardsettings.domain.CardSettingsInteractor import com.tangem.tap.features.details.ui.common.utils.getResetToFactoryDescription import com.tangem.tap.store diff --git a/app/src/main/java/com/tangem/tap/features/disclaimer/Disclaimer.kt b/app/src/main/java/com/tangem/tap/features/disclaimer/Disclaimer.kt index 9cda07b754..3524b38f40 100644 --- a/app/src/main/java/com/tangem/tap/features/disclaimer/Disclaimer.kt +++ b/app/src/main/java/com/tangem/tap/features/disclaimer/Disclaimer.kt @@ -24,12 +24,6 @@ abstract class BaseDisclaimer( override suspend fun isAccepted(): Boolean = dataProvider.isAccepted() } -class DummyDisclaimer : Disclaimer { - override fun getUri(): Uri = Uri.parse("https://tangem.com/tangem_tos.html") - override suspend fun accept() {} - override suspend fun isAccepted(): Boolean = false -} - class TangemDisclaimer(dataProvider: DisclaimerDataProvider) : BaseDisclaimer(dataProvider) { override fun getUri(): Uri = Uri.parse("$baseUrl/tangem_tos.html") } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerAction.kt b/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerAction.kt deleted file mode 100644 index 9611dc80b5..0000000000 --- a/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerAction.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.tangem.tap.features.disclaimer.redux - -import com.tangem.tap.common.entities.ProgressState -import com.tangem.tap.features.disclaimer.Disclaimer -import org.rekotlin.Action - -sealed class DisclaimerAction : Action { - - data class SetDisclaimer(val disclaimer: Disclaimer) : DisclaimerAction() - - data class Show( - val from: DisclaimerSource, - val callback: DisclaimerCallback? = null, - ) : DisclaimerAction() - - object AcceptDisclaimer : DisclaimerAction() - object OnBackPressed : DisclaimerAction() - - data class OnProgressStateChanged(val state: ProgressState?) : DisclaimerAction() -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerMiddleware.kt b/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerMiddleware.kt deleted file mode 100644 index 60ffa51781..0000000000 --- a/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerMiddleware.kt +++ /dev/null @@ -1,45 +0,0 @@ -package com.tangem.tap.features.disclaimer.redux - -import com.tangem.common.routing.AppRoute -import com.tangem.common.routing.AppRouter -import com.tangem.tap.common.extensions.dispatchNavigationAction -import com.tangem.tap.common.redux.AppState -import com.tangem.tap.mainScope -import com.tangem.tap.store -import kotlinx.coroutines.launch -import org.rekotlin.Action -import org.rekotlin.Middleware - -class DisclaimerMiddleware { - val disclaimerMiddleware: Middleware = { dispatch, state -> - { next -> - { action -> - state()?.let { handleDisclaimerMiddleware(action, it) } - next(action) - } - } - } -} - -private fun handleDisclaimerMiddleware(action: Action, appState: AppState) { - val state = appState.disclaimerState - - when (action) { - is DisclaimerAction.Show -> { - store.dispatchNavigationAction { - push(AppRoute.Disclaimer(isTosAccepted = action.from == DisclaimerSource.Details)) - } - } - is DisclaimerAction.AcceptDisclaimer -> { - mainScope.launch { - state.disclaimer.accept() - store.dispatchNavigationAction(AppRouter::pop) - state.callback?.onAccept?.invoke() - } - } - is DisclaimerAction.OnBackPressed -> { - store.dispatchNavigationAction(AppRouter::pop) - state.callback?.onDismiss?.invoke() - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerReducer.kt b/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerReducer.kt deleted file mode 100644 index 9b655697ba..0000000000 --- a/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerReducer.kt +++ /dev/null @@ -1,31 +0,0 @@ -package com.tangem.tap.features.disclaimer.redux - -import com.tangem.tap.common.redux.AppState -import org.rekotlin.Action - -object DisclaimerReducer { - fun reduce(action: Action, state: AppState): DisclaimerState = internalReduce(action, state) -} - -private fun internalReduce(action: Action, state: AppState): DisclaimerState { - if (action !is DisclaimerAction) return state.disclaimerState - - val disclaimerState = state.disclaimerState - - return when (action) { - is DisclaimerAction.SetDisclaimer -> disclaimerState.copy( - disclaimer = action.disclaimer, - ) - is DisclaimerAction.Show -> disclaimerState.copy( - showedFrom = action.from, - callback = action.callback, - ) - is DisclaimerAction.AcceptDisclaimer, is DisclaimerAction.OnBackPressed -> disclaimerState.copy( - callback = null, - progressState = null, - ) - is DisclaimerAction.OnProgressStateChanged -> disclaimerState.copy( - progressState = action.state, - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerSource.kt b/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerSource.kt deleted file mode 100644 index cdfcbbdb90..0000000000 --- a/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerSource.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.tangem.tap.features.disclaimer.redux - -enum class DisclaimerSource { - Home, Details -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerState.kt b/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerState.kt deleted file mode 100644 index c5ccfc7cfc..0000000000 --- a/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerState.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.tangem.tap.features.disclaimer.redux - -import com.tangem.common.extensions.VoidCallback - -import com.tangem.tap.common.entities.ProgressState -import com.tangem.tap.features.disclaimer.Disclaimer -import com.tangem.tap.features.disclaimer.DummyDisclaimer -import org.rekotlin.StateType - -data class DisclaimerState( - val disclaimer: Disclaimer = DummyDisclaimer(), - val showedFrom: DisclaimerSource = DisclaimerSource.Home, - val callback: DisclaimerCallback? = null, - val progressState: ProgressState? = null, -) : StateType - -data class DisclaimerCallback( - val onAccept: VoidCallback? = null, - val onDismiss: VoidCallback? = null, -) \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/disclaimer/ui/DisclaimerFragment.kt b/app/src/main/java/com/tangem/tap/features/disclaimer/ui/DisclaimerFragment.kt deleted file mode 100644 index 9d217e6111..0000000000 --- a/app/src/main/java/com/tangem/tap/features/disclaimer/ui/DisclaimerFragment.kt +++ /dev/null @@ -1,139 +0,0 @@ -package com.tangem.tap.features.disclaimer.ui - -import android.os.Bundle -import android.view.View -import android.view.View.OVER_SCROLL_NEVER -import android.webkit.WebView -import androidx.lifecycle.lifecycleScope -import androidx.transition.TransitionInflater -import by.kirich1409.viewbindingdelegate.viewBinding - -import com.tangem.core.ui.extensions.setStatusBarColor -import com.tangem.tap.common.entities.ProgressState -import com.tangem.tap.common.extensions.beginDelayedTransition -import com.tangem.tap.common.extensions.hide -import com.tangem.tap.common.extensions.show -import com.tangem.tap.common.redux.AppState -import com.tangem.tap.features.BaseFragment -import com.tangem.tap.features.addBackPressHandler -import com.tangem.tap.features.disclaimer.Disclaimer -import com.tangem.tap.features.disclaimer.redux.DisclaimerAction -import com.tangem.tap.features.disclaimer.redux.DisclaimerSource -import com.tangem.tap.features.disclaimer.redux.DisclaimerState -import com.tangem.tap.store -import com.tangem.wallet.R -import com.tangem.wallet.databinding.FragmentDisclaimerBinding -import kotlinx.coroutines.launch -import org.rekotlin.StoreSubscriber - -class DisclaimerFragment : BaseFragment(R.layout.fragment_disclaimer), StoreSubscriber { - - private val binding: FragmentDisclaimerBinding by viewBinding(FragmentDisclaimerBinding::bind) - private val webViewClient = DisclaimerWebViewClient() - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - addBackPressHandler(handler = this) - - binding.apply { - toolbar.setNavigationOnClickListener { handleOnBackPressed() } - webView.apply { - settings.allowFileAccess = false - settings.javaScriptEnabled = false - overScrollMode = OVER_SCROLL_NEVER - webViewClient = this@DisclaimerFragment.webViewClient - } - webView.hide() - groupError.hide() - groupAccept.hide() - groupLoading.hide() - - btnAccept.setOnClickListener { - store.dispatch(DisclaimerAction.AcceptDisclaimer) - } - btnRepeat.setOnClickListener { - webViewClient.reset() - } - } - } - - override fun onStart() { - super.onStart() - setStatusBarColor(R.color.background_secondary) - - webViewClient.onProgressStateChanged = { store.dispatch(DisclaimerAction.OnProgressStateChanged(it)) } - store.subscribe(subscriber = this) { state -> - state - .skipRepeats { oldState, newState -> oldState.disclaimerState == newState.disclaimerState } - .select(AppState::disclaimerState) - } - } - - override fun onStop() { - webViewClient.onProgressStateChanged = null - store.unsubscribe(this) - super.onStop() - } - - override fun configureTransitions() { - val inflater = TransitionInflater.from(requireContext()) - when (store.state.disclaimerState.showedFrom) { - DisclaimerSource.Home -> { - enterTransition = inflater.inflateTransition(android.R.transition.slide_bottom) - exitTransition = inflater.inflateTransition(android.R.transition.slide_top) - } - DisclaimerSource.Details -> { - super.configureTransitions() - } - } - } - - override fun handleOnBackPressed() { - store.dispatch(DisclaimerAction.OnBackPressed) - } - - override fun newState(state: DisclaimerState) { - return with(binding) { - if (activity == null || view == null) return - - updateUiVisibility(state.disclaimer, state.progressState) - } - } - - private fun updateUiVisibility(disclaimer: Disclaimer, progressState: ProgressState?) = with(binding) { - when (progressState) { - ProgressState.Loading -> { - root.beginDelayedTransition() - webView.hide() - groupError.hide() - groupAccept.hide() - groupLoading.show() - } - ProgressState.Done -> { - root.beginDelayedTransition() - groupError.hide() - groupLoading.hide() - webView.show() - lifecycleScope.launch { - groupAccept.show(!disclaimer.isAccepted()) - } - } - ProgressState.Error -> { - root.beginDelayedTransition() - webView.show() - groupAccept.show() - groupLoading.hide() - groupError.hide() - webView.loadLocalTermsOfServices() - } - else -> { - webView.setBackgroundColor(resources.getColor(R.color.transparent, null)) - webView.loadUrl(disclaimer.getUri().toString()) - } - } - } - - private fun WebView.loadLocalTermsOfServices() { - loadData(localTermsOfServices, "text/html", "UTF-8") - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/disclaimer/ui/DisclaimerWebViewClient.kt b/app/src/main/java/com/tangem/tap/features/disclaimer/ui/DisclaimerWebViewClient.kt deleted file mode 100644 index c64d0b7543..0000000000 --- a/app/src/main/java/com/tangem/tap/features/disclaimer/ui/DisclaimerWebViewClient.kt +++ /dev/null @@ -1,64 +0,0 @@ -package com.tangem.tap.features.disclaimer.ui - -import android.graphics.Bitmap -import android.webkit.* -import com.tangem.common.extensions.ifNotNull -import com.tangem.tap.common.entities.ProgressState - -class DisclaimerWebViewClient : WebViewClient() { - - var onProgressStateChanged: ((ProgressState) -> Unit)? = null - - private var loadingUrl: String? = null - private var loadedUrl: String? = null - - private var progressState: ProgressState = ProgressState.Loading - set(value) { - field = value - onProgressStateChanged?.invoke(value) - } - - fun reset() { - loadingUrl = null - loadedUrl = null - progressState = ProgressState.Loading - } - - override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) { - super.onPageStarted(view, url, favicon) - - if (loadingUrl != url) progressState = ProgressState.Loading - loadingUrl = url - } - - override fun onPageFinished(view: WebView?, url: String?) { - super.onPageFinished(view, url) - - if (loadedUrl != url) progressState = ProgressState.Done - loadedUrl = url - } - - override fun onReceivedError(view: WebView?, resourceRequest: WebResourceRequest?, error: WebResourceError?) { - super.onReceivedError(view, resourceRequest, error) - error?.let { progressState = ProgressState.Error } - } - - override fun onReceivedHttpError( - view: WebView?, - resourceRequest: WebResourceRequest?, - errorResponse: WebResourceResponse?, - ) { - super.onReceivedHttpError(view, resourceRequest, errorResponse) - - ifNotNull(resourceRequest, errorResponse) { request, response -> - if (request.url?.toString() != loadingUrl || response.statusCode < RESPONSE_USER_ERROR_STATUS_CODE) return - if (progressState != ProgressState.Done) return - - progressState = ProgressState.Error - } - } - - companion object { - private const val RESPONSE_USER_ERROR_STATUS_CODE = 400 - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/disclaimer/ui/LocalTermOfServices.kt b/app/src/main/java/com/tangem/tap/features/disclaimer/ui/LocalTermOfServices.kt deleted file mode 100644 index 6651d0fa75..0000000000 --- a/app/src/main/java/com/tangem/tap/features/disclaimer/ui/LocalTermOfServices.kt +++ /dev/null @@ -1,66 +0,0 @@ -package com.tangem.tap.features.disclaimer.ui - -internal val localTermsOfServices = """ - - - - - - - Legal Disclaimer - - -

Legal Disclaimer

-

    1. Tangem application (Software)

-

    The Software is intended for usage only with Tangem hardware wallets (Cards) via NFC interface. The - Software DOES NOT:

-

    a) Generate, store, transmit, or have access to private (secret) cryptographic keys to blockchain - wallets holding digital assets, including crypto-currency.

-

    b) Generate, store, transmit, or have access to secret keys, passwords, passphrases, recovery phrases - that can be used to restore or to copy private (secret) keys to blockchain wallets holding digital assets, including - crypto-currency.

-

    c) Provide exchange, trading, investment services on behalf of Tangem AG.

-

    2. Risks related to the use of Software

-

    Tangem will not be responsible for any losses, damages or claims arising from events falling within the - scope of the following five categories:

-

    a) Mistakes made by the user of any cryptocurrency-related software or service, e.g., forgotten - passwords, payments sent to wrong addresses, and accidental deletion of blockchain wallets on Cards.

-

    b) Problems of Software and/or any blockchain- or cryptocurrency- related software or service, e.g., - corrupted files, incorrectly constructed transactions, unsafe cryptographic libraries, malware.

-

    c) Technical failures in the hardware of the user, including Cards, of any cryptocurrency-related - software or service, e.g., data loss due to a faulty or damaged storage device.

-

    d) Security problems experienced by the user of any cryptocurrency-related software or service, e.g., - unauthorized access to users' wallets and/or accounts.

-

    e) Actions or inactions of third parties and/or events experienced by third parties, e.g., bankruptcy - of service providers, information security attacks on service providers, and fraud conducted by third parties.

-

    3. Trading and Investment risks

-

    There is considerable exposure to risk in any crypto-currency or other digital asset exchange - transaction. Any transaction involving currencies involves risks including, but not limited to, the potential for - changing economic conditions that may substantially affect the price or liquidity of a currency. Investments in - crypto-currency exchange speculation may also be susceptible to sharp rises and falls as the relevant market values - fluctuate. It is for this reason that when speculating in such markets it is advisable to use only risk capital.

-

    4. Electronic Trading Risks

-

    Before you engage in transactions using an electronic system, you should carefully review the rules and - regulations of the exchanges offering the system and/or listing the instruments you intend to trade. Online trading - has inherent risk due to system response and access times that may vary due to market conditions, system - performance, and other factors. You should understand these and additional risks before trading.

-

    5. Compliance with tax obligations        

-

    The users of the Software are solely responsible to determinate what, if any, taxes apply to their - crypto-currency transactions. The owners of, or contributors to, the Software are NOT responsible for determining - the taxes that apply to crypto-currency transactions.        

-

    6. No warranties        

-

    The Software is provided on an "as is" basis without any warranties of any kind regarding the - Software and/or any content, data, materials and/or services provided on the Software.       -  

-

    7. Limitation of liability

-

    Unless otherwise required by law, in no event shall the owners of, or contributors to, the Software be - liable for any damages of any kind, including, but not limited to, loss of use, loss of profits, or loss of data - arising out of or in any way connected with the use of the Software. In no way are the owners of, or contributors - to, the Software responsible for the actions, decisions, or other behavior taken or not taken by you in reliance - upon the Software.

-

    8. Last amendment

-

    This disclaimer was amended for the last time on October 1st, 2020.

- -""".trimIndent() \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/home/compose/StoriesScreen.kt b/app/src/main/java/com/tangem/tap/features/home/compose/StoriesScreen.kt index 9f4e9fbaa9..f33229cf24 100644 --- a/app/src/main/java/com/tangem/tap/features/home/compose/StoriesScreen.kt +++ b/app/src/main/java/com/tangem/tap/features/home/compose/StoriesScreen.kt @@ -58,7 +58,9 @@ internal fun StoriesScreen( } StoriesScreenContent( - modifier = Modifier.fillMaxSize().testTag(TestTags.STORIES_SCREEN), + modifier = Modifier + .fillMaxSize() + .testTag(TestTags.STORIES_SCREEN), config = StoriesScreenContentConfig( storiesSize = state.stories.lastIndex, currentStoryIndex = currentStoryIndex, @@ -157,7 +159,7 @@ private fun StoriesScreenContent(config: StoriesScreenContentConfig, modifier: M duration = currentStoryDuration, ) Stories.RevolutionaryWallet -> StoriesRevolutionaryWallet() - is Stories.UltraSecureBackup -> StoriesUltraSecureBackup( + Stories.UltraSecureBackup -> StoriesUltraSecureBackup( isPaused = isPaused, stepDuration = currentStoryDuration, ) diff --git a/app/src/main/java/com/tangem/tap/features/home/featuretoggles/HomeFeatureToggles.kt b/app/src/main/java/com/tangem/tap/features/home/featuretoggles/HomeFeatureToggles.kt new file mode 100644 index 0000000000..ce8c0bcec3 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/features/home/featuretoggles/HomeFeatureToggles.kt @@ -0,0 +1,12 @@ +package com.tangem.tap.features.home.featuretoggles + +import com.tangem.core.featuretoggle.manager.FeatureTogglesManager +import javax.inject.Inject + +class HomeFeatureToggles @Inject constructor( + private val featureTogglesManager: FeatureTogglesManager, +) { + + val isMigrateUserCountryCodeEnabled: Boolean + get() = featureTogglesManager.isFeatureEnabled(name = "MIGRATE_USER_COUNTRY_CODE_ENABLED") +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/home/redux/HomeAction.kt b/app/src/main/java/com/tangem/tap/features/home/redux/HomeAction.kt index e3f0375cc1..05ba17df63 100644 --- a/app/src/main/java/com/tangem/tap/features/home/redux/HomeAction.kt +++ b/app/src/main/java/com/tangem/tap/features/home/redux/HomeAction.kt @@ -15,6 +15,4 @@ sealed class HomeAction : Action { data class ReadCard(val scope: CoroutineScope) : HomeAction() data class ScanInProgress(val scanInProgress: Boolean) : HomeAction() - - data class UpdateCountryCode(val userCountryCode: String) : HomeAction() } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/home/redux/HomeReducer.kt b/app/src/main/java/com/tangem/tap/features/home/redux/HomeReducer.kt index f9d977fdec..ab41e3d89f 100644 --- a/app/src/main/java/com/tangem/tap/features/home/redux/HomeReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/home/redux/HomeReducer.kt @@ -10,16 +10,10 @@ object HomeReducer { private fun internalReduce(action: Action, appState: AppState): HomeState { if (action !is HomeAction) return appState.homeState - var state = appState.homeState - when (action) { + return when (action) { is HomeAction.ScanInProgress -> { - state = state.copy(scanInProgress = action.scanInProgress) + appState.homeState.copy(scanInProgress = action.scanInProgress) } - is HomeAction.UpdateCountryCode -> { - state.onCountryCodeUpdate(state, action.userCountryCode) - } - else -> {} + else -> appState.homeState } - - return state } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/home/redux/HomeState.kt b/app/src/main/java/com/tangem/tap/features/home/redux/HomeState.kt index 2e584d3d35..5341631157 100644 --- a/app/src/main/java/com/tangem/tap/features/home/redux/HomeState.kt +++ b/app/src/main/java/com/tangem/tap/features/home/redux/HomeState.kt @@ -1,56 +1,24 @@ package com.tangem.tap.features.home.redux -import androidx.compose.runtime.Immutable -import androidx.compose.runtime.MutableState -import androidx.compose.runtime.mutableStateOf +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.toImmutableList import org.rekotlin.StateType -import java.util.Locale -@Immutable data class HomeState( val scanInProgress: Boolean = false, - val stories: List = initDefaultStories(), + val stories: ImmutableList = Stories.entries.toImmutableList(), ) : StateType { - val firstStory: Stories - get() = stories[0] + val firstStory: Stories get() = stories[0] fun stepOf(story: Stories): Int = stories.indexOf(story) - - fun onCountryCodeUpdate(homeState: HomeState, countryCode: String) { - val isNewWalletAvailable = !(countryCode == RUSSIA_COUNTRY_CODE || countryCode == BELARUS_COUNTRY_CODE) - homeState.stories.forEach { - it.isNewWalletAvailable.value = isNewWalletAvailable - } - } - - companion object { - private const val RUSSIA_COUNTRY_CODE = "ru" - private const val BELARUS_COUNTRY_CODE = "by" - fun initDefaultStories(): List = listOf( - Stories.TangemIntro, - Stories.RevolutionaryWallet, - Stories.UltraSecureBackup, - Stories.Currencies, - Stories.Web3, - Stories.WalletForEveryone, - ) - - fun isNewWalletAvailableInit(): Boolean { - val locale = Locale.getDefault().language - return !(locale == RUSSIA_COUNTRY_CODE || locale == BELARUS_COUNTRY_CODE) - } - } } -sealed class Stories( - val duration: Int, - val isNewWalletAvailable: MutableState = mutableStateOf(HomeState.isNewWalletAvailableInit()), -) { - object TangemIntro : Stories(duration = 6000) - object RevolutionaryWallet : Stories(duration = 6000) - object UltraSecureBackup : Stories(duration = 6000) - object Currencies : Stories(duration = 6000) - object Web3 : Stories(duration = 6000) - object WalletForEveryone : Stories(duration = 6000) +enum class Stories(val duration: Int = 6000) { + TangemIntro, + RevolutionaryWallet, + UltraSecureBackup, + Currencies, + Web3, + WalletForEveryone, } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/main/MainViewModel.kt b/app/src/main/java/com/tangem/tap/features/main/MainViewModel.kt index 6ba358cced..e9db3ee67e 100644 --- a/app/src/main/java/com/tangem/tap/features/main/MainViewModel.kt +++ b/app/src/main/java/com/tangem/tap/features/main/MainViewModel.kt @@ -13,16 +13,15 @@ import com.tangem.domain.balancehiding.BalanceHidingSettings import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase import com.tangem.domain.balancehiding.ListenToFlipsUseCase import com.tangem.domain.balancehiding.UpdateBalanceHidingSettingsUseCase -import com.tangem.domain.feedback.FeedbackManagerFeatureToggles import com.tangem.domain.settings.DeleteDeprecatedLogsUseCase import com.tangem.domain.settings.IncrementAppLaunchCounterUseCase +import com.tangem.domain.settings.usercountry.FetchUserCountryUseCase import com.tangem.domain.staking.FetchStakingTokensUseCase -import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.features.staking.api.featuretoggles.StakingFeatureToggles import com.tangem.tap.common.extensions.setContext +import com.tangem.tap.features.home.featuretoggles.HomeFeatureToggles import com.tangem.tap.features.main.model.MainScreenState -import com.tangem.tap.store import com.tangem.utils.coroutines.CoroutineDispatcherProvider import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.* @@ -41,12 +40,12 @@ internal class MainViewModel @Inject constructor( private val incrementAppLaunchCounterUseCase: IncrementAppLaunchCounterUseCase, private val blockchainSDKFactory: BlockchainSDKFactory, private val userWalletsListManager: UserWalletsListManager, - private val walletManagersFacade: WalletManagersFacade, - private val feedbackManagerFeatureToggles: FeedbackManagerFeatureToggles, private val dispatchers: CoroutineDispatcherProvider, stakingFeatureToggles: StakingFeatureToggles, private val fetchStakingTokensUseCase: FetchStakingTokensUseCase, private val apiConfigsManager: ApiConfigsManager, + homeFeatureToggles: HomeFeatureToggles, + private val fetchUserCountryUseCase: FetchUserCountryUseCase, getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase, ) : ViewModel(), MainIntents { @@ -67,6 +66,14 @@ internal class MainViewModel @Inject constructor( viewModelScope.launch(dispatchers.main) { incrementAppLaunchCounterUseCase() } + if (homeFeatureToggles.isMigrateUserCountryCodeEnabled) { + viewModelScope.launch { + fetchUserCountryUseCase().onLeft { + Timber.e("Unable to fetch the user country code $it") + } + } + } + updateAppCurrencies() observeFlips() displayBalancesHidingStatusToast() @@ -97,19 +104,6 @@ internal class MainViewModel @Inject constructor( .onEach { userWallet -> Analytics.setContext(userWallet.scanResponse) Analytics.send(Basic.WalletOpened()) - - if (!feedbackManagerFeatureToggles.isLocalLogsEnabled) { - store.state.globalState.feedbackManager?.infoHolder?.let { infoHolder -> - infoHolder.setCardInfo(userWallet.scanResponse) - - walletManagersFacade - .getAll(userWallet.walletId) - .distinctUntilChanged() - .onEach(infoHolder::setWalletsInfo) - .catch { Timber.e(it) } - .launchIn(viewModelScope) - } - } } .flowOn(dispatchers.io) .launchIn(viewModelScope) diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingHelper.kt b/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingHelper.kt index bc085c6dca..35007254c1 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingHelper.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingHelper.kt @@ -1,22 +1,30 @@ package com.tangem.tap.features.onboarding +import com.tangem.blockchain.common.WalletManager import com.tangem.common.doOnFailure import com.tangem.common.doOnSuccess import com.tangem.common.extensions.guard import com.tangem.common.routing.AppRoute import com.tangem.core.analytics.Analytics import com.tangem.core.analytics.models.Basic - +import com.tangem.data.common.currency.CryptoCurrencyFactory import com.tangem.domain.common.util.cardTypesResolver import com.tangem.domain.common.util.twinsIsTwinned import com.tangem.domain.models.scan.CardDTO import com.tangem.domain.models.scan.ProductType import com.tangem.domain.models.scan.ScanResponse +import com.tangem.domain.settings.usercountry.models.UserCountry import com.tangem.domain.wallets.builder.UserWalletBuilder import com.tangem.domain.wallets.builder.UserWalletIdBuilder import com.tangem.tap.common.analytics.converters.ParamCardCurrencyConverter +import com.tangem.tap.common.analytics.events.AnalyticsParam +import com.tangem.tap.common.analytics.events.Onboarding import com.tangem.tap.common.extensions.* +import com.tangem.tap.common.redux.AppDialog +import com.tangem.tap.common.redux.global.GlobalState import com.tangem.tap.features.demo.DemoHelper +import com.tangem.tap.features.onboarding.products.wallet.redux.OnboardingWalletAction +import com.tangem.tap.features.home.RUSSIA_COUNTRY_CODE import com.tangem.tap.features.saveWallet.redux.SaveWalletAction import com.tangem.tap.mainScope import com.tangem.tap.proxy.redux.DaggerGraphState @@ -75,6 +83,56 @@ object OnboardingHelper { } } + fun saveWallet( + scanResponse: ScanResponse, + accessCode: String? = null, + backupCardsIds: List? = null, + hasBackupError: Boolean = false, + ) { + Analytics.setContext(scanResponse) + scope.launch { + val settingsRepository = store.inject(DaggerGraphState::settingsRepository) + when { + // When should save user wallets, then save card without navigate to save wallet screen + store.inject(DaggerGraphState::walletsRepository).shouldSaveUserWalletsSync() -> { + store.dispatchWithMain( + SaveWalletAction.ProvideBackupInfo( + scanResponse = scanResponse, + accessCode = accessCode, + backupCardsIds = backupCardsIds?.toSet(), + ), + ) + + store.dispatchWithMain( + SaveWalletAction.SaveWalletAfterBackup( + hasBackupError = hasBackupError, + shouldNavigateToWallet = false, + ), + ) + } + // When should not save user wallets but device has biometry and save wallet screen has not been shown, + // then open save wallet screen + tangemSdkManager.checkCanUseBiometry() && settingsRepository.shouldShowSaveUserWalletScreen() -> { + proceedWithScanResponse(scanResponse, backupCardsIds, hasBackupError) + + delay(timeMillis = 1_200) + + store.dispatchOnMain( + SaveWalletAction.ProvideBackupInfo( + scanResponse = scanResponse, + accessCode = accessCode, + backupCardsIds = backupCardsIds?.toSet(), + ), + ) + } + // If device has no biometry and save wallet screen has been shown, then go through old scenario + else -> { + proceedWithScanResponse(scanResponse, backupCardsIds, hasBackupError) + } + } + } + } + fun trySaveWalletAndNavigateToWalletScreen( scanResponse: ScanResponse, accessCode: String? = null, @@ -96,7 +154,12 @@ object OnboardingHelper { ), ) - store.dispatchWithMain(SaveWalletAction.SaveWalletAfterBackup(hasBackupError)) + store.dispatchWithMain( + SaveWalletAction.SaveWalletAfterBackup( + hasBackupError = hasBackupError, + shouldNavigateToWallet = true, + ), + ) } // When should not save user wallets but device has biometry and save wallet screen has not been shown, // then open save wallet screen @@ -138,6 +201,39 @@ object OnboardingHelper { } } + fun handleTopUpAction(walletManager: WalletManager, scanResponse: ScanResponse, globalState: GlobalState) { + val blockchain = walletManager.wallet.blockchain + val cryptoCurrency = CryptoCurrencyFactory().createCoin( + blockchain = blockchain, + extraDerivationPath = null, + scanResponse = scanResponse, + ) ?: return + + val topUpUrl = walletManager.getTopUpUrl(cryptoCurrency) ?: return + + val currencyType = AnalyticsParam.CurrencyType.Blockchain(blockchain) + Analytics.send(Onboarding.Topup.ButtonBuyCrypto(currencyType)) + + scope.launch { + val homeFeatureToggles = store.inject(DaggerGraphState::homeFeatureToggles) + + val isRussia = if (homeFeatureToggles.isMigrateUserCountryCodeEnabled) { + val getUserCountryCodeUseCase = store.inject(DaggerGraphState::getUserCountryUseCase) + + getUserCountryCodeUseCase().isRight { it is UserCountry.Russia } + } else { + globalState.userCountryCode == RUSSIA_COUNTRY_CODE + } + + if (isRussia) { + val dialogData = AppDialog.RussianCardholdersWarningDialog.Data(topUpUrl) + store.dispatchDialogShow(AppDialog.RussianCardholdersWarningDialog(dialogData)) + } else { + store.dispatchOpenUrl(topUpUrl) + } + } + } + private suspend fun proceedWithScanResponse( scanResponse: ScanResponse, backupCardsIds: List?, @@ -160,6 +256,7 @@ object OnboardingHelper { } .doOnSuccess { mainScope.launch { store.onUserWalletSelected(userWallet) } + store.dispatch(OnboardingWalletAction.WalletSaved(userWallet.walletId)) } } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingManager.kt b/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingManager.kt index d37b7153d1..a0db9b19f8 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingManager.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingManager.kt @@ -11,7 +11,6 @@ import com.tangem.operations.attestation.CardVerifyAndGetInfo import com.tangem.operations.attestation.OnlineCardVerifier import com.tangem.tap.common.entities.ProgressState import com.tangem.tap.common.extensions.inject -import com.tangem.tap.common.extensions.isPositive import com.tangem.tap.common.extensions.safeUpdate import com.tangem.tap.domain.TapError import com.tangem.tap.domain.extensions.getOrLoadCardArtworkUrl @@ -20,6 +19,7 @@ import com.tangem.tap.domain.model.hasPendingTransactions import com.tangem.tap.features.demo.isDemoCard import com.tangem.tap.proxy.redux.DaggerGraphState import com.tangem.tap.store +import com.tangem.utils.extensions.isPositive import timber.log.Timber import java.math.BigDecimal diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingMenuProvider.kt b/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingMenuProvider.kt index 89ffc2161c..c619d4bd17 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingMenuProvider.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingMenuProvider.kt @@ -7,12 +7,15 @@ import androidx.core.view.MenuProvider import com.tangem.core.analytics.Analytics import com.tangem.core.analytics.models.AnalyticsParam import com.tangem.core.analytics.models.Basic +import com.tangem.domain.feedback.models.FeedbackEmailType import com.tangem.domain.models.scan.ScanResponse -import com.tangem.tap.common.feedback.SupportInfo -import com.tangem.tap.common.redux.global.GlobalAction +import com.tangem.tap.common.extensions.inject +import com.tangem.tap.proxy.redux.DaggerGraphState +import com.tangem.tap.scope import com.tangem.tap.store import com.tangem.utils.Provider import com.tangem.wallet.R +import kotlinx.coroutines.launch /** [REDACTED_AUTHOR] @@ -28,13 +31,15 @@ class OnboardingMenuProvider( override fun onMenuItemSelected(menuItem: MenuItem): Boolean = when (menuItem.itemId) { R.id.menu_item_chat_support -> { Analytics.send(Basic.ButtonSupport(AnalyticsParam.ScreensSources.Intro)) - // changed on email support [REDACTED_TASK_KEY] - store.dispatch( - GlobalAction.SendEmail( - feedbackData = SupportInfo(), - scanResponse = scanResponseProvider(), - ), - ) + + val cardInfo = store.inject(DaggerGraphState::getCardInfoUseCase).invoke(scanResponseProvider()).getOrNull() + ?: error("CardInfo must be not null") + + scope.launch { + store.inject(DaggerGraphState::sendFeedbackEmailUseCase) + .invoke(type = FeedbackEmailType.DirectUserRequest(cardInfo)) + } + true } else -> false diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/note/OnboardingNoteFragment.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/note/OnboardingNoteFragment.kt index 757ec91454..97746d2d70 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/note/OnboardingNoteFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/note/OnboardingNoteFragment.kt @@ -14,7 +14,6 @@ import com.tangem.core.navigation.ShareElement import com.tangem.domain.models.scan.ScanResponse import com.tangem.tap.common.analytics.events.Onboarding import com.tangem.tap.common.extensions.getDrawableCompat -import com.tangem.tap.common.extensions.stripZeroPlainString import com.tangem.tap.common.toggleWidget.RefreshBalanceWidget import com.tangem.tap.common.transitions.InternalNoteLayoutTransition import com.tangem.tap.features.addBackPressHandler @@ -24,6 +23,7 @@ import com.tangem.tap.features.onboarding.products.note.redux.OnboardingNoteActi import com.tangem.tap.features.onboarding.products.note.redux.OnboardingNoteState import com.tangem.tap.features.onboarding.products.note.redux.OnboardingNoteStep import com.tangem.tap.store +import com.tangem.utils.extensions.stripZeroPlainString import com.tangem.wallet.R /** diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteMiddleware.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteMiddleware.kt index 52af2f7d66..d47862a648 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteMiddleware.kt @@ -4,12 +4,8 @@ import com.tangem.common.CompletionResult import com.tangem.common.extensions.guard import com.tangem.common.routing.AppRouter import com.tangem.core.analytics.Analytics - -import com.tangem.data.common.currency.CryptoCurrencyFactory import com.tangem.domain.common.extensions.makePrimaryWalletManager import com.tangem.domain.common.extensions.withMainContext -import com.tangem.domain.common.util.derivationStyleProvider -import com.tangem.tap.common.analytics.events.AnalyticsParam import com.tangem.tap.common.analytics.events.Onboarding import com.tangem.tap.common.entities.ProgressState import com.tangem.tap.common.extensions.* @@ -20,7 +16,6 @@ import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.domain.TapError import com.tangem.tap.domain.model.Currency import com.tangem.tap.features.demo.DemoHelper -import com.tangem.tap.features.home.RUSSIA_COUNTRY_CODE import com.tangem.tap.features.onboarding.OnboardingDialog import com.tangem.tap.features.onboarding.OnboardingHelper import com.tangem.tap.mainScope @@ -178,23 +173,11 @@ private fun handleNoteAction(appState: () -> AppState?, action: Action, dispatch return } - val blockchain = walletManager.wallet.blockchain - val cryptoCurrency = CryptoCurrencyFactory().createCoin( - blockchain, - null, - scanResponse.derivationStyleProvider, - ) ?: return - val topUpUrl = walletManager.getTopUpUrl(cryptoCurrency) ?: return - - val currencyType = AnalyticsParam.CurrencyType.Blockchain(blockchain) - Analytics.send(Onboarding.Topup.ButtonBuyCrypto(currencyType)) - - if (globalState.userCountryCode == RUSSIA_COUNTRY_CODE) { - val dialogData = AppDialog.RussianCardholdersWarningDialog.Data(topUpUrl) - store.dispatchDialogShow(AppDialog.RussianCardholdersWarningDialog(dialogData)) - } else { - store.dispatchOpenUrl(topUpUrl) - } + OnboardingHelper.handleTopUpAction( + walletManager = walletManager, + scanResponse = scanResponse, + globalState = globalState, + ) } is OnboardingNoteAction.Done -> { store.dispatch(GlobalAction.Onboarding.Stop) diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt index 047a5caaa8..ef29db32d4 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt @@ -6,16 +6,12 @@ import com.tangem.common.extensions.guard import com.tangem.common.routing.AppRoute import com.tangem.common.routing.utils.popTo import com.tangem.core.analytics.Analytics - -import com.tangem.data.common.currency.CryptoCurrencyFactory import com.tangem.domain.common.extensions.makePrimaryWalletManager import com.tangem.domain.common.extensions.withMainContext -import com.tangem.domain.common.util.derivationStyleProvider import com.tangem.domain.common.util.twinsIsTwinned import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.wallets.builder.UserWalletIdBuilder import com.tangem.domain.wallets.legacy.asLockable -import com.tangem.tap.common.analytics.events.AnalyticsParam import com.tangem.tap.common.analytics.events.Onboarding import com.tangem.tap.common.entities.ProgressState import com.tangem.tap.common.extensions.* @@ -26,7 +22,6 @@ import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.domain.TapError import com.tangem.tap.domain.model.Currency import com.tangem.tap.domain.twins.TwinCardsManager -import com.tangem.tap.features.home.RUSSIA_COUNTRY_CODE import com.tangem.tap.features.onboarding.OnboardingDialog import com.tangem.tap.features.onboarding.OnboardingHelper import com.tangem.tap.mainScope @@ -301,24 +296,11 @@ private fun handle(action: Action, dispatch: DispatchFunction) { return } - val scanResponse = onboardingManager?.scanResponse ?: return - val blockchain = walletManager.wallet.blockchain - val cryptoCurrency = CryptoCurrencyFactory().createCoin( - blockchain, - null, - scanResponse.derivationStyleProvider, - ) ?: return - val topUpUrl = walletManager.getTopUpUrl(cryptoCurrency) ?: return - - val currencyType = AnalyticsParam.CurrencyType.Blockchain(blockchain) - Analytics.send(Onboarding.Topup.ButtonBuyCrypto(currencyType)) - - if (globalState.userCountryCode == RUSSIA_COUNTRY_CODE) { - val dialogData = AppDialog.RussianCardholdersWarningDialog.Data(topUpUrl) - store.dispatchDialogShow(AppDialog.RussianCardholdersWarningDialog(dialogData)) - } else { - store.dispatchOpenUrl(topUpUrl) - } + OnboardingHelper.handleTopUpAction( + walletManager = walletManager, + scanResponse = onboardingManager?.scanResponse ?: return, + globalState = globalState, + ) } TwinCardsAction.Done -> { val scanResponse = getScanResponse() diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/OnboardingTwinsFragment.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/OnboardingTwinsFragment.kt index 76880fb5e1..f058c94f3b 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/OnboardingTwinsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/OnboardingTwinsFragment.kt @@ -21,7 +21,10 @@ import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.wallets.models.Artwork import com.tangem.sdk.ui.widget.leapfrogWidget.LeapfrogWidget import com.tangem.tap.common.analytics.events.Onboarding -import com.tangem.tap.common.extensions.* +import com.tangem.tap.common.extensions.beginDelayedTransition +import com.tangem.tap.common.extensions.getDrawableCompat +import com.tangem.tap.common.extensions.hide +import com.tangem.tap.common.extensions.show import com.tangem.tap.common.toggleWidget.RefreshBalanceWidget import com.tangem.tap.common.transitions.InternalNoteLayoutTransition import com.tangem.tap.domain.twins.TwinsCardWidget @@ -35,6 +38,7 @@ import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsState import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsStep import com.tangem.tap.store import com.tangem.utils.Provider +import com.tangem.utils.extensions.stripZeroPlainString import com.tangem.wallet.R import com.tangem.wallet.databinding.LayoutOnboardingContainerTopBinding import dagger.hilt.android.AndroidEntryPoint diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletAction.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletAction.kt index 3538c3bb27..64ce8d1864 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletAction.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletAction.kt @@ -2,6 +2,7 @@ package com.tangem.tap.features.onboarding.products.wallet.redux import android.net.Uri import com.tangem.common.CompletionResult +import com.tangem.domain.wallets.models.UserWalletId import com.tangem.feature.onboarding.data.model.CreateWalletResponse import com.tangem.feature.onboarding.presentation.wallet2.analytics.SeedPhraseSource import com.tangem.tap.domain.tasks.product.CreateProductWalletTaskResponse @@ -28,6 +29,8 @@ sealed class OnboardingWalletAction : Action { class SetThirdCardArtworkUrl(val artworkUri: Uri?) : OnboardingWalletAction() data object OnBackPressed : OnboardingWalletAction() + + data class WalletSaved(val userWalletId: UserWalletId) : OnboardingWalletAction() } sealed class OnboardingWallet2Action : OnboardingWalletAction() { @@ -89,6 +92,8 @@ sealed class BackupAction : Action { data class FinishBackup(val withAnalytics: Boolean = true) : BackupAction() + data class BackupFinished(val userWalletId: UserWalletId?) : BackupAction() + data object DiscardBackup : BackupAction() data object DiscardSavedBackup : BackupAction() data object ResumeFoundUnfinishedBackup : BackupAction() diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt index 95b2fd2452..98bca6119a 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt @@ -5,7 +5,6 @@ import com.google.firebase.crashlytics.FirebaseCrashlytics import com.tangem.common.CompletionResult import com.tangem.common.card.Card import com.tangem.common.core.TangemSdkError -import com.tangem.common.extensions.guard import com.tangem.common.extensions.ifNotNull import com.tangem.common.extensions.toHexString import com.tangem.common.routing.AppRoute @@ -19,6 +18,7 @@ import com.tangem.domain.models.scan.CardDTO import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.wallets.builder.UserWalletBuilder import com.tangem.domain.wallets.models.Artwork +import com.tangem.domain.wallets.models.UserWallet import com.tangem.feature.onboarding.data.model.CreateWalletResponse import com.tangem.feature.onboarding.presentation.wallet2.analytics.SeedPhraseSource import com.tangem.feature.wallet.presentation.wallet.domain.BackupValidator @@ -164,16 +164,7 @@ private fun handleWalletAction(action: Action) { } is OnboardingWalletAction.FinishOnboarding -> { store.dispatch(GlobalAction.Onboarding.Stop) - - if (scanResponse == null) { - action.scope.launch { - readCard { newScanResponse -> - handleFinishOnboardind(newScanResponse) - } - } - } else { - handleFinishOnboardind(scanResponse) - } + navigateToWalletScreen() } is OnboardingWalletAction.ResumeBackup -> { val newAction = when (val backupState = backupService.currentState) { @@ -197,10 +188,10 @@ private fun handleWalletAction(action: Action) { } } -private fun handleFinishOnboardind(scanResponse: ScanResponse) { +private fun handleFinishBackup(scanResponse: ScanResponse) { val backupState = store.state.onboardingWalletState.backupState val updatedScanResponse = updateScanResponseAfterBackup(scanResponse, backupState) - OnboardingHelper.trySaveWalletAndNavigateToWalletScreen( + OnboardingHelper.saveWallet( scanResponse = updatedScanResponse, accessCode = backupState.accessCode, backupCardsIds = backupState.backupCardIds, @@ -208,7 +199,18 @@ private fun handleFinishOnboardind(scanResponse: ScanResponse) { ) } -private suspend fun readCard(onSuccess: (ScanResponse) -> Unit) { +private fun navigateToWalletScreen() { + mainScope.launch { + val settingsRepository = store.inject(DaggerGraphState::settingsRepository) + store.dispatchNavigationAction { replaceAll(AppRoute.Wallet) } + if (tangemSdkManager.checkCanUseBiometry() && settingsRepository.shouldShowSaveUserWalletScreen()) { + delay(timeMillis = 1_800) + store.dispatchNavigationAction { push(AppRoute.SaveWallet) } + } + } +} + +private suspend fun readCard(onSuccess: suspend (ScanResponse) -> Unit) { val shouldSaveAccessCodes = store.inject(DaggerGraphState::settingsRepository).shouldSaveAccessCodes() store.inject(DaggerGraphState::cardSdkConfigRepository).setAccessCodeRequestPolicy( @@ -403,7 +405,7 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction) val onboardingWalletState = appState()?.onboardingWalletState ?: return val backupState = onboardingWalletState.backupState - val scanResponse = globalState.onboardingState.onboardingManager?.scanResponse + var scanResponse = globalState.onboardingState.onboardingManager?.scanResponse val card = scanResponse?.card when (action) { @@ -573,6 +575,15 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction) cardIds = gatherCardIds(backupState, card), ) } + if (scanResponse == null) { + scope.launch { + readCard { newScanResponse -> + handleFinishBackup(newScanResponse) + } + } + } else { + handleFinishBackup(scanResponse) + } } is BackupAction.FinishBackup -> { scope.launch { @@ -580,28 +591,31 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction) Analytics.send(Onboarding.Backup.Finished(backupState.backupCardsNumber)) } + var userWallet: UserWallet? = null if (scanResponse != null) { - val walletNameGenerateUseCase = store.inject(DaggerGraphState::generateWalletNameUseCase) - val userWallet = UserWalletBuilder(scanResponse, walletNameGenerateUseCase) - .backupCardsIds(backupState.backupCardIds.toSet()) - .build() - .guard { - Timber.e("User wallet not created") - return@launch - } + userWallet = createUserWallet( + scanResponse = requireNotNull(value = scanResponse, lazyMessage = { "ScanResponse is null" }), + backupState = backupState, + ) val userWalletsListManager = store.inject(DaggerGraphState::generalUserWalletsListManager) - userWalletsListManager.update( - userWalletId = userWallet.walletId, - update = { wallet -> - wallet.copy( - scanResponse = updateScanResponseAfterBackup( - scanResponse = wallet.scanResponse, - backupState = backupState, + userWalletsListManager.save( + userWallet = userWallet.copy( + scanResponse = updateScanResponseAfterBackup( + scanResponse = requireNotNull( + value = scanResponse, + lazyMessage = { "ScanResponse is null" }, ), - ) - }, + backupState = backupState, + ), + ), + canOverride = true, ) + } else { + readCard { newScanResponse -> + scanResponse = newScanResponse + userWallet = createUserWallet(newScanResponse, backupState) + } } val notActivatedCardIds = gatherCardIds(backupState, card).mapNotNull { @@ -613,11 +627,18 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction) } // All cardIds may already be activated if the backup was skipped before. - if (notActivatedCardIds.isEmpty()) return@launch + if (notActivatedCardIds.isEmpty()) { + delay(1000) + store.dispatch(BackupAction.BackupFinished(userWallet?.walletId)) + return@launch + } Analytics.send(Onboarding.Finished()) store.state.globalState.onboardingState.onboardingManager?.finishActivation(notActivatedCardIds) + handleFinishBackup(requireNotNull(scanResponse)) + delay(1000) + store.dispatch(BackupAction.BackupFinished(userWalletId = userWallet?.walletId)) } } @@ -629,6 +650,16 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction) } } +private suspend fun createUserWallet(scanResponse: ScanResponse, backupState: BackupState): UserWallet { + val walletNameGenerateUseCase = store.inject(DaggerGraphState::generateWalletNameUseCase) + return requireNotNull( + value = UserWalletBuilder(scanResponse, walletNameGenerateUseCase) + .backupCardsIds(backupState.backupCardIds.toSet()) + .build(), + lazyMessage = { "User wallet not created" }, + ) +} + fun updateArtworks(addedBackupCardsCount: Int, card: Card) { mainScope.launch { withIOContext { diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletReducer.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletReducer.kt index 035db68bae..ca8bfeb584 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletReducer.kt @@ -1,6 +1,7 @@ package com.tangem.tap.features.onboarding.products.wallet.redux import com.tangem.domain.common.util.cardTypesResolver +import com.tangem.domain.redux.OnboardingManageTokensAction import com.tangem.tap.backupService import com.tangem.tap.common.redux.AppState import com.tangem.tap.common.redux.global.GlobalAction @@ -10,12 +11,23 @@ object OnboardingWalletReducer { fun reduce(action: Action, state: AppState): OnboardingWalletState = internalReduce(action, state) } +@Suppress("CyclomaticComplexMethod") private fun internalReduce(action: Action, appState: AppState): OnboardingWalletState { val state = appState.onboardingWalletState return when (action) { is GlobalAction.Onboarding -> ReducerForGlobalAction.reduce(action, state) - is BackupAction -> state.copy(backupState = BackupReducer.reduce(action, state.backupState)) + is BackupAction.BackupFinished -> { + state.copy( + step = if (action.userWalletId != null) { + OnboardingWalletStep.ManageTokens + } else { + OnboardingWalletStep.Done + }, + userWalletId = action.userWalletId, + ) + } + is BackupAction -> state.copy(backupState = BackupReducer.reduce(action = action, state = state.backupState)) is OnboardingWallet2Action -> OnboardingWallet2Reducer.reduce(action, state) is OnboardingWalletAction.GetToCreateWalletStep -> state.copy( step = OnboardingWalletStep.CreateWallet, @@ -36,6 +48,11 @@ private fun internalReduce(action: Action, appState: AppState): OnboardingWallet walletImages = state.walletImages.copy(thirdCardImage = action.artworkUri), ) } + is OnboardingManageTokensAction.CurrenciesSaved -> state.copy(step = OnboardingWalletStep.Done) + is OnboardingWalletAction.WalletSaved -> state.copy( + step = OnboardingWalletStep.ManageTokens, + userWalletId = action.userWalletId, + ) is OnboardingWalletAction.Done -> state.copy(step = OnboardingWalletStep.Done) else -> state } diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletState.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletState.kt index 853678f202..192798e4cb 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletState.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletState.kt @@ -3,6 +3,7 @@ package com.tangem.tap.features.onboarding.products.wallet.redux import android.graphics.Bitmap import android.net.Uri import com.tangem.domain.redux.StateDialog +import com.tangem.domain.wallets.models.UserWalletId import org.rekotlin.StateType /** @@ -15,18 +16,19 @@ data class OnboardingWalletState( val walletImages: WalletImages = WalletImages(), val showConfetti: Boolean = false, val isRingOnboarding: Boolean = false, + val userWalletId: UserWalletId? = null, ) : StateType { @Suppress("MagicNumber") fun getMaxProgress(): Int { - val baseProgress = 6 + val baseProgress = 7 return getWallet2Progress() + baseProgress } @Suppress("ComplexMethod", "MagicNumber") fun getProgressStep(): Int { val progressByStep = when (step) { - OnboardingWalletStep.CreateWallet -> 1 + OnboardingWalletStep.CreateWallet, OnboardingWalletStep.None -> 1 OnboardingWalletStep.Backup -> { when (backupState.backupStep) { BackupStep.InitBackup -> 2 @@ -36,11 +38,11 @@ data class OnboardingWalletState( BackupStep.ReenterAccessCode -> 4 BackupStep.SetAccessCode -> 4 BackupStep.WritePrimaryCard, is BackupStep.WriteBackupCard -> 5 - BackupStep.Finished -> getMaxProgress() + BackupStep.Finished -> 6 } } + OnboardingWalletStep.ManageTokens -> 6 OnboardingWalletStep.Done -> getMaxProgress() - else -> 1 } return getWallet2Progress() + progressByStep @@ -60,7 +62,7 @@ data class OnboardingWallet2State( ) enum class OnboardingWalletStep { - None, CreateWallet, Backup, Done + None, CreateWallet, Backup, ManageTokens, Done } data class BackupState( diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/OnboardingWalletFragment.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/OnboardingWalletFragment.kt index fb9acfefd5..94c56bfd2c 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/OnboardingWalletFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/OnboardingWalletFragment.kt @@ -3,6 +3,8 @@ package com.tangem.tap.features.onboarding.products.wallet.ui import android.content.res.ColorStateList import android.net.Uri import android.os.Bundle +import android.os.Handler +import android.os.Looper import android.util.TypedValue import android.view.View import android.view.ViewGroup @@ -10,12 +12,16 @@ import android.view.WindowManager import android.widget.FrameLayout import android.widget.ImageView import androidx.appcompat.app.AppCompatActivity +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.ui.Modifier import androidx.core.view.MenuProvider import androidx.fragment.app.viewModels import androidx.lifecycle.lifecycleScope import androidx.transition.TransitionManager import by.kirich1409.viewbindingdelegate.viewBinding import coil.load +import com.arkivanov.decompose.defaultComponentContext import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.tabs.TabLayoutMediator import com.tangem.common.CardIdFormatter @@ -25,20 +31,26 @@ import com.tangem.common.routing.AppRoute import com.tangem.core.analytics.Analytics import com.tangem.core.analytics.models.AnalyticsParam import com.tangem.core.analytics.models.Basic +import com.tangem.core.decompose.context.AppComponentContext +import com.tangem.core.decompose.context.childByContext +import com.tangem.core.decompose.di.RootAppComponentContext import com.tangem.core.ui.extensions.setStatusBarColor +import com.tangem.core.ui.res.TangemTheme +import com.tangem.core.ui.windowsize.rememberWindowSize import com.tangem.datasource.utils.isNullOrEmpty import com.tangem.domain.common.util.cardTypesResolver +import com.tangem.domain.feedback.models.FeedbackEmailType +import com.tangem.domain.wallets.models.UserWalletId import com.tangem.feature.onboarding.data.model.CreateWalletResponse import com.tangem.feature.onboarding.presentation.wallet2.analytics.SeedPhraseSource import com.tangem.feature.onboarding.presentation.wallet2.viewmodel.SeedPhraseMediator import com.tangem.feature.onboarding.presentation.wallet2.viewmodel.SeedPhraseRouter import com.tangem.feature.onboarding.presentation.wallet2.viewmodel.SeedPhraseViewModel +import com.tangem.features.managetokens.component.OnboardingManageTokensComponent import com.tangem.sdk.ui.widget.leapfrogWidget.LeapfrogWidget import com.tangem.sdk.ui.widget.leapfrogWidget.PropertyCalculator import com.tangem.tap.common.analytics.events.Onboarding import com.tangem.tap.common.extensions.* -import com.tangem.tap.common.feedback.SupportInfo -import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.features.BaseFragment import com.tangem.tap.features.FragmentOnBackPressedHandler import com.tangem.tap.features.addBackPressHandler @@ -46,6 +58,8 @@ import com.tangem.tap.features.onboarding.OnboardingMenuProvider import com.tangem.tap.features.onboarding.products.wallet.redux.* import com.tangem.tap.features.onboarding.products.wallet.ui.dialogs.AccessCodeDialog import com.tangem.tap.mainScope +import com.tangem.tap.proxy.redux.DaggerGraphState +import com.tangem.tap.scope import com.tangem.tap.store import com.tangem.utils.Provider import com.tangem.wallet.R @@ -55,6 +69,7 @@ import com.tangem.wallet.databinding.ViewOnboardingProgressBinding import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch import org.rekotlin.StoreSubscriber +import javax.inject.Inject @Suppress("LargeClass", "MagicNumber") @AndroidEntryPoint @@ -63,10 +78,20 @@ class OnboardingWalletFragment : StoreSubscriber, FragmentOnBackPressedHandler { + @Inject + internal lateinit var onboardingManageTokensComponentFactory: OnboardingManageTokensComponent.Factory + + @Inject + @RootAppComponentContext + internal lateinit var rootComponentContext: AppComponentContext + + private var onboardingManageTokensComponent: OnboardingManageTokensComponent? = null + internal val binding: FragmentOnboardingWalletBinding by viewBinding(FragmentOnboardingWalletBinding::bind) internal val pbBinding: ViewOnboardingProgressBinding by viewBinding(ViewOnboardingProgressBinding::bind) internal val bindingSeedPhrase: LayoutOnboardingSeedPhraseBinding by lazy { binding.onboardingSeedPhraseContainer } + private val bindingManageTokens by lazy { binding.onboardingManageTokensContainer } private val canSkipBackup by lazy { arguments?.getBoolean(AppRoute.OnboardingWallet.CAN_SKIP_BACKUP_KEY) ?: true } @@ -172,26 +197,28 @@ class OnboardingWalletFragment : override fun onStop() { super.onStop() + onboardingManageTokensComponent = null store.unsubscribe(this) } override fun newState(state: OnboardingWalletState) { if (activity == null || view == null) return + Handler(Looper.getMainLooper()).post { + animator.updateBackupState(state.backupState) + requireActivity().invalidateOptionsMenu() - animator.updateBackupState(state.backupState) - requireActivity().invalidateOptionsMenu() + pbBinding.pbState.max = state.getMaxProgress() + pbBinding.pbState.progress = state.getProgressStep() - pbBinding.pbState.max = state.getMaxProgress() - pbBinding.pbState.progress = state.getProgressStep() - - when { - state.wallet2State != null -> { - seedPhraseStateHandler.newState(this, state, seedPhraseViewModel) - updateWalletImagesState(state.walletImages) - } - else -> { - updateWalletImagesState(state.walletImages) - handleOnboardingStep(state) + when { + state.wallet2State != null -> { + seedPhraseStateHandler.newState(this, state, seedPhraseViewModel) + updateWalletImagesState(state.walletImages) + } + else -> { + updateWalletImagesState(state.walletImages) + handleOnboardingStep(state) + } } } } @@ -219,14 +246,53 @@ class OnboardingWalletFragment : internal fun handleOnboardingStep(state: OnboardingWalletState) { when (state.step) { OnboardingWalletStep.CreateWallet -> setupCreateWalletState() - OnboardingWalletStep.Backup -> setBackupState( - state = state.backupState, - ) - + OnboardingWalletStep.Backup -> setBackupState(state = state.backupState) + OnboardingWalletStep.ManageTokens -> setManageTokensState(requireNotNull(state.userWalletId)) + OnboardingWalletStep.Done -> showSuccess() else -> {} } } + private fun initializeOnboardingManageTokensComponent(userWalletId: UserWalletId) { + val componentContext = rootComponentContext.childByContext( + componentContext = defaultComponentContext(onBackPressedDispatcher = null), + ) + onboardingManageTokensComponent = onboardingManageTokensComponentFactory.create( + context = componentContext, + params = OnboardingManageTokensComponent.Params(userWalletId = userWalletId), + ) + } + + private fun setManageTokensState(userWalletId: UserWalletId) { + with(binding) { + tvHeader.show() + tvBody.show() + viewPagerBackupInfo.hide() + tabLayoutBackupInfo.hide() + onboardingWalletContainer.show() + layoutButtonsCommon.btnWalletAlternativeAction.hide() + onboardingWalletContainer.hide() + toolbar.title = getText(R.string.onboarding_add_tokens) + } + pbBinding.pbState.show() + bindingSeedPhrase.onboardingSeedPhraseContainer.hide() + if (onboardingManageTokensComponent == null) { + initializeOnboardingManageTokensComponent(userWalletId) + } + with(bindingManageTokens) { + onboardingManageTokensContainer.hide() + onboardingManageTokensContainer.show() + onboardingManageTokensContainer.setContent { + TangemTheme( + isDark = isSystemInDarkTheme(), + windowSize = rememberWindowSize(activity = requireActivity()), + ) { + onboardingManageTokensComponent?.Content(modifier = Modifier.fillMaxSize()) + } + } + } + } + private fun setupCreateWalletState() = with(binding) { layoutButtonsCommon.btnWalletMainAction.setText(R.string.onboarding_create_wallet_button_create_wallet) layoutButtonsCommon.btnWalletMainAction.setIconResource(R.drawable.ic_tangem_24) @@ -255,7 +321,10 @@ class OnboardingWalletFragment : BackupStep.ReenterAccessCode -> showReenterAccessCode(state) is BackupStep.WritePrimaryCard -> showWritePrimaryCard(state) is BackupStep.WriteBackupCard -> showWriteBackupCard(state) - BackupStep.Finished -> showSuccess() + BackupStep.Finished -> { + // don't need to navigate here" + // showSuccess() + } } } @@ -453,6 +522,8 @@ class OnboardingWalletFragment : tvBody.show() viewPagerBackupInfo.hide() tabLayoutBackupInfo.hide() + onboardingWalletContainer.show() + bindingManageTokens.onboardingManageTokensContainer.hide() tvBody.text = getText(R.string.onboarding_subtitle_success_tangem_wallet_onboarding) layoutButtonsCommon.btnWalletMainAction.text = getText(R.string.onboarding_button_continue_wallet) @@ -510,14 +581,16 @@ class OnboardingWalletFragment : onBack = ::legacyOnBackHandler, onOpenChat = { Analytics.send(Basic.ButtonSupport(AnalyticsParam.ScreensSources.Intro)) - // changed on email support [REDACTED_TASK_KEY] - store.dispatch( - GlobalAction.SendEmail( - feedbackData = SupportInfo(), - scanResponse = store.state.globalState.onboardingState.onboardingManager?.scanResponse - ?: error("ScanResponse must be not null"), - ), - ) + + val scanResponse = requireNotNull(store.state.globalState.onboardingState.onboardingManager?.scanResponse) + + val getCardInfoUseCase = store.inject(DaggerGraphState::getCardInfoUseCase) + val cardInfo = requireNotNull(getCardInfoUseCase.invoke(scanResponse).getOrNull()) + + scope.launch { + store.inject(DaggerGraphState::sendFeedbackEmailUseCase) + .invoke(type = FeedbackEmailType.DirectUserRequest(cardInfo)) + } }, onOpenUriClick = { uri -> store.dispatchOpenUrl(uri.toString()) diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/dialogs/WalletActivationErrorDialog.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/dialogs/WalletActivationErrorDialog.kt index 45c8213362..aa0bf35450 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/dialogs/WalletActivationErrorDialog.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/dialogs/WalletActivationErrorDialog.kt @@ -6,12 +6,15 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.tangem.core.analytics.Analytics import com.tangem.core.analytics.models.AnalyticsParam import com.tangem.core.analytics.models.Basic +import com.tangem.domain.feedback.models.FeedbackEmailType import com.tangem.tap.common.extensions.dispatchDialogHide -import com.tangem.tap.common.feedback.SupportInfo -import com.tangem.tap.common.redux.global.GlobalAction +import com.tangem.tap.common.extensions.inject import com.tangem.tap.features.onboarding.OnboardingDialog +import com.tangem.tap.proxy.redux.DaggerGraphState +import com.tangem.tap.scope import com.tangem.tap.store import com.tangem.wallet.R +import kotlinx.coroutines.launch object WalletActivationErrorDialog { @@ -23,13 +26,17 @@ object WalletActivationErrorDialog { setNegativeButton(R.string.common_support) { _, _ -> // changed on email support [REDACTED_TASK_KEY] Analytics.send(Basic.ButtonSupport(AnalyticsParam.ScreensSources.Intro)) - store.dispatch( - GlobalAction.SendEmail( - feedbackData = SupportInfo(), - scanResponse = store.state.globalState.onboardingState.onboardingManager?.scanResponse - ?: error("ScanResponse must be not null"), - ), - ) + + val scanResponse = store.state.globalState.onboardingState.onboardingManager?.scanResponse + ?: error("ScanResponse must be not null") + + val cardInfo = store.inject(DaggerGraphState::getCardInfoUseCase).invoke(scanResponse).getOrNull() + ?: error("CardInfo must be not null") + + scope.launch { + store.inject(DaggerGraphState::sendFeedbackEmailUseCase) + .invoke(type = FeedbackEmailType.DirectUserRequest(cardInfo)) + } } setOnDismissListener { store.dispatchDialogHide() } setCancelable(false) diff --git a/app/src/main/java/com/tangem/tap/features/saveWallet/redux/SaveWalletAction.kt b/app/src/main/java/com/tangem/tap/features/saveWallet/redux/SaveWalletAction.kt index e79ea8b9fe..f4981a8c5c 100644 --- a/app/src/main/java/com/tangem/tap/features/saveWallet/redux/SaveWalletAction.kt +++ b/app/src/main/java/com/tangem/tap/features/saveWallet/redux/SaveWalletAction.kt @@ -24,5 +24,8 @@ internal sealed interface SaveWalletAction : Action { data object Cancel : SaveWalletAction } - data class SaveWalletAfterBackup(val hasBackupError: Boolean) : SaveWalletAction + data class SaveWalletAfterBackup( + val hasBackupError: Boolean, + val shouldNavigateToWallet: Boolean, + ) : SaveWalletAction } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/saveWallet/redux/SaveWalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/saveWallet/redux/SaveWalletMiddleware.kt index 7cb2506f8e..c8e093611d 100644 --- a/app/src/main/java/com/tangem/tap/features/saveWallet/redux/SaveWalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/saveWallet/redux/SaveWalletMiddleware.kt @@ -16,6 +16,7 @@ import com.tangem.tap.common.extensions.dispatchWithMain import com.tangem.tap.common.extensions.inject import com.tangem.tap.common.extensions.onUserWalletSelected import com.tangem.tap.common.redux.AppState +import com.tangem.tap.features.onboarding.products.wallet.redux.OnboardingWalletAction import com.tangem.tap.proxy.redux.DaggerGraphState import com.tangem.utils.coroutines.JobHolder import com.tangem.utils.coroutines.saveIn @@ -44,7 +45,11 @@ internal class SaveWalletMiddleware { is SaveWalletAction.AllowToUseBiometrics -> allowToUseBiometrics(state) is SaveWalletAction.EnrollBiometrics.Enroll -> enrollBiometrics() is SaveWalletAction.Dismiss -> dismiss(state) - is SaveWalletAction.SaveWalletAfterBackup -> saveWalletAfterBackup(state, action.hasBackupError) + is SaveWalletAction.SaveWalletAfterBackup -> saveWalletAfterBackup( + state = state, + hasBackupError = action.hasBackupError, + shouldNavigateToWallet = action.shouldNavigateToWallet, + ) is SaveWalletAction.AllowToUseBiometrics.Success, is SaveWalletAction.AllowToUseBiometrics.Error, is SaveWalletAction.ProvideBackupInfo, @@ -55,7 +60,11 @@ internal class SaveWalletMiddleware { } } - private fun saveWalletAfterBackup(state: SaveWalletState, hasBackupError: Boolean) { + private fun saveWalletAfterBackup( + state: SaveWalletState, + hasBackupError: Boolean, + shouldNavigateToWallet: Boolean, + ) { scope.launch { val backupInfo = state.backupInfo ?: error("Backup info is null") @@ -77,8 +86,13 @@ internal class SaveWalletMiddleware { .doOnFailure { error -> Timber.e(error, "Unable to save user wallet") } - .doOnSuccess { mainScope.launch { store.onUserWalletSelected(userWallet) } } - .doOnResult { navigateToWallet() } + .doOnSuccess { + mainScope.launch { store.onUserWalletSelected(userWallet) } + if (!shouldNavigateToWallet) { + store.dispatch(OnboardingWalletAction.WalletSaved(userWallet.walletId)) + } + } + .doOnResult { if (shouldNavigateToWallet) navigateToWallet() } } } diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/data/DefaultTokensListRepository.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/data/DefaultTokensListRepository.kt deleted file mode 100644 index ca1cf6190f..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/data/DefaultTokensListRepository.kt +++ /dev/null @@ -1,61 +0,0 @@ -package com.tangem.tap.features.tokens.impl.data - -import androidx.paging.Pager -import androidx.paging.PagingConfig -import androidx.paging.PagingData -import com.tangem.datasource.api.tangemTech.TangemTechApi -import com.tangem.datasource.local.testnet.TestnetTokensStorage -import com.tangem.domain.common.TapWorkarounds.isTestCard -import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase -import com.tangem.tap.features.tokens.impl.domain.TokensListRepository -import com.tangem.tap.features.tokens.impl.domain.models.Token -import com.tangem.utils.coroutines.CoroutineDispatcherProvider -import kotlinx.coroutines.flow.Flow - -/** - * Default repository implementation of tokens list feature - * - * @property tangemTechApi Tangem Tech API - * @property dispatchers coroutine dispatchers provider - * @property getSelectedWalletSyncUseCase use case that returns selected wallet - * @property testnetTokensStorage storage for getting testnet tokens data - * -[REDACTED_AUTHOR] - */ -internal class DefaultTokensListRepository( - private val tangemTechApi: TangemTechApi, - private val dispatchers: CoroutineDispatcherProvider, - private val getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase, - private val testnetTokensStorage: TestnetTokensStorage, -) : TokensListRepository { - - override fun getAvailableTokens(searchText: String?, needFilterExcluded: Boolean): Flow> { - return Pager( - config = PagingConfig( - pageSize = 100, - prefetchDistance = 70, - enablePlaceholders = false, - ), - pagingSourceFactory = { - val defaultSource = TangemApiTokensPagingSource( - api = tangemTechApi, - dispatchers = dispatchers, - getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase, - searchText = searchText, - needFilterExcluded = needFilterExcluded, - ) - - getSelectedWalletSyncUseCase().fold( - ifLeft = { defaultSource }, - ifRight = { - if (it.scanResponse.card.isTestCard) { - TestnetTokensPagingSource(testnetTokensStorage, searchText) - } else { - defaultSource - } - }, - ) - }, - ).flow - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/data/TangemApiTokensPagingSource.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/data/TangemApiTokensPagingSource.kt deleted file mode 100644 index dcacf9fef2..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/data/TangemApiTokensPagingSource.kt +++ /dev/null @@ -1,78 +0,0 @@ -package com.tangem.tap.features.tokens.impl.data - -import androidx.paging.PagingSource -import androidx.paging.PagingState -import com.tangem.blockchain.common.Blockchain -import com.tangem.blockchainsdk.utils.isSupportedInApp -import com.tangem.blockchainsdk.utils.toNetworkId -import com.tangem.datasource.api.common.response.getOrThrow -import com.tangem.datasource.api.tangemTech.TangemTechApi -import com.tangem.domain.common.extensions.supportedBlockchains -import com.tangem.domain.common.util.cardTypesResolver -import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase -import com.tangem.tap.features.tokens.impl.data.converters.CoinsResponseConverter -import com.tangem.tap.features.tokens.impl.domain.models.Token -import com.tangem.utils.coroutines.CoroutineDispatcherProvider -import com.tangem.utils.coroutines.runCatching - -/** - * Paging source that get tokens by Tangem Tech API - * - * @property api Tangem Tech API - * @property dispatchers coroutine dispatchers provider - * @property getSelectedWalletSyncUseCase use case that returns selected wallet - * @property searchText search text - * @property needFilterExcluded filter networks that are not supported in the app - */ -internal class TangemApiTokensPagingSource( - private val api: TangemTechApi, - private val dispatchers: CoroutineDispatcherProvider, - private val getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase, - private val searchText: String?, - private val needFilterExcluded: Boolean = false, -) : PagingSource() { - - private val coinsResponseConverter = CoinsResponseConverter(needFilterExcluded) - - private val allAvailableBlockchains by lazy { - Blockchain.entries - .filter { - it.isTestnet().not() && (needFilterExcluded.not() || it.isSupportedInApp()) - } - } - - override fun getRefreshKey(state: PagingState): Int? { - return state.anchorPosition?.let { anchorPosition -> - state.closestPageToPosition(anchorPosition)?.prevKey?.plus(other = 1) - ?: state.closestPageToPosition(anchorPosition)?.nextKey?.minus(other = 1) - } - } - - override suspend fun load(params: LoadParams): LoadResult { - val page = params.key ?: 0 - - return runCatching(dispatchers.io) { - val supportedBlockchains = getSelectedWalletSyncUseCase().fold( - ifLeft = { allAvailableBlockchains }, - ifRight = { it.scanResponse.card.supportedBlockchains(it.scanResponse.cardTypesResolver) }, - ) - - api.getCoins( - networkIds = supportedBlockchains.joinToString(separator = ",", transform = Blockchain::toNetworkId), - active = true, - searchText = searchText, - offset = page * params.loadSize, - limit = params.loadSize, - ).getOrThrow() - }.fold( - onSuccess = { response -> - LoadResult.Page( - data = coinsResponseConverter.convert(response), - prevKey = if (page == 0) null else page.minus(other = 1), - nextKey = if (response.coins.isEmpty()) null else page.plus(other = 1), - ) - }, - onFailure = { LoadResult.Error(it) }, - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/data/TestnetTokensPagingSource.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/data/TestnetTokensPagingSource.kt deleted file mode 100644 index 9525c329ba..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/data/TestnetTokensPagingSource.kt +++ /dev/null @@ -1,43 +0,0 @@ -package com.tangem.tap.features.tokens.impl.data - -import androidx.paging.PagingSource -import androidx.paging.PagingState -import com.tangem.datasource.local.testnet.TestnetTokensStorage -import com.tangem.datasource.local.testnet.models.TestnetTokensConfig -import com.tangem.tap.features.tokens.impl.data.converters.TestnetTokensConfigConverter -import com.tangem.tap.features.tokens.impl.domain.models.Token - -/** - * Paging source that get tokens by testnet tokens config - * - * @property testnetTokensStorage testnet tokens config storage - * @property searchText search text - */ -internal class TestnetTokensPagingSource( - private val testnetTokensStorage: TestnetTokensStorage, - private val searchText: String?, -) : PagingSource() { - - override fun getRefreshKey(state: PagingState): Int? = null - - override suspend fun load(params: LoadParams): LoadResult { - return LoadResult.Page( - data = TestnetTokensConfigConverter.convert( - value = testnetTokensStorage.getConfig().searchByText(searchText), - ), - prevKey = null, - nextKey = null, - ) - } - - private fun TestnetTokensConfig.searchByText(searchText: String?): TestnetTokensConfig { - if (searchText.isNullOrBlank()) return this - - return copy( - tokens = tokens.filter { token -> - token.symbol.contains(other = searchText, ignoreCase = true) || - token.name.contains(other = searchText, ignoreCase = true) - }, - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/data/converters/CoinsResponseConverter.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/data/converters/CoinsResponseConverter.kt deleted file mode 100644 index 2d620d45e8..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/data/converters/CoinsResponseConverter.kt +++ /dev/null @@ -1,57 +0,0 @@ -package com.tangem.tap.features.tokens.impl.data.converters - -import com.tangem.blockchain.common.Blockchain -import com.tangem.blockchainsdk.utils.fromNetworkId -import com.tangem.blockchainsdk.utils.isSupportedInApp -import com.tangem.datasource.api.tangemTech.models.CoinsResponse -import com.tangem.tap.features.tokens.impl.domain.models.Token -import com.tangem.utils.converter.Converter - -/** - * Converter from data model [CoinsResponse] to list of domain models [Token] - * -[REDACTED_AUTHOR] - */ -internal class CoinsResponseConverter(val needFilterExcluded: Boolean) : Converter> { - - override fun convert(value: CoinsResponse): List { - return value.coins.map { token -> - Token( - id = token.id, - name = token.name, - symbol = token.symbol, - iconUrl = getIconUrl(token.id, value.imageHost), - networks = token.networks.mapNotNull { network -> - val blockchain = Blockchain.fromNetworkId(network.networkId) ?: return@mapNotNull null - - if (needFilterExcluded && !blockchain.isSupportedInApp()) { - return@mapNotNull null - } - - // filter tokens, if contractAddress != null, assume that it is a token - if (network.contractAddress != null && - !blockchain.canHandleTokens() - ) { - return@mapNotNull null - } - - Token.Network( - id = network.networkId, - blockchain = blockchain, - address = network.contractAddress, - iconUrl = getIconUrl(network.networkId, value.imageHost), - decimalCount = network.decimalCount?.toInt(), - ) - }, - ) - }.filter { it.networks.isNotEmpty() } - } - - fun getIconUrl(id: String, imageHost: String? = null): String { - return "${imageHost ?: DEFAULT_IMAGE_HOST}large/$id.png" - } - - private companion object { - const val DEFAULT_IMAGE_HOST = "https://s3.eu-central-1.amazonaws.com/tangem.api/coins/" - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/data/converters/TestnetTokensConfigConverter.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/data/converters/TestnetTokensConfigConverter.kt deleted file mode 100644 index 561c8c123a..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/data/converters/TestnetTokensConfigConverter.kt +++ /dev/null @@ -1,38 +0,0 @@ -package com.tangem.tap.features.tokens.impl.data.converters - -import com.tangem.blockchain.common.Blockchain -import com.tangem.blockchainsdk.utils.fromNetworkId -import com.tangem.datasource.local.testnet.models.TestnetTokensConfig -import com.tangem.tap.features.tokens.impl.domain.models.Token -import com.tangem.utils.converter.Converter - -/** - * Converter from data model [TestnetTokensConfig] to list of domain models [Token] - * -[REDACTED_AUTHOR] - */ -internal object TestnetTokensConfigConverter : Converter> { - - private val coinsResponseConverter = CoinsResponseConverter(needFilterExcluded = false) - override fun convert(value: TestnetTokensConfig): List { - return value.tokens.map { token -> - Token( - id = token.id, - name = token.name, - symbol = token.symbol, - iconUrl = coinsResponseConverter.getIconUrl(token.id), - networks = token.networks?.mapNotNull { network -> - val blockchain = Blockchain.fromNetworkId(network.id) ?: return@mapNotNull null - - Token.Network( - id = network.id, - blockchain = blockchain, - address = network.address, - iconUrl = coinsResponseConverter.getIconUrl(network.id), - decimalCount = network.decimalCount, - ) - }.orEmpty(), - ) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/di/TokensListInteractorModule.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/di/TokensListInteractorModule.kt deleted file mode 100644 index 464420346b..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/di/TokensListInteractorModule.kt +++ /dev/null @@ -1,40 +0,0 @@ -package com.tangem.tap.features.tokens.impl.di - -import com.tangem.datasource.api.tangemTech.TangemTechApi -import com.tangem.datasource.local.testnet.TestnetTokensStorage -import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase -import com.tangem.tap.features.tokens.impl.data.DefaultTokensListRepository -import com.tangem.tap.features.tokens.impl.domain.DefaultTokensListInteractor -import com.tangem.tap.features.tokens.impl.domain.TokensListInteractor -import com.tangem.utils.coroutines.CoroutineDispatcherProvider -import dagger.Module -import dagger.Provides -import dagger.hilt.InstallIn -import dagger.hilt.android.components.ViewModelComponent -import dagger.hilt.android.scopes.ViewModelScoped - -/** -[REDACTED_AUTHOR] - */ -@Module -@InstallIn(ViewModelComponent::class) -internal object TokensListInteractorModule { - - @Provides - @ViewModelScoped - fun provideTokensListInteractor( - tangemTechApi: TangemTechApi, - dispatchers: CoroutineDispatcherProvider, - getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase, - testnetTokensStorage: TestnetTokensStorage, - ): TokensListInteractor { - return DefaultTokensListInteractor( - repository = DefaultTokensListRepository( - tangemTechApi = tangemTechApi, - dispatchers = dispatchers, - getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase, - testnetTokensStorage = testnetTokensStorage, - ), - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/di/TokensListRepositoryModule.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/di/TokensListRepositoryModule.kt deleted file mode 100644 index 186545138b..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/di/TokensListRepositoryModule.kt +++ /dev/null @@ -1,37 +0,0 @@ -package com.tangem.tap.features.tokens.impl.di - -import com.tangem.datasource.api.tangemTech.TangemTechApi -import com.tangem.datasource.local.testnet.TestnetTokensStorage -import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase -import com.tangem.tap.features.tokens.impl.data.DefaultTokensListRepository -import com.tangem.tap.features.tokens.impl.domain.TokensListRepository -import com.tangem.utils.coroutines.CoroutineDispatcherProvider -import dagger.Module -import dagger.Provides -import dagger.hilt.InstallIn -import dagger.hilt.components.SingletonComponent -import javax.inject.Singleton - -/** -[REDACTED_AUTHOR] - */ -@Module -@InstallIn(SingletonComponent::class) -internal object TokensListRepositoryModule { - - @Provides - @Singleton - fun providesTokensListRepository( - tangemTechApi: TangemTechApi, - dispatchers: CoroutineDispatcherProvider, - getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase, - testnetTokensStorage: TestnetTokensStorage, - ): TokensListRepository { - return DefaultTokensListRepository( - tangemTechApi = tangemTechApi, - dispatchers = dispatchers, - getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase, - testnetTokensStorage = testnetTokensStorage, - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/di/TokensListRouterModule.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/di/TokensListRouterModule.kt deleted file mode 100644 index 2a7da5cca4..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/di/TokensListRouterModule.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.tangem.tap.features.tokens.impl.di - -import com.tangem.tap.features.tokens.impl.presentation.router.DefaultTokensListRouter -import com.tangem.tap.features.tokens.impl.presentation.router.TokensListRouter -import dagger.Module -import dagger.Provides -import dagger.hilt.InstallIn -import dagger.hilt.android.components.ViewModelComponent -import dagger.hilt.android.scopes.ViewModelScoped - -/** -[REDACTED_AUTHOR] - */ -@Module -@InstallIn(ViewModelComponent::class) -internal object TokensListRouterModule { - - @Provides - @ViewModelScoped - fun provideTokensListRouter(): TokensListRouter = DefaultTokensListRouter() -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/domain/DefaultTokensListInteractor.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/domain/DefaultTokensListInteractor.kt deleted file mode 100644 index 0cb9da8c42..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/domain/DefaultTokensListInteractor.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.tangem.tap.features.tokens.impl.domain - -import androidx.paging.PagingData -import com.tangem.tap.features.tokens.impl.domain.models.Token -import kotlinx.coroutines.flow.Flow - -/** - * Default implementation of tokens list interactor - * - * @property repository repository of tokens list feature - */ -internal class DefaultTokensListInteractor(private val repository: TokensListRepository) : TokensListInteractor { - - override fun getTokensList(searchText: String, needFilterExcluded: Boolean): Flow> { - return repository.getAvailableTokens( - searchText = searchText.ifBlank(defaultValue = { null }), - needFilterExcluded = needFilterExcluded, - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/domain/TokensListInteractor.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/domain/TokensListInteractor.kt deleted file mode 100644 index 4b8edb914d..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/domain/TokensListInteractor.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.tangem.tap.features.tokens.impl.domain - -import androidx.paging.PagingData -import com.tangem.tap.features.tokens.impl.domain.models.Token -import kotlinx.coroutines.flow.Flow - -/** - * Interactor of tokens list feature - * -[REDACTED_AUTHOR] - */ -internal interface TokensListInteractor { - - /** Get tokens list using filter by text [searchText] */ - fun getTokensList(searchText: String, needFilterExcluded: Boolean): Flow> -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/domain/TokensListRepository.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/domain/TokensListRepository.kt deleted file mode 100644 index 67a9626b6b..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/domain/TokensListRepository.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.tangem.tap.features.tokens.impl.domain - -import androidx.paging.PagingData -import com.tangem.tap.features.tokens.impl.domain.models.Token -import kotlinx.coroutines.flow.Flow - -/** - * Repository of tokens list feature - * -[REDACTED_AUTHOR] - */ -internal interface TokensListRepository { - - /** - * Get available tokens list - * - * @param searchText search text - * @param needFilterExcluded flag that determines if excluded tokens should be filtered - * - * @throws com.tangem.datasource.api.common.response.ApiResponseError - */ - fun getAvailableTokens(searchText: String?, needFilterExcluded: Boolean): Flow> -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/domain/models/Token.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/domain/models/Token.kt deleted file mode 100644 index 72c6ecfdae..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/domain/models/Token.kt +++ /dev/null @@ -1,42 +0,0 @@ -package com.tangem.tap.features.tokens.impl.domain.models - -import com.tangem.blockchain.common.Blockchain - -/** - * Domain model of token for tokens list screen - * - * @property id token id - * @property name token name - * @property symbol token brief name. Example, "BTC" - * @property iconUrl token icon url - * @property networks token networks - * -[REDACTED_AUTHOR] - */ -internal data class Token( - val id: String, - val name: String, - val symbol: String, - val iconUrl: String, - val networks: List, -) { - - /** - * Domain model of network for tokens list screen - * - * @property id network id - * @property blockchain blockchain - * @property address address. If address equals null, it means it is the main network of token - * @property iconUrl network icon url - * @property decimalCount decimal count - * -[REDACTED_AUTHOR] - */ - data class Network( - val id: String, - val blockchain: Blockchain, - val address: String?, - val iconUrl: String, - val decimalCount: Int?, - ) -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/TokensListFragment.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/TokensListFragment.kt deleted file mode 100644 index ed260691fe..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/TokensListFragment.kt +++ /dev/null @@ -1,34 +0,0 @@ -package com.tangem.tap.features.tokens.impl.presentation - -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalLifecycleOwner -import androidx.hilt.navigation.compose.hiltViewModel -import com.tangem.core.ui.UiDependencies -import com.tangem.core.ui.screen.ComposeFragment -import com.tangem.tap.features.tokens.impl.presentation.ui.TokensListScreen -import com.tangem.tap.features.tokens.impl.presentation.viewmodels.TokensListViewModel -import dagger.hilt.android.AndroidEntryPoint -import javax.inject.Inject - -/** - * Fragment with list of tokens - * -[REDACTED_AUTHOR] - */ -@AndroidEntryPoint -internal class TokensListFragment : ComposeFragment() { - - @Inject - override lateinit var uiDependencies: UiDependencies - - @Composable - override fun ScreenContent(modifier: Modifier) { - val viewModel = hiltViewModel().apply { - LocalLifecycleOwner.current.lifecycle.addObserver(this) - } - TokensListScreen( - stateHolder = viewModel.uiState, - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/models/SupportTokensState.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/models/SupportTokensState.kt deleted file mode 100644 index 0917dcb2f9..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/models/SupportTokensState.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.tangem.tap.features.tokens.impl.presentation.models - -/** - * State that shows is token support by given card - */ -sealed class SupportTokensState { - - object NetworkTokensUnsupported : SupportTokensState() - object UnsupportedCurve : SupportTokensState() - object SupportedToken : SupportTokensState() -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/router/DefaultTokensListRouter.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/router/DefaultTokensListRouter.kt deleted file mode 100644 index d9142d235c..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/router/DefaultTokensListRouter.kt +++ /dev/null @@ -1,77 +0,0 @@ -package com.tangem.tap.features.tokens.impl.presentation.router - -import com.tangem.blockchain.common.Blockchain -import com.tangem.common.routing.AppRoute -import com.tangem.common.routing.AppRouter - -import com.tangem.tap.common.extensions.dispatchDialogShow -import com.tangem.tap.common.extensions.dispatchNavigationAction -import com.tangem.tap.common.extensions.dispatchNotification -import com.tangem.tap.common.redux.AppDialog -import com.tangem.tap.store -import com.tangem.wallet.R - -/** - * Default implementation of tokens list router - * FIXME("Necessary to avoid using redux actions") - * -[REDACTED_AUTHOR] - */ -internal class DefaultTokensListRouter : TokensListRouter { - - override fun popBackStack() { - store.dispatchNavigationAction(AppRouter::pop) - } - - override fun openAddCustomTokenScreen() { - store.dispatchNavigationAction { push(AppRoute.AddCustomToken) } - } - - override fun showAddressCopiedNotification() { - store.dispatchNotification(R.string.contract_address_copied_message) - } - - override fun openUnableHideMainTokenAlert(tokenName: String, tokenSymbol: String, networkName: String) { - store.dispatchDialogShow( - dialog = AppDialog.TokensAreLinkedDialog( - currencyTitle = tokenName, - currencySymbol = tokenSymbol, - networkName = networkName, - ), - ) - } - - override fun openRemoveWalletAlert(tokenName: String, onOkClick: () -> Unit) { - store.dispatchDialogShow( - dialog = AppDialog.RemoveWalletDialog(currencyTitle = tokenName, onOk = onOkClick), - ) - } - - override fun openUnsupportedNetworkAlert(blockchain: Blockchain) { - val alert = AppDialog.SimpleOkDialogRes( - headerId = R.string.common_warning, - messageId = R.string.alert_manage_tokens_unsupported_curve_message, - args = listOf(blockchain.getNetworkName()), - ) - store.dispatchDialogShow(alert) - } - - override fun showGenericErrorAlertAndPopBack() { - val alert = AppDialog.SimpleOkDialogRes( - headerId = R.string.common_error, - messageId = R.string.common_unknown_error, - onOk = { store.dispatchNavigationAction(AppRouter::pop) }, - ) - store.dispatchDialogShow(alert) - } - - override fun openNetworkTokensNotSupportAlert(networkName: String) { - store.dispatchDialogShow( - AppDialog.SimpleOkDialogRes( - headerId = R.string.common_warning, - messageId = R.string.alert_manage_tokens_unsupported_message, - args = listOf(networkName), - ), - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/router/TokensListRouter.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/router/TokensListRouter.kt deleted file mode 100644 index a11e584564..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/router/TokensListRouter.kt +++ /dev/null @@ -1,46 +0,0 @@ -package com.tangem.tap.features.tokens.impl.presentation.router - -import com.tangem.blockchain.common.Blockchain - -/** Tokens list feature router */ -internal interface TokensListRouter { - - /** Return to last screen */ - fun popBackStack() - - /** Open adding custom token screen */ - fun openAddCustomTokenScreen() - - /** Show notification to inform about copied address */ - fun showAddressCopiedNotification() - - /** - * Open alert if unable to hide the main token - * - * @param tokenName token name - * @param tokenSymbol token brief name - * @param networkName blockchain network full name - */ - fun openUnableHideMainTokenAlert(tokenName: String, tokenSymbol: String, networkName: String) - - /** - * Open alert to remove wallet - * - * @param tokenName token name - * @param onOkClick lambda be invoked if OkButton is been clicked - */ - fun openRemoveWalletAlert(tokenName: String, onOkClick: () -> Unit) - - /** Open alert if solana network is unsupported - * - * @param blockchain blockchain to show alert - */ - fun openUnsupportedNetworkAlert(blockchain: Blockchain) - - fun showGenericErrorAlertAndPopBack() - - /** - * Open alert with unsupported networks tokens error - */ - fun openNetworkTokensNotSupportAlert(networkName: String) -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/states/NetworkItemState.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/states/NetworkItemState.kt deleted file mode 100644 index a78f074e16..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/states/NetworkItemState.kt +++ /dev/null @@ -1,82 +0,0 @@ -package com.tangem.tap.features.tokens.impl.presentation.states - -import androidx.compose.runtime.MutableState -import com.tangem.blockchain.common.Blockchain -import com.tangem.core.ui.extensions.getActiveIconRes -import com.tangem.core.ui.extensions.getGreyedOutIconRes - -/** - * Network item state - * -[REDACTED_AUTHOR] - */ -sealed interface NetworkItemState { - - /** Network name */ - val name: String - - /** Network protocol name */ - val protocolName: String - - /** Network icon id from resources */ - val iconResId: MutableState - - /** Flag that determines if the network is the main network for the token */ - val isMainNetwork: Boolean - - /** - * Network item state that is available for read - * - * @property name network name - * @property protocolName network protocol name - * @property iconResId network icon id from resources - * @property isMainNetwork flag that determines if the network is the main network for the token - */ - data class ReadContent( - override val name: String, - override val protocolName: String, - override val iconResId: MutableState, - override val isMainNetwork: Boolean, - ) : NetworkItemState - - /** - * Network item state that is available for read and edit - * - * @property name network name - * @property protocolName network protocol name - * @property iconResId network icon id from resources - * @property isMainNetwork flag that determines if the network is the main network for the token - * @property isAdded flag that determines if the user has saved the token - * @property id network id - * @property address contract address - * @property decimalCount decimal count - * @property blockchain blockchain - * @property onToggleClick lambda be invoked when switch is been toggled - * @property onNetworkClick lambda be invoked when network item is been clicked - */ - data class ManageContent( - override val name: String, - override val protocolName: String, - override val iconResId: MutableState, - override val isMainNetwork: Boolean, - val isAdded: MutableState, - val id: String, - val address: String?, - val decimalCount: Int?, - val blockchain: Blockchain, - val onToggleClick: (TokenItemState.ManageContent, ManageContent) -> Unit, - val onNetworkClick: () -> Unit, - ) : NetworkItemState { - - /** - * Change toggle state [isAdded]. - * - * It is a hack that helps us to change element of flow - */ - fun changeToggleState() { - val reverseState = !isAdded.value - isAdded.value = reverseState - iconResId.value = if (reverseState) getActiveIconRes(blockchain.id) else getGreyedOutIconRes(blockchain.id) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/states/TokenItemState.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/states/TokenItemState.kt deleted file mode 100644 index a5f9c615fd..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/states/TokenItemState.kt +++ /dev/null @@ -1,68 +0,0 @@ -package com.tangem.tap.features.tokens.impl.presentation.states - -import androidx.compose.runtime.Immutable -import kotlinx.collections.immutable.ImmutableList - -/** - * Token item state. - * All subclasses is stable, but @Immutable annotation is required to use this sealed class like as - * field of TokensListStateHolder. - * -[REDACTED_AUTHOR] - */ -@Immutable -sealed interface TokenItemState { - - /** Token id */ - val id: String - - /** Token full name (name with symbol) */ - val fullName: String - - /** Token icon url */ - val iconUrl: String - - /** List of networks */ - val networks: ImmutableList - - /** Token composed id that unique for tokens in different networks */ - val composedId: String - - /** - * Token item state that is available for read - * - * @property id token id - * @property fullName token name - * @property iconUrl token icon url - * @property networks list of networks that is available for read - * @property composedId token composed id to use in lists - */ - data class ReadContent( - override val id: String, - override val fullName: String, - override val iconUrl: String, - override val networks: ImmutableList, - override val composedId: String, - ) : TokenItemState - - /** - * Token item state that is available for read and manage - * - * @property id token id - * @property fullName token name - * @property iconUrl token icon url - * @property networks list of networks is available for read and edit - * @property composedId token composed id to use in lists - * @property name token name - * @property symbol token brief name - */ - data class ManageContent( - override val id: String, - override val fullName: String, - override val iconUrl: String, - override val networks: ImmutableList, - override val composedId: String, - val name: String, - val symbol: String, - ) : TokenItemState -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/states/TokensListStateHolder.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/states/TokensListStateHolder.kt deleted file mode 100644 index bf48a93269..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/states/TokensListStateHolder.kt +++ /dev/null @@ -1,101 +0,0 @@ -package com.tangem.tap.features.tokens.impl.presentation.states - -import androidx.compose.runtime.Immutable -import androidx.paging.LoadState -import androidx.paging.PagingData -import kotlinx.coroutines.flow.Flow - -/** - * State holder for screen with list of tokens - * -[REDACTED_AUTHOR] - */ -@Immutable -internal sealed interface TokensListStateHolder { - - /** Toolbar state */ - val toolbarState: TokensListToolbarState - - /** Loading state */ - val isLoading: Boolean - - /** Flag that determines if warning block is visible */ - val isDifferentAddressesBlockVisible: Boolean - - /** Tokens list */ - val tokens: Flow> - - /** Callback to be invoked when [tokens] loading state is been changed */ - val onTokensLoadStateChanged: (LoadState) -> Unit - - /** - * Util function that allow to make a copy - * - * @param toolbarState toolbar state - * @param isLoading loading state - * @param isDifferentAddressesBlockVisible flag that determines if warning block is visible - * @param tokens tokens list - * @param onTokensLoadStateChanged callback to be invoked when tokens loading state is been changed - */ - fun copySealed( - toolbarState: TokensListToolbarState = this.toolbarState, - isLoading: Boolean = this.isLoading, - isDifferentAddressesBlockVisible: Boolean = this.isDifferentAddressesBlockVisible, - tokens: Flow> = this.tokens, - onTokensLoadStateChanged: (LoadState) -> Unit = this.onTokensLoadStateChanged, - ): TokensListStateHolder { - return when (this) { - is ManageContent -> copy( - toolbarState, - isLoading, - isDifferentAddressesBlockVisible, - tokens, - onTokensLoadStateChanged, - ) - is ReadContent -> copy( - toolbarState, - isLoading, - isDifferentAddressesBlockVisible, - tokens, - onTokensLoadStateChanged, - ) - } - } - - /** - * State screen that is available only for read - * - * @property toolbarState toolbar state - * @property isLoading loading state - * @property isDifferentAddressesBlockVisible flag that determines if warning block is visible - * @property tokens tokens list - * @property onTokensLoadStateChanged callback to be invoked when tokens loading state is been changed - */ - data class ReadContent( - override val toolbarState: TokensListToolbarState, - override val isLoading: Boolean, - override val isDifferentAddressesBlockVisible: Boolean, - override val tokens: Flow>, - override val onTokensLoadStateChanged: (LoadState) -> Unit, - ) : TokensListStateHolder - - /** - * State screen that is available for read and manage - * - * @property toolbarState toolbar state - * @property isLoading loading state - * @property isDifferentAddressesBlockVisible flag that determines if warning block is visible - * @property tokens tokens list - * @property onTokensLoadStateChanged callback to be invoked when tokens loading state is been changed - * @property onSaveButtonClick callback to be invoked when SaveButton is being clicked - */ - data class ManageContent( - override val toolbarState: TokensListToolbarState, - override val isLoading: Boolean, - override val isDifferentAddressesBlockVisible: Boolean, - override val tokens: Flow>, - override val onTokensLoadStateChanged: (LoadState) -> Unit, - val onSaveButtonClick: () -> Unit, - val isSavingInProgress: Boolean, - ) : TokensListStateHolder -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/states/TokensListToolbarState.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/states/TokensListToolbarState.kt deleted file mode 100644 index a269659991..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/states/TokensListToolbarState.kt +++ /dev/null @@ -1,68 +0,0 @@ -package com.tangem.tap.features.tokens.impl.presentation.states - -import androidx.compose.runtime.Immutable - -/** - * Toolbar state. - * All subclasses is stable, but @Immutable annotation is required to use this sealed class like as - * field of TokensListStateHolder. - */ -@Immutable -sealed interface TokensListToolbarState { - - /** Callback to be invoked when BackButton is being clicked */ - val onBackButtonClick: () -> Unit - - /** Toolbar state as title */ - sealed interface Title : TokensListToolbarState { - - /** Toolbar title id from resources */ - val titleResId: Int - - /** Callback to be invoked when SearchButton is being clicked */ - val onSearchButtonClick: () -> Unit - - /** - * Title state that is available only for read - * - * @property onBackButtonClick callback to be invoked when BackButton is being clicked - * @property titleResId toolbar title id from resources - * @property onSearchButtonClick callback to be invoked when SearchButton is being clicked - */ - data class Read( - override val onBackButtonClick: () -> Unit, - override val titleResId: Int, - override val onSearchButtonClick: () -> Unit, - ) : Title - - /** - * Title state that is available for read and manage - * - * @property onBackButtonClick callback to be invoked when BackButton is being clicked - * @property titleResId toolbar title id from resources - * @property onSearchButtonClick callback to be invoked when SearchButton is being clicked - * @property onAddCustomTokenClick callback to be invoked when AddCustomTokenButton is being clicked - */ - data class Manage( - override val onBackButtonClick: () -> Unit, - override val titleResId: Int, - override val onSearchButtonClick: () -> Unit, - val onAddCustomTokenClick: () -> Unit, - ) : Title - } - - /** - * Toolbar state as input field - * - * @property onBackButtonClick callback to be invoked when BackButton is being clicked - * @property value input value - * @property onValueChange lambda to be invoked when search value is being changed - * @property onCleanButtonClick callback to be invoked when CleanButton is being clicked - */ - data class InputField( - override val onBackButtonClick: () -> Unit, - val value: String, - val onValueChange: (String) -> Unit, - val onCleanButtonClick: () -> Unit, - ) : TokensListToolbarState -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/ui/BriefNetworksList.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/ui/BriefNetworksList.kt deleted file mode 100644 index 4091e53c06..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/ui/BriefNetworksList.kt +++ /dev/null @@ -1,144 +0,0 @@ -package com.tangem.tap.features.tokens.impl.presentation.ui - -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.Icon -import androidx.compose.material.Text -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.draw.drawWithContent -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.TextUnit -import androidx.compose.ui.unit.TextUnitType -import com.tangem.core.ui.res.TangemTheme -import com.tangem.tap.features.tokens.impl.presentation.states.NetworkItemState -import kotlinx.collections.immutable.ImmutableCollection - -/** This const configures how many items show to user and hide more than*/ -private const val MAX_VISIBLE_BRIEF_ICONS = 9 - -/** -[REDACTED_AUTHOR] - */ -@Composable -internal fun BriefNetworksList( - isCollapsed: Boolean, - networks: ImmutableCollection, - modifier: Modifier = Modifier, -) { - AnimatedVisibility( - visible = isCollapsed, - modifier = modifier, - enter = fadeIn(), - exit = fadeOut(), - ) { - Row(horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing4)) { - for ((index, network) in networks.withIndex()) { - if (index < MAX_VISIBLE_BRIEF_ICONS) { - key(network.name + network.protocolName) { - BriefNetworkItem(model = network) - } - } else { - if (networks.size < MAX_VISIBLE_BRIEF_ICONS + 1) { - key(network.name + network.protocolName) { - BriefNetworkItem(model = network) - } - } else { - HasMoreItem(moreCount = networks.size - index) - break - } - } - } - } - } -} - -/** -[REDACTED_AUTHOR] - */ -@Composable -internal fun BriefNetworkItem(model: NetworkItemState, modifier: Modifier = Modifier) { - val isAdded = model is NetworkItemState.ManageContent && model.isAdded.value - Box(modifier = modifier.size(size = TangemTheme.dimens.size20)) { - if (!isAdded) { - Box( - modifier = Modifier - .size(TangemTheme.dimens.size20) - .clip(CircleShape) - .background(TangemTheme.colors.control.unchecked), - ) - } - Icon( - painter = painterResource(id = model.iconResId.value), - contentDescription = null, - modifier = Modifier - .size(size = TangemTheme.dimens.size20) - .clip(CircleShape), - tint = if (isAdded) Color.Unspecified else TangemTheme.colors.text.tertiary, - ) - - if (model.isMainNetwork) { - Box( - modifier = Modifier - .align(Alignment.TopEnd) - .size(TangemTheme.dimens.size7) - .clip(CircleShape) - .background(TangemTheme.colors.background.primary), - contentAlignment = Alignment.Center, - ) { - Box( - modifier = Modifier - .size(TangemTheme.dimens.size5) - .clip(CircleShape) - .background(TangemTheme.colors.icon.accent), - ) - } - } - } -} - -@Suppress("MagicNumber") -@Composable -internal fun HasMoreItem(moreCount: Int) { - val count = if (moreCount > 99) 99 else moreCount - val themeTextStyle = TangemTheme.typography.overline.copy( - letterSpacing = TextUnit(value = 0f, type = TextUnitType.Sp), - ) - var textStyle by remember(themeTextStyle) { mutableStateOf(themeTextStyle) } - var readyToDraw by remember(themeTextStyle) { mutableStateOf(false) } - - Box( - modifier = Modifier - .size(size = TangemTheme.dimens.size20) - .clip(CircleShape) - .background(TangemTheme.colors.control.unchecked), - ) { - Text( - modifier = Modifier - .align(Alignment.Center) - .drawWithContent { if (readyToDraw) drawContent() }, - text = "+$count", - style = textStyle, - color = TangemTheme.colors.text.tertiary, - overflow = TextOverflow.Clip, - onTextLayout = { textLayoutResult -> - if (textLayoutResult.hasVisualOverflow) { - textStyle = textStyle.copy(fontSize = textStyle.fontSize * 0.9) - } else { - readyToDraw = true - } - }, - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/ui/DetailedNetworksList.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/ui/DetailedNetworksList.kt deleted file mode 100644 index 12620898b6..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/ui/DetailedNetworksList.kt +++ /dev/null @@ -1,163 +0,0 @@ -package com.tangem.tap.features.tokens.impl.presentation.ui - -import android.content.res.Configuration -import androidx.compose.animation.* -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.combinedClickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.* -import androidx.compose.material.Switch -import androidx.compose.material.SwitchDefaults -import androidx.compose.material.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.key -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalClipboardManager -import androidx.compose.ui.text.AnnotatedString -import androidx.compose.ui.text.SpanStyle -import androidx.compose.ui.text.buildAnnotatedString -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.withStyle -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.sp -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.tap.features.tokens.impl.presentation.states.NetworkItemState -import com.tangem.tap.features.tokens.impl.presentation.states.TokenItemState -import kotlinx.collections.immutable.ImmutableCollection - -/** -[REDACTED_AUTHOR] - */ -@Composable -internal fun DetailedNetworksList( - isExpanded: Boolean, - token: TokenItemState, - networks: ImmutableCollection, - modifier: Modifier = Modifier, -) { - AnimatedVisibility( - visible = isExpanded, - modifier = modifier, - enter = fadeIn() + expandVertically(), - exit = shrinkVertically() + fadeOut(), - ) { - Column { - networks.forEachIndexed { index, network -> - key(network.name + network.protocolName) { - DetailedNetworkItem(token = token, network = network, isLastItem = networks.size - 1 == index) - } - } - } - } -} - -@OptIn(ExperimentalFoundationApi::class) -@Composable -private fun DetailedNetworkItem(token: TokenItemState, network: NetworkItemState, isLastItem: Boolean) { - val clipboardManager = LocalClipboardManager.current - val itemHeight = TangemTheme.dimens.size50 - - Row( - modifier = Modifier - .combinedClickable( - enabled = network is NetworkItemState.ManageContent, - onLongClick = { - if (network is NetworkItemState.ManageContent && network.address != null) { - clipboardManager.setText(AnnotatedString(text = network.address)) - network.onNetworkClick() - } - }, - onClick = {}, - indication = null, - interactionSource = remember { MutableInteractionSource() }, - ) - .fillMaxWidth() - .heightIn(min = itemHeight) - .padding(start = TangemTheme.dimens.spacing38), - verticalAlignment = Alignment.CenterVertically, - ) { - NetworkItemArrow(itemHeight = itemHeight, isLastItem = isLastItem) - Spacer(modifier = Modifier.width(TangemTheme.dimens.spacing16)) - BriefNetworkItem(model = network) - Spacer(modifier = Modifier.width(TangemTheme.dimens.spacing6)) - NetworkTitle(model = network) - - if (network is NetworkItemState.ManageContent) { - Switch( - checked = network.isAdded.value, - onCheckedChange = { - network.onToggleClick( - requireNotNull(token as? TokenItemState.ManageContent), - network, - ) - }, - modifier = Modifier.padding(start = TangemTheme.dimens.spacing16, end = TangemTheme.dimens.spacing8), - colors = SwitchDefaults.colors( - checkedThumbColor = TangemTheme.colors.control.key, - checkedTrackColor = TangemTheme.colors.icon.accent, - uncheckedThumbColor = TangemTheme.colors.control.key, - uncheckedTrackColor = TangemTheme.colors.icon.informative, - ), - ) - } - } -} - -@Composable -private fun RowScope.NetworkTitle(model: NetworkItemState) { - Text( - modifier = Modifier.weight(1f), - text = buildAnnotatedString { - append(text = model.name) - append(text = " ") - withStyle( - style = SpanStyle( - fontWeight = FontWeight.Normal, - color = if (model.isMainNetwork) { - TangemTheme.colors.icon.accent - } else { - TangemTheme.colors.icon.secondary - }, - ), - ) { - append(text = model.protocolName) - } - }, - fontWeight = FontWeight.SemiBold, - fontSize = 13.sp, - color = if (model is NetworkItemState.ManageContent && model.isAdded.value) { - TangemTheme.colors.text.primary1 - } else { - TangemTheme.colors.text.secondary - }, - ) -} - -@Preview -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun Preview_DetailedNetworksList_ManageAccess() { - TangemThemePreview { - DetailedNetworksList( - isExpanded = true, - token = TokenListPreviewData.createManageToken(), - networks = TokenListPreviewData.createManageNetworksList(), - ) - } -} - -@Preview -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun Preview_DetailedNetworksList_ReadAccess() { - TangemThemePreview { - DetailedNetworksList( - isExpanded = true, - token = TokenListPreviewData.createReadToken(), - networks = TokenListPreviewData.createReadNetworksList(), - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/ui/NetworkItemArrow.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/ui/NetworkItemArrow.kt deleted file mode 100644 index b51b65f1c0..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/ui/NetworkItemArrow.kt +++ /dev/null @@ -1,58 +0,0 @@ -package com.tangem.tap.features.tokens.impl.presentation.ui - -import android.content.res.Configuration -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.material.Icon -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.core.ui.res.TangemTheme -import com.tangem.wallet.R - -private const val SPECIAL_HEIGHT_3_5 = 3.5 - -/** -[REDACTED_AUTHOR] - */ -@Composable -internal fun NetworkItemArrow(itemHeight: Dp, isLastItem: Boolean) { - Box(modifier = Modifier.height(height = itemHeight)) { - if (!isLastItem) { - Box( - modifier = Modifier - .padding(start = TangemTheme.dimens.spacing0_5) - .background(color = TangemTheme.colors.stroke.primary) - .size(width = TangemTheme.dimens.size1, height = itemHeight), - ) - } - - Icon( - painter = painterResource(id = R.drawable.ic_link), - contentDescription = null, - modifier = Modifier.height(height = itemHeight / 2 + SPECIAL_HEIGHT_3_5.dp), - tint = TangemTheme.colors.stroke.primary, - ) - } -} - -@Preview -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun Preview_NetworkItemArrow_Column() { - TangemThemePreview { - Column( - modifier = Modifier - .fillMaxWidth() - .background(color = TangemTheme.colors.background.primary) - .padding(start = TangemTheme.dimens.size36), - ) { - NetworkItemArrow(itemHeight = TangemTheme.dimens.size62, isLastItem = false) - NetworkItemArrow(itemHeight = TangemTheme.dimens.size62, isLastItem = true) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/ui/TokenItem.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/ui/TokenItem.kt deleted file mode 100644 index ce1967b48b..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/ui/TokenItem.kt +++ /dev/null @@ -1,236 +0,0 @@ -package com.tangem.tap.features.tokens.impl.presentation.ui - -import android.content.res.Configuration -import androidx.compose.animation.* -import androidx.compose.foundation.background -import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.foundation.layout.* -import androidx.compose.material.Icon -import androidx.compose.material.IconButton -import androidx.compose.material.Text -import androidx.compose.runtime.* -import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.toArgb -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.tooling.preview.Preview -import androidx.constraintlayout.compose.ConstraintLayout -import androidx.constraintlayout.compose.Dimension -import coil.compose.SubcomposeAsyncImage -import coil.request.ImageRequest -import com.tangem.core.ui.components.CurrencyPlaceholderIcon -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.utils.ImageBackgroundContrastChecker -import com.tangem.tap.features.tokens.impl.presentation.states.TokenItemState -import com.tangem.wallet.R -import kotlinx.coroutines.launch - -/** -[REDACTED_AUTHOR] - */ -@Suppress("LongMethod") -@Composable -internal fun TokenItem(model: TokenItemState) { - var isExpanded by rememberSaveable { mutableStateOf(value = false) } - var iconBackgroundColor by remember { mutableStateOf(Color.Transparent) } - - ConstraintLayout( - modifier = Modifier - .fillMaxWidth() - .background(color = TangemTheme.colors.background.primary) - .padding(top = TangemTheme.dimens.spacing16), - ) { - val (icon, title, availableNetworksText) = createRefs() - val (briefNetworksList, detailedNetworksList, changeNetworksViewButton) = createRefs() - - val spacing16 = TangemTheme.dimens.spacing16 - val spacing6 = TangemTheme.dimens.spacing6 - - Box( - modifier = Modifier - .background( - color = iconBackgroundColor, - shape = TangemTheme.shapes.roundedCorners8, - ) - .size(TangemTheme.dimens.size46) - .constrainAs(icon) { - top.linkTo(parent.top) - start.linkTo(anchor = parent.start, margin = spacing16) - }, - ) { - Icon( - name = model.fullName, - iconUrl = model.iconUrl, - onContrastCalculate = { iconBackgroundColor = it }, - ) - } - - Title( - title = model.fullName, - modifier = Modifier.constrainAs(title) { - top.linkTo(parent.top) - start.linkTo(icon.end, margin = spacing16) - end.linkTo(anchor = changeNetworksViewButton.start, margin = spacing16) - width = Dimension.fillToConstraints - }, - ) - - Subtitle( - isExpanded = isExpanded, - modifier = Modifier.constrainAs(availableNetworksText) { - top.linkTo(title.bottom, margin = spacing6) - start.linkTo(icon.end, margin = spacing16) - end.linkTo(anchor = changeNetworksViewButton.start, margin = spacing16) - width = Dimension.fillToConstraints - }, - ) - - BriefNetworksList( - isCollapsed = !isExpanded, - networks = model.networks, - modifier = Modifier.constrainAs(briefNetworksList) { - top.linkTo(title.bottom, margin = spacing6) - start.linkTo(icon.end, margin = spacing16) - end.linkTo(anchor = changeNetworksViewButton.start, margin = spacing16) - width = Dimension.fillToConstraints - }, - ) - - DetailedNetworksList( - isExpanded = isExpanded, - token = model, - networks = model.networks, - modifier = Modifier.constrainAs(detailedNetworksList) { - top.linkTo(anchor = availableNetworksText.bottom, margin = spacing16) - centerHorizontallyTo(parent) - width = Dimension.fillToConstraints - }, - ) - - ChangeNetworksViewButton( - isExpanded = isExpanded, - onClick = { isExpanded = !isExpanded }, - modifier = Modifier.constrainAs(changeNetworksViewButton) { - top.linkTo(parent.top) - end.linkTo(anchor = parent.end, margin = spacing6) - if (!isExpanded) bottom.linkTo(parent.bottom) - }, - ) - } -} - -@Composable -private fun Icon(name: String, iconUrl: String, onContrastCalculate: (Color) -> Unit, modifier: Modifier = Modifier) { - val pixelsSize = with(LocalDensity.current) { TangemTheme.dimens.size46.roundToPx() } - val iconModifier = modifier - .size(size = TangemTheme.dimens.size46) - .clip(TangemTheme.shapes.roundedCorners8) - - var iconBackgroundColor by remember { mutableStateOf(Color.Transparent) } - var isBackgroundColorDefined by remember { mutableStateOf(false) } - val itemBackgroundColor = TangemTheme.colors.background.primary.toArgb() - val isDarkTheme = isSystemInDarkTheme() - val coroutineScope = rememberCoroutineScope() - - SubcomposeAsyncImage( - modifier = iconModifier, - model = ImageRequest.Builder(context = LocalContext.current) - .data(data = iconUrl) - .size(size = pixelsSize) - .memoryCacheKey(key = iconUrl + pixelsSize) - .crossfade(enable = true) - .allowHardware(false) - .listener( - onSuccess = { _, result -> - if (!isBackgroundColorDefined && isDarkTheme) { - coroutineScope.launch { - val color = ImageBackgroundContrastChecker( - drawable = result.drawable, - backgroundColor = itemBackgroundColor, - size = pixelsSize, - ).getContrastColor(isDarkTheme = true) - onContrastCalculate(color) - iconBackgroundColor = color - isBackgroundColorDefined = true - } - } - }, - ) - .build(), - contentDescription = null, - loading = { CurrencyPlaceholderIcon(id = name, modifier = iconModifier) }, - error = { CurrencyPlaceholderIcon(id = name, modifier = iconModifier) }, - ) -} - -@Composable -private fun Title(title: String, modifier: Modifier = Modifier) { - Text( - text = title, - modifier = modifier, - color = TangemTheme.colors.text.primary1, - textAlign = TextAlign.Start, - maxLines = 1, - style = TangemTheme.typography.body1, - ) -} - -@Composable -private fun Subtitle(isExpanded: Boolean, modifier: Modifier = Modifier) { - AnimatedVisibility( - visible = isExpanded, - modifier = modifier, - enter = fadeIn() + expandVertically(), - exit = shrinkVertically() + fadeOut(), - ) { - Text( - text = stringResource(id = R.string.currency_subtitle_expanded), - color = TangemTheme.colors.text.secondary, - maxLines = 1, - style = TangemTheme.typography.body2, - ) - } -} - -@Composable -private fun ChangeNetworksViewButton(isExpanded: Boolean, onClick: () -> Unit, modifier: Modifier = Modifier) { - IconButton(onClick = onClick, modifier = modifier.size(size = TangemTheme.dimens.size46)) { - AnimatedContent( - targetState = isExpanded, - transitionSpec = { (fadeIn() + scaleIn()).togetherWith(scaleOut() + fadeOut()) }, - ) { isExpanded -> - Icon( - painter = painterResource( - id = if (isExpanded) R.drawable.ic_arrow_extended else R.drawable.ic_arrow_collapsed, - ), - contentDescription = null, - tint = TangemTheme.colors.icon.secondary, - ) - } - } -} - -@Preview(showBackground = true) -@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun Preview_TokenItem_ManageAccess() { - TangemThemePreview { - TokenItem(model = TokenListPreviewData.createManageToken()) - } -} - -@Preview(showBackground = true) -@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun Preview_TokenItem_ReadAccess() { - TangemThemePreview { - TokenItem(model = TokenListPreviewData.createReadToken()) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/ui/TokenListPreviewData.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/ui/TokenListPreviewData.kt deleted file mode 100644 index fafeb5d244..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/ui/TokenListPreviewData.kt +++ /dev/null @@ -1,92 +0,0 @@ -package com.tangem.tap.features.tokens.impl.presentation.ui - -import androidx.compose.runtime.mutableStateOf -import com.tangem.blockchain.common.Blockchain -import com.tangem.tap.features.tokens.impl.presentation.states.NetworkItemState -import com.tangem.tap.features.tokens.impl.presentation.states.TokenItemState -import com.tangem.wallet.R -import kotlinx.collections.immutable.ImmutableList -import kotlinx.collections.immutable.persistentListOf - -/** -[REDACTED_AUTHOR] - */ -object TokenListPreviewData { - - fun createManageToken(): TokenItemState.ManageContent { - return TokenItemState.ManageContent( - fullName = "Tether (USDT)", - iconUrl = "https://s3.eu-central-1.amazonaws.com/tangem.api/coins/large/tether.png", - networks = createManageNetworksList(), - composedId = "11231", - id = "", - name = "Tether", - symbol = "", - ) - } - - fun createReadToken(): TokenItemState.ReadContent { - return TokenItemState.ReadContent( - id = "1", - fullName = "Tether (USDT)", - iconUrl = "https://s3.eu-central-1.amazonaws.com/tangem.api/coins/large/tether.png", - networks = createReadNetworksList(), - composedId = "11231", - ) - } - - fun createManageNetworksList(): ImmutableList { - return persistentListOf( - NetworkItemState.ManageContent( - name = "Ethereum", - protocolName = "MAIN", - iconResId = mutableStateOf(R.drawable.ic_eth_16), - isMainNetwork = true, - isAdded = mutableStateOf(true), - id = "", - address = null, - onToggleClick = { _, _ -> }, - onNetworkClick = {}, - decimalCount = null, - blockchain = Blockchain.Ethereum, - ), - NetworkItemState.ManageContent( - name = "BNB SMART CHAIN", - protocolName = "BEP20", - iconResId = mutableStateOf(R.drawable.ic_bsc_16), - isMainNetwork = false, - isAdded = mutableStateOf(false), - id = "", - address = null, - onToggleClick = { _, _ -> }, - onNetworkClick = {}, - decimalCount = null, - blockchain = Blockchain.BSC, - ), - ) - } - - fun createReadNetworksList(): ImmutableList { - return persistentListOf( - NetworkItemState.ReadContent( - name = "Ethereum", - protocolName = "MAIN", - iconResId = mutableStateOf(R.drawable.ic_eth_16), - isMainNetwork = true, - ), - NetworkItemState.ReadContent( - name = "BNB SMART CHAIN", - protocolName = "BEP20", - iconResId = mutableStateOf(R.drawable.ic_bsc_16), - isMainNetwork = false, - ), - // check icon clipping - NetworkItemState.ReadContent( - name = "SHIBARIUM", - protocolName = "BEP20", - iconResId = mutableStateOf(R.drawable.ic_shibarium_22), - isMainNetwork = false, - ), - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/ui/TokensListScreen.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/ui/TokensListScreen.kt deleted file mode 100644 index d045437bb8..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/ui/TokensListScreen.kt +++ /dev/null @@ -1,271 +0,0 @@ -package com.tangem.tap.features.tokens.impl.presentation.ui - -import android.content.res.Configuration -import androidx.activity.compose.BackHandler -import androidx.compose.animation.Crossfade -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.CircularProgressIndicator -import androidx.compose.material.FabPosition -import androidx.compose.material.Scaffold -import androidx.compose.material.Text -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.layout.onSizeChanged -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.platform.LocalSoftwareKeyboardController -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.tooling.preview.PreviewParameter -import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.TextUnit -import androidx.compose.ui.unit.TextUnitType -import androidx.compose.ui.unit.dp -import androidx.paging.PagingData -import androidx.paging.compose.LazyPagingItems -import androidx.paging.compose.collectAsLazyPagingItems -import androidx.paging.compose.itemContentType -import androidx.paging.compose.itemKey -import com.tangem.core.ui.components.BottomFade -import com.tangem.core.ui.components.NavigationBar3ButtonsScrim -import com.tangem.core.ui.components.PrimaryButton -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.core.ui.res.TangemTheme -import com.tangem.tap.features.tokens.impl.presentation.states.TokenItemState -import com.tangem.tap.features.tokens.impl.presentation.states.TokensListStateHolder -import com.tangem.tap.features.tokens.impl.presentation.states.TokensListToolbarState -import com.tangem.wallet.R -import kotlinx.coroutines.flow.collectLatest -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.emptyFlow -import kotlinx.coroutines.flow.flowOf - -/** - * Tokens list screen - * - * @param stateHolder state holder - * -[REDACTED_AUTHOR] - */ -@Composable -internal fun TokensListScreen(stateHolder: TokensListStateHolder, modifier: Modifier = Modifier) { - BackHandler(onBack = stateHolder.toolbarState.onBackButtonClick) - - var floatingButtonHeight by remember { mutableStateOf(value = 0.dp) } - - Scaffold( - modifier = modifier, - topBar = { - TokensListToolbar(state = stateHolder.toolbarState) - }, - floatingActionButton = { - if (stateHolder is TokensListStateHolder.ManageContent) { - val density = LocalDensity.current - val verticalPadding = TangemTheme.dimens.spacing32 - - SaveChangesButton( - modifier = Modifier - .navigationBarsPadding() - .onSizeChanged { - with(density) { floatingButtonHeight = it.height.toDp() + verticalPadding } - }, - showProgress = stateHolder.isSavingInProgress, - onClick = stateHolder.onSaveButtonClick, - ) - } - }, - floatingActionButtonPosition = FabPosition.Center, - backgroundColor = TangemTheme.colors.background.secondary, - ) { _ -> - val tokens = stateHolder.tokens.collectAsLazyPagingItems() - - if (stateHolder !is TokensListStateHolder.ManageContent) { - NavigationBar3ButtonsScrim() - } - - Box { - TokensListContent( - isDifferentAddressesBlockVisible = stateHolder.isDifferentAddressesBlockVisible, - tokens = tokens, - bottomMarginDp = floatingButtonHeight, - ) - - if (stateHolder is TokensListStateHolder.ManageContent) { - BottomFade(Modifier.align(Alignment.BottomCenter)) - } - } - - Crossfade(targetState = stateHolder.isLoading, label = "Update progress bar visibility") { - if (it) { - LoadingContent() - } - } - - LaunchedEffect(key1 = tokens.loadState.refresh) { - stateHolder.onTokensLoadStateChanged(tokens.loadState.refresh) - } - } -} - -@Composable -private fun LoadingContent() { - Box( - modifier = Modifier - .fillMaxSize() - .background(color = TangemTheme.colors.background.primary), - contentAlignment = Alignment.Center, - ) { - CircularProgressIndicator(color = TangemTheme.colors.icon.accent) - } -} - -@Composable -private fun TokensListContent( - isDifferentAddressesBlockVisible: Boolean, - tokens: LazyPagingItems, - bottomMarginDp: Dp, -) { - val state = rememberLazyListState() - val bottomBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() } - - LazyColumn( - modifier = Modifier - .background(color = TangemTheme.colors.background.primary) - .imePadding() - .fillMaxSize(), - state = state, - contentPadding = PaddingValues( - bottom = bottomMarginDp + bottomBarHeight, - ), - ) { - item( - key = "DifferentAddressesWarning$isDifferentAddressesBlockVisible", - contentType = "DifferentAddressesWarning$isDifferentAddressesBlockVisible", - ) { - if (isDifferentAddressesBlockVisible) DifferentAddressesWarning() - } - - tokens.itemKey(TokenItemState::composedId) - tokens.itemContentType(TokenItemState::composedId) - - items(items = tokens.itemSnapshotList.items, key = TokenItemState::composedId) { - TokenItem(model = it) - } - } - - val keyboardController = LocalSoftwareKeyboardController.current - LaunchedEffect(key1 = state) { - snapshotFlow(state::isScrollInProgress) - .distinctUntilChanged() - .collectLatest { if (it) keyboardController?.hide() } - } -} - -@Composable -private fun DifferentAddressesWarning() { - Box( - modifier = Modifier - .padding(TangemTheme.dimens.spacing16) - .background( - color = TangemTheme.colors.button.disabled, - shape = RoundedCornerShape(TangemTheme.dimens.radius10), - ), - contentAlignment = Alignment.Center, - ) { - val text = stringResource(id = R.string.warning_manage_tokens_legacy_derivation_message) - Text( - text = text, - modifier = Modifier.padding( - horizontal = TangemTheme.dimens.spacing16, - vertical = TangemTheme.dimens.spacing8, - ), - color = TangemTheme.colors.text.tertiary, - textAlign = TextAlign.Start, - style = TangemTheme.typography.body2.copy( - letterSpacing = TextUnit(value = 0.5f, type = TextUnitType.Sp), - lineHeight = TextUnit(value = 25f, type = TextUnitType.Sp), - ), - ) - } -} - -@Composable -private fun SaveChangesButton(showProgress: Boolean, onClick: () -> Unit, modifier: Modifier = Modifier) { - PrimaryButton( - modifier = modifier - .imePadding() - .padding(horizontal = TangemTheme.dimens.spacing16) - .fillMaxWidth(), - text = stringResource(id = R.string.common_save_changes), - showProgress = showProgress, - onClick = onClick, - ) -} - -@Preview(showSystemUi = true) -@Preview(showSystemUi = true, uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun Preview_TokensListScreen( - @PreviewParameter(TokensListScreenProvider::class) stateHolder: TokensListStateHolder, -) { - TangemThemePreview { - TokensListScreen(stateHolder) - } -} - -private class TokensListScreenProvider : CollectionPreviewParameterProvider( - collection = listOf( - TokensListStateHolder.ReadContent( - toolbarState = TokensListToolbarState.Title.Manage( - titleResId = R.string.main_manage_tokens, - onBackButtonClick = {}, - onSearchButtonClick = {}, - onAddCustomTokenClick = {}, - ), - isLoading = true, - isDifferentAddressesBlockVisible = false, - tokens = emptyFlow(), - onTokensLoadStateChanged = {}, - ), - TokensListStateHolder.ManageContent( - toolbarState = TokensListToolbarState.Title.Manage( - titleResId = R.string.main_manage_tokens, - onBackButtonClick = {}, - onSearchButtonClick = {}, - onAddCustomTokenClick = {}, - ), - isLoading = false, - isDifferentAddressesBlockVisible = true, - tokens = flowOf( - PagingData.from( - listOf(TokenListPreviewData.createManageToken()), - ), - ), - onSaveButtonClick = {}, - onTokensLoadStateChanged = {}, - isSavingInProgress = false, - ), - TokensListStateHolder.ReadContent( - toolbarState = TokensListToolbarState.Title.Read( - titleResId = R.string.common_search_tokens, - onBackButtonClick = {}, - onSearchButtonClick = {}, - ), - isLoading = false, - isDifferentAddressesBlockVisible = false, - tokens = flowOf( - PagingData.from( - listOf(TokenListPreviewData.createManageToken()), - ), - ), - onTokensLoadStateChanged = {}, - ), - ), -) \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/ui/TokensListToolbar.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/ui/TokensListToolbar.kt deleted file mode 100644 index 0a4dd9c309..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/ui/TokensListToolbar.kt +++ /dev/null @@ -1,221 +0,0 @@ -package com.tangem.tap.features.tokens.impl.presentation.ui - -import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.text.BasicTextField -import androidx.compose.foundation.text.KeyboardActions -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.ExperimentalComposeUiApi -import androidx.compose.ui.Modifier -import androidx.compose.ui.focus.FocusRequester -import androidx.compose.ui.focus.focusRequester -import androidx.compose.ui.graphics.SolidColor -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.platform.LocalSoftwareKeyboardController -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.input.ImeAction -import androidx.compose.ui.text.input.KeyboardType -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.sp -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.tap.features.tokens.impl.presentation.states.TokensListToolbarState -import com.tangem.tap.features.tokens.impl.presentation.states.TokensListToolbarState.InputField -import com.tangem.tap.features.tokens.impl.presentation.states.TokensListToolbarState.Title -import com.tangem.wallet.R -import kotlinx.coroutines.delay - -/** -[REDACTED_AUTHOR] - */ -@Composable -internal fun TokensListToolbar(state: TokensListToolbarState) { - val toolbarElevation = if (isSystemInDarkTheme()) { - TangemTheme.dimens.elevation0 - } else { - AppBarDefaults.TopAppBarElevation - } - val statusBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getTop(this).toDp() } - - TopAppBar( - backgroundColor = TangemTheme.colors.background.secondary, - contentPadding = PaddingValues( - start = TangemTheme.dimens.spacing4, - end = TangemTheme.dimens.spacing4, - top = statusBarHeight, - ), - elevation = toolbarElevation, - ) { - IconButton(onClick = state.onBackButtonClick) { - Icon( - painter = painterResource(id = R.drawable.ic_back_24), - contentDescription = "Go back", - tint = TangemTheme.colors.icon.primary1, - ) - } - - when (state) { - is Title -> TitleContent(state = state, modifier = Modifier.weight(1f)) - is InputField -> InputContent(state = state, modifier = Modifier.weight(1f)) - } - } -} - -@Composable -private fun TitleContent(state: Title, modifier: Modifier = Modifier) { - Text( - text = stringResource(id = state.titleResId), - modifier = modifier.padding(horizontal = TangemTheme.dimens.spacing26), - color = TangemTheme.colors.text.primary1, - maxLines = 1, - style = TangemTheme.typography.h3, - ) - - IconButton(onClick = state.onSearchButtonClick) { - Icon( - painter = painterResource(id = R.drawable.ic_search_24), - contentDescription = "Search", - tint = TangemTheme.colors.icon.primary1, - ) - } - - if (state is Title.Manage) { - IconButton(onClick = state.onAddCustomTokenClick) { - Icon( - painter = painterResource(id = R.drawable.ic_plus_24), - contentDescription = "Add custom token", - tint = TangemTheme.colors.icon.primary1, - ) - } - } -} - -@OptIn(ExperimentalComposeUiApi::class) -@Composable -private fun InputContent(state: InputField, modifier: Modifier = Modifier) { - val focusRequester = remember { FocusRequester() } - val keyboardController = LocalSoftwareKeyboardController.current - - BasicTextField( - value = state.value, - onValueChange = state.onValueChange, - modifier = modifier.focusRequester(focusRequester), - textStyle = TangemTheme.typography.subtitle1.copy( - fontWeight = FontWeight.Normal, - color = TangemTheme.colors.text.primary1, - ), - keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text, imeAction = ImeAction.Search), - keyboardActions = KeyboardActions(onSearch = { keyboardController?.hide() }), - singleLine = true, - maxLines = 1, - cursorBrush = SolidColor(value = TangemTheme.colors.stroke.secondary), - ) { innerTextField -> - Row(verticalAlignment = Alignment.CenterVertically) { - Box( - modifier = Modifier - .weight(1f) - .padding( - start = TangemTheme.dimens.spacing28, - top = TangemTheme.dimens.spacing2, - end = TangemTheme.dimens.spacing16, - ), - ) { - Hint(value = state.value) - innerTextField() - } - - IconButton(onClick = state.onCleanButtonClick) { - Icon( - painter = painterResource(id = R.drawable.ic_cross_rounded_24), - contentDescription = "Clean entered value", - tint = TangemTheme.colors.icon.secondary, - ) - } - } - } - - // This is a hack because Compose can't show the keyboard if the input field is not found. - // So first I request focus and make a delay and then show the keyboard. - val keyboardManager = LocalSoftwareKeyboardController.current - LaunchedEffect(keyboardManager) { - focusRequester.requestFocus() - delay(timeMillis = 100) - keyboardManager?.show() - } -} - -@Composable -private fun Hint(value: String) { - if (value.isBlank()) { - Row( - modifier = Modifier.padding(start = TangemTheme.dimens.spacing4), - horizontalArrangement = Arrangement.spacedBy(space = TangemTheme.dimens.spacing4), - verticalAlignment = Alignment.CenterVertically, - ) { - Icon( - painter = painterResource(id = R.drawable.ic_search_24), - contentDescription = null, - tint = TangemTheme.colors.icon.secondary, - ) - Text( - text = stringResource(id = R.string.common_search), - modifier = Modifier.padding(bottom = TangemTheme.dimens.spacing2), - color = TangemTheme.colors.text.tertiary, - maxLines = 1, - // FIXME("Incorrect typography. Replace with typography from design system") - style = TangemTheme.typography.subtitle1.copy(fontSize = 18.sp, fontWeight = FontWeight.Normal), - ) - } - } -} - -@Preview -@Composable -private fun Preview_AddTokensToolbar_EditAccess() { - TangemThemePreview { - TokensListToolbar( - state = Title.Manage( - titleResId = R.string.main_manage_tokens, - onBackButtonClick = {}, - onSearchButtonClick = {}, - onAddCustomTokenClick = {}, - ), - ) - } -} - -@Preview -@Composable -private fun Preview_AddTokensToolbar_ReadAccess() { - TangemThemePreview { - TokensListToolbar( - state = Title.Read( - titleResId = R.string.common_search_tokens, - onBackButtonClick = {}, - onSearchButtonClick = {}, - ), - ) - } -} - -@Preview -@Composable -private fun Preview_AddTokensToolbar_SearchInputField() { - var value by remember { mutableStateOf("") } - - TangemThemePreview { - TokensListToolbar( - state = InputField( - onBackButtonClick = {}, - value = value, - onValueChange = { value = it }, - onCleanButtonClick = { value = "" }, - ), - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/viewmodels/TokensListAnalyticsSender.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/viewmodels/TokensListAnalyticsSender.kt deleted file mode 100644 index 95d0e9371e..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/viewmodels/TokensListAnalyticsSender.kt +++ /dev/null @@ -1,63 +0,0 @@ -package com.tangem.tap.features.tokens.impl.presentation.viewmodels - -import com.tangem.blockchain.common.Blockchain -import com.tangem.blockchain.common.Token -import com.tangem.core.analytics.api.AnalyticsEventHandler -import com.tangem.tap.common.analytics.events.AnalyticsParam -import com.tangem.tap.common.analytics.events.ManageTokens - -/** Analytics sender for tokens list screen */ -class TokensListAnalyticsSender(private val analyticsEventHandler: AnalyticsEventHandler) { - - fun sendWhenScreenOpened() { - analyticsEventHandler.send(event = ManageTokens.ScreenOpened()) - } - - fun sendWhenTokenAdded(token: Token) { - analyticsEventHandler.send( - event = ManageTokens.TokenSwitcherChanged( - type = AnalyticsParam.CurrencyType.Token(token), - state = AnalyticsParam.OnOffState.On, - ), - ) - } - - fun sendWhenBlockchainAdded(blockchain: Blockchain) { - analyticsEventHandler.send( - event = ManageTokens.TokenSwitcherChanged( - type = AnalyticsParam.CurrencyType.Blockchain(blockchain), - state = AnalyticsParam.OnOffState.On, - ), - ) - } - - fun sendWhenTokenRemoved(token: Token) { - analyticsEventHandler.send( - event = ManageTokens.TokenSwitcherChanged( - type = AnalyticsParam.CurrencyType.Token(token), - state = AnalyticsParam.OnOffState.Off, - ), - ) - } - - fun sendWhenBlockchainRemoved(blockchain: Blockchain) { - analyticsEventHandler.send( - event = ManageTokens.TokenSwitcherChanged( - type = AnalyticsParam.CurrencyType.Blockchain(blockchain), - state = AnalyticsParam.OnOffState.Off, - ), - ) - } - - fun sendWhenSaveButtonClicked() { - analyticsEventHandler.send(ManageTokens.ButtonSaveChanges()) - } - - fun sendWhenTokenSearched() { - analyticsEventHandler.send(ManageTokens.TokenSearched()) - } - - fun sendWhenAddCustomTokenClicked() { - analyticsEventHandler.send(ManageTokens.ButtonCustomToken()) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/viewmodels/TokensListCryptoCurrencies.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/viewmodels/TokensListCryptoCurrencies.kt deleted file mode 100644 index da83face06..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/viewmodels/TokensListCryptoCurrencies.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.tangem.tap.features.tokens.impl.presentation.viewmodels - -import com.tangem.blockchain.common.Blockchain -import com.tangem.domain.tokens.TokenWithBlockchain - -internal data class TokensListCryptoCurrencies( - val coins: List, - val tokens: List, -) \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/viewmodels/TokensListMigration.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/viewmodels/TokensListMigration.kt deleted file mode 100644 index 0cf70b6b4f..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/viewmodels/TokensListMigration.kt +++ /dev/null @@ -1,172 +0,0 @@ -package com.tangem.tap.features.tokens.impl.presentation.viewmodels - -import arrow.core.Either -import com.tangem.blockchain.common.Blockchain -import com.tangem.blockchain.common.Token -import com.tangem.common.routing.AppRoute -import com.tangem.data.common.currency.CryptoCurrencyFactory -import com.tangem.domain.card.DerivePublicKeysUseCase -import com.tangem.domain.common.util.derivationStyleProvider -import com.tangem.domain.tokens.AddCryptoCurrenciesUseCase -import com.tangem.domain.tokens.GetCryptoCurrenciesUseCase -import com.tangem.domain.tokens.TokenWithBlockchain -import com.tangem.domain.tokens.model.CryptoCurrency -import com.tangem.domain.wallets.models.UserWallet -import com.tangem.domain.wallets.models.UserWalletId -import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase -import com.tangem.tap.common.extensions.dispatchDebugErrorNotification -import com.tangem.tap.common.extensions.dispatchNavigationAction -import com.tangem.tap.common.extensions.inject -import com.tangem.tap.proxy.redux.DaggerGraphState -import com.tangem.tap.store -import timber.log.Timber -import kotlin.properties.Delegates - -/** - * Class that divide a new and legacy logic when user uses tokens list screen - * - * @property getSelectedWalletSyncUseCase use case that returns selected wallet - * @property getCurrenciesUseCase use case that returns crypto currencies of a specified wallet - */ -internal class TokensListMigration( - private val getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase, - private val getCurrenciesUseCase: GetCryptoCurrenciesUseCase, - private val derivePublicKeysUseCase: DerivePublicKeysUseCase, - private val addCryptoCurrenciesUseCase: AddCryptoCurrenciesUseCase, -) { - - private var currentNewCoins: List by Delegates.notNull() - private var currentNewTokens: List by Delegates.notNull() - private var currentUserWallet: UserWallet by Delegates.notNull() - - private val cryptoCurrencyFactory by lazy { CryptoCurrencyFactory() } - - suspend fun getCurrentCryptoCurrencies(): TokensListCryptoCurrencies { - return when (val selectedWalletEither = getSelectedWalletSyncUseCase()) { - is Either.Left -> { - Timber.e(selectedWalletEither.value.toString()) - TokensListCryptoCurrencies(coins = emptyList(), tokens = emptyList()) - } - is Either.Right -> { - currentUserWallet = selectedWalletEither.value - - when ( - val currenciesEither = getCurrenciesUseCase.getSync( - userWalletId = selectedWalletEither.value.walletId, - ) - ) { - is Either.Left -> { - Timber.e(currenciesEither.value.toString()) - TokensListCryptoCurrencies(coins = emptyList(), tokens = emptyList()) - } - is Either.Right -> { - TokensListCryptoCurrencies( - coins = currenciesEither.value - .filterIsInstance() - .filterNot { it.isCustom } - .also { currentNewCoins = it } - .map { Blockchain.fromId(it.network.id.value) }, - tokens = currenciesEither.value - .filterIsInstance() - .filterNot(CryptoCurrency.Token::isCustom) - .also { currentNewTokens = it } - .map { token -> - TokenWithBlockchain( - token = Token( - name = token.name, - symbol = token.symbol, - contractAddress = token.contractAddress, - decimals = token.decimals, - id = token.id.rawCurrencyId, - ), - blockchain = Blockchain.fromId(token.network.id.value), - ) - }, - ) - } - } - } - } - } - - suspend fun onSaveButtonClick( - changedTokensList: MutableList, - changedBlockchainList: List, - ) { - val changedTokens = changedTokensList.mapNotNull { - cryptoCurrencyFactory.createToken( - sdkToken = it.token, - blockchain = it.blockchain, - extraDerivationPath = null, - derivationStyleProvider = currentUserWallet.scanResponse.derivationStyleProvider, - ) - } - - val changedCoins = changedBlockchainList.mapNotNull { - cryptoCurrencyFactory.createCoin( - blockchain = it, - extraDerivationPath = null, - derivationStyleProvider = currentUserWallet.scanResponse.derivationStyleProvider, - ) - } - - val blockchainsToAdd = changedCoins.filterNot(currentNewCoins::contains) - val blockchainsToRemove = currentNewCoins.filterNot(changedCoins::contains) - - val tokensToAdd = changedTokens.filterNot(currentNewTokens::contains) - val tokensToRemove = currentNewTokens.filterNot { token -> changedTokens.any { it == token } } - - removeCurrenciesIfNeeded( - userWalletId = currentUserWallet.walletId, - currencies = blockchainsToRemove + tokensToRemove, - ) - - val isNothingToDoWithTokens = tokensToAdd.isEmpty() && tokensToRemove.isEmpty() - val isNothingToDoWithBlockchain = blockchainsToAdd.isEmpty() && blockchainsToRemove.isEmpty() - if (isNothingToDoWithTokens && isNothingToDoWithBlockchain) { - store.dispatchDebugErrorNotification(message = "Nothing to save") - navigateToWallet() - return - } - - val currencyList = blockchainsToAdd + tokensToAdd - - derivePublicKeysUseCase(userWalletId = currentUserWallet.walletId, currencies = currencyList) - .onRight { - addCryptoCurrenciesUseCase(userWalletId = currentUserWallet.walletId, currencies = currencyList) - navigateToWallet() - } - .onLeft { Timber.e(it, "Failed to derive public keys") } - } - - private fun navigateToWallet() { - store.dispatchNavigationAction { - val route = AppRoute.Wallet - - if (route in stack) { - popTo(route) - } else { - replaceAll(route) - } - } - } - - private suspend fun removeCurrenciesIfNeeded(userWalletId: UserWalletId, currencies: List) { - if (currencies.isEmpty()) return - val currenciesRepository = store.inject(DaggerGraphState::currenciesRepository) - val walletManagersFacade = store.inject(DaggerGraphState::walletManagersFacade) - - currenciesRepository.removeCurrencies(userWalletId = userWalletId, currencies = currencies) - - walletManagersFacade.remove( - userWalletId = userWalletId, - networks = currencies - .filterIsInstance() - .mapTo(hashSetOf(), CryptoCurrency::network), - ) - walletManagersFacade.removeTokens( - userWalletId = userWalletId, - tokens = currencies.filterIsInstance().toSet(), - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/viewmodels/TokensListViewModel.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/viewmodels/TokensListViewModel.kt deleted file mode 100644 index 736278526e..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/viewmodels/TokensListViewModel.kt +++ /dev/null @@ -1,496 +0,0 @@ -package com.tangem.tap.features.tokens.impl.presentation.viewmodels - -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableIntStateOf -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.setValue -import androidx.lifecycle.DefaultLifecycleObserver -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import androidx.paging.* -import com.tangem.blockchain.common.Blockchain -import com.tangem.blockchainsdk.utils.fromNetworkId -import com.tangem.core.analytics.api.AnalyticsEventHandler -import com.tangem.core.ui.extensions.getActiveIconRes -import com.tangem.core.ui.extensions.getGreyedOutIconRes -import com.tangem.domain.card.DerivePublicKeysUseCase -import com.tangem.domain.common.TapWorkarounds.useOldStyleDerivation -import com.tangem.domain.common.extensions.canHandleBlockchain -import com.tangem.domain.common.extensions.canHandleToken -import com.tangem.domain.common.extensions.supportedTokens -import com.tangem.domain.common.util.cardTypesResolver -import com.tangem.domain.tokens.AddCryptoCurrenciesUseCase -import com.tangem.domain.tokens.GetCryptoCurrenciesUseCase -import com.tangem.domain.tokens.TokenWithBlockchain -import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase -import com.tangem.tap.common.extensions.networkNameWithoutTestnet -import com.tangem.tap.common.extensions.getNetworkStandardName -import com.tangem.tap.features.customtoken.impl.presentation.models.SupportBlockchainType -import com.tangem.tap.features.tokens.impl.domain.TokensListInteractor -import com.tangem.tap.features.tokens.impl.domain.models.Token -import com.tangem.tap.features.tokens.impl.domain.models.Token.Network -import com.tangem.tap.features.tokens.impl.presentation.models.SupportTokensState -import com.tangem.tap.features.tokens.impl.presentation.router.TokensListRouter -import com.tangem.tap.features.tokens.impl.presentation.states.NetworkItemState -import com.tangem.tap.features.tokens.impl.presentation.states.TokenItemState -import com.tangem.tap.features.tokens.impl.presentation.states.TokensListStateHolder -import com.tangem.tap.features.tokens.impl.presentation.states.TokensListToolbarState -import com.tangem.tap.store -import com.tangem.utils.coroutines.AppCoroutineDispatcherProvider -import com.tangem.utils.coroutines.Debouncer -import com.tangem.wallet.R -import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.collections.immutable.toImmutableList -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.flowOf -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.launch -import kotlinx.coroutines.plus -import timber.log.Timber -import javax.inject.Inject -import kotlin.properties.Delegates -import com.tangem.blockchain.common.Token as BlockchainToken - -/** - * ViewModel for tokens list screen - * - * @property interactor feature interactor - * @property router feature router - * @property dispatchers coroutine dispatchers provider - * @property getSelectedWalletSyncUseCase use case that returns selected wallet - * @param analyticsEventHandler analytics event handler - * -[REDACTED_AUTHOR] - */ -@Suppress("LongParameterList") -@HiltViewModel -internal class TokensListViewModel @Inject constructor( - private val interactor: TokensListInteractor, - private val router: TokensListRouter, - private val dispatchers: AppCoroutineDispatcherProvider, - private val getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase, - derivePublicKeysUseCase: DerivePublicKeysUseCase, - addCryptoCurrenciesUseCase: AddCryptoCurrenciesUseCase, - analyticsEventHandler: AnalyticsEventHandler, - getCurrenciesUseCase: GetCryptoCurrenciesUseCase, -) : ViewModel(), DefaultLifecycleObserver { - - private val isManageAccess = store.state.tokensState.isManageAccess - private val analyticsSender = TokensListAnalyticsSender(analyticsEventHandler) - private val actionsHandler = ActionsHandler(router = router, debouncer = Debouncer()) - - /** Screen state */ - var uiState by mutableStateOf(value = getInitialUiState()) - private set - - private var currentTokensList: List by Delegates.notNull() - private var currentBlockchainList: List by Delegates.notNull() - - private var changedTokensList: MutableList = mutableListOf() - private var changedBlockchainList: MutableList = mutableListOf() - - private val tokensListMigration = TokensListMigration( - getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase, - getCurrenciesUseCase = getCurrenciesUseCase, - derivePublicKeysUseCase = derivePublicKeysUseCase, - addCryptoCurrenciesUseCase = addCryptoCurrenciesUseCase, - ) - - init { - viewModelScope.launch(dispatchers.main) { - val (currentCoins, currentTokens) = tokensListMigration.getCurrentCryptoCurrencies() - - currentBlockchainList = currentCoins - currentTokensList = currentTokens - - changedBlockchainList = currentCoins.toMutableList() - changedTokensList = currentTokens.toMutableList() - - uiState = uiState.copySealed(tokens = getTokensListBySearchText(text = "")) - } - } - - override fun onCreate(owner: LifecycleOwner) { - if (isManageAccess) analyticsSender.sendWhenScreenOpened() - } - - private fun getInitialUiState(): TokensListStateHolder { - return if (isManageAccess) { - TokensListStateHolder.ManageContent( - toolbarState = getInitialToolbarState(), - isLoading = true, - isDifferentAddressesBlockVisible = isDifferentAddressesBlockVisible(), - tokens = getInitialTokensList(), - onTokensLoadStateChanged = actionsHandler::onTokensLoadStateChanged, - isSavingInProgress = false, - onSaveButtonClick = actionsHandler::onSaveButtonClick, - ) - } else { - TokensListStateHolder.ReadContent( - toolbarState = getInitialToolbarState(), - isLoading = true, - isDifferentAddressesBlockVisible = isDifferentAddressesBlockVisible(), - tokens = getInitialTokensList(), - onTokensLoadStateChanged = actionsHandler::onTokensLoadStateChanged, - ) - } - } - - private fun getInitialToolbarState(): TokensListToolbarState { - return if (isManageAccess) { - TokensListToolbarState.Title.Manage( - titleResId = R.string.add_tokens_title, - onBackButtonClick = actionsHandler::onBackButtonClick, - onSearchButtonClick = actionsHandler::onSearchButtonClick, - onAddCustomTokenClick = actionsHandler::onAddCustomTokenClick, - ) - } else { - TokensListToolbarState.Title.Read( - titleResId = R.string.common_search_tokens, - onBackButtonClick = actionsHandler::onBackButtonClick, - onSearchButtonClick = actionsHandler::onSearchButtonClick, - ) - } - } - - private fun isDifferentAddressesBlockVisible(): Boolean { - return getSelectedWalletSyncUseCase().fold( - ifLeft = { false }, - ifRight = { it.scanResponse.card.useOldStyleDerivation }, - ) - } - - private fun getInitialTokensList(): Flow> { - return flowOf( - value = PagingData.empty( - sourceLoadStates = LoadStates(LoadState.Loading, LoadState.Loading, LoadState.Loading), - mediatorLoadStates = LoadStates(LoadState.Loading, LoadState.Loading, LoadState.Loading), - ), - ) - } - - private fun createManageTokenContent(token: Token): TokenItemState.ManageContent { - val currentTime = System.nanoTime() - return TokenItemState.ManageContent( - fullName = getTokenFullName(token), - iconUrl = token.iconUrl, - networks = token.networks.map(::createManageNetworkContent).toImmutableList(), - composedId = token.id + currentTime, - id = token.id, - name = token.name, - symbol = token.symbol, - ) - } - - private fun createManageNetworkContent(network: Network): NetworkItemState.ManageContent { - return NetworkItemState.ManageContent( - name = network.blockchain.networkNameWithoutTestnet.uppercase(), - protocolName = getNetworkProtocolName(network), - iconResId = mutableIntStateOf(value = getNetworkIconResId(network.address, network.blockchain)), - isMainNetwork = isMainNetwork(network), - isAdded = mutableStateOf( - isAdded(address = network.address, blockchain = network.blockchain), - ), - id = network.id, - address = network.address, - decimalCount = network.decimalCount, - blockchain = network.blockchain, - onToggleClick = actionsHandler::onToggleClick, - onNetworkClick = actionsHandler::onNetworkClick, - ) - } - - private fun createReadTokenContent(token: Token): TokenItemState.ReadContent { - val currentTime = System.nanoTime() - return TokenItemState.ReadContent( - id = token.id, - fullName = getTokenFullName(token), - iconUrl = token.iconUrl, - networks = token.networks.map(::createReadNetworkContent).toImmutableList(), - composedId = token.id + currentTime, - ) - } - - private fun createReadNetworkContent(network: Network): NetworkItemState.ReadContent { - return NetworkItemState.ReadContent( - name = network.blockchain.networkNameWithoutTestnet.uppercase(), - protocolName = getNetworkProtocolName(network), - iconResId = mutableIntStateOf(value = getNetworkIconResId(network.address, network.blockchain)), - isMainNetwork = isMainNetwork(network), - ) - } - - private fun getTokenFullName(token: Token) = "${token.name} (${token.symbol})" - - private fun getNetworkProtocolName(network: Network): String { - return if (network.address == null) { - MAIN_NETWORK_LABEL - } else { - network.blockchain.getNetworkStandardName().uppercase() - } - } - - private fun getNetworkIconResId(address: String?, blockchain: Blockchain): Int { - return if (isAdded(address = address, blockchain = blockchain)) { - getActiveIconRes(blockchain.id) - } else { - getGreyedOutIconRes(blockchain.id) - } - } - - private fun isMainNetwork(network: Network) = network.address == null - - private fun isAdded(address: String?, blockchain: Blockchain?): Boolean { - return if (address != null) { - changedTokensList.any { addedToken -> - address == addedToken.token.contractAddress && blockchain == addedToken.blockchain - } - } else { - changedBlockchainList.contains(blockchain) - } - } - - private fun getTokensListBySearchText(text: String): Flow> { - return interactor.getTokensList(searchText = text, needFilterExcluded = !isManageAccess) - .mapToTokenItemState() - .cachedIn(viewModelScope) - } - - private fun Flow>.mapToTokenItemState(): Flow> { - return map { pagingData -> - pagingData.map { token -> - if (isManageAccess) createManageTokenContent(token) else createReadTokenContent(token) - } - } - } - - private inner class ActionsHandler( - private val router: TokensListRouter, - private val debouncer: Debouncer, - ) { - - fun onBackButtonClick() { - router.popBackStack() - } - - fun onSearchButtonClick() { - uiState = uiState.copySealed( - toolbarState = TokensListToolbarState.InputField( - onBackButtonClick = this::onBackButtonClick, - value = "", - onValueChange = this::onSearchValueChange, - onCleanButtonClick = this::onCleanButtonClick, - ), - ) - } - - fun onAddCustomTokenClick() { - analyticsSender.sendWhenAddCustomTokenClicked() - router.openAddCustomTokenScreen() - } - - fun onToggleClick(toggledToken: TokenItemState.ManageContent, toggledNetwork: NetworkItemState.ManageContent) { - val blockchain = Blockchain.fromNetworkId( - networkId = if (toggledNetwork.address == null) toggledNetwork.id else toggledToken.id, - ) - if (toggledNetwork.address == null && blockchain != null) { - updateBlockchainItem(toggledNetwork, blockchain) - } else { - updateTokenItem(toggledToken, toggledNetwork) - } - } - - fun onNetworkClick() { - router.showAddressCopiedNotification() - } - - fun onTokensLoadStateChanged(state: LoadState) { - uiState = uiState.copySealed(isLoading = state is LoadState.Loading) - } - - fun onSaveButtonClick() { - val state = uiState as? TokensListStateHolder.ManageContent ?: return - - analyticsSender.sendWhenSaveButtonClicked() - - viewModelScope.launch(dispatchers.main) { - uiState = state.copy(isSavingInProgress = true) - - tokensListMigration.onSaveButtonClick( - changedTokensList = changedTokensList, - changedBlockchainList = changedBlockchainList, - ) - - uiState = state.copy(isSavingInProgress = false) - } - } - - private fun onSearchValueChange(newValue: String) { - val state = requireNotNull(uiState.toolbarState as? TokensListToolbarState.InputField) - uiState = uiState.copySealed(toolbarState = state.copy(value = newValue)) - - debouncer.debounce(waitMs = 800L, coroutineScope = viewModelScope + dispatchers.io) { - uiState = uiState.copySealed(tokens = getSearchedTokensList(newValue)) - } - } - - private fun getSearchedTokensList(searchText: String): Flow> { - analyticsSender.sendWhenTokenSearched() - return getTokensListBySearchText(text = searchText) - } - - private fun onCleanButtonClick() { - val state = requireNotNull(uiState.toolbarState as? TokensListToolbarState.InputField) - - if (state.value.isEmpty()) { - uiState = uiState.copySealed(toolbarState = getInitialToolbarState()) - } else { - onSearchValueChange(newValue = "") - } - } - - private fun updateBlockchainItem(toggledNetwork: NetworkItemState.ManageContent, blockchain: Blockchain) { - val isRemoveAction = changedBlockchainList.contains(blockchain) - - if (isRemoveAction) { - val isTokenWithSameBlockchainFound = changedTokensList.any { it.blockchain == blockchain } - val isAddedOnMainScreen = currentBlockchainList.contains(blockchain) - - if (isTokenWithSameBlockchainFound) { - router.openUnableHideMainTokenAlert( - tokenName = blockchain.name, - tokenSymbol = blockchain.currency, - networkName = blockchain.getNetworkName(), - ) - } else if (isAddedOnMainScreen) { - router.openRemoveWalletAlert( - tokenName = blockchain.name, - onOkClick = { - analyticsSender.sendWhenBlockchainAdded(blockchain) - changedBlockchainList.remove(blockchain) - toggledNetwork.changeToggleState() - }, - ) - } else { - analyticsSender.sendWhenBlockchainRemoved(blockchain) - changedBlockchainList.remove(blockchain) - toggledNetwork.changeToggleState() - } - } else { - when (getSupportBlockchainType(blockchain)) { - SupportBlockchainType.SUPPORTED -> { - analyticsSender.sendWhenBlockchainAdded(blockchain) - changedBlockchainList.add(blockchain) - toggledNetwork.changeToggleState() - } - SupportBlockchainType.UNSUPPORTED -> { - router.openUnsupportedNetworkAlert(blockchain) - } - SupportBlockchainType.UNABLE_TO_DETERMINE -> { - router.showGenericErrorAlertAndPopBack() - } - } - } - } - - private fun updateTokenItem( - toggledToken: TokenItemState.ManageContent, - toggledNetwork: NetworkItemState.ManageContent, - ) { - val token = TokenWithBlockchain( - token = BlockchainToken( - id = toggledToken.id, - name = toggledToken.name, - symbol = toggledToken.symbol, - contractAddress = requireNotNull(toggledNetwork.address), - decimals = requireNotNull(toggledNetwork.decimalCount), - ), - blockchain = toggledNetwork.blockchain, - ) - - val isRemoveAction = changedTokensList.contains(token) - - if (isRemoveAction) { - val isAddedOnMainScreen = currentTokensList.contains(token) - - if (isAddedOnMainScreen) { - router.openRemoveWalletAlert( - tokenName = token.token.name, - onOkClick = { - analyticsSender.sendWhenTokenRemoved(token.token) - changedTokensList.remove(token) - toggledNetwork.changeToggleState() - }, - ) - } else { - analyticsSender.sendWhenTokenRemoved(token.token) - changedTokensList.remove(token) - toggledNetwork.changeToggleState() - } - } else { - when (isUnsupportedToken(token.blockchain)) { - SupportTokensState.NetworkTokensUnsupported -> { - router.openNetworkTokensNotSupportAlert(token.blockchain.getNetworkName()) - } - SupportTokensState.SupportedToken -> { - analyticsSender.sendWhenTokenAdded(token.token) - changedTokensList.add(token) - toggledNetwork.changeToggleState() - } - SupportTokensState.UnsupportedCurve -> { - router.openUnsupportedNetworkAlert(token.blockchain) - } - null -> { - Timber.e("Something went wrong in isUnsupportedToken (no scanResponse found)") - } - } - } - } - } - - private fun isUnsupportedToken(blockchain: Blockchain): SupportTokensState? { - return getSelectedWalletSyncUseCase().fold( - ifLeft = { null }, - ifRight = { - val cardTypesResolver = it.scanResponse.cardTypesResolver - val supportedTokens = it.scanResponse.card.supportedTokens(cardTypesResolver) - - // refactor this later by moving all this logic in card config - if (blockchain == Blockchain.Solana && !supportedTokens.contains(Blockchain.Solana)) { - return SupportTokensState.NetworkTokensUnsupported - } - val canHandleToken = it.scanResponse.card.canHandleToken( - supportedTokens = supportedTokens, - blockchain = blockchain, - cardTypesResolver = cardTypesResolver, - ) - if (!canHandleToken) { - return SupportTokensState.UnsupportedCurve - } - return SupportTokensState.SupportedToken - }, - ) - } - - private fun getSupportBlockchainType(blockchain: Blockchain): SupportBlockchainType { - return getSelectedWalletSyncUseCase().fold( - ifLeft = { SupportBlockchainType.UNABLE_TO_DETERMINE }, - ifRight = { - val canHandleBlockchain = it.scanResponse.card.canHandleBlockchain( - blockchain = blockchain, - cardTypesResolver = it.scanResponse.cardTypesResolver, - ) - if (canHandleBlockchain) { - SupportBlockchainType.SUPPORTED - } else { - SupportBlockchainType.UNSUPPORTED - } - }, - ) - } - - private companion object { - const val MAIN_NETWORK_LABEL = "MAIN" - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensReducer.kt b/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensReducer.kt deleted file mode 100644 index 389a02219a..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensReducer.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.tangem.tap.features.tokens.legacy.redux - -import com.tangem.domain.tokens.TokensAction -import com.tangem.tap.common.redux.AppState -import org.rekotlin.Action - -object TokensReducer { - fun reduce(action: Action, state: AppState): TokensState = internalReduce(action, state) -} - -private fun internalReduce(action: Action, state: AppState): TokensState { - if (action !is TokensAction) return state.tokensState - - return when (action) { - is TokensAction.SetArgs.ManageAccess -> state.tokensState.copy(isManageAccess = true) - is TokensAction.SetArgs.ReadAccess -> state.tokensState.copy(isManageAccess = false) - else -> state.tokensState - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensState.kt b/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensState.kt deleted file mode 100644 index 14c5d9d721..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensState.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.tangem.tap.features.tokens.legacy.redux - -import org.rekotlin.StateType - -data class TokensState(val isManageAccess: Boolean = false) : StateType \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/TradeCryptoMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/TradeCryptoMiddleware.kt index 1abdf861b9..2f26b2a39a 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/TradeCryptoMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/TradeCryptoMiddleware.kt @@ -5,6 +5,7 @@ import com.tangem.blockchain.common.Blockchain import com.tangem.common.routing.AppRoute import com.tangem.common.routing.AppRouter import com.tangem.core.analytics.Analytics +import com.tangem.domain.settings.usercountry.models.UserCountry import com.tangem.domain.tokens.legacy.TradeCryptoAction import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.tokens.model.NetworkAddress @@ -70,16 +71,26 @@ object TradeCryptoMiddleware { isDarkTheme = MutableAppThemeModeHolder.isDarkThemeActive, ) - if (action.checkUserLocation && state()?.globalState?.userCountryCode == RUSSIA_COUNTRY_CODE) { - val dialogData = topUrl?.let { - AppDialog.RussianCardholdersWarningDialog.Data(topUpUrl = it) - } - store.dispatchDialogShow(AppDialog.RussianCardholdersWarningDialog(data = dialogData)) - return - } + scope.launch { + val homeFeatureToggles = store.inject(DaggerGraphState::homeFeatureToggles) - if (currency is CryptoCurrency.Token && currency.network.isTestnet) { - scope.launch { + val isRussia = if (homeFeatureToggles.isMigrateUserCountryCodeEnabled) { + val getUserCountryCodeUseCase = store.inject(DaggerGraphState::getUserCountryUseCase) + + getUserCountryCodeUseCase().isRight { it is UserCountry.Russia } + } else { + state()?.globalState?.userCountryCode == RUSSIA_COUNTRY_CODE + } + + if (action.checkUserLocation && isRussia) { + val dialogData = topUrl?.let { + AppDialog.RussianCardholdersWarningDialog.Data(topUpUrl = it) + } + store.dispatchDialogShow(AppDialog.RussianCardholdersWarningDialog(data = dialogData)) + return@launch + } + + if (currency is CryptoCurrency.Token && currency.network.isTestnet) { val walletManager = store.inject(DaggerGraphState::walletManagersFacade) .getOrCreateWalletManager( userWalletId = action.userWallet.walletId, @@ -97,13 +108,13 @@ object TradeCryptoMiddleware { walletManager = walletManager, destinationAddress = currency.contractAddress, ) + return@launch } - return - } - topUrl?.let { - store.dispatchOpenUrl(it) - Analytics.send(Token.Topup.ScreenOpened()) + topUrl?.let { + store.dispatchOpenUrl(it) + Analytics.send(Token.Topup.ScreenOpened()) + } } } diff --git a/app/src/main/java/com/tangem/tap/network/auth/DefaultStakeKitAuthProvider.kt b/app/src/main/java/com/tangem/tap/network/auth/DefaultStakeKitAuthProvider.kt index a5ef219c9b..ba0534ae88 100644 --- a/app/src/main/java/com/tangem/tap/network/auth/DefaultStakeKitAuthProvider.kt +++ b/app/src/main/java/com/tangem/tap/network/auth/DefaultStakeKitAuthProvider.kt @@ -1,13 +1,13 @@ package com.tangem.tap.network.auth -import com.tangem.datasource.config.ConfigManager +import com.tangem.datasource.local.config.environment.EnvironmentConfigStorage import com.tangem.lib.auth.StakeKitAuthProvider internal class DefaultStakeKitAuthProvider( - private val configManager: ConfigManager, + private val environmentConfigStorage: EnvironmentConfigStorage, ) : StakeKitAuthProvider { override fun getApiKey(): String { - return configManager.config.stakeKitApiKey ?: error("No StakeKit api key provided") + return environmentConfigStorage.getConfigSync().stakeKitApiKey ?: error("No StakeKit api key provided") } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/network/auth/di/AuthModule.kt b/app/src/main/java/com/tangem/tap/network/auth/di/AuthModule.kt index 41aa591911..54d0fdbc78 100644 --- a/app/src/main/java/com/tangem/tap/network/auth/di/AuthModule.kt +++ b/app/src/main/java/com/tangem/tap/network/auth/di/AuthModule.kt @@ -1,7 +1,7 @@ package com.tangem.tap.network.auth.di import com.tangem.datasource.api.common.AuthProvider -import com.tangem.datasource.config.ConfigManager +import com.tangem.datasource.local.config.environment.EnvironmentConfigStorage import com.tangem.datasource.local.userwallet.UserWalletsStore import com.tangem.lib.auth.ExpressAuthProvider import com.tangem.lib.auth.StakeKitAuthProvider @@ -35,8 +35,8 @@ class AuthModule { @Provides @Singleton - fun provideStakeKitAuthProvider(configManager: ConfigManager): StakeKitAuthProvider { - return DefaultStakeKitAuthProvider(configManager) + fun provideStakeKitAuthProvider(environmentConfigStorage: EnvironmentConfigStorage): StakeKitAuthProvider { + return DefaultStakeKitAuthProvider(environmentConfigStorage) } @Provides diff --git a/app/src/main/java/com/tangem/tap/network/exchangeServices/CryptoCurrencyConverter.kt b/app/src/main/java/com/tangem/tap/network/exchangeServices/CryptoCurrencyConverter.kt index d7a9569c4c..520d262847 100644 --- a/app/src/main/java/com/tangem/tap/network/exchangeServices/CryptoCurrencyConverter.kt +++ b/app/src/main/java/com/tangem/tap/network/exchangeServices/CryptoCurrencyConverter.kt @@ -3,7 +3,6 @@ package com.tangem.tap.network.exchangeServices import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.Token import com.tangem.data.common.currency.CryptoCurrencyFactory -import com.tangem.domain.common.util.derivationStyleProvider import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.tap.common.extensions.inject import com.tangem.tap.domain.model.Currency @@ -21,10 +20,9 @@ internal class CryptoCurrencyConverter : TwoWayConverter { route.asFragmentChild(Provider { AccessCodeRecoveryFragment() }) } - is AppRoute.AddCustomToken -> { - route.asFragmentChild(Provider { AddCustomTokenFragment() }) - } is AppRoute.AppCurrencySelector -> { route.asFragmentChild(Provider { AppCurrencySelectorFragment() }) } @@ -98,49 +85,37 @@ internal class ChildFactory @Inject constructor( route.asFragmentChild(Provider { CardSettingsFragment() }) } is AppRoute.Details -> { - if (detailsFeatureToggles.isRedesignEnabled) { - route.asComponentChild( - contextProvider = contextProvider(route, contextFactory), - params = DetailsComponent.Params(route.userWalletId), - componentFactory = detailsComponentFactory, - ) - } else { - route.asFragmentChild(Provider { DetailsFragment() }) - } + route.asComponentChild( + contextProvider = contextProvider(route, contextFactory), + params = DetailsComponent.Params(route.userWalletId), + componentFactory = detailsComponentFactory, + ) } is AppRoute.DetailsSecurity -> { route.asFragmentChild(Provider { SecurityModeFragment() }) } is AppRoute.Disclaimer -> { - if (pushNotificationsFeatureToggles.isPushNotificationsEnabled) { - route.asComponentChild( - contextProvider = contextProvider(route, contextFactory), - params = DisclaimerComponent.Params(route.isTosAccepted), - componentFactory = disclaimerComponentFactory, - ) - } else { - route.asFragmentChild(Provider { DisclaimerFragment() }) - } + route.asComponentChild( + contextProvider = contextProvider(route, contextFactory), + params = DisclaimerComponent.Params(route.isTosAccepted), + componentFactory = disclaimerComponentFactory, + ) } is AppRoute.Home -> { route.asFragmentChild(Provider { HomeFragment() }) } is AppRoute.ManageTokens -> { - if (manageTokensToggles.isFeatureEnabled) { - val source = when (route.source) { - AppRoute.ManageTokens.Source.SETTINGS -> ManageTokensSource.SETTINGS - AppRoute.ManageTokens.Source.ONBOARDING -> ManageTokensSource.ONBOARDING - AppRoute.ManageTokens.Source.STORIES -> ManageTokensSource.STORIES - } - - route.asComponentChild( - contextProvider = contextProvider(route, contextFactory), - params = ManageTokensComponent.Params(route.userWalletId, source), - componentFactory = manageTokensComponentFactory, - ) - } else { - route.asFragmentChild(Provider { TokensListFragment() }) + val source = when (route.source) { + AppRoute.ManageTokens.Source.SETTINGS -> ManageTokensSource.SETTINGS + AppRoute.ManageTokens.Source.ONBOARDING -> ManageTokensSource.ONBOARDING + AppRoute.ManageTokens.Source.STORIES -> ManageTokensSource.STORIES } + + route.asComponentChild( + contextProvider = contextProvider(route, contextFactory), + params = ManageTokensComponent.Params(route.userWalletId, source), + componentFactory = manageTokensComponentFactory, + ) } is AppRoute.OnboardingNote -> { route.asFragmentChild(Provider { OnboardingNoteFragment() }) diff --git a/app/src/main/res/layout/fragment_disclaimer.xml b/app/src/main/res/layout/fragment_disclaimer.xml deleted file mode 100644 index 346cab4f03..0000000000 --- a/app/src/main/res/layout/fragment_disclaimer.xml +++ /dev/null @@ -1,129 +0,0 @@ - - - - - - - - - - - - - - - - - - - -