diff --git a/.travis.yml b/.travis.yml index b766c865..c22764f4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: objective-c -osx_image: xcode10 -xcode_workspace: Neuron.xcworkspace -xcode_scheme: Neuron +osx_image: xcode10.1 +xcode_workspace: Cyton.xcworkspace +xcode_scheme: Cyton xcode_destination: platform=iOS Simulator,OS=11.3,name=iPhone X before_install: - travis_wait pod repo update --silent diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..c4931b07 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,15 @@ +All notable changes to this project will be documented in this file. + +# [v0.7.1](https://github.com/cryptape/cyton-ios/compare/v0.7.0...v0.7.1) (2019-01-22) + +### BREAKING CHANGES + +* Rename the project to `Cyton`. Change top module from `AppChain` to `CITA`. +* Support internationalization. +* Fix known bugs. + +--- + +* 修改钱包名称为 Cyton , 修改项目中的 “AppChain” 为 “CITA”。 +* 增加国际化,支持中文和英文。 +* 修复已知 BUG 。 diff --git a/Neuron.xcodeproj/project.pbxproj b/Cyton.xcodeproj/project.pbxproj similarity index 76% rename from Neuron.xcodeproj/project.pbxproj rename to Cyton.xcodeproj/project.pbxproj index 5537cad9..4e5a236c 100644 --- a/Neuron.xcodeproj/project.pbxproj +++ b/Cyton.xcodeproj/project.pbxproj @@ -28,52 +28,56 @@ 1A6007A221A2AA9A00C7B712 /* PageItemAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A6007A121A2AA9A00C7B712 /* PageItemAppearance.swift */; }; 1A60B6FC2186DB1C00FEFB3A /* Web3Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A60B6FB2186DB1C00FEFB3A /* Web3Utils.swift */; }; 1A69465C21916BE5000093A2 /* EthereumTxSender.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A69465B21916BE5000093A2 /* EthereumTxSender.swift */; }; - 1A69465E21916C3D000093A2 /* AppChainTxSender.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A69465D21916C3D000093A2 /* AppChainTxSender.swift */; }; + 1A69465E21916C3D000093A2 /* CITATxSender.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A69465D21916C3D000093A2 /* CITATxSender.swift */; }; 1A6946602192A0B0000093A2 /* GasCalculator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A69465F2192A0B0000093A2 /* GasCalculator.swift */; }; 1A6946622192BFD9000093A2 /* GasCalculatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A6946612192BFD9000093A2 /* GasCalculatorTests.swift */; }; - 1A75EBFD21A1948F008D484B /* SendTransaction.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1A75EBFC21A1948F008D484B /* SendTransaction.storyboard */; }; - 1A75EBFF21A194B2008D484B /* SendTransactionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A75EBFE21A194B1008D484B /* SendTransactionViewController.swift */; }; 1A9204E421634212004B54DC /* ToastActivityView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1A9204E321634212004B54DC /* ToastActivityView.xib */; }; + 1A9A025A21B90968002F2108 /* URLRequest+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A9A025921B90968002F2108 /* URLRequest+Extension.swift */; }; 1AB0CC492194FC1000A7C0CF /* UIntExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AB0CC482194FC1000A7C0CF /* UIntExtensionTests.swift */; }; 1AB287742179654300DCC14D /* WalletManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AB287732179654300DCC14D /* WalletManagerTests.swift */; }; 1AB3D1CF21709F6700557E9D /* UIStoryboard+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AB3D1CE21709F6700557E9D /* UIStoryboard+Extension.swift */; }; 1AB3D1D221709F9600557E9D /* UIStoryboardExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AB3D1D121709F9600557E9D /* UIStoryboardExtensionTests.swift */; }; - 1AE3145121A2F5A300F92B2A /* TransactionParamBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AE3145021A2F5A300F92B2A /* TransactionParamBuilder.swift */; }; 1AEBF3E4219BA1E700653FF5 /* BigUInt+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AEBF3E3219BA1E700653FF5 /* BigUInt+Extension.swift */; }; 1AEBF3E6219BA22600653FF5 /* BigUIntExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AEBF3E5219BA22600653FF5 /* BigUIntExtensionTests.swift */; }; 1AEF127C21A677B600202373 /* AboutUs.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1AEF127B21A677B600202373 /* AboutUs.storyboard */; }; - 3B9D2E9C9E858D6634948E6D /* Pods_Neuron.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8CC6FD685582D038A3767657 /* Pods_Neuron.framework */; }; - 6E3B2B6B219D938F0095257D /* SentTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E3B2B6A219D938F0095257D /* SentTransaction.swift */; }; + 3B9D2E9C9E858D6634948E6D /* Pods_Cyton.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8CC6FD685582D038A3767657 /* Pods_Cyton.framework */; }; 6E3B2B6D219ED9240095257D /* Ethereum+TransactionDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E3B2B6C219ED9230095257D /* Ethereum+TransactionDetails.swift */; }; - 6E3B2B6F219ED9340095257D /* Ethereum+TransactionStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E3B2B6E219ED9340095257D /* Ethereum+TransactionStatus.swift */; }; - 6E3B2B71219EDA230095257D /* AppChain+TransactionDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E3B2B70219EDA230095257D /* AppChain+TransactionDetails.swift */; }; - 6E3B2B73219EDB870095257D /* AppChain+TransactionStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E3B2B72219EDB870095257D /* AppChain+TransactionStatus.swift */; }; - 6E3B2B75219EDE200095257D /* TransactionStatusManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E3B2B74219EDE200095257D /* TransactionStatusManager.swift */; }; + 6E3B2B71219EDA230095257D /* CITA+TransactionDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E3B2B70219EDA230095257D /* CITA+TransactionDetails.swift */; }; 6E7D3838219C173D0031177B /* TransactionDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E7D3837219C173D0031177B /* TransactionDetails.swift */; }; - 6E7D3842219C47940031177B /* TransactionHistoryPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E7D3841219C47940031177B /* TransactionHistoryPresenter.swift */; }; - 6E8168F921887A31007641BA /* TransactionGasPriceViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E8168F821887A31007641BA /* TransactionGasPriceViewController.swift */; }; 6E83CB8D216F573100029324 /* ProductAgreementViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E83CB88216F573100029324 /* ProductAgreementViewController.swift */; }; 6E83CB8E216F573100029324 /* GuideService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E83CB89216F573100029324 /* GuideService.swift */; }; 6E83CB8F216F573100029324 /* Guide.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6E83CB8A216F573100029324 /* Guide.storyboard */; }; 6E83CB90216F573100029324 /* GuideCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E83CB8B216F573100029324 /* GuideCollectionViewCell.swift */; }; 6E83CB91216F573100029324 /* GuideViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E83CB8C216F573100029324 /* GuideViewController.swift */; }; - 6E83CB93216F581800029324 /* ProductAgreement.txt in Resources */ = {isa = PBXBuildFile; fileRef = 6E83CB92216F581800029324 /* ProductAgreement.txt */; }; 6E859CB82176DC3100637E1C /* Overlay.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6E859CB72176DC3100637E1C /* Overlay.storyboard */; }; + 6E85C12A21C7542900670F8B /* CreateWalletGuideViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E85C12921C7542900670F8B /* CreateWalletGuideViewController.swift */; }; + 6E86071521CB39C80055387C /* guide_page_1@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6E86071721CB39C80055387C /* guide_page_1@3x.png */; }; + 6E86072121CB39F80055387C /* guide_page_1@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6E86072321CB39F80055387C /* guide_page_1@2x.png */; }; 6E867E03216C3EC800BD6FE5 /* AuthSelectWalletViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E867E02216C3EC800BD6FE5 /* AuthSelectWalletViewController.swift */; }; 6E867E05216C3F1500BD6FE5 /* AuthPasswordViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E867E04216C3F1500BD6FE5 /* AuthPasswordViewController.swift */; }; 6E867E09216C862900BD6FE5 /* NoScreenshot.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E867E08216C862900BD6FE5 /* NoScreenshot.swift */; }; 6E867E0D216C92A900BD6FE5 /* OverlayPresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E867E0C216C92A900BD6FE5 /* OverlayPresentable.swift */; }; 6E867E0F216CA4EB00BD6FE5 /* SettingAuthenticationTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E867E0E216CA4EB00BD6FE5 /* SettingAuthenticationTableViewCell.swift */; }; 6E867E11216CA51600BD6FE5 /* SettingCurrencyTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E867E10216CA51600BD6FE5 /* SettingCurrencyTableViewCell.swift */; }; - 6E876841218022F30032EBCE /* TokenProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E876840218022F30032EBCE /* TokenProfile.swift */; }; 6E876845218031670032EBCE /* UInt+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E876844218031670032EBCE /* UInt+Extension.swift */; }; + 6E877F4321C8C89E00C65511 /* TransactionDetailsParamBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E877F4221C8C89E00C65511 /* TransactionDetailsParamBuilder.swift */; }; + 6E878DD221BF944000526B6A /* TaskThread.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E878DD121BF944000526B6A /* TaskThread.swift */; }; 6E8962032194575B00D2C0AD /* DoubleExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E8962022194575B00D2C0AD /* DoubleExtensionTests.swift */; }; - 6E8AFB0D21A7E7B800F81DC6 /* TransactionGasCostViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E8AFB0C21A7E7B800F81DC6 /* TransactionGasCostViewController.swift */; }; + 6E8A837021B62DA30051B3EB /* TransactionHistory.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6E8A836A21B62DA30051B3EB /* TransactionHistory.storyboard */; }; + 6E8A837121B62DA30051B3EB /* TransactionHistoryPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E8A836B21B62DA30051B3EB /* TransactionHistoryPresenter.swift */; }; + 6E8A837221B62DA30051B3EB /* TransactionHistoryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E8A836C21B62DA30051B3EB /* TransactionHistoryViewController.swift */; }; + 6E8A838121B62E0A0051B3EB /* SendTransactionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E8A837A21B62E0A0051B3EB /* SendTransactionViewController.swift */; }; + 6E8A838221B62E0A0051B3EB /* SendTransaction.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6E8A837B21B62E0A0051B3EB /* SendTransaction.storyboard */; }; + 6E8A838321B62E0A0051B3EB /* TransactionGasCostViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E8A837C21B62E0A0051B3EB /* TransactionGasCostViewController.swift */; }; + 6E8A838421B62E0A0051B3EB /* TransactionParamBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E8A837D21B62E0A0051B3EB /* TransactionParamBuilder.swift */; }; + 6E8A838621B62E0A0051B3EB /* TransactionSwitchTokenViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E8A837F21B62E0A0051B3EB /* TransactionSwitchTokenViewController.swift */; }; + 6E8A838721B62E0A0051B3EB /* TransactonSender.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E8A838021B62E0A0051B3EB /* TransactonSender.swift */; }; + 6E8A838921B777A60051B3EB /* NSDecimalNumber+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E8A838821B777A60051B3EB /* NSDecimalNumber+Extension.swift */; }; + 6E8A838B21B8C4780051B3EB /* TransactionDetailsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E8A838A21B8C4780051B3EB /* TransactionDetailsViewController.swift */; }; + 6E8A838D21B8C49F0051B3EB /* TransactionDetails.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6E8A838C21B8C49F0051B3EB /* TransactionDetails.storyboard */; }; 6E8BFC3121AFDBB5004752CC /* EthereumBalanceLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E8BFC3021AFDBB5004752CC /* EthereumBalanceLoader.swift */; }; 6E8BFC3721B00948004752CC /* TokenPriceLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E8BFC3621B00948004752CC /* TokenPriceLoader.swift */; }; 6E8D77F021A5264F00EA7674 /* WalletQRCodeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E8D77EF21A5264F00EA7674 /* WalletQRCodeViewController.swift */; }; - 6E8D77F221A54B8100EA7674 /* TransactionSwitchTokenViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E8D77F121A54B8100EA7674 /* TransactionSwitchTokenViewController.swift */; }; - 6E90D06921704C1D00B98363 /* SensorsAnalytics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E90D06821704C1D00B98363 /* SensorsAnalytics.swift */; }; 6E96B3E521B4E38C000F935B /* DAppPermissionsMessageHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E96B3E421B4E38C000F935B /* DAppPermissionsMessageHandler.swift */; }; 6E9B947B21A4080300D67357 /* DesignableButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E9B947A21A4080300D67357 /* DesignableButton.swift */; }; 6E9B947D21A4083100D67357 /* DesignableGradientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E9B947C21A4083100D67357 /* DesignableGradientView.swift */; }; @@ -88,6 +92,15 @@ 6EABFB10219933EB00305ED5 /* DAppDeviceMotionMessageHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EABFB0F219933EB00305ED5 /* DAppDeviceMotionMessageHandler.swift */; }; 6EABFB122199520F00305ED5 /* DAppTakePhotoMessageHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EABFB112199520F00305ED5 /* DAppTakePhotoMessageHandler.swift */; }; 6EABFB1421995AB800305ED5 /* DAppGyroscopeMessageHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EABFB1321995AB800305ED5 /* DAppGyroscopeMessageHandler.swift */; }; + 6EB4E84121D62B3A00B93FAB /* EthereumLocalTxPool.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EB4E84021D62B3900B93FAB /* EthereumLocalTxPool.swift */; }; + 6EDBE3A121DE02EA0087DA38 /* CITALocalTxPool.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EDBE3A021DE02EA0087DA38 /* CITALocalTxPool.swift */; }; + 6EE37EA121C782FE00F62F2C /* WalletIconPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EE37EA021C782FE00F62F2C /* WalletIconPickerViewController.swift */; }; + 6EEDED6821CB3C8200FC3BCE /* guide_page_2@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6EEDED6521CB3C8200FC3BCE /* guide_page_2@2x.png */; }; + 6EEDED7B21CB3D1700FC3BCE /* guide_page_2@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6EEDED7821CB3D1700FC3BCE /* guide_page_2@3x.png */; }; + 6EEDED9821CB3DD700FC3BCE /* guide_page_3@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6EEDED9521CB3DD700FC3BCE /* guide_page_3@3x.png */; }; + 6EEDEDA121CB3DFC00FC3BCE /* guide_page_3@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6EEDED9E21CB3DFB00FC3BCE /* guide_page_3@2x.png */; }; + 6EEDEDA221CB3F3500FC3BCE /* product_agreement.txt in Resources */ = {isa = PBXBuildFile; fileRef = 6EEDEDA421CB3F3500FC3BCE /* product_agreement.txt */; }; + 6EEDEDA721CB4CF100FC3BCE /* EthereumTokenProfileLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EEDEDA621CB4CF100FC3BCE /* EthereumTokenProfileLoader.swift */; }; 6EF8F40C2175CAD9004B7587 /* UIControl+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EF8F40B2175CAD9004B7587 /* UIControl+Extension.swift */; }; 6EF8F4102176029E004B7587 /* OpenAuthViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EF8F40F2176029E004B7587 /* OpenAuthViewController.swift */; }; 8905660720D0AC120041D4B4 /* AppModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8905660620D0AC120041D4B4 /* AppModel.swift */; }; @@ -104,6 +117,7 @@ 8928C27A20B2A61900C3103E /* WalletViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8928C27820B2A61900C3103E /* WalletViewController.swift */; }; 8928C2A320B41BCA00C3103E /* SelectWalletController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8928C2A120B41BCA00C3103E /* SelectWalletController.swift */; }; 892A1985215A55F400B2293D /* Double+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 892A1984215A55F400B2293D /* Double+Extension.swift */; }; + 892E5B1821B61F0100298845 /* CITA+ERC20.swift in Sources */ = {isa = PBXBuildFile; fileRef = 892E5B1721B61F0000298845 /* CITA+ERC20.swift */; }; 892F79B921A547340035B08B /* ModifyWalletNamePageItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 892F79B821A547340035B08B /* ModifyWalletNamePageItem.swift */; }; 8935BA55216EE65500C37263 /* WKWebViewConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8935BA54216EE65500C37263 /* WKWebViewConfiguration.swift */; }; 8935BA57216EEDEC00C37263 /* WKWebViewConfigConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8935BA56216EEDEC00C37263 /* WKWebViewConfigConstants.swift */; }; @@ -115,24 +129,25 @@ 89422FEB21A7F9CA00DD8744 /* CollectionTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89422FEA21A7F9C900DD8744 /* CollectionTableViewCell.swift */; }; 8951A84C2170A5CC00043228 /* DAppAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8951A84B2170A5CC00043228 /* DAppAction.swift */; }; 8955580520DCA7F700FC92D8 /* PasswordValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8955580420DCA7F700FC92D8 /* PasswordValidator.swift */; }; + 895F713421C630E800F41107 /* VerifyMnemonicViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 895F713321C630E800F41107 /* VerifyMnemonicViewController.swift */; }; 8964A17D20BE7F750086848F /* MessageSignController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8964A17B20BE7F750086848F /* MessageSignController.swift */; }; 8964A18020BE94F70086848F /* NEPickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8964A17F20BE94F70086848F /* NEPickerView.swift */; }; 8964A18720BFE6860086848F /* ImportWalletController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8964A18520BFE6850086848F /* ImportWalletController.swift */; }; 8964A18D20C0E4BE0086848F /* GenerateMnemonicController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8964A18B20C0E4BE0086848F /* GenerateMnemonicController.swift */; }; - 8964A19320C115A70086848F /* VerifyMnemonicViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8964A19120C115A70086848F /* VerifyMnemonicViewController.swift */; }; 8964A19620C12FB70086848F /* ButtonTagView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8964A19520C12FB70086848F /* ButtonTagView.swift */; }; 8964A19820C15EA20086848F /* ButtonTagUpView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8964A19720C15EA20086848F /* ButtonTagUpView.swift */; }; 896812CB20F726D000731C8C /* dappOpration.js in Resources */ = {isa = PBXBuildFile; fileRef = 896812CA20F726D000731C8C /* dappOpration.js */; }; + 896B32BB21BF865900C4DA7F /* CITA+AddToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = 896B32BA21BF865900C4DA7F /* CITA+AddToken.swift */; }; + 896B32BD21BFAD3B00C4DA7F /* ShowTokenPageItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 896B32BC21BFAD3B00C4DA7F /* ShowTokenPageItem.swift */; }; + 896B32BF21BFAEBC00C4DA7F /* TokenMessageView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 896B32BE21BFAEBC00C4DA7F /* TokenMessageView.xib */; }; + 896CEA9A21B91E4500B1A7D4 /* DefaultTokenAndChain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 896CEA9921B91E4500B1A7D4 /* DefaultTokenAndChain.swift */; }; 896D042D20AE69C1002CFF6A /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 896D042C20AE69C1002CFF6A /* AppDelegate.swift */; }; 896D043220AE69C1002CFF6A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 896D043020AE69C1002CFF6A /* Main.storyboard */; }; 896D043420AE69C5002CFF6A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 896D043320AE69C5002CFF6A /* Assets.xcassets */; }; 896D043720AE69C5002CFF6A /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 896D043520AE69C5002CFF6A /* LaunchScreen.storyboard */; }; - 896D044220AE69C5002CFF6A /* NeuronTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 896D044120AE69C5002CFF6A /* NeuronTests.swift */; }; - 896D044D20AE69C5002CFF6A /* NeuronUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 896D044C20AE69C5002CFF6A /* NeuronUITests.swift */; }; - 8972FD0F218B54A100C27147 /* AdvancedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8972FD0E218B54A100C27147 /* AdvancedViewController.swift */; }; - 8978846321AD26690034AF4F /* neuron.js in Resources */ = {isa = PBXBuildFile; fileRef = 8978846221AD26690034AF4F /* neuron.js */; }; 897AFC5B2130129500383A12 /* CurrencyViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 897AFC592130129500383A12 /* CurrencyViewController.swift */; }; 8981212A218D3161000813C8 /* QRCodeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89812129218D3161000813C8 /* QRCodeViewController.swift */; }; + 89880A2321C269F100A34A0B /* CITA+Balance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89880A2221C269F100A34A0B /* CITA+Balance.swift */; }; 898889C62136521100D04AA8 /* KeystoreViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 898889C52136521100D04AA8 /* KeystoreViewController.swift */; }; 898889C82136526800D04AA8 /* MnemonicViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 898889C72136526800D04AA8 /* MnemonicViewController.swift */; }; 898889CA2136528B00D04AA8 /* PrivatekeyViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 898889C92136528B00D04AA8 /* PrivatekeyViewController.swift */; }; @@ -142,29 +157,24 @@ 898A1A0320B5717A00ECB465 /* ManageAssetViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 898A1A0120B5717A00ECB465 /* ManageAssetViewController.swift */; }; 898A1A0720B5797700ECB465 /* AssetTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 898A1A0520B5797700ECB465 /* AssetTableViewCell.swift */; }; 898A1A0B20B64F6000ECB465 /* AddAssetController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 898A1A0920B64F6000ECB465 /* AddAssetController.swift */; }; - 898A1A0F20B6539800ECB465 /* AddAssetTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 898A1A0D20B6539800ECB465 /* AddAssetTableViewCell.swift */; }; - 898A1A1020B6539800ECB465 /* AddAssetTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 898A1A0E20B6539800ECB465 /* AddAssetTableViewCell.xib */; }; 898A1A1720B6BE6E00ECB465 /* ChangePasswordController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 898A1A1520B6BE6E00ECB465 /* ChangePasswordController.swift */; }; 898A1A1B20B7A6BB00ECB465 /* CreateWalletController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 898A1A1920B7A6BB00ECB465 /* CreateWalletController.swift */; }; - 898A1A2620B7DAA300ECB465 /* TransactionTableviewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 898A1A2420B7DAA300ECB465 /* TransactionTableviewCell.swift */; }; - 898A1A2A20B7F0FC00ECB465 /* TradeDetailsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 898A1A2820B7F0FC00ECB465 /* TradeDetailsController.swift */; }; - 898A1A2B20B7F0FC00ECB465 /* TradeDetailsController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 898A1A2920B7F0FC00ECB465 /* TradeDetailsController.xib */; }; - 898A1A2F20B8044900ECB465 /* TradeTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 898A1A2D20B8044900ECB465 /* TradeTableViewCell.swift */; }; - 898A1A3020B8044900ECB465 /* TradeTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 898A1A2E20B8044900ECB465 /* TradeTableViewCell.xib */; }; 898CA98320EA0F210059ECA3 /* TokenModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 898CA98220EA0F210059ECA3 /* TokenModel.swift */; }; - 898CA98A20EA2E770059ECA3 /* tokens-eth.json in Resources */ = {isa = PBXBuildFile; fileRef = 898CA98920EA2E760059ECA3 /* tokens-eth.json */; }; - 899AD19921100F2B00A8AC09 /* NervosNativeTokenService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 899AD19821100F2B00A8AC09 /* NervosNativeTokenService.swift */; }; - 899AD19B211011F300A8AC09 /* AppChainNetwork.swift in Sources */ = {isa = PBXBuildFile; fileRef = 899AD19A211011F300A8AC09 /* AppChainNetwork.swift */; }; + 899AD19B211011F300A8AC09 /* CITANetwork.swift in Sources */ = {isa = PBXBuildFile; fileRef = 899AD19A211011F300A8AC09 /* CITANetwork.swift */; }; 89A196192175D9C800BD5FA4 /* DAppDataHandle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89A196182175D9C800BD5FA4 /* DAppDataHandle.swift */; }; 89A1961B2175E7F300BD5FA4 /* DAppCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89A1961A2175E7F300BD5FA4 /* DAppCommand.swift */; }; 89A87C892173097000588674 /* WalletNameValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89A87C882173097000588674 /* WalletNameValidator.swift */; }; 89A87C8B217312CC00588674 /* WalletNameValidatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89A87C8A217312CC00588674 /* WalletNameValidatorTests.swift */; }; 89AB35CA213D113E00A2BF48 /* WalletTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89AB35C9213D113E00A2BF48 /* WalletTableViewCell.swift */; }; 89B01A24216DAC5A00BFAAF4 /* DAppBrowser.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 89B01A23216DAC5A00BFAAF4 /* DAppBrowser.storyboard */; }; + 89B2742321EC2AA0001A6A93 /* CytonTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89B2742221EC2AA0001A6A93 /* CytonTests.swift */; }; + 89B2742521EC2AAD001A6A93 /* CytonUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89B2742421EC2AAD001A6A93 /* CytonUITests.swift */; }; + 89B2742721EC2B35001A6A93 /* cyton.js in Resources */ = {isa = PBXBuildFile; fileRef = 89B2742621EC2B35001A6A93 /* cyton.js */; }; 89B296ED20F4CBA7008558A7 /* ServerAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89B296EC20F4CBA7008558A7 /* ServerAPI.swift */; }; 89B895B120F8B0CD00B9468B /* BrowserViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89B895B020F8B0CD00B9468B /* BrowserViewController.swift */; }; 89BA4B5621AE333E0084439B /* MnemonicValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89BA4B5521AE333E0084439B /* MnemonicValidator.swift */; }; 89BA4B5821AE410F0084439B /* MnemonicValidatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89BA4B5721AE410F0084439B /* MnemonicValidatorTests.swift */; }; + 89BD0ECA21B77FA2002D10BD /* ChainModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89BD0EC921B77FA2002D10BD /* ChainModel.swift */; }; 89BEBE6B20EF82B6007D2705 /* EthereumNetwork.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89BEBE6A20EF82B6007D2705 /* EthereumNetwork.swift */; }; 89BEBE7220F12647007D2705 /* CommonWebViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89BEBE7120F12647007D2705 /* CommonWebViewController.swift */; }; 89C25C5A20BBA38300007EC1 /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89C25C5820BBA38300007EC1 /* SettingsViewController.swift */; }; @@ -174,8 +184,6 @@ 89C614572140D4C500DC3DF4 /* currency.plist in Resources */ = {isa = PBXBuildFile; fileRef = 89C614562140D4C500DC3DF4 /* currency.plist */; }; 89C614592140FE6600DC3DF4 /* CurrencyTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89C614582140FE6600DC3DF4 /* CurrencyTableViewCell.swift */; }; 89C6145E2141038300DC3DF4 /* LocalCurrencyService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89C6145D2141038300DC3DF4 /* LocalCurrencyService.swift */; }; - 89C614602141421400DC3DF4 /* TransactionHistoryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89C6145F2141421400DC3DF4 /* TransactionHistoryViewController.swift */; }; - 89CA1FAC213F822B00669B2C /* tokens-list.json in Resources */ = {isa = PBXBuildFile; fileRef = 89CA1FAB213F822B00669B2C /* tokens-list.json */; }; 89CFA12621424CAB00635A54 /* AboutUsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89CFA12521424CAB00635A54 /* AboutUsViewController.swift */; }; 89D4AC2E20D59F270097E02B /* WalletManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89D4AC2520D59F270097E02B /* WalletManager.swift */; }; 89D4AC3820D8DB610097E02B /* NotificationName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89D4AC3720D8DB610097E02B /* NotificationName.swift */; }; @@ -188,14 +196,18 @@ 89D935252139363A002FAEEC /* TokenTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89D935242139363A002FAEEC /* TokenTableViewCell.swift */; }; 89F7966D213A6B680064808A /* ERC721TableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89F7966C213A6B680064808A /* ERC721TableViewCell.swift */; }; 89F7966F213BD5680064808A /* Assets.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 89F7966E213BD5680064808A /* Assets.storyboard */; }; - 89F79671213BD8C40064808A /* TransactionHistory.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 89F79670213BD8C40064808A /* TransactionHistory.storyboard */; }; 89F9E73E20DEBDE8009E68D4 /* ExportKeystoreController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89F9E73C20DEBDE8009E68D4 /* ExportKeystoreController.swift */; }; 89F9E73F20DEBDE8009E68D4 /* ExportKeystoreController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 89F9E73D20DEBDE8009E68D4 /* ExportKeystoreController.xib */; }; + 89FA2E2321BE39DF001EA590 /* SelectChainTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89FA2E2221BE39DF001EA590 /* SelectChainTableViewCell.swift */; }; + 89FA2E2521BE39F3001EA590 /* ContractAddressTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89FA2E2421BE39F3001EA590 /* ContractAddressTableViewCell.swift */; }; + 89FA2E2721BE83AF001EA590 /* SwitchChainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89FA2E2621BE83AF001EA590 /* SwitchChainViewController.swift */; }; 89FC542D20D4142D00D5D27C /* SkipBackupFiles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89FC542C20D4142D00D5D27C /* SkipBackupFiles.swift */; }; 89FE21DA20EDB10900A09302 /* CustomERC20TokenService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89FE21D920EDB10900A09302 /* CustomERC20TokenService.swift */; }; 89FE21DE20EDB70000A09302 /* SendTransactionError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89FE21DD20EDB70000A09302 /* SendTransactionError.swift */; }; - E2E67496168FEDCBC828A891 /* Pods_NeuronUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3502E1744CFA926363F980D0 /* Pods_NeuronUITests.framework */; }; - FEA60F4E8F81CB701C31AE44 /* Pods_NeuronTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB1ED6C1CFAD097B034BA2EF /* Pods_NeuronTests.framework */; }; + D595D7ED21F079A8006FBDDC /* Web3Error+Description.swift in Sources */ = {isa = PBXBuildFile; fileRef = D595D7EC21F079A8006FBDDC /* Web3Error+Description.swift */; }; + D595D7EF21F0816A006FBDDC /* String+Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = D595D7EE21F0816A006FBDDC /* String+Error.swift */; }; + E2E67496168FEDCBC828A891 /* Pods_CytonUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3502E1744CFA926363F980D0 /* Pods_CytonUITests.framework */; }; + FEA60F4E8F81CB701C31AE44 /* Pods_CytonTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB1ED6C1CFAD097B034BA2EF /* Pods_CytonTests.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -204,14 +216,14 @@ containerPortal = 896D042120AE69C1002CFF6A /* Project object */; proxyType = 1; remoteGlobalIDString = 896D042820AE69C1002CFF6A; - remoteInfo = Neuron; + remoteInfo = Cyton; }; 896D044920AE69C5002CFF6A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 896D042120AE69C1002CFF6A /* Project object */; proxyType = 1; remoteGlobalIDString = 896D042820AE69C1002CFF6A; - remoteInfo = Neuron; + remoteInfo = Cyton; }; /* End PBXContainerItemProxy section */ @@ -238,54 +250,58 @@ 1A6007A121A2AA9A00C7B712 /* PageItemAppearance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageItemAppearance.swift; sourceTree = ""; }; 1A60B6FB2186DB1C00FEFB3A /* Web3Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Web3Utils.swift; sourceTree = ""; }; 1A69465B21916BE5000093A2 /* EthereumTxSender.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EthereumTxSender.swift; sourceTree = ""; }; - 1A69465D21916C3D000093A2 /* AppChainTxSender.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppChainTxSender.swift; sourceTree = ""; }; + 1A69465D21916C3D000093A2 /* CITATxSender.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CITATxSender.swift; sourceTree = ""; }; 1A69465F2192A0B0000093A2 /* GasCalculator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GasCalculator.swift; sourceTree = ""; }; 1A6946612192BFD9000093A2 /* GasCalculatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GasCalculatorTests.swift; sourceTree = ""; }; - 1A75EBFC21A1948F008D484B /* SendTransaction.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = SendTransaction.storyboard; sourceTree = ""; }; - 1A75EBFE21A194B1008D484B /* SendTransactionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SendTransactionViewController.swift; sourceTree = ""; }; 1A9204E321634212004B54DC /* ToastActivityView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ToastActivityView.xib; sourceTree = ""; }; + 1A9A025921B90968002F2108 /* URLRequest+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URLRequest+Extension.swift"; sourceTree = ""; }; 1AB0CC482194FC1000A7C0CF /* UIntExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIntExtensionTests.swift; sourceTree = ""; }; 1AB287732179654300DCC14D /* WalletManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletManagerTests.swift; sourceTree = ""; }; 1AB3D1CE21709F6700557E9D /* UIStoryboard+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIStoryboard+Extension.swift"; sourceTree = ""; }; - 1AB3D1D121709F9600557E9D /* UIStoryboardExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = UIStoryboardExtensionTests.swift; path = NeuronTests/Extensions/UIKit/UIStoryboardExtensionTests.swift; sourceTree = SOURCE_ROOT; }; - 1AE3145021A2F5A300F92B2A /* TransactionParamBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionParamBuilder.swift; sourceTree = ""; }; + 1AB3D1D121709F9600557E9D /* UIStoryboardExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = UIStoryboardExtensionTests.swift; path = CytonTests/Extensions/UIKit/UIStoryboardExtensionTests.swift; sourceTree = SOURCE_ROOT; }; 1AEBF3E3219BA1E700653FF5 /* BigUInt+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BigUInt+Extension.swift"; sourceTree = ""; }; 1AEBF3E5219BA22600653FF5 /* BigUIntExtensionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BigUIntExtensionTests.swift; sourceTree = ""; }; 1AEF127B21A677B600202373 /* AboutUs.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = AboutUs.storyboard; sourceTree = ""; }; - 1D270F090888C6AD9CF6A055 /* Pods-Neuron.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Neuron.release.xcconfig"; path = "Pods/Target Support Files/Pods-Neuron/Pods-Neuron.release.xcconfig"; sourceTree = ""; }; - 21C5F1D714208410CA8D77B9 /* Pods-Neuron.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Neuron.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Neuron/Pods-Neuron.debug.xcconfig"; sourceTree = ""; }; - 3502E1744CFA926363F980D0 /* Pods_NeuronUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_NeuronUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E3B2B6A219D938F0095257D /* SentTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentTransaction.swift; sourceTree = ""; }; + 1D270F090888C6AD9CF6A055 /* Pods-Cyton.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Cyton.release.xcconfig"; path = "Pods/Target Support Files/Pods-Cyton/Pods-Cyton.release.xcconfig"; sourceTree = ""; }; + 21C5F1D714208410CA8D77B9 /* Pods-Cyton.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Cyton.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Cyton/Pods-Cyton.debug.xcconfig"; sourceTree = ""; }; + 3502E1744CFA926363F980D0 /* Pods_CytonUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CytonUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 6E3B2B6C219ED9230095257D /* Ethereum+TransactionDetails.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Ethereum+TransactionDetails.swift"; sourceTree = ""; }; - 6E3B2B6E219ED9340095257D /* Ethereum+TransactionStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Ethereum+TransactionStatus.swift"; sourceTree = ""; }; - 6E3B2B70219EDA230095257D /* AppChain+TransactionDetails.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppChain+TransactionDetails.swift"; sourceTree = ""; }; - 6E3B2B72219EDB870095257D /* AppChain+TransactionStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppChain+TransactionStatus.swift"; sourceTree = ""; }; - 6E3B2B74219EDE200095257D /* TransactionStatusManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionStatusManager.swift; sourceTree = ""; }; + 6E3B2B70219EDA230095257D /* CITA+TransactionDetails.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CITA+TransactionDetails.swift"; sourceTree = ""; }; 6E7D3837219C173D0031177B /* TransactionDetails.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionDetails.swift; sourceTree = ""; }; - 6E7D3841219C47940031177B /* TransactionHistoryPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionHistoryPresenter.swift; sourceTree = ""; }; - 6E8168F821887A31007641BA /* TransactionGasPriceViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionGasPriceViewController.swift; sourceTree = ""; }; 6E83CB88216F573100029324 /* ProductAgreementViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProductAgreementViewController.swift; sourceTree = ""; }; 6E83CB89216F573100029324 /* GuideService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GuideService.swift; sourceTree = ""; }; 6E83CB8A216F573100029324 /* Guide.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Guide.storyboard; sourceTree = ""; }; 6E83CB8B216F573100029324 /* GuideCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GuideCollectionViewCell.swift; sourceTree = ""; }; 6E83CB8C216F573100029324 /* GuideViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GuideViewController.swift; sourceTree = ""; }; - 6E83CB92216F581800029324 /* ProductAgreement.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ProductAgreement.txt; sourceTree = ""; }; 6E859CB72176DC3100637E1C /* Overlay.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Overlay.storyboard; sourceTree = ""; }; + 6E85C12921C7542900670F8B /* CreateWalletGuideViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CreateWalletGuideViewController.swift; sourceTree = ""; }; + 6E86071621CB39C80055387C /* en */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = en; path = "en.lproj/guide_page_1@3x.png"; sourceTree = ""; }; + 6E86072221CB39F80055387C /* en */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = en; path = "en.lproj/guide_page_1@2x.png"; sourceTree = ""; }; 6E867E02216C3EC800BD6FE5 /* AuthSelectWalletViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthSelectWalletViewController.swift; sourceTree = ""; }; 6E867E04216C3F1500BD6FE5 /* AuthPasswordViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthPasswordViewController.swift; sourceTree = ""; }; 6E867E08216C862900BD6FE5 /* NoScreenshot.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoScreenshot.swift; sourceTree = ""; }; 6E867E0C216C92A900BD6FE5 /* OverlayPresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OverlayPresentable.swift; sourceTree = ""; }; 6E867E0E216CA4EB00BD6FE5 /* SettingAuthenticationTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingAuthenticationTableViewCell.swift; sourceTree = ""; }; 6E867E10216CA51600BD6FE5 /* SettingCurrencyTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingCurrencyTableViewCell.swift; sourceTree = ""; }; - 6E876840218022F30032EBCE /* TokenProfile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokenProfile.swift; sourceTree = ""; }; 6E876844218031670032EBCE /* UInt+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UInt+Extension.swift"; sourceTree = ""; }; + 6E877F4221C8C89E00C65511 /* TransactionDetailsParamBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionDetailsParamBuilder.swift; sourceTree = ""; }; + 6E878DD121BF944000526B6A /* TaskThread.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskThread.swift; sourceTree = ""; }; 6E8962022194575B00D2C0AD /* DoubleExtensionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DoubleExtensionTests.swift; sourceTree = ""; }; - 6E8AFB0C21A7E7B800F81DC6 /* TransactionGasCostViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionGasCostViewController.swift; sourceTree = ""; }; + 6E8A836A21B62DA30051B3EB /* TransactionHistory.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = TransactionHistory.storyboard; sourceTree = ""; }; + 6E8A836B21B62DA30051B3EB /* TransactionHistoryPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionHistoryPresenter.swift; sourceTree = ""; }; + 6E8A836C21B62DA30051B3EB /* TransactionHistoryViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionHistoryViewController.swift; sourceTree = ""; }; + 6E8A837A21B62E0A0051B3EB /* SendTransactionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SendTransactionViewController.swift; sourceTree = ""; }; + 6E8A837B21B62E0A0051B3EB /* SendTransaction.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = SendTransaction.storyboard; sourceTree = ""; }; + 6E8A837C21B62E0A0051B3EB /* TransactionGasCostViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionGasCostViewController.swift; sourceTree = ""; }; + 6E8A837D21B62E0A0051B3EB /* TransactionParamBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionParamBuilder.swift; sourceTree = ""; }; + 6E8A837F21B62E0A0051B3EB /* TransactionSwitchTokenViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionSwitchTokenViewController.swift; sourceTree = ""; }; + 6E8A838021B62E0A0051B3EB /* TransactonSender.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactonSender.swift; sourceTree = ""; }; + 6E8A838821B777A60051B3EB /* NSDecimalNumber+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSDecimalNumber+Extension.swift"; sourceTree = ""; }; + 6E8A838A21B8C4780051B3EB /* TransactionDetailsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionDetailsViewController.swift; sourceTree = ""; }; + 6E8A838C21B8C49F0051B3EB /* TransactionDetails.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = TransactionDetails.storyboard; sourceTree = ""; }; 6E8BFC3021AFDBB5004752CC /* EthereumBalanceLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EthereumBalanceLoader.swift; sourceTree = ""; }; 6E8BFC3621B00948004752CC /* TokenPriceLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokenPriceLoader.swift; sourceTree = ""; }; 6E8D77EF21A5264F00EA7674 /* WalletQRCodeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletQRCodeViewController.swift; sourceTree = ""; }; - 6E8D77F121A54B8100EA7674 /* TransactionSwitchTokenViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionSwitchTokenViewController.swift; sourceTree = ""; }; - 6E90D06821704C1D00B98363 /* SensorsAnalytics.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SensorsAnalytics.swift; sourceTree = ""; }; 6E96B3E421B4E38C000F935B /* DAppPermissionsMessageHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DAppPermissionsMessageHandler.swift; sourceTree = ""; }; 6E9B947A21A4080300D67357 /* DesignableButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DesignableButton.swift; sourceTree = ""; }; 6E9B947C21A4083100D67357 /* DesignableGradientView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DesignableGradientView.swift; sourceTree = ""; }; @@ -300,16 +316,30 @@ 6EABFB0F219933EB00305ED5 /* DAppDeviceMotionMessageHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DAppDeviceMotionMessageHandler.swift; sourceTree = ""; }; 6EABFB112199520F00305ED5 /* DAppTakePhotoMessageHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DAppTakePhotoMessageHandler.swift; sourceTree = ""; }; 6EABFB1321995AB800305ED5 /* DAppGyroscopeMessageHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DAppGyroscopeMessageHandler.swift; sourceTree = ""; }; + 6EB4E84021D62B3900B93FAB /* EthereumLocalTxPool.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EthereumLocalTxPool.swift; sourceTree = ""; }; + 6EDBE3A021DE02EA0087DA38 /* CITALocalTxPool.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CITALocalTxPool.swift; sourceTree = ""; }; + 6EE37EA021C782FE00F62F2C /* WalletIconPickerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletIconPickerViewController.swift; sourceTree = ""; }; + 6EEDED4F21CB3B3B00FC3BCE /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "zh-Hans"; path = "zh-Hans.lproj/guide_page_1@3x.png"; sourceTree = ""; }; + 6EEDED5021CB3B3B00FC3BCE /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "zh-Hans"; path = "zh-Hans.lproj/guide_page_1@2x.png"; sourceTree = ""; }; + 6EEDED6621CB3C8200FC3BCE /* en */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = en; path = "en.lproj/guide_page_2@2x.png"; sourceTree = ""; }; + 6EEDED6721CB3C8200FC3BCE /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "zh-Hans"; path = "zh-Hans.lproj/guide_page_2@2x.png"; sourceTree = ""; }; + 6EEDED7921CB3D1700FC3BCE /* en */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = en; path = "en.lproj/guide_page_2@3x.png"; sourceTree = ""; }; + 6EEDED7A21CB3D1700FC3BCE /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "zh-Hans"; path = "zh-Hans.lproj/guide_page_2@3x.png"; sourceTree = ""; }; + 6EEDED9621CB3DD700FC3BCE /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "zh-Hans"; path = "zh-Hans.lproj/guide_page_3@3x.png"; sourceTree = ""; }; + 6EEDED9721CB3DD700FC3BCE /* en */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = en; path = "en.lproj/guide_page_3@3x.png"; sourceTree = ""; }; + 6EEDED9F21CB3DFB00FC3BCE /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "zh-Hans"; path = "zh-Hans.lproj/guide_page_3@2x.png"; sourceTree = ""; }; + 6EEDEDA021CB3DFB00FC3BCE /* en */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = en; path = "en.lproj/guide_page_3@2x.png"; sourceTree = ""; }; + 6EEDEDA321CB3F3500FC3BCE /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text; name = "zh-Hans"; path = "zh-Hans.lproj/product_agreement.txt"; sourceTree = ""; }; + 6EEDEDA621CB4CF100FC3BCE /* EthereumTokenProfileLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EthereumTokenProfileLoader.swift; sourceTree = ""; }; 6EF8F40B2175CAD9004B7587 /* UIControl+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIControl+Extension.swift"; sourceTree = ""; }; 6EF8F40F2176029E004B7587 /* OpenAuthViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenAuthViewController.swift; sourceTree = ""; }; - 71EE3A6382628C3632FE594F /* Pods-NeuronTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NeuronTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-NeuronTests/Pods-NeuronTests.release.xcconfig"; sourceTree = ""; }; + 71EE3A6382628C3632FE594F /* Pods-CytonTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CytonTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-CytonTests/Pods-CytonTests.release.xcconfig"; sourceTree = ""; }; 8905660620D0AC120041D4B4 /* AppModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppModel.swift; sourceTree = ""; }; 8913437020C78F1000A17AEF /* WalletModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletModel.swift; sourceTree = ""; }; 8913437420C7D3A400A17AEF /* Toast.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Toast.swift; sourceTree = ""; }; 8913437720CA56CA00A17AEF /* RealmConfigurator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealmConfigurator.swift; sourceTree = ""; }; 891B663C213EAA1900B0FCB0 /* WalletManagement.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = WalletManagement.storyboard; sourceTree = ""; }; 891C2482211165AC007C639D /* TokenMacro.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokenMacro.swift; sourceTree = ""; }; - 8928C22020AE779B00C3103E /* Neuron-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Neuron-Bridging-Header.h"; sourceTree = ""; }; 8928C24220AE908300C3103E /* MainViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainViewController.swift; sourceTree = ""; }; 8928C24420AE90C000C3103E /* BaseNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseNavigationController.swift; sourceTree = ""; }; 8928C24820AE91E600C3103E /* DappViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DappViewController.swift; sourceTree = ""; }; @@ -318,6 +348,7 @@ 8928C27820B2A61900C3103E /* WalletViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletViewController.swift; sourceTree = ""; }; 8928C2A120B41BCA00C3103E /* SelectWalletController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectWalletController.swift; sourceTree = ""; }; 892A1984215A55F400B2293D /* Double+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Double+Extension.swift"; sourceTree = ""; }; + 892E5B1721B61F0000298845 /* CITA+ERC20.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CITA+ERC20.swift"; sourceTree = ""; }; 892F79B821A547340035B08B /* ModifyWalletNamePageItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModifyWalletNamePageItem.swift; sourceTree = ""; }; 8935BA54216EE65500C37263 /* WKWebViewConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WKWebViewConfiguration.swift; sourceTree = ""; }; 8935BA56216EEDEC00C37263 /* WKWebViewConfigConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WKWebViewConfigConstants.swift; sourceTree = ""; }; @@ -327,32 +358,34 @@ 89422FE521A7F92300DD8744 /* DAppModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DAppModel.swift; sourceTree = ""; }; 89422FE721A7F97300DD8744 /* MyDAppViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MyDAppViewController.swift; sourceTree = ""; }; 89422FEA21A7F9C900DD8744 /* CollectionTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollectionTableViewCell.swift; sourceTree = ""; }; + 89450B7721D37FD500CE1921 /* en */ = {isa = PBXFileReference; lastKnownFileType = text; name = en; path = en.lproj/product_agreement.txt; sourceTree = ""; }; 8951A84B2170A5CC00043228 /* DAppAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DAppAction.swift; sourceTree = ""; }; 8955580420DCA7F700FC92D8 /* PasswordValidator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasswordValidator.swift; sourceTree = ""; }; + 895F713321C630E800F41107 /* VerifyMnemonicViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VerifyMnemonicViewController.swift; sourceTree = ""; }; 8964A17B20BE7F750086848F /* MessageSignController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageSignController.swift; sourceTree = ""; }; 8964A17F20BE94F70086848F /* NEPickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NEPickerView.swift; sourceTree = ""; }; 8964A18520BFE6850086848F /* ImportWalletController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImportWalletController.swift; sourceTree = ""; }; 8964A18B20C0E4BE0086848F /* GenerateMnemonicController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenerateMnemonicController.swift; sourceTree = ""; }; - 8964A19120C115A70086848F /* VerifyMnemonicViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerifyMnemonicViewController.swift; sourceTree = ""; }; 8964A19520C12FB70086848F /* ButtonTagView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonTagView.swift; sourceTree = ""; }; 8964A19720C15EA20086848F /* ButtonTagUpView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonTagUpView.swift; sourceTree = ""; }; 896812CA20F726D000731C8C /* dappOpration.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = dappOpration.js; sourceTree = ""; }; - 896D042920AE69C1002CFF6A /* Neuron.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Neuron.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 896B32BA21BF865900C4DA7F /* CITA+AddToken.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CITA+AddToken.swift"; sourceTree = ""; }; + 896B32BC21BFAD3B00C4DA7F /* ShowTokenPageItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShowTokenPageItem.swift; sourceTree = ""; }; + 896B32BE21BFAEBC00C4DA7F /* TokenMessageView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TokenMessageView.xib; sourceTree = ""; }; + 896CEA9921B91E4500B1A7D4 /* DefaultTokenAndChain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultTokenAndChain.swift; sourceTree = ""; }; + 896D042920AE69C1002CFF6A /* Cyton.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Cyton.app; sourceTree = BUILT_PRODUCTS_DIR; }; 896D042C20AE69C1002CFF6A /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 896D043120AE69C1002CFF6A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 896D043320AE69C5002CFF6A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 896D043620AE69C5002CFF6A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 896D043820AE69C5002CFF6A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 896D043D20AE69C5002CFF6A /* NeuronTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NeuronTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 896D044120AE69C5002CFF6A /* NeuronTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NeuronTests.swift; sourceTree = ""; }; + 896D043D20AE69C5002CFF6A /* CytonTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CytonTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 896D044320AE69C5002CFF6A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 896D044820AE69C5002CFF6A /* NeuronUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NeuronUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 896D044C20AE69C5002CFF6A /* NeuronUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NeuronUITests.swift; sourceTree = ""; }; + 896D044820AE69C5002CFF6A /* CytonUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CytonUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 896D044E20AE69C5002CFF6A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 8972FD0E218B54A100C27147 /* AdvancedViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvancedViewController.swift; sourceTree = ""; }; - 8978846221AD26690034AF4F /* neuron.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = neuron.js; sourceTree = ""; }; 897AFC592130129500383A12 /* CurrencyViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrencyViewController.swift; sourceTree = ""; }; 89812129218D3161000813C8 /* QRCodeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCodeViewController.swift; sourceTree = ""; }; + 89880A2221C269F100A34A0B /* CITA+Balance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CITA+Balance.swift"; sourceTree = ""; }; 898889C52136521100D04AA8 /* KeystoreViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeystoreViewController.swift; sourceTree = ""; }; 898889C72136526800D04AA8 /* MnemonicViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MnemonicViewController.swift; sourceTree = ""; }; 898889C92136528B00D04AA8 /* PrivatekeyViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivatekeyViewController.swift; sourceTree = ""; }; @@ -362,29 +395,26 @@ 898A1A0120B5717A00ECB465 /* ManageAssetViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManageAssetViewController.swift; sourceTree = ""; }; 898A1A0520B5797700ECB465 /* AssetTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetTableViewCell.swift; sourceTree = ""; }; 898A1A0920B64F6000ECB465 /* AddAssetController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddAssetController.swift; sourceTree = ""; }; - 898A1A0D20B6539800ECB465 /* AddAssetTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddAssetTableViewCell.swift; sourceTree = ""; }; - 898A1A0E20B6539800ECB465 /* AddAssetTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AddAssetTableViewCell.xib; sourceTree = ""; }; 898A1A1520B6BE6E00ECB465 /* ChangePasswordController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChangePasswordController.swift; sourceTree = ""; }; 898A1A1920B7A6BB00ECB465 /* CreateWalletController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateWalletController.swift; sourceTree = ""; }; - 898A1A2420B7DAA300ECB465 /* TransactionTableviewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionTableviewCell.swift; sourceTree = ""; }; - 898A1A2820B7F0FC00ECB465 /* TradeDetailsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TradeDetailsController.swift; sourceTree = ""; }; - 898A1A2920B7F0FC00ECB465 /* TradeDetailsController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TradeDetailsController.xib; sourceTree = ""; }; - 898A1A2D20B8044900ECB465 /* TradeTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TradeTableViewCell.swift; sourceTree = ""; }; - 898A1A2E20B8044900ECB465 /* TradeTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TradeTableViewCell.xib; sourceTree = ""; }; 898CA98220EA0F210059ECA3 /* TokenModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokenModel.swift; sourceTree = ""; }; - 898CA98920EA2E760059ECA3 /* tokens-eth.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "tokens-eth.json"; sourceTree = ""; }; - 899AD19821100F2B00A8AC09 /* NervosNativeTokenService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NervosNativeTokenService.swift; sourceTree = ""; }; - 899AD19A211011F300A8AC09 /* AppChainNetwork.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppChainNetwork.swift; sourceTree = ""; }; + 899AD19A211011F300A8AC09 /* CITANetwork.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CITANetwork.swift; sourceTree = ""; }; 89A196182175D9C800BD5FA4 /* DAppDataHandle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DAppDataHandle.swift; sourceTree = ""; }; 89A1961A2175E7F300BD5FA4 /* DAppCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DAppCommand.swift; sourceTree = ""; }; 89A87C882173097000588674 /* WalletNameValidator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletNameValidator.swift; sourceTree = ""; }; 89A87C8A217312CC00588674 /* WalletNameValidatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletNameValidatorTests.swift; sourceTree = ""; }; 89AB35C9213D113E00A2BF48 /* WalletTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletTableViewCell.swift; sourceTree = ""; }; 89B01A23216DAC5A00BFAAF4 /* DAppBrowser.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = DAppBrowser.storyboard; sourceTree = ""; }; + 89B2742121EC2A8F001A6A93 /* Cyton-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Cyton-Bridging-Header.h"; sourceTree = ""; }; + 89B2742221EC2AA0001A6A93 /* CytonTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CytonTests.swift; sourceTree = ""; }; + 89B2742421EC2AAD001A6A93 /* CytonUITests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CytonUITests.swift; sourceTree = ""; }; + 89B2742621EC2B35001A6A93 /* cyton.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = cyton.js; sourceTree = ""; }; + 89B2742821EC3318001A6A93 /* Cyton.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Cyton.entitlements; sourceTree = ""; }; 89B296EC20F4CBA7008558A7 /* ServerAPI.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ServerAPI.swift; sourceTree = ""; }; 89B895B020F8B0CD00B9468B /* BrowserViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrowserViewController.swift; sourceTree = ""; }; 89BA4B5521AE333E0084439B /* MnemonicValidator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MnemonicValidator.swift; sourceTree = ""; }; 89BA4B5721AE410F0084439B /* MnemonicValidatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MnemonicValidatorTests.swift; sourceTree = ""; }; + 89BD0EC921B77FA2002D10BD /* ChainModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChainModel.swift; sourceTree = ""; }; 89BEBE6A20EF82B6007D2705 /* EthereumNetwork.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EthereumNetwork.swift; sourceTree = ""; }; 89BEBE7120F12647007D2705 /* CommonWebViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommonWebViewController.swift; sourceTree = ""; }; 89C25C5820BBA38300007EC1 /* SettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = ""; }; @@ -394,10 +424,7 @@ 89C614562140D4C500DC3DF4 /* currency.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = currency.plist; sourceTree = ""; }; 89C614582140FE6600DC3DF4 /* CurrencyTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrencyTableViewCell.swift; sourceTree = ""; }; 89C6145D2141038300DC3DF4 /* LocalCurrencyService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalCurrencyService.swift; sourceTree = ""; }; - 89C6145F2141421400DC3DF4 /* TransactionHistoryViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionHistoryViewController.swift; sourceTree = ""; }; - 89CA1FAB213F822B00669B2C /* tokens-list.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "tokens-list.json"; sourceTree = ""; }; 89CFA12521424CAB00635A54 /* AboutUsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutUsViewController.swift; sourceTree = ""; }; - 89D40EF520DCF1E00062C545 /* Neuron.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Neuron.entitlements; sourceTree = ""; }; 89D4AC2520D59F270097E02B /* WalletManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletManager.swift; sourceTree = ""; }; 89D4AC3720D8DB610097E02B /* NotificationName.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationName.swift; sourceTree = ""; }; 89D84CE021475755006B0287 /* NFTService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NFTService.swift; sourceTree = ""; }; @@ -409,17 +436,21 @@ 89D935242139363A002FAEEC /* TokenTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokenTableViewCell.swift; sourceTree = ""; }; 89F7966C213A6B680064808A /* ERC721TableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ERC721TableViewCell.swift; sourceTree = ""; }; 89F7966E213BD5680064808A /* Assets.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Assets.storyboard; sourceTree = ""; }; - 89F79670213BD8C40064808A /* TransactionHistory.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = TransactionHistory.storyboard; sourceTree = ""; }; 89F9E73C20DEBDE8009E68D4 /* ExportKeystoreController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExportKeystoreController.swift; sourceTree = ""; }; 89F9E73D20DEBDE8009E68D4 /* ExportKeystoreController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ExportKeystoreController.xib; sourceTree = ""; }; + 89FA2E2221BE39DF001EA590 /* SelectChainTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectChainTableViewCell.swift; sourceTree = ""; }; + 89FA2E2421BE39F3001EA590 /* ContractAddressTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContractAddressTableViewCell.swift; sourceTree = ""; }; + 89FA2E2621BE83AF001EA590 /* SwitchChainViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwitchChainViewController.swift; sourceTree = ""; }; 89FC542C20D4142D00D5D27C /* SkipBackupFiles.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SkipBackupFiles.swift; sourceTree = ""; }; 89FE21D920EDB10900A09302 /* CustomERC20TokenService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomERC20TokenService.swift; sourceTree = ""; }; 89FE21DD20EDB70000A09302 /* SendTransactionError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendTransactionError.swift; sourceTree = ""; }; - 8CC6FD685582D038A3767657 /* Pods_Neuron.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Neuron.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - C43FB42A510FDF667FD64169 /* Pods-NeuronUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NeuronUITests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-NeuronUITests/Pods-NeuronUITests.debug.xcconfig"; sourceTree = ""; }; - DB16ADF7FEC17385D266EA00 /* Pods-NeuronUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NeuronUITests.release.xcconfig"; path = "Pods/Target Support Files/Pods-NeuronUITests/Pods-NeuronUITests.release.xcconfig"; sourceTree = ""; }; - DB57BA5F3596655B01B46EF1 /* Pods-NeuronTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NeuronTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-NeuronTests/Pods-NeuronTests.debug.xcconfig"; sourceTree = ""; }; - FB1ED6C1CFAD097B034BA2EF /* Pods_NeuronTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_NeuronTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 8CC6FD685582D038A3767657 /* Pods_Cyton.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Cyton.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + C43FB42A510FDF667FD64169 /* Pods-CytonUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CytonUITests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CytonUITests/Pods-CytonUITests.debug.xcconfig"; sourceTree = ""; }; + D595D7EC21F079A8006FBDDC /* Web3Error+Description.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Web3Error+Description.swift"; sourceTree = ""; }; + D595D7EE21F0816A006FBDDC /* String+Error.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Error.swift"; sourceTree = ""; }; + DB16ADF7FEC17385D266EA00 /* Pods-CytonUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CytonUITests.release.xcconfig"; path = "Pods/Target Support Files/Pods-CytonUITests/Pods-CytonUITests.release.xcconfig"; sourceTree = ""; }; + DB57BA5F3596655B01B46EF1 /* Pods-CytonTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CytonTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CytonTests/Pods-CytonTests.debug.xcconfig"; sourceTree = ""; }; + FB1ED6C1CFAD097B034BA2EF /* Pods_CytonTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CytonTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -427,7 +458,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 3B9D2E9C9E858D6634948E6D /* Pods_Neuron.framework in Frameworks */, + 3B9D2E9C9E858D6634948E6D /* Pods_Cyton.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -435,7 +466,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - FEA60F4E8F81CB701C31AE44 /* Pods_NeuronTests.framework in Frameworks */, + FEA60F4E8F81CB701C31AE44 /* Pods_CytonTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -443,7 +474,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - E2E67496168FEDCBC828A891 /* Pods_NeuronUITests.framework in Frameworks */, + E2E67496168FEDCBC828A891 /* Pods_CytonUITests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -505,6 +536,8 @@ children = ( 1A60079621A274D000C7B712 /* SendTransactionSummaryView.xib */, 1A60079B21A28B8C00C7B712 /* TxSummaryPageItem.swift */, + 896B32BE21BFAEBC00C4DA7F /* TokenMessageView.xib */, + 896B32BC21BFAD3B00C4DA7F /* ShowTokenPageItem.swift */, 1A1E1B8A21A3CF3A00C24D10 /* SignMessagePageItem.swift */, 1A60079D21A28C1400C7B712 /* PasswordPageItem.swift */, 892F79B821A547340035B08B /* ModifyWalletNamePageItem.swift */, @@ -523,23 +556,25 @@ 89FE21D920EDB10900A09302 /* CustomERC20TokenService.swift */, 1A19C2DD21B12DE800C289D0 /* EthereumMessageSigner.swift */, 89D84CE021475755006B0287 /* NFTService.swift */, - 6E876840218022F30032EBCE /* TokenProfile.swift */, 6E3B2B6C219ED9230095257D /* Ethereum+TransactionDetails.swift */, - 6E3B2B6E219ED9340095257D /* Ethereum+TransactionStatus.swift */, + 6EEDEDA621CB4CF100FC3BCE /* EthereumTokenProfileLoader.swift */, + 6EB4E84021D62B3900B93FAB /* EthereumLocalTxPool.swift */, ); path = Ethereum; sourceTree = ""; }; - 1A69465621904551000093A2 /* AppChain */ = { + 1A69465621904551000093A2 /* CITA */ = { isa = PBXGroup; children = ( - 899AD19A211011F300A8AC09 /* AppChainNetwork.swift */, - 1A69465D21916C3D000093A2 /* AppChainTxSender.swift */, - 899AD19821100F2B00A8AC09 /* NervosNativeTokenService.swift */, - 6E3B2B70219EDA230095257D /* AppChain+TransactionDetails.swift */, - 6E3B2B72219EDB870095257D /* AppChain+TransactionStatus.swift */, - ); - path = AppChain; + 899AD19A211011F300A8AC09 /* CITANetwork.swift */, + 1A69465D21916C3D000093A2 /* CITATxSender.swift */, + 89880A2221C269F100A34A0B /* CITA+Balance.swift */, + 6E3B2B70219EDA230095257D /* CITA+TransactionDetails.swift */, + 892E5B1721B61F0000298845 /* CITA+ERC20.swift */, + 896B32BA21BF865900C4DA7F /* CITA+AddToken.swift */, + 6EDBE3A021DE02EA0087DA38 /* CITALocalTxPool.swift */, + ); + path = CITA; sourceTree = ""; }; 1A694657219046DB000093A2 /* Foundation */ = { @@ -549,6 +584,9 @@ 6E876844218031670032EBCE /* UInt+Extension.swift */, 892A1984215A55F400B2293D /* Double+Extension.swift */, 1A3C652B212EAC4800F1A0AA /* String+Extension.swift */, + 6E8A838821B777A60051B3EB /* NSDecimalNumber+Extension.swift */, + D595D7EC21F079A8006FBDDC /* Web3Error+Description.swift */, + D595D7EE21F0816A006FBDDC /* String+Error.swift */, ); path = Foundation; sourceTree = ""; @@ -560,6 +598,7 @@ 1AB3D1CE21709F6700557E9D /* UIStoryboard+Extension.swift */, 6EF8F40B2175CAD9004B7587 /* UIControl+Extension.swift */, 1A2B226821A7907500556744 /* UIColor+Extension.swift */, + 1A9A025921B90968002F2108 /* URLRequest+Extension.swift */, ); path = UIKit; sourceTree = ""; @@ -585,11 +624,12 @@ 1A91E1E321A63561000EFD40 /* Realm */ = { isa = PBXGroup; children = ( - 89422FE521A7F92300DD8744 /* DAppModel.swift */, 8913437720CA56CA00A17AEF /* RealmConfigurator.swift */, + 89422FE521A7F92300DD8744 /* DAppModel.swift */, 8905660620D0AC120041D4B4 /* AppModel.swift */, 8913437020C78F1000A17AEF /* WalletModel.swift */, 898CA98220EA0F210059ECA3 /* TokenModel.swift */, + 89BD0EC921B77FA2002D10BD /* ChainModel.swift */, ); path = Realm; sourceTree = ""; @@ -622,12 +662,12 @@ 638FD5929E22E012CA4314D1 /* Pods */ = { isa = PBXGroup; children = ( - 21C5F1D714208410CA8D77B9 /* Pods-Neuron.debug.xcconfig */, - 1D270F090888C6AD9CF6A055 /* Pods-Neuron.release.xcconfig */, - DB57BA5F3596655B01B46EF1 /* Pods-NeuronTests.debug.xcconfig */, - 71EE3A6382628C3632FE594F /* Pods-NeuronTests.release.xcconfig */, - C43FB42A510FDF667FD64169 /* Pods-NeuronUITests.debug.xcconfig */, - DB16ADF7FEC17385D266EA00 /* Pods-NeuronUITests.release.xcconfig */, + 21C5F1D714208410CA8D77B9 /* Pods-Cyton.debug.xcconfig */, + 1D270F090888C6AD9CF6A055 /* Pods-Cyton.release.xcconfig */, + DB57BA5F3596655B01B46EF1 /* Pods-CytonTests.debug.xcconfig */, + 71EE3A6382628C3632FE594F /* Pods-CytonTests.release.xcconfig */, + C43FB42A510FDF667FD64169 /* Pods-CytonUITests.debug.xcconfig */, + DB16ADF7FEC17385D266EA00 /* Pods-CytonUITests.release.xcconfig */, ); name = Pods; sourceTree = ""; @@ -644,6 +684,52 @@ path = Guide; sourceTree = ""; }; + 6E86070821CB39BC0055387C /* guide_image */ = { + isa = PBXGroup; + children = ( + 6E86072321CB39F80055387C /* guide_page_1@2x.png */, + 6E86071721CB39C80055387C /* guide_page_1@3x.png */, + 6EEDED6521CB3C8200FC3BCE /* guide_page_2@2x.png */, + 6EEDED7821CB3D1700FC3BCE /* guide_page_2@3x.png */, + 6EEDED9E21CB3DFB00FC3BCE /* guide_page_3@2x.png */, + 6EEDED9521CB3DD700FC3BCE /* guide_page_3@3x.png */, + ); + path = guide_image; + sourceTree = ""; + }; + 6E8A836921B62DA30051B3EB /* History */ = { + isa = PBXGroup; + children = ( + 6E8A836A21B62DA30051B3EB /* TransactionHistory.storyboard */, + 6E8A836B21B62DA30051B3EB /* TransactionHistoryPresenter.swift */, + 6E8A836C21B62DA30051B3EB /* TransactionHistoryViewController.swift */, + ); + path = History; + sourceTree = ""; + }; + 6E8A836D21B62DA30051B3EB /* Details */ = { + isa = PBXGroup; + children = ( + 6E8A838C21B8C49F0051B3EB /* TransactionDetails.storyboard */, + 6E8A838A21B8C4780051B3EB /* TransactionDetailsViewController.swift */, + 6E877F4221C8C89E00C65511 /* TransactionDetailsParamBuilder.swift */, + ); + path = Details; + sourceTree = ""; + }; + 6E8A837921B62E0A0051B3EB /* Send */ = { + isa = PBXGroup; + children = ( + 6E8A837B21B62E0A0051B3EB /* SendTransaction.storyboard */, + 6E8A838021B62E0A0051B3EB /* TransactonSender.swift */, + 6E8A837D21B62E0A0051B3EB /* TransactionParamBuilder.swift */, + 6E8A837A21B62E0A0051B3EB /* SendTransactionViewController.swift */, + 6E8A837C21B62E0A0051B3EB /* TransactionGasCostViewController.swift */, + 6E8A837F21B62E0A0051B3EB /* TransactionSwitchTokenViewController.swift */, + ); + path = Send; + sourceTree = ""; + }; 6E9D7CBB216B37E90044176D /* Authentication */ = { isa = PBXGroup; children = ( @@ -680,7 +766,6 @@ 89B895B020F8B0CD00B9468B /* BrowserViewController.swift */, 8935BA54216EE65500C37263 /* WKWebViewConfiguration.swift */, 89C25C6B20BD421E00007EC1 /* ContractController.swift */, - 8972FD0E218B54A100C27147 /* AdvancedViewController.swift */, 8964A17B20BE7F750086848F /* MessageSignController.swift */, ); path = WebView; @@ -718,7 +803,7 @@ isa = PBXGroup; children = ( 898CA98420EA21E90059ECA3 /* Common */, - 1A69465621904551000093A2 /* AppChain */, + 1A69465621904551000093A2 /* CITA */, 1A694655219044FE000093A2 /* Ethereum */, 89D4AC1F20D59F270097E02B /* WalletManager */, ); @@ -766,12 +851,11 @@ 8928C22520AE7C6200C3103E /* Resource */ = { isa = PBXGroup; children = ( + 6E86070821CB39BC0055387C /* guide_image */, 8935BA5A216EFCF000C37263 /* init.js */, + 89B2742621EC2B35001A6A93 /* cyton.js */, 896812CA20F726D000731C8C /* dappOpration.js */, - 8978846221AD26690034AF4F /* neuron.js */, - 6E83CB92216F581800029324 /* ProductAgreement.txt */, - 898CA98920EA2E760059ECA3 /* tokens-eth.json */, - 89CA1FAB213F822B00669B2C /* tokens-list.json */, + 6EEDEDA421CB3F3500FC3BCE /* product_agreement.txt */, 89C614562140D4C500DC3DF4 /* currency.plist */, ); path = Resource; @@ -782,7 +866,7 @@ children = ( 8928C22A20AE7CB500C3103E /* Common */, 6E83CB87216F573100029324 /* Guide */, - 8928C22720AE7CB500C3103E /* Dapp */, + 8928C22720AE7CB500C3103E /* DApp */, 8928C27320B29ABB00C3103E /* Wallet */, 8922685820DE4EA50021A85F /* Settings */, 898A1A1D20B7B4F300ECB465 /* Transaction */, @@ -791,7 +875,7 @@ path = Sections; sourceTree = ""; }; - 8928C22720AE7CB500C3103E /* Dapp */ = { + 8928C22720AE7CB500C3103E /* DApp */ = { isa = PBXGroup; children = ( 890E3112219BC56A00561F3D /* WebView */, @@ -799,7 +883,7 @@ 6EABFB0921991AF900305ED5 /* Native */, 89422FE921A7F9C900DD8744 /* TableViewCell */, ); - path = Dapp; + path = DApp; sourceTree = ""; }; 8928C22A20AE7CB500C3103E /* Common */ = { @@ -848,9 +932,10 @@ isa = PBXGroup; children = ( 89C3BF062134E3F200872BD0 /* AddWallet.storyboard */, + 6E85C12921C7542900670F8B /* CreateWalletGuideViewController.swift */, 898A1A1920B7A6BB00ECB465 /* CreateWalletController.swift */, + 895F713321C630E800F41107 /* VerifyMnemonicViewController.swift */, 8964A18B20C0E4BE0086848F /* GenerateMnemonicController.swift */, - 8964A19120C115A70086848F /* VerifyMnemonicViewController.swift */, ); path = AddWallet; sourceTree = ""; @@ -875,9 +960,9 @@ 896D042020AE69C1002CFF6A = { isa = PBXGroup; children = ( - 896D042B20AE69C1002CFF6A /* Neuron */, - 896D044020AE69C5002CFF6A /* NeuronTests */, - 896D044B20AE69C5002CFF6A /* NeuronUITests */, + 896D042B20AE69C1002CFF6A /* Cyton */, + 896D044020AE69C5002CFF6A /* CytonTests */, + 896D044B20AE69C5002CFF6A /* CytonUITests */, 896D042A20AE69C1002CFF6A /* Products */, 638FD5929E22E012CA4314D1 /* Pods */, 89BCA81AE0CA58529FA94CB3 /* Frameworks */, @@ -887,14 +972,14 @@ 896D042A20AE69C1002CFF6A /* Products */ = { isa = PBXGroup; children = ( - 896D042920AE69C1002CFF6A /* Neuron.app */, - 896D043D20AE69C5002CFF6A /* NeuronTests.xctest */, - 896D044820AE69C5002CFF6A /* NeuronUITests.xctest */, + 896D042920AE69C1002CFF6A /* Cyton.app */, + 896D043D20AE69C5002CFF6A /* CytonTests.xctest */, + 896D044820AE69C5002CFF6A /* CytonUITests.xctest */, ); name = Products; sourceTree = ""; }; - 896D042B20AE69C1002CFF6A /* Neuron */ = { + 896D042B20AE69C1002CFF6A /* Cyton */ = { isa = PBXGroup; children = ( 1A3C652A212EAC0F00F1A0AA /* Extensions */, @@ -909,33 +994,33 @@ 896D043020AE69C1002CFF6A /* Main.storyboard */, 896D043520AE69C5002CFF6A /* LaunchScreen.storyboard */, 896D043320AE69C5002CFF6A /* Assets.xcassets */, - 89D40EF520DCF1E00062C545 /* Neuron.entitlements */, 896D043820AE69C5002CFF6A /* Info.plist */, 1A5515EC218D3F0300D34791 /* Localizable.strings */, - 8928C22020AE779B00C3103E /* Neuron-Bridging-Header.h */, + 89B2742121EC2A8F001A6A93 /* Cyton-Bridging-Header.h */, + 89B2742821EC3318001A6A93 /* Cyton.entitlements */, ); - path = Neuron; + path = Cyton; sourceTree = ""; }; - 896D044020AE69C5002CFF6A /* NeuronTests */ = { + 896D044020AE69C5002CFF6A /* CytonTests */ = { isa = PBXGroup; children = ( 1AB3D1D021709F7600557E9D /* Extensions */, 1A1E841521717E8800B15E88 /* Utils */, 1AB28771217964F500DCC14D /* Service */, - 896D044120AE69C5002CFF6A /* NeuronTests.swift */, + 89B2742221EC2AA0001A6A93 /* CytonTests.swift */, 896D044320AE69C5002CFF6A /* Info.plist */, ); - path = NeuronTests; + path = CytonTests; sourceTree = ""; }; - 896D044B20AE69C5002CFF6A /* NeuronUITests */ = { + 896D044B20AE69C5002CFF6A /* CytonUITests */ = { isa = PBXGroup; children = ( - 896D044C20AE69C5002CFF6A /* NeuronUITests.swift */, + 89B2742421EC2AAD001A6A93 /* CytonUITests.swift */, 896D044E20AE69C5002CFF6A /* Info.plist */, ); - path = NeuronUITests; + path = CytonUITests; sourceTree = ""; }; 898A170B2199819F00DE89A0 /* ImportWallet */ = { @@ -956,6 +1041,7 @@ 8928C27820B2A61900C3103E /* WalletViewController.swift */, 6E9B947E21A4086400D67357 /* WalletPresenter.swift */, 6E8D77EF21A5264F00EA7674 /* WalletQRCodeViewController.swift */, + 89D935242139363A002FAEEC /* TokenTableViewCell.swift */, ); path = Home; sourceTree = ""; @@ -975,6 +1061,7 @@ 89F7966E213BD5680064808A /* Assets.storyboard */, 898A1A0920B64F6000ECB465 /* AddAssetController.swift */, 898A1A0120B5717A00ECB465 /* ManageAssetViewController.swift */, + 89FA2E2621BE83AF001EA590 /* SwitchChainViewController.swift */, ); path = Assets; sourceTree = ""; @@ -987,6 +1074,7 @@ 898A1A1520B6BE6E00ECB465 /* ChangePasswordController.swift */, 89F9E73C20DEBDE8009E68D4 /* ExportKeystoreController.swift */, 89F9E73D20DEBDE8009E68D4 /* ExportKeystoreController.xib */, + 6EE37EA021C782FE00F62F2C /* WalletIconPickerViewController.swift */, ); path = WalletDetails; sourceTree = ""; @@ -995,12 +1083,11 @@ isa = PBXGroup; children = ( 89AB35C9213D113E00A2BF48 /* WalletTableViewCell.swift */, - 89D935242139363A002FAEEC /* TokenTableViewCell.swift */, 89F7966C213A6B680064808A /* ERC721TableViewCell.swift */, 89D84CE62147C671006B0287 /* TraitsCollectionViewCell.swift */, 898A1A0520B5797700ECB465 /* AssetTableViewCell.swift */, - 898A1A0D20B6539800ECB465 /* AddAssetTableViewCell.swift */, - 898A1A0E20B6539800ECB465 /* AddAssetTableViewCell.xib */, + 89FA2E2221BE39DF001EA590 /* SelectChainTableViewCell.swift */, + 89FA2E2421BE39F3001EA590 /* ContractAddressTableViewCell.swift */, ); path = TableViewCell; sourceTree = ""; @@ -1008,41 +1095,21 @@ 898A1A1D20B7B4F300ECB465 /* Transaction */ = { isa = PBXGroup; children = ( - 1A75EBFC21A1948F008D484B /* SendTransaction.storyboard */, - 1A75EBFE21A194B1008D484B /* SendTransactionViewController.swift */, - 1AE3145021A2F5A300F92B2A /* TransactionParamBuilder.swift */, - 6E8AFB0C21A7E7B800F81DC6 /* TransactionGasCostViewController.swift */, - 6E8168F821887A31007641BA /* TransactionGasPriceViewController.swift */, - 6E8D77F121A54B8100EA7674 /* TransactionSwitchTokenViewController.swift */, - 89F79670213BD8C40064808A /* TransactionHistory.storyboard */, - 89C6145F2141421400DC3DF4 /* TransactionHistoryViewController.swift */, - 6E7D3841219C47940031177B /* TransactionHistoryPresenter.swift */, - 898A1A2820B7F0FC00ECB465 /* TradeDetailsController.swift */, - 898A1A2920B7F0FC00ECB465 /* TradeDetailsController.xib */, - 898A1A2C20B8033C00ECB465 /* Views */, + 6E8A837921B62E0A0051B3EB /* Send */, + 6E8A836921B62DA30051B3EB /* History */, + 6E8A836D21B62DA30051B3EB /* Details */, ); path = Transaction; sourceTree = ""; }; - 898A1A2C20B8033C00ECB465 /* Views */ = { - isa = PBXGroup; - children = ( - 898A1A2420B7DAA300ECB465 /* TransactionTableviewCell.swift */, - 898A1A2D20B8044900ECB465 /* TradeTableViewCell.swift */, - 898A1A2E20B8044900ECB465 /* TradeTableViewCell.xib */, - ); - path = Views; - sourceTree = ""; - }; 898CA98420EA21E90059ECA3 /* Common */ = { isa = PBXGroup; children = ( 89C6145D2141038300DC3DF4 /* LocalCurrencyService.swift */, - 6E90D06821704C1D00B98363 /* SensorsAnalytics.swift */, - 6E3B2B6A219D938F0095257D /* SentTransaction.swift */, - 6E3B2B74219EDE200095257D /* TransactionStatusManager.swift */, 6E8BFC3621B00948004752CC /* TokenPriceLoader.swift */, 89FE21DD20EDB70000A09302 /* SendTransactionError.swift */, + 896CEA9921B91E4500B1A7D4 /* DefaultTokenAndChain.swift */, + 6E878DD121BF944000526B6A /* TaskThread.swift */, ); path = Common; sourceTree = ""; @@ -1050,9 +1117,9 @@ 89BCA81AE0CA58529FA94CB3 /* Frameworks */ = { isa = PBXGroup; children = ( - 8CC6FD685582D038A3767657 /* Pods_Neuron.framework */, - FB1ED6C1CFAD097B034BA2EF /* Pods_NeuronTests.framework */, - 3502E1744CFA926363F980D0 /* Pods_NeuronUITests.framework */, + 8CC6FD685582D038A3767657 /* Pods_Cyton.framework */, + FB1ED6C1CFAD097B034BA2EF /* Pods_CytonTests.framework */, + 3502E1744CFA926363F980D0 /* Pods_CytonUITests.framework */, ); name = Frameworks; sourceTree = ""; @@ -1070,9 +1137,9 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 896D042820AE69C1002CFF6A /* Neuron */ = { + 896D042820AE69C1002CFF6A /* Cyton */ = { isa = PBXNativeTarget; - buildConfigurationList = 896D045120AE69C5002CFF6A /* Build configuration list for PBXNativeTarget "Neuron" */; + buildConfigurationList = 896D045120AE69C5002CFF6A /* Build configuration list for PBXNativeTarget "Cyton" */; buildPhases = ( F48D79ACA9DA22B734D8BF82 /* [CP] Check Pods Manifest.lock */, 896D042520AE69C1002CFF6A /* Sources */, @@ -1085,14 +1152,14 @@ ); dependencies = ( ); - name = Neuron; - productName = Neuron; - productReference = 896D042920AE69C1002CFF6A /* Neuron.app */; + name = Cyton; + productName = Cyton; + productReference = 896D042920AE69C1002CFF6A /* Cyton.app */; productType = "com.apple.product-type.application"; }; - 896D043C20AE69C5002CFF6A /* NeuronTests */ = { + 896D043C20AE69C5002CFF6A /* CytonTests */ = { isa = PBXNativeTarget; - buildConfigurationList = 896D045420AE69C5002CFF6A /* Build configuration list for PBXNativeTarget "NeuronTests" */; + buildConfigurationList = 896D045420AE69C5002CFF6A /* Build configuration list for PBXNativeTarget "CytonTests" */; buildPhases = ( 8CCB63F0933A35BAC15289B9 /* [CP] Check Pods Manifest.lock */, 896D043920AE69C5002CFF6A /* Sources */, @@ -1104,14 +1171,14 @@ dependencies = ( 896D043F20AE69C5002CFF6A /* PBXTargetDependency */, ); - name = NeuronTests; - productName = NeuronTests; - productReference = 896D043D20AE69C5002CFF6A /* NeuronTests.xctest */; + name = CytonTests; + productName = CytonTests; + productReference = 896D043D20AE69C5002CFF6A /* CytonTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; - 896D044720AE69C5002CFF6A /* NeuronUITests */ = { + 896D044720AE69C5002CFF6A /* CytonUITests */ = { isa = PBXNativeTarget; - buildConfigurationList = 896D045720AE69C5002CFF6A /* Build configuration list for PBXNativeTarget "NeuronUITests" */; + buildConfigurationList = 896D045720AE69C5002CFF6A /* Build configuration list for PBXNativeTarget "CytonUITests" */; buildPhases = ( 6ED304CBD81C419EE9F1043A /* [CP] Check Pods Manifest.lock */, 896D044420AE69C5002CFF6A /* Sources */, @@ -1123,9 +1190,9 @@ dependencies = ( 896D044A20AE69C5002CFF6A /* PBXTargetDependency */, ); - name = NeuronUITests; - productName = NeuronUITests; - productReference = 896D044820AE69C5002CFF6A /* NeuronUITests.xctest */; + name = CytonUITests; + productName = CytonUITests; + productReference = 896D044820AE69C5002CFF6A /* CytonUITests.xctest */; productType = "com.apple.product-type.bundle.ui-testing"; }; /* End PBXNativeTarget section */ @@ -1146,7 +1213,7 @@ enabled = 0; }; com.apple.Push = { - enabled = 1; + enabled = 0; }; }; }; @@ -1162,7 +1229,7 @@ }; }; }; - buildConfigurationList = 896D042420AE69C1002CFF6A /* Build configuration list for PBXProject "Neuron" */; + buildConfigurationList = 896D042420AE69C1002CFF6A /* Build configuration list for PBXProject "Cyton" */; compatibilityVersion = "Xcode 9.3"; developmentRegion = en; hasScannedForEncodings = 0; @@ -1176,9 +1243,9 @@ projectDirPath = ""; projectRoot = ""; targets = ( - 896D042820AE69C1002CFF6A /* Neuron */, - 896D043C20AE69C5002CFF6A /* NeuronTests */, - 896D044720AE69C5002CFF6A /* NeuronUITests */, + 896D042820AE69C1002CFF6A /* Cyton */, + 896D043C20AE69C5002CFF6A /* CytonTests */, + 896D044720AE69C5002CFF6A /* CytonUITests */, ); }; /* End PBXProject section */ @@ -1188,38 +1255,41 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 6EEDED6821CB3C8200FC3BCE /* guide_page_2@2x.png in Resources */, + 6E8A838D21B8C49F0051B3EB /* TransactionDetails.storyboard in Resources */, + 6EEDED9821CB3DD700FC3BCE /* guide_page_3@3x.png in Resources */, 1A207DD32137B4B7008DC306 /* SwitchWallet.storyboard in Resources */, - 6E83CB93216F581800029324 /* ProductAgreement.txt in Resources */, + 6E8A838221B62E0A0051B3EB /* SendTransaction.storyboard in Resources */, + 6EEDEDA221CB3F3500FC3BCE /* product_agreement.txt in Resources */, 89D84CE3214790B5006B0287 /* NFTDetail.storyboard in Resources */, - 898A1A2B20B7F0FC00ECB465 /* TradeDetailsController.xib in Resources */, 89F9E73F20DEBDE8009E68D4 /* ExportKeystoreController.xib in Resources */, + 6EEDED7B21CB3D1700FC3BCE /* guide_page_2@3x.png in Resources */, 891B663D213EAA1900B0FCB0 /* WalletManagement.storyboard in Resources */, 896D043720AE69C5002CFF6A /* LaunchScreen.storyboard in Resources */, - 898A1A1020B6539800ECB465 /* AddAssetTableViewCell.xib in Resources */, 1A60079721A274D000C7B712 /* SendTransactionSummaryView.xib in Resources */, 6E859CB82176DC3100637E1C /* Overlay.storyboard in Resources */, - 898CA98A20EA2E770059ECA3 /* tokens-eth.json in Resources */, - 8978846321AD26690034AF4F /* neuron.js in Resources */, - 89CA1FAC213F822B00669B2C /* tokens-list.json in Resources */, + 6EEDEDA121CB3DFC00FC3BCE /* guide_page_3@2x.png in Resources */, 1AEF127C21A677B600202373 /* AboutUs.storyboard in Resources */, 6E83CB8F216F573100029324 /* Guide.storyboard in Resources */, + 6E8A837021B62DA30051B3EB /* TransactionHistory.storyboard in Resources */, 89C3BF072134E3F200872BD0 /* AddWallet.storyboard in Resources */, 1A5515EA218D3F0300D34791 /* Localizable.strings in Resources */, + 6E86071521CB39C80055387C /* guide_page_1@3x.png in Resources */, 8935BA5B216EFCF000C37263 /* init.js in Resources */, 1A2BFA1821338FEB0065496B /* Settings.storyboard in Resources */, - 1A75EBFD21A1948F008D484B /* SendTransaction.storyboard in Resources */, 89F7966F213BD5680064808A /* Assets.storyboard in Resources */, 6E9D7CC1216B3AE40044176D /* Authentication.storyboard in Resources */, 1A2BFA1A213513D60065496B /* Wallet.storyboard in Resources */, 896D043420AE69C5002CFF6A /* Assets.xcassets in Resources */, 896D043220AE69C1002CFF6A /* Main.storyboard in Resources */, 1A207DD72137D8F5008DC306 /* TabbedButtonsView.xib in Resources */, - 89F79671213BD8C40064808A /* TransactionHistory.storyboard in Resources */, 89B01A24216DAC5A00BFAAF4 /* DAppBrowser.storyboard in Resources */, + 89B2742721EC2B35001A6A93 /* cyton.js in Resources */, + 896B32BF21BFAEBC00C4DA7F /* TokenMessageView.xib in Resources */, 1A9204E421634212004B54DC /* ToastActivityView.xib in Resources */, 896812CB20F726D000731C8C /* dappOpration.js in Resources */, 89C614572140D4C500DC3DF4 /* currency.plist in Resources */, - 898A1A3020B8044900ECB465 /* TradeTableViewCell.xib in Resources */, + 6E86072121CB39F80055387C /* guide_page_1@2x.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1252,7 +1322,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "if which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi"; + shellScript = "if which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n"; }; 350E1210298C0D04F3B3B8B2 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; @@ -1260,16 +1330,15 @@ files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-Neuron/Pods-Neuron-frameworks.sh", + "${SRCROOT}/Pods/Target Support Files/Pods-Cyton/Pods-Cyton-frameworks.sh", "${BUILT_PRODUCTS_DIR}/Alamofire/Alamofire.framework", - "${BUILT_PRODUCTS_DIR}/AppChainSwift/AppChain.framework", "${BUILT_PRODUCTS_DIR}/BigInt/BigInt.framework", "${BUILT_PRODUCTS_DIR}/BulletinBoard/BLTNBoard.framework", + "${BUILT_PRODUCTS_DIR}/CITA/CITA.framework", "${BUILT_PRODUCTS_DIR}/CryptoSwift/CryptoSwift.framework", "${BUILT_PRODUCTS_DIR}/EFQRCode/EFQRCode.framework", "${BUILT_PRODUCTS_DIR}/EthereumABI/EthereumABI.framework", "${BUILT_PRODUCTS_DIR}/EthereumAddress/EthereumAddress.framework", - "${BUILT_PRODUCTS_DIR}/IGIdenticon/IGIdenticon.framework", "${BUILT_PRODUCTS_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework", "${BUILT_PRODUCTS_DIR}/PromiseKit/PromiseKit.framework", "${BUILT_PRODUCTS_DIR}/QRCodeReader.swift/QRCodeReader.framework", @@ -1277,7 +1346,6 @@ "${BUILT_PRODUCTS_DIR}/Realm/Realm.framework", "${BUILT_PRODUCTS_DIR}/RealmSwift/RealmSwift.framework", "${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework", - "${BUILT_PRODUCTS_DIR}/SensorsAnalyticsSDK/SensorsAnalyticsSDK.framework", "${BUILT_PRODUCTS_DIR}/SipHash/SipHash.framework", "${BUILT_PRODUCTS_DIR}/SwiftProtobuf/SwiftProtobuf.framework", "${BUILT_PRODUCTS_DIR}/SwiftRLP/SwiftRLP.framework", @@ -1289,14 +1357,13 @@ name = "[CP] Embed Pods Frameworks"; outputPaths = ( "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Alamofire.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AppChain.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BigInt.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BLTNBoard.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CITA.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CryptoSwift.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/EFQRCode.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/EthereumABI.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/EthereumAddress.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IGIdenticon.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IQKeyboardManagerSwift.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PromiseKit.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/QRCodeReader.framework", @@ -1304,7 +1371,6 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Realm.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RealmSwift.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SensorsAnalyticsSDK.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SipHash.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftProtobuf.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftRLP.framework", @@ -1315,7 +1381,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Neuron/Pods-Neuron-frameworks.sh\"\n"; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Cyton/Pods-Cyton-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; 6ED304CBD81C419EE9F1043A /* [CP] Check Pods Manifest.lock */ = { @@ -1329,7 +1395,7 @@ ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-NeuronUITests-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-CytonUITests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -1347,7 +1413,7 @@ ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-NeuronTests-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-CytonTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -1365,7 +1431,7 @@ ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Neuron-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-Cyton-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -1380,7 +1446,6 @@ buildActionMask = 2147483647; files = ( 8935BA57216EEDEC00C37263 /* WKWebViewConfigConstants.swift in Sources */, - 6E8D77F221A54B8100EA7674 /* TransactionSwitchTokenViewController.swift in Sources */, 892A1985215A55F400B2293D /* Double+Extension.swift in Sources */, 8964A19820C15EA20086848F /* ButtonTagUpView.swift in Sources */, 1A3C652C212EAC4800F1A0AA /* String+Extension.swift in Sources */, @@ -1393,88 +1458,94 @@ 898A19F020B5176A00ECB465 /* WalletDetailController.swift in Sources */, 8928C24320AE908300C3103E /* MainViewController.swift in Sources */, 8964A19620C12FB70086848F /* ButtonTagView.swift in Sources */, + 89BD0ECA21B77FA2002D10BD /* ChainModel.swift in Sources */, 6E83CB90216F573100029324 /* GuideCollectionViewCell.swift in Sources */, 1AEBF3E4219BA1E700653FF5 /* BigUInt+Extension.swift in Sources */, 1A6007A221A2AA9A00C7B712 /* PageItemAppearance.swift in Sources */, 1A19C2DE21B12DE800C289D0 /* EthereumMessageSigner.swift in Sources */, - 6E7D3842219C47940031177B /* TransactionHistoryPresenter.swift in Sources */, 6E9B947D21A4083100D67357 /* DesignableGradientView.swift in Sources */, 89B895B120F8B0CD00B9468B /* BrowserViewController.swift in Sources */, 89D84CE72147C671006B0287 /* TraitsCollectionViewCell.swift in Sources */, - 6E8168F921887A31007641BA /* TransactionGasPriceViewController.swift in Sources */, 6E83CB8D216F573100029324 /* ProductAgreementViewController.swift in Sources */, 8905660720D0AC120041D4B4 /* AppModel.swift in Sources */, + 6E8A838121B62E0A0051B3EB /* SendTransactionViewController.swift in Sources */, 6E3B2B6D219ED9240095257D /* Ethereum+TransactionDetails.swift in Sources */, - 898A1A0F20B6539800ECB465 /* AddAssetTableViewCell.swift in Sources */, + 892E5B1821B61F0100298845 /* CITA+ERC20.swift in Sources */, + D595D7ED21F079A8006FBDDC /* Web3Error+Description.swift in Sources */, 6E9B947B21A4080300D67357 /* DesignableButton.swift in Sources */, 89A87C892173097000588674 /* WalletNameValidator.swift in Sources */, - 6E3B2B6B219D938F0095257D /* SentTransaction.swift in Sources */, 1A5515E521898A1000D34791 /* WalletKeystoreManager.swift in Sources */, 6EABFB10219933EB00305ED5 /* DAppDeviceMotionMessageHandler.swift in Sources */, 6EF8F40C2175CAD9004B7587 /* UIControl+Extension.swift in Sources */, 898CA98320EA0F210059ECA3 /* TokenModel.swift in Sources */, 6E8D77F021A5264F00EA7674 /* WalletQRCodeViewController.swift in Sources */, 8989E2D32188440D008A1BDE /* SwitchNetworkTableViewCell.swift in Sources */, + 6EDBE3A121DE02EA0087DA38 /* CITALocalTxPool.swift in Sources */, 898A1A1720B6BE6E00ECB465 /* ChangePasswordController.swift in Sources */, + 6EEDEDA721CB4CF100FC3BCE /* EthereumTokenProfileLoader.swift in Sources */, 6EABFB0D21991CB300305ED5 /* DAppNativeMessageHandler.swift in Sources */, + 6E8A837221B62DA30051B3EB /* TransactionHistoryViewController.swift in Sources */, 6E83CB91216F573100029324 /* GuideViewController.swift in Sources */, 8928C24520AE90C000C3103E /* BaseNavigationController.swift in Sources */, 6E83CB8E216F573100029324 /* GuideService.swift in Sources */, 8964A18020BE94F70086848F /* NEPickerView.swift in Sources */, 1AB3D1CF21709F6700557E9D /* UIStoryboard+Extension.swift in Sources */, - 899AD19B211011F300A8AC09 /* AppChainNetwork.swift in Sources */, + 899AD19B211011F300A8AC09 /* CITANetwork.swift in Sources */, 1A207DD52137D8CF008DC306 /* TabbedButtonsView.swift in Sources */, 8928C27A20B2A61900C3103E /* WalletViewController.swift in Sources */, - 898A1A2620B7DAA300ECB465 /* TransactionTableviewCell.swift in Sources */, 897AFC5B2130129500383A12 /* CurrencyViewController.swift in Sources */, 898889C82136526800D04AA8 /* MnemonicViewController.swift in Sources */, - 1AE3145121A2F5A300F92B2A /* TransactionParamBuilder.swift in Sources */, 1A5515E7218D36B600D34791 /* WalletManager+Errors.swift in Sources */, 89422FEB21A7F9CA00DD8744 /* CollectionTableViewCell.swift in Sources */, 6E867E0D216C92A900BD6FE5 /* OverlayPresentable.swift in Sources */, 89D84CE121475755006B0287 /* NFTService.swift in Sources */, - 898A1A2A20B7F0FC00ECB465 /* TradeDetailsController.swift in Sources */, 89A196192175D9C800BD5FA4 /* DAppDataHandle.swift in Sources */, 89D84CEB2148C03B006B0287 /* NFTHeaderReusableView.swift in Sources */, + 6E8A838421B62E0A0051B3EB /* TransactionParamBuilder.swift in Sources */, 8964A17D20BE7F750086848F /* MessageSignController.swift in Sources */, 6E867E11216CA51600BD6FE5 /* SettingCurrencyTableViewCell.swift in Sources */, - 6E876841218022F30032EBCE /* TokenProfile.swift in Sources */, 8928C2A320B41BCA00C3103E /* SelectWalletController.swift in Sources */, + 89880A2321C269F100A34A0B /* CITA+Balance.swift in Sources */, 89D4AC2E20D59F270097E02B /* WalletManager.swift in Sources */, 89FE21DA20EDB10900A09302 /* CustomERC20TokenService.swift in Sources */, + 896B32BB21BF865900C4DA7F /* CITA+AddToken.swift in Sources */, 8913437120C78F1000A17AEF /* WalletModel.swift in Sources */, 6E9D7CBE216B386F0044176D /* AuthenticationViewController.swift in Sources */, + 6E878DD221BF944000526B6A /* TaskThread.swift in Sources */, 6E9D7CC5216B490D0044176D /* AuthDeviceViewController.swift in Sources */, + 89FA2E2321BE39DF001EA590 /* SelectChainTableViewCell.swift in Sources */, 89F7966D213A6B680064808A /* ERC721TableViewCell.swift in Sources */, 89422FE821A7F97300DD8744 /* MyDAppViewController.swift in Sources */, - 8964A19320C115A70086848F /* VerifyMnemonicViewController.swift in Sources */, + 89FA2E2721BE83AF001EA590 /* SwitchChainViewController.swift in Sources */, 898A1A0B20B64F6000ECB465 /* AddAssetController.swift in Sources */, 89F9E73E20DEBDE8009E68D4 /* ExportKeystoreController.swift in Sources */, 89D935252139363A002FAEEC /* TokenTableViewCell.swift in Sources */, 1A60079E21A28C1400C7B712 /* PasswordPageItem.swift in Sources */, - 89C614602141421400DC3DF4 /* TransactionHistoryViewController.swift in Sources */, 8913437820CA56CA00A17AEF /* RealmConfigurator.swift in Sources */, 8955580520DCA7F700FC92D8 /* PasswordValidator.swift in Sources */, 6E867E0F216CA4EB00BD6FE5 /* SettingAuthenticationTableViewCell.swift in Sources */, + 6E8A838921B777A60051B3EB /* NSDecimalNumber+Extension.swift in Sources */, 898A1A1B20B7A6BB00ECB465 /* CreateWalletController.swift in Sources */, 8935BA5D216F48A800C37263 /* Method.swift in Sources */, 892F79B921A547340035B08B /* ModifyWalletNamePageItem.swift in Sources */, 1A2B226921A7907500556744 /* UIColor+Extension.swift in Sources */, 6E876845218031670032EBCE /* UInt+Extension.swift in Sources */, - 6E90D06921704C1D00B98363 /* SensorsAnalytics.swift in Sources */, + 895F713421C630E800F41107 /* VerifyMnemonicViewController.swift in Sources */, 6E8BFC3121AFDBB5004752CC /* EthereumBalanceLoader.swift in Sources */, 6E96B3E521B4E38C000F935B /* DAppPermissionsMessageHandler.swift in Sources */, + 896CEA9A21B91E4500B1A7D4 /* DefaultTokenAndChain.swift in Sources */, + 6E8A838721B62E0A0051B3EB /* TransactonSender.swift in Sources */, 89D84CE92147D926006B0287 /* NFTDetailViewController.swift in Sources */, 898A1A0320B5717A00ECB465 /* ManageAssetViewController.swift in Sources */, - 6E3B2B73219EDB870095257D /* AppChain+TransactionStatus.swift in Sources */, 1A60B6FC2186DB1C00FEFB3A /* Web3Utils.swift in Sources */, - 1A75EBFF21A194B2008D484B /* SendTransactionViewController.swift in Sources */, 6EF8F4102176029E004B7587 /* OpenAuthViewController.swift in Sources */, 6E9B948121A408B400D67357 /* Token.swift in Sources */, + 6E877F4321C8C89E00C65511 /* TransactionDetailsParamBuilder.swift in Sources */, 6E9B947F21A4086400D67357 /* WalletPresenter.swift in Sources */, 89C3BF09213521DE00872BD0 /* UIView+Extension.swift in Sources */, 896D042D20AE69C1002CFF6A /* AppDelegate.swift in Sources */, 6E867E03216C3EC800BD6FE5 /* AuthSelectWalletViewController.swift in Sources */, + 6E8A838621B62E0A0051B3EB /* TransactionSwitchTokenViewController.swift in Sources */, 89BEBE6B20EF82B6007D2705 /* EthereumNetwork.swift in Sources */, 1A60079C21A28B8C00C7B712 /* TxSummaryPageItem.swift in Sources */, 89BEBE7220F12647007D2705 /* CommonWebViewController.swift in Sources */, @@ -1482,40 +1553,44 @@ 8964A18720BFE6860086848F /* ImportWalletController.swift in Sources */, 8989E2CF21883400008A1BDE /* SwitchNetworkViewController.swift in Sources */, 898A1A0720B5797700ECB465 /* AssetTableViewCell.swift in Sources */, - 899AD19921100F2B00A8AC09 /* NervosNativeTokenService.swift in Sources */, 89C25C6D20BD421E00007EC1 /* ContractController.swift in Sources */, - 6E3B2B6F219ED9340095257D /* Ethereum+TransactionStatus.swift in Sources */, + 6E8A838B21B8C4780051B3EB /* TransactionDetailsViewController.swift in Sources */, 8935BA5F216F631A00C37263 /* ScriptMessageProxy.swift in Sources */, 6E8BFC3721B00948004752CC /* TokenPriceLoader.swift in Sources */, + 6E85C12A21C7542900670F8B /* CreateWalletGuideViewController.swift in Sources */, + D595D7EF21F0816A006FBDDC /* String+Error.swift in Sources */, 8928C25920AEB18100C3103E /* NibLoadable.swift in Sources */, + 6EE37EA121C782FE00F62F2C /* WalletIconPickerViewController.swift in Sources */, 8951A84C2170A5CC00043228 /* DAppAction.swift in Sources */, - 898A1A2F20B8044900ECB465 /* TradeTableViewCell.swift in Sources */, 89D4AC3820D8DB610097E02B /* NotificationName.swift in Sources */, 89A1961B2175E7F300BD5FA4 /* DAppCommand.swift in Sources */, 89B296ED20F4CBA7008558A7 /* ServerAPI.swift in Sources */, 89AB35CA213D113E00A2BF48 /* WalletTableViewCell.swift in Sources */, 89422FE621A7F92300DD8744 /* DAppModel.swift in Sources */, 8928C24920AE91E600C3103E /* DappViewController.swift in Sources */, + 89FA2E2521BE39F3001EA590 /* ContractAddressTableViewCell.swift in Sources */, + 6EB4E84121D62B3A00B93FAB /* EthereumLocalTxPool.swift in Sources */, 1A6007A021A29C2C00C7B712 /* SuccessPageItem.swift in Sources */, 6E867E09216C862900BD6FE5 /* NoScreenshot.swift in Sources */, 89C614592140FE6600DC3DF4 /* CurrencyTableViewCell.swift in Sources */, - 8972FD0F218B54A100C27147 /* AdvancedViewController.swift in Sources */, 89C6145E2141038300DC3DF4 /* LocalCurrencyService.swift in Sources */, 89CFA12621424CAB00635A54 /* AboutUsViewController.swift in Sources */, 89BA4B5621AE333E0084439B /* MnemonicValidator.swift in Sources */, - 6E3B2B71219EDA230095257D /* AppChain+TransactionDetails.swift in Sources */, - 1A69465E21916C3D000093A2 /* AppChainTxSender.swift in Sources */, + 6E3B2B71219EDA230095257D /* CITA+TransactionDetails.swift in Sources */, + 1A69465E21916C3D000093A2 /* CITATxSender.swift in Sources */, 8928C26B20AED5C100C3103E /* SearchAppController.swift in Sources */, 8981212A218D3161000813C8 /* QRCodeViewController.swift in Sources */, - 6E8AFB0D21A7E7B800F81DC6 /* TransactionGasCostViewController.swift in Sources */, 8964A18D20C0E4BE0086848F /* GenerateMnemonicController.swift in Sources */, 6EABFB0B21991BC200305ED5 /* DAppQRCodeMessageHandler.swift in Sources */, 1A6946602192A0B0000093A2 /* GasCalculator.swift in Sources */, + 6E8A838321B62E0A0051B3EB /* TransactionGasCostViewController.swift in Sources */, + 1A9A025A21B90968002F2108 /* URLRequest+Extension.swift in Sources */, + 6E8A837121B62DA30051B3EB /* TransactionHistoryPresenter.swift in Sources */, 89D84CED2148C056006B0287 /* NFTFooterReusableView.swift in Sources */, 1A092245213580C900CAED5D /* NFTViewController.swift in Sources */, 89FE21DE20EDB70000A09302 /* SendTransactionError.swift in Sources */, + 896B32BD21BFAD3B00C4DA7F /* ShowTokenPageItem.swift in Sources */, 891C2483211165AC007C639D /* TokenMacro.swift in Sources */, - 6E3B2B75219EDE200095257D /* TransactionStatusManager.swift in Sources */, 6E9D7CBA216B04EF0044176D /* AuthenticationService.swift in Sources */, 6EABFB1421995AB800305ED5 /* DAppGyroscopeMessageHandler.swift in Sources */, 898889C62136521100D04AA8 /* KeystoreViewController.swift in Sources */, @@ -1530,11 +1605,11 @@ buildActionMask = 2147483647; files = ( 1AEBF3E6219BA22600653FF5 /* BigUIntExtensionTests.swift in Sources */, + 89B2742321EC2AA0001A6A93 /* CytonTests.swift in Sources */, 89A87C8B217312CC00588674 /* WalletNameValidatorTests.swift in Sources */, 1AB3D1D221709F9600557E9D /* UIStoryboardExtensionTests.swift in Sources */, 6E8962032194575B00D2C0AD /* DoubleExtensionTests.swift in Sources */, 1AB0CC492194FC1000A7C0CF /* UIntExtensionTests.swift in Sources */, - 896D044220AE69C5002CFF6A /* NeuronTests.swift in Sources */, 1A6946622192BFD9000093A2 /* GasCalculatorTests.swift in Sources */, 1AB287742179654300DCC14D /* WalletManagerTests.swift in Sources */, 89BA4B5821AE410F0084439B /* MnemonicValidatorTests.swift in Sources */, @@ -1546,7 +1621,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 896D044D20AE69C5002CFF6A /* NeuronUITests.swift in Sources */, + 89B2742521EC2AAD001A6A93 /* CytonUITests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1555,12 +1630,12 @@ /* Begin PBXTargetDependency section */ 896D043F20AE69C5002CFF6A /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 896D042820AE69C1002CFF6A /* Neuron */; + target = 896D042820AE69C1002CFF6A /* Cyton */; targetProxy = 896D043E20AE69C5002CFF6A /* PBXContainerItemProxy */; }; 896D044A20AE69C5002CFF6A /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 896D042820AE69C1002CFF6A /* Neuron */; + target = 896D042820AE69C1002CFF6A /* Cyton */; targetProxy = 896D044920AE69C5002CFF6A /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ @@ -1575,6 +1650,69 @@ name = Localizable.strings; sourceTree = ""; }; + 6E86071721CB39C80055387C /* guide_page_1@3x.png */ = { + isa = PBXVariantGroup; + children = ( + 6E86071621CB39C80055387C /* en */, + 6EEDED4F21CB3B3B00FC3BCE /* zh-Hans */, + ); + name = "guide_page_1@3x.png"; + sourceTree = ""; + }; + 6E86072321CB39F80055387C /* guide_page_1@2x.png */ = { + isa = PBXVariantGroup; + children = ( + 6E86072221CB39F80055387C /* en */, + 6EEDED5021CB3B3B00FC3BCE /* zh-Hans */, + ); + name = "guide_page_1@2x.png"; + sourceTree = ""; + }; + 6EEDED6521CB3C8200FC3BCE /* guide_page_2@2x.png */ = { + isa = PBXVariantGroup; + children = ( + 6EEDED6621CB3C8200FC3BCE /* en */, + 6EEDED6721CB3C8200FC3BCE /* zh-Hans */, + ); + name = "guide_page_2@2x.png"; + sourceTree = ""; + }; + 6EEDED7821CB3D1700FC3BCE /* guide_page_2@3x.png */ = { + isa = PBXVariantGroup; + children = ( + 6EEDED7921CB3D1700FC3BCE /* en */, + 6EEDED7A21CB3D1700FC3BCE /* zh-Hans */, + ); + name = "guide_page_2@3x.png"; + sourceTree = ""; + }; + 6EEDED9521CB3DD700FC3BCE /* guide_page_3@3x.png */ = { + isa = PBXVariantGroup; + children = ( + 6EEDED9621CB3DD700FC3BCE /* zh-Hans */, + 6EEDED9721CB3DD700FC3BCE /* en */, + ); + name = "guide_page_3@3x.png"; + sourceTree = ""; + }; + 6EEDED9E21CB3DFB00FC3BCE /* guide_page_3@2x.png */ = { + isa = PBXVariantGroup; + children = ( + 6EEDED9F21CB3DFB00FC3BCE /* zh-Hans */, + 6EEDEDA021CB3DFB00FC3BCE /* en */, + ); + name = "guide_page_3@2x.png"; + sourceTree = ""; + }; + 6EEDEDA421CB3F3500FC3BCE /* product_agreement.txt */ = { + isa = PBXVariantGroup; + children = ( + 6EEDEDA321CB3F3500FC3BCE /* zh-Hans */, + 89450B7721D37FD500CE1921 /* en */, + ); + name = product_agreement.txt; + sourceTree = ""; + }; 896D043020AE69C1002CFF6A /* Main.storyboard */ = { isa = PBXVariantGroup; children = ( @@ -1712,18 +1850,17 @@ }; 896D045220AE69C5002CFF6A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 21C5F1D714208410CA8D77B9 /* Pods-Neuron.debug.xcconfig */; + baseConfigurationReference = 21C5F1D714208410CA8D77B9 /* Pods-Cyton.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ADDRESS_SANITIZER_CONTAINER_OVERFLOW = NO; CLANG_ENABLE_CODE_COVERAGE = YES; - CODE_SIGN_ENTITLEMENTS = Neuron/Neuron.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; ENABLE_BITCODE = YES; - INFOPLIST_FILE = Neuron/Info.plist; + INFOPLIST_FILE = Cyton/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -1731,11 +1868,11 @@ ); ONLY_ACTIVE_ARCH = YES; OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" -D DEBUG"; - PRODUCT_BUNDLE_IDENTIFIER = com.nervos.neuron; + PRODUCT_BUNDLE_IDENTIFIER = "com.crytape.cita-wallet"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_OBJC_BRIDGING_HEADER = "Neuron/Neuron-Bridging-Header.h"; + SWIFT_OBJC_BRIDGING_HEADER = "Cyton/Cyton-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = 1; @@ -1745,29 +1882,28 @@ }; 896D045320AE69C5002CFF6A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 1D270F090888C6AD9CF6A055 /* Pods-Neuron.release.xcconfig */; + baseConfigurationReference = 1D270F090888C6AD9CF6A055 /* Pods-Cyton.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ADDRESS_SANITIZER_CONTAINER_OVERFLOW = NO; CLANG_ENABLE_CODE_COVERAGE = YES; - CODE_SIGN_ENTITLEMENTS = Neuron/Neuron.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; ENABLE_BITCODE = YES; - INFOPLIST_FILE = Neuron/Info.plist; + INFOPLIST_FILE = Cyton/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); ONLY_ACTIVE_ARCH = NO; - PRODUCT_BUNDLE_IDENTIFIER = com.nervos.neuron; + PRODUCT_BUNDLE_IDENTIFIER = "com.crytape.cita-wallet"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_OBJC_BRIDGING_HEADER = "Neuron/Neuron-Bridging-Header.h"; + SWIFT_OBJC_BRIDGING_HEADER = "Cyton/Cyton-Bridging-Header.h"; SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = 1; USER_HEADER_SEARCH_PATHS = "$(PODS_ROOT)/**"; @@ -1776,104 +1912,104 @@ }; 896D045520AE69C5002CFF6A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = DB57BA5F3596655B01B46EF1 /* Pods-NeuronTests.debug.xcconfig */; + baseConfigurationReference = DB57BA5F3596655B01B46EF1 /* Pods-CytonTests.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = NeuronTests/Info.plist; + INFOPLIST_FILE = CytonTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = org.nervos.NeuronTests; + PRODUCT_BUNDLE_IDENTIFIER = org.nervos.CytonTests; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Neuron.app/Neuron"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Cyton.app/Cyton"; USER_HEADER_SEARCH_PATHS = "$(PODS_ROOT)/**"; }; name = Debug; }; 896D045620AE69C5002CFF6A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 71EE3A6382628C3632FE594F /* Pods-NeuronTests.release.xcconfig */; + baseConfigurationReference = 71EE3A6382628C3632FE594F /* Pods-CytonTests.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = NeuronTests/Info.plist; + INFOPLIST_FILE = CytonTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = org.nervos.NeuronTests; + PRODUCT_BUNDLE_IDENTIFIER = org.nervos.CytonTests; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Neuron.app/Neuron"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Cyton.app/Cyton"; USER_HEADER_SEARCH_PATHS = "$(PODS_ROOT)/**"; }; name = Release; }; 896D045820AE69C5002CFF6A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = C43FB42A510FDF667FD64169 /* Pods-NeuronUITests.debug.xcconfig */; + baseConfigurationReference = C43FB42A510FDF667FD64169 /* Pods-CytonUITests.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = NeuronUITests/Info.plist; + INFOPLIST_FILE = CytonUITests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = org.nervos.NeuronUITests; + PRODUCT_BUNDLE_IDENTIFIER = org.nervos.CytonUITests; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_TARGET_NAME = Neuron; + TEST_TARGET_NAME = Cyton; }; name = Debug; }; 896D045920AE69C5002CFF6A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = DB16ADF7FEC17385D266EA00 /* Pods-NeuronUITests.release.xcconfig */; + baseConfigurationReference = DB16ADF7FEC17385D266EA00 /* Pods-CytonUITests.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = NeuronUITests/Info.plist; + INFOPLIST_FILE = CytonUITests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = org.nervos.NeuronUITests; + PRODUCT_BUNDLE_IDENTIFIER = org.nervos.CytonUITests; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_TARGET_NAME = Neuron; + TEST_TARGET_NAME = Cyton; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 896D042420AE69C1002CFF6A /* Build configuration list for PBXProject "Neuron" */ = { + 896D042420AE69C1002CFF6A /* Build configuration list for PBXProject "Cyton" */ = { isa = XCConfigurationList; buildConfigurations = ( 896D044F20AE69C5002CFF6A /* Debug */, @@ -1882,7 +2018,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 896D045120AE69C5002CFF6A /* Build configuration list for PBXNativeTarget "Neuron" */ = { + 896D045120AE69C5002CFF6A /* Build configuration list for PBXNativeTarget "Cyton" */ = { isa = XCConfigurationList; buildConfigurations = ( 896D045220AE69C5002CFF6A /* Debug */, @@ -1891,7 +2027,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 896D045420AE69C5002CFF6A /* Build configuration list for PBXNativeTarget "NeuronTests" */ = { + 896D045420AE69C5002CFF6A /* Build configuration list for PBXNativeTarget "CytonTests" */ = { isa = XCConfigurationList; buildConfigurations = ( 896D045520AE69C5002CFF6A /* Debug */, @@ -1900,7 +2036,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 896D045720AE69C5002CFF6A /* Build configuration list for PBXNativeTarget "NeuronUITests" */ = { + 896D045720AE69C5002CFF6A /* Build configuration list for PBXNativeTarget "CytonUITests" */ = { isa = XCConfigurationList; buildConfigurations = ( 896D045820AE69C5002CFF6A /* Debug */, diff --git a/Neuron.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Cyton.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from Neuron.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to Cyton.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/Neuron.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Cyton.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from Neuron.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to Cyton.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/Cyton.xcodeproj/xcshareddata/xcschemes/Cyton.xcscheme b/Cyton.xcodeproj/xcshareddata/xcschemes/Cyton.xcscheme new file mode 100644 index 00000000..9743a7ae --- /dev/null +++ b/Cyton.xcodeproj/xcshareddata/xcschemes/Cyton.xcscheme @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Neuron.xcworkspace/contents.xcworkspacedata b/Cyton.xcworkspace/contents.xcworkspacedata similarity index 80% rename from Neuron.xcworkspace/contents.xcworkspacedata rename to Cyton.xcworkspace/contents.xcworkspacedata index 02a462bc..a8676c78 100644 --- a/Neuron.xcworkspace/contents.xcworkspacedata +++ b/Cyton.xcworkspace/contents.xcworkspacedata @@ -2,7 +2,7 @@ + location = "group:Cyton.xcodeproj"> diff --git a/Neuron.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Cyton.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from Neuron.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to Cyton.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/Neuron/AppDelegate.swift b/Cyton/AppDelegate.swift similarity index 78% rename from Neuron/AppDelegate.swift rename to Cyton/AppDelegate.swift index e6ba2392..d8d584f9 100644 --- a/Neuron/AppDelegate.swift +++ b/Cyton/AppDelegate.swift @@ -1,6 +1,6 @@ // // AppDelegate.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/5/18. // Copyright © 2018年 cryptape. All rights reserved. @@ -14,8 +14,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool { - hookSensorsDebugWarning() - skipBackupFiles() RealmConfigurator.configure() @@ -26,8 +24,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate { setupKeyboard() GuideService.shared.register() AuthenticationService.shared.register() - SensorsAnalytics.configureSensors() - _ = TransactionStatusManager.manager + EthereumLocalTxPool.pool.register() + CITALocalTxPool.pool.register() return true } @@ -45,18 +43,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate { SkipBackupFiles(paths: paths).skip() } - private func hookSensorsDebugWarning() { - guard let cls = NSClassFromString("SensorsAnalyticsSDK") else { return } - let originalSelector = NSSelectorFromString("showDebugModeWarning:withNoMoreButton:") - let swizzledSelector = #selector(sensorsShowDebugModeWarning(message:showNoMore:)) - guard let swizzledMethod = class_getInstanceMethod(self.classForCoder, swizzledSelector) else { return } - let swizzledMethodImp = method_getImplementation(swizzledMethod) - class_replaceMethod(cls, originalSelector, swizzledMethodImp, method_getTypeEncoding(swizzledMethod)) - } - - @objc func sensorsShowDebugModeWarning(message: String, showNoMore: Bool) { - } - func applicationWillResignActive(_ application: UIApplication) { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. diff --git "a/Neuron/Assets.xcassets/AppIcon.appiconset/1024\347\272\277024.jpg" "b/Cyton/Assets.xcassets/AppIcon.appiconset/1024\347\272\277024.jpg" similarity index 100% rename from "Neuron/Assets.xcassets/AppIcon.appiconset/1024\347\272\277024.jpg" rename to "Cyton/Assets.xcassets/AppIcon.appiconset/1024\347\272\277024.jpg" diff --git a/Neuron/Assets.xcassets/AppIcon.appiconset/120x120-1.jpg b/Cyton/Assets.xcassets/AppIcon.appiconset/120x120-1.jpg similarity index 100% rename from Neuron/Assets.xcassets/AppIcon.appiconset/120x120-1.jpg rename to Cyton/Assets.xcassets/AppIcon.appiconset/120x120-1.jpg diff --git a/Neuron/Assets.xcassets/AppIcon.appiconset/120x120.jpg b/Cyton/Assets.xcassets/AppIcon.appiconset/120x120.jpg similarity index 100% rename from Neuron/Assets.xcassets/AppIcon.appiconset/120x120.jpg rename to Cyton/Assets.xcassets/AppIcon.appiconset/120x120.jpg diff --git "a/Neuron/Assets.xcassets/AppIcon.appiconset/180\347\272\27780.jpg" "b/Cyton/Assets.xcassets/AppIcon.appiconset/180\347\272\27780.jpg" similarity index 100% rename from "Neuron/Assets.xcassets/AppIcon.appiconset/180\347\272\27780.jpg" rename to "Cyton/Assets.xcassets/AppIcon.appiconset/180\347\272\27780.jpg" diff --git a/Neuron/Assets.xcassets/AppIcon.appiconset/40x40.jpg b/Cyton/Assets.xcassets/AppIcon.appiconset/40x40.jpg similarity index 100% rename from Neuron/Assets.xcassets/AppIcon.appiconset/40x40.jpg rename to Cyton/Assets.xcassets/AppIcon.appiconset/40x40.jpg diff --git a/Neuron/Assets.xcassets/AppIcon.appiconset/58x58.jpg b/Cyton/Assets.xcassets/AppIcon.appiconset/58x58.jpg similarity index 100% rename from Neuron/Assets.xcassets/AppIcon.appiconset/58x58.jpg rename to Cyton/Assets.xcassets/AppIcon.appiconset/58x58.jpg diff --git a/Neuron/Assets.xcassets/AppIcon.appiconset/60x60.jpg b/Cyton/Assets.xcassets/AppIcon.appiconset/60x60.jpg similarity index 100% rename from Neuron/Assets.xcassets/AppIcon.appiconset/60x60.jpg rename to Cyton/Assets.xcassets/AppIcon.appiconset/60x60.jpg diff --git a/Neuron/Assets.xcassets/AppIcon.appiconset/80x80.jpg b/Cyton/Assets.xcassets/AppIcon.appiconset/80x80.jpg similarity index 100% rename from Neuron/Assets.xcassets/AppIcon.appiconset/80x80.jpg rename to Cyton/Assets.xcassets/AppIcon.appiconset/80x80.jpg diff --git a/Neuron/Assets.xcassets/AppIcon.appiconset/87x87.jpg b/Cyton/Assets.xcassets/AppIcon.appiconset/87x87.jpg similarity index 100% rename from Neuron/Assets.xcassets/AppIcon.appiconset/87x87.jpg rename to Cyton/Assets.xcassets/AppIcon.appiconset/87x87.jpg diff --git a/Neuron/Assets.xcassets/AppIcon.appiconset/Contents.json b/Cyton/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/AppIcon.appiconset/Contents.json rename to Cyton/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/Neuron/Assets.xcassets/Authentication/Contents.json b/Cyton/Assets.xcassets/Authentication/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Authentication/Contents.json rename to Cyton/Assets.xcassets/Authentication/Contents.json diff --git a/Neuron/Assets.xcassets/Authentication/ethereum_network.imageset/Contents.json b/Cyton/Assets.xcassets/Authentication/ethereum_network.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Authentication/ethereum_network.imageset/Contents.json rename to Cyton/Assets.xcassets/Authentication/ethereum_network.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Authentication/ethereum_network.imageset/ethereum_network@2x.png b/Cyton/Assets.xcassets/Authentication/ethereum_network.imageset/ethereum_network@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Authentication/ethereum_network.imageset/ethereum_network@2x.png rename to Cyton/Assets.xcassets/Authentication/ethereum_network.imageset/ethereum_network@2x.png diff --git a/Neuron/Assets.xcassets/Authentication/ethereum_network.imageset/ethereum_network@3x.png b/Cyton/Assets.xcassets/Authentication/ethereum_network.imageset/ethereum_network@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Authentication/ethereum_network.imageset/ethereum_network@3x.png rename to Cyton/Assets.xcassets/Authentication/ethereum_network.imageset/ethereum_network@3x.png diff --git a/Neuron/Assets.xcassets/Authentication/faceId_icon.imageset/Contents.json b/Cyton/Assets.xcassets/Authentication/faceId_icon.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Authentication/faceId_icon.imageset/Contents.json rename to Cyton/Assets.xcassets/Authentication/faceId_icon.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Authentication/faceId_icon.imageset/Group 3.png b/Cyton/Assets.xcassets/Authentication/faceId_icon.imageset/Group 3.png similarity index 100% rename from Neuron/Assets.xcassets/Authentication/faceId_icon.imageset/Group 3.png rename to Cyton/Assets.xcassets/Authentication/faceId_icon.imageset/Group 3.png diff --git a/Neuron/Assets.xcassets/Authentication/faceId_login_icon.imageset/Contents.json b/Cyton/Assets.xcassets/Authentication/faceId_login_icon.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Authentication/faceId_login_icon.imageset/Contents.json rename to Cyton/Assets.xcassets/Authentication/faceId_login_icon.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Authentication/faceId_login_icon.imageset/Group 3 Copy.png b/Cyton/Assets.xcassets/Authentication/faceId_login_icon.imageset/Group 3 Copy.png similarity index 100% rename from Neuron/Assets.xcassets/Authentication/faceId_login_icon.imageset/Group 3 Copy.png rename to Cyton/Assets.xcassets/Authentication/faceId_login_icon.imageset/Group 3 Copy.png diff --git a/Neuron/Assets.xcassets/Authentication/icon_authentication.imageset/Contents.json b/Cyton/Assets.xcassets/Authentication/icon_authentication.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Authentication/icon_authentication.imageset/Contents.json rename to Cyton/Assets.xcassets/Authentication/icon_authentication.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Authentication/icon_authentication.imageset/Group 13@2x.png b/Cyton/Assets.xcassets/Authentication/icon_authentication.imageset/Group 13@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Authentication/icon_authentication.imageset/Group 13@2x.png rename to Cyton/Assets.xcassets/Authentication/icon_authentication.imageset/Group 13@2x.png diff --git a/Neuron/Assets.xcassets/Authentication/icon_down.imageset/Contents.json b/Cyton/Assets.xcassets/Authentication/icon_down.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Authentication/icon_down.imageset/Contents.json rename to Cyton/Assets.xcassets/Authentication/icon_down.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Authentication/icon_down.imageset/Path 46.png b/Cyton/Assets.xcassets/Authentication/icon_down.imageset/Path 46.png similarity index 100% rename from Neuron/Assets.xcassets/Authentication/icon_down.imageset/Path 46.png rename to Cyton/Assets.xcassets/Authentication/icon_down.imageset/Path 46.png diff --git a/Neuron/Assets.xcassets/Authentication/password_login_icon.imageset/Contents.json b/Cyton/Assets.xcassets/Authentication/password_login_icon.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Authentication/password_login_icon.imageset/Contents.json rename to Cyton/Assets.xcassets/Authentication/password_login_icon.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Authentication/password_login_icon.imageset/Group 13.png b/Cyton/Assets.xcassets/Authentication/password_login_icon.imageset/Group 13.png similarity index 100% rename from Neuron/Assets.xcassets/Authentication/password_login_icon.imageset/Group 13.png rename to Cyton/Assets.xcassets/Authentication/password_login_icon.imageset/Group 13.png diff --git a/Neuron/Assets.xcassets/Authentication/touchId_icon.imageset/Contents.json b/Cyton/Assets.xcassets/Authentication/touchId_icon.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Authentication/touchId_icon.imageset/Contents.json rename to Cyton/Assets.xcassets/Authentication/touchId_icon.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Authentication/touchId_icon.imageset/Group 12@3x.png b/Cyton/Assets.xcassets/Authentication/touchId_icon.imageset/Group 12@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Authentication/touchId_icon.imageset/Group 12@3x.png rename to Cyton/Assets.xcassets/Authentication/touchId_icon.imageset/Group 12@3x.png diff --git a/Neuron/Assets.xcassets/Authentication/touchId_login_icon.imageset/Contents.json b/Cyton/Assets.xcassets/Authentication/touchId_login_icon.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Authentication/touchId_login_icon.imageset/Contents.json rename to Cyton/Assets.xcassets/Authentication/touchId_login_icon.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Authentication/touchId_login_icon.imageset/Group 12 Copy.png b/Cyton/Assets.xcassets/Authentication/touchId_login_icon.imageset/Group 12 Copy.png similarity index 100% rename from Neuron/Assets.xcassets/Authentication/touchId_login_icon.imageset/Group 12 Copy.png rename to Cyton/Assets.xcassets/Authentication/touchId_login_icon.imageset/Group 12 Copy.png diff --git a/Neuron/Assets.xcassets/Contents.json b/Cyton/Assets.xcassets/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Contents.json rename to Cyton/Assets.xcassets/Contents.json diff --git a/Neuron/Assets.xcassets/DApp Browser/Contents.json b/Cyton/Assets.xcassets/DApp Browser/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/DApp Browser/Contents.json rename to Cyton/Assets.xcassets/DApp Browser/Contents.json diff --git a/Neuron/Assets.xcassets/DApp Browser/dapp_collection.imageset/Contents.json b/Cyton/Assets.xcassets/DApp Browser/dapp_collection.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/DApp Browser/dapp_collection.imageset/Contents.json rename to Cyton/Assets.xcassets/DApp Browser/dapp_collection.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/DApp Browser/dapp_collection.imageset/dapp_collection@2x.png b/Cyton/Assets.xcassets/DApp Browser/dapp_collection.imageset/dapp_collection@2x.png similarity index 100% rename from Neuron/Assets.xcassets/DApp Browser/dapp_collection.imageset/dapp_collection@2x.png rename to Cyton/Assets.xcassets/DApp Browser/dapp_collection.imageset/dapp_collection@2x.png diff --git a/Neuron/Assets.xcassets/DApp Browser/dapp_collection.imageset/dapp_collection@3x.png b/Cyton/Assets.xcassets/DApp Browser/dapp_collection.imageset/dapp_collection@3x.png similarity index 100% rename from Neuron/Assets.xcassets/DApp Browser/dapp_collection.imageset/dapp_collection@3x.png rename to Cyton/Assets.xcassets/DApp Browser/dapp_collection.imageset/dapp_collection@3x.png diff --git a/Neuron/Assets.xcassets/DApp Browser/dapp_default.imageset/Contents.json b/Cyton/Assets.xcassets/DApp Browser/dapp_default.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/DApp Browser/dapp_default.imageset/Contents.json rename to Cyton/Assets.xcassets/DApp Browser/dapp_default.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/DApp Browser/dapp_default.imageset/dapp_default@2x.png b/Cyton/Assets.xcassets/DApp Browser/dapp_default.imageset/dapp_default@2x.png similarity index 100% rename from Neuron/Assets.xcassets/DApp Browser/dapp_default.imageset/dapp_default@2x.png rename to Cyton/Assets.xcassets/DApp Browser/dapp_default.imageset/dapp_default@2x.png diff --git a/Neuron/Assets.xcassets/DApp Browser/dapp_default.imageset/dapp_default@3x.png b/Cyton/Assets.xcassets/DApp Browser/dapp_default.imageset/dapp_default@3x.png similarity index 100% rename from Neuron/Assets.xcassets/DApp Browser/dapp_default.imageset/dapp_default@3x.png rename to Cyton/Assets.xcassets/DApp Browser/dapp_default.imageset/dapp_default@3x.png diff --git a/Neuron/Assets.xcassets/DApp Browser/webview_ahead_off.imageset/Contents.json b/Cyton/Assets.xcassets/DApp Browser/webview_ahead_off.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/DApp Browser/webview_ahead_off.imageset/Contents.json rename to Cyton/Assets.xcassets/DApp Browser/webview_ahead_off.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/DApp Browser/webview_ahead_off.imageset/webview_ahead_off@2x.png b/Cyton/Assets.xcassets/DApp Browser/webview_ahead_off.imageset/webview_ahead_off@2x.png similarity index 100% rename from Neuron/Assets.xcassets/DApp Browser/webview_ahead_off.imageset/webview_ahead_off@2x.png rename to Cyton/Assets.xcassets/DApp Browser/webview_ahead_off.imageset/webview_ahead_off@2x.png diff --git a/Neuron/Assets.xcassets/DApp Browser/webview_ahead_off.imageset/webview_ahead_off@3x.png b/Cyton/Assets.xcassets/DApp Browser/webview_ahead_off.imageset/webview_ahead_off@3x.png similarity index 100% rename from Neuron/Assets.xcassets/DApp Browser/webview_ahead_off.imageset/webview_ahead_off@3x.png rename to Cyton/Assets.xcassets/DApp Browser/webview_ahead_off.imageset/webview_ahead_off@3x.png diff --git a/Neuron/Assets.xcassets/DApp Browser/webview_ahead_on.imageset/Contents.json b/Cyton/Assets.xcassets/DApp Browser/webview_ahead_on.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/DApp Browser/webview_ahead_on.imageset/Contents.json rename to Cyton/Assets.xcassets/DApp Browser/webview_ahead_on.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/DApp Browser/webview_ahead_on.imageset/webview_ahead_on@2x.png b/Cyton/Assets.xcassets/DApp Browser/webview_ahead_on.imageset/webview_ahead_on@2x.png similarity index 100% rename from Neuron/Assets.xcassets/DApp Browser/webview_ahead_on.imageset/webview_ahead_on@2x.png rename to Cyton/Assets.xcassets/DApp Browser/webview_ahead_on.imageset/webview_ahead_on@2x.png diff --git a/Neuron/Assets.xcassets/DApp Browser/webview_ahead_on.imageset/webview_ahead_on@3x.png b/Cyton/Assets.xcassets/DApp Browser/webview_ahead_on.imageset/webview_ahead_on@3x.png similarity index 100% rename from Neuron/Assets.xcassets/DApp Browser/webview_ahead_on.imageset/webview_ahead_on@3x.png rename to Cyton/Assets.xcassets/DApp Browser/webview_ahead_on.imageset/webview_ahead_on@3x.png diff --git a/Neuron/Assets.xcassets/DApp Browser/webview_back_off.imageset/Contents.json b/Cyton/Assets.xcassets/DApp Browser/webview_back_off.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/DApp Browser/webview_back_off.imageset/Contents.json rename to Cyton/Assets.xcassets/DApp Browser/webview_back_off.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/DApp Browser/webview_back_off.imageset/webview_back_off@2x.png b/Cyton/Assets.xcassets/DApp Browser/webview_back_off.imageset/webview_back_off@2x.png similarity index 100% rename from Neuron/Assets.xcassets/DApp Browser/webview_back_off.imageset/webview_back_off@2x.png rename to Cyton/Assets.xcassets/DApp Browser/webview_back_off.imageset/webview_back_off@2x.png diff --git a/Neuron/Assets.xcassets/DApp Browser/webview_back_off.imageset/webview_back_off@3x.png b/Cyton/Assets.xcassets/DApp Browser/webview_back_off.imageset/webview_back_off@3x.png similarity index 100% rename from Neuron/Assets.xcassets/DApp Browser/webview_back_off.imageset/webview_back_off@3x.png rename to Cyton/Assets.xcassets/DApp Browser/webview_back_off.imageset/webview_back_off@3x.png diff --git a/Neuron/Assets.xcassets/DApp Browser/webview_back_on.imageset/Contents.json b/Cyton/Assets.xcassets/DApp Browser/webview_back_on.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/DApp Browser/webview_back_on.imageset/Contents.json rename to Cyton/Assets.xcassets/DApp Browser/webview_back_on.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/DApp Browser/webview_back_on.imageset/webview_back_on@2x.png b/Cyton/Assets.xcassets/DApp Browser/webview_back_on.imageset/webview_back_on@2x.png similarity index 100% rename from Neuron/Assets.xcassets/DApp Browser/webview_back_on.imageset/webview_back_on@2x.png rename to Cyton/Assets.xcassets/DApp Browser/webview_back_on.imageset/webview_back_on@2x.png diff --git a/Neuron/Assets.xcassets/DApp Browser/webview_back_on.imageset/webview_back_on@3x.png b/Cyton/Assets.xcassets/DApp Browser/webview_back_on.imageset/webview_back_on@3x.png similarity index 100% rename from Neuron/Assets.xcassets/DApp Browser/webview_back_on.imageset/webview_back_on@3x.png rename to Cyton/Assets.xcassets/DApp Browser/webview_back_on.imageset/webview_back_on@3x.png diff --git a/Neuron/Assets.xcassets/Error/Contents.json b/Cyton/Assets.xcassets/Error/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Error/Contents.json rename to Cyton/Assets.xcassets/Error/Contents.json diff --git a/Neuron/Assets.xcassets/Error/blank_icon.imageset/Contents.json b/Cyton/Assets.xcassets/Error/blank_icon.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Error/blank_icon.imageset/Contents.json rename to Cyton/Assets.xcassets/Error/blank_icon.imageset/Contents.json diff --git "a/Neuron/Assets.xcassets/Error/blank_icon.imageset/\347\251\272\347\231\275\351\241\265\351\235\242@2x.png" "b/Cyton/Assets.xcassets/Error/blank_icon.imageset/\347\251\272\347\231\275\351\241\265\351\235\242@2x.png" similarity index 100% rename from "Neuron/Assets.xcassets/Error/blank_icon.imageset/\347\251\272\347\231\275\351\241\265\351\235\242@2x.png" rename to "Cyton/Assets.xcassets/Error/blank_icon.imageset/\347\251\272\347\231\275\351\241\265\351\235\242@2x.png" diff --git "a/Neuron/Assets.xcassets/Error/blank_icon.imageset/\347\251\272\347\231\275\351\241\265\351\235\242@3x.png" "b/Cyton/Assets.xcassets/Error/blank_icon.imageset/\347\251\272\347\231\275\351\241\265\351\235\242@3x.png" similarity index 100% rename from "Neuron/Assets.xcassets/Error/blank_icon.imageset/\347\251\272\347\231\275\351\241\265\351\235\242@3x.png" rename to "Cyton/Assets.xcassets/Error/blank_icon.imageset/\347\251\272\347\231\275\351\241\265\351\235\242@3x.png" diff --git a/Neuron/Assets.xcassets/Error/fail_icon.imageset/Contents.json b/Cyton/Assets.xcassets/Error/fail_icon.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Error/fail_icon.imageset/Contents.json rename to Cyton/Assets.xcassets/Error/fail_icon.imageset/Contents.json diff --git "a/Neuron/Assets.xcassets/Error/fail_icon.imageset/\345\244\261\350\264\245\351\241\265\351\235\242@2x.png" "b/Cyton/Assets.xcassets/Error/fail_icon.imageset/\345\244\261\350\264\245\351\241\265\351\235\242@2x.png" similarity index 100% rename from "Neuron/Assets.xcassets/Error/fail_icon.imageset/\345\244\261\350\264\245\351\241\265\351\235\242@2x.png" rename to "Cyton/Assets.xcassets/Error/fail_icon.imageset/\345\244\261\350\264\245\351\241\265\351\235\242@2x.png" diff --git "a/Neuron/Assets.xcassets/Error/fail_icon.imageset/\345\244\261\350\264\245\351\241\265\351\235\242@3x.png" "b/Cyton/Assets.xcassets/Error/fail_icon.imageset/\345\244\261\350\264\245\351\241\265\351\235\242@3x.png" similarity index 100% rename from "Neuron/Assets.xcassets/Error/fail_icon.imageset/\345\244\261\350\264\245\351\241\265\351\235\242@3x.png" rename to "Cyton/Assets.xcassets/Error/fail_icon.imageset/\345\244\261\350\264\245\351\241\265\351\235\242@3x.png" diff --git a/Neuron/Assets.xcassets/Guide/Contents.json b/Cyton/Assets.xcassets/Guide/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Guide/Contents.json rename to Cyton/Assets.xcassets/Guide/Contents.json diff --git a/Neuron/Assets.xcassets/Guide/icon_check_no.imageset/Contents.json b/Cyton/Assets.xcassets/Guide/icon_check_no.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Guide/icon_check_no.imageset/Contents.json rename to Cyton/Assets.xcassets/Guide/icon_check_no.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Guide/icon_check_no.imageset/Group Copy@2x.png b/Cyton/Assets.xcassets/Guide/icon_check_no.imageset/Group Copy@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Guide/icon_check_no.imageset/Group Copy@2x.png rename to Cyton/Assets.xcassets/Guide/icon_check_no.imageset/Group Copy@2x.png diff --git a/Neuron/Assets.xcassets/Guide/icon_check_no.imageset/Group Copy@3x.png b/Cyton/Assets.xcassets/Guide/icon_check_no.imageset/Group Copy@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Guide/icon_check_no.imageset/Group Copy@3x.png rename to Cyton/Assets.xcassets/Guide/icon_check_no.imageset/Group Copy@3x.png diff --git a/Neuron/Assets.xcassets/Guide/icon_check_yes.imageset/Contents.json b/Cyton/Assets.xcassets/Guide/icon_check_yes.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Guide/icon_check_yes.imageset/Contents.json rename to Cyton/Assets.xcassets/Guide/icon_check_yes.imageset/Contents.json diff --git "a/Neuron/Assets.xcassets/Guide/icon_check_yes.imageset/\351\200\211\344\270\255.png" "b/Cyton/Assets.xcassets/Guide/icon_check_yes.imageset/\351\200\211\344\270\255.png" similarity index 100% rename from "Neuron/Assets.xcassets/Guide/icon_check_yes.imageset/\351\200\211\344\270\255.png" rename to "Cyton/Assets.xcassets/Guide/icon_check_yes.imageset/\351\200\211\344\270\255.png" diff --git a/Neuron/Assets.xcassets/Icons/Contents.json b/Cyton/Assets.xcassets/Icons/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Icons/Contents.json rename to Cyton/Assets.xcassets/Icons/Contents.json diff --git a/Neuron/Assets.xcassets/Icons/add_asset.imageset/Contents.json b/Cyton/Assets.xcassets/Icons/add_asset.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Icons/add_asset.imageset/Contents.json rename to Cyton/Assets.xcassets/Icons/add_asset.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Icons/add_asset.imageset/add_asset@2x.png b/Cyton/Assets.xcassets/Icons/add_asset.imageset/add_asset@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/add_asset.imageset/add_asset@2x.png rename to Cyton/Assets.xcassets/Icons/add_asset.imageset/add_asset@2x.png diff --git a/Neuron/Assets.xcassets/Icons/add_asset.imageset/add_asset@3x.png b/Cyton/Assets.xcassets/Icons/add_asset.imageset/add_asset@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/add_asset.imageset/add_asset@3x.png rename to Cyton/Assets.xcassets/Icons/add_asset.imageset/add_asset@3x.png diff --git a/Neuron/Assets.xcassets/Icons/add_wallet.imageset/Contents.json b/Cyton/Assets.xcassets/Icons/add_wallet.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Icons/add_wallet.imageset/Contents.json rename to Cyton/Assets.xcassets/Icons/add_wallet.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Icons/add_wallet.imageset/add_wallet@2x.png b/Cyton/Assets.xcassets/Icons/add_wallet.imageset/add_wallet@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/add_wallet.imageset/add_wallet@2x.png rename to Cyton/Assets.xcassets/Icons/add_wallet.imageset/add_wallet@2x.png diff --git a/Neuron/Assets.xcassets/Icons/add_wallet.imageset/add_wallet@3x.png b/Cyton/Assets.xcassets/Icons/add_wallet.imageset/add_wallet@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/add_wallet.imageset/add_wallet@3x.png rename to Cyton/Assets.xcassets/Icons/add_wallet.imageset/add_wallet@3x.png diff --git a/Neuron/Assets.xcassets/Icons/close.imageset/Contents.json b/Cyton/Assets.xcassets/Icons/close.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Icons/close.imageset/Contents.json rename to Cyton/Assets.xcassets/Icons/close.imageset/Contents.json diff --git "a/Neuron/Assets.xcassets/Icons/close.imageset/\345\205\263\351\227\255 (1).png" "b/Cyton/Assets.xcassets/Icons/close.imageset/\345\205\263\351\227\255 (1).png" similarity index 100% rename from "Neuron/Assets.xcassets/Icons/close.imageset/\345\205\263\351\227\255 (1).png" rename to "Cyton/Assets.xcassets/Icons/close.imageset/\345\205\263\351\227\255 (1).png" diff --git a/Neuron/Assets.xcassets/Icons/copy.imageset/Contents.json b/Cyton/Assets.xcassets/Icons/copy.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Icons/copy.imageset/Contents.json rename to Cyton/Assets.xcassets/Icons/copy.imageset/Contents.json diff --git "a/Neuron/Assets.xcassets/Icons/copy.imageset/\345\244\215\345\210\266.png" "b/Cyton/Assets.xcassets/Icons/copy.imageset/\345\244\215\345\210\266.png" similarity index 100% rename from "Neuron/Assets.xcassets/Icons/copy.imageset/\345\244\215\345\210\266.png" rename to "Cyton/Assets.xcassets/Icons/copy.imageset/\345\244\215\345\210\266.png" diff --git "a/Neuron/Assets.xcassets/Icons/copy.imageset/\345\244\215\345\210\266@2x.png" "b/Cyton/Assets.xcassets/Icons/copy.imageset/\345\244\215\345\210\266@2x.png" similarity index 100% rename from "Neuron/Assets.xcassets/Icons/copy.imageset/\345\244\215\345\210\266@2x.png" rename to "Cyton/Assets.xcassets/Icons/copy.imageset/\345\244\215\345\210\266@2x.png" diff --git "a/Neuron/Assets.xcassets/Icons/copy.imageset/\345\244\215\345\210\266@3x.png" "b/Cyton/Assets.xcassets/Icons/copy.imageset/\345\244\215\345\210\266@3x.png" similarity index 100% rename from "Neuron/Assets.xcassets/Icons/copy.imageset/\345\244\215\345\210\266@3x.png" rename to "Cyton/Assets.xcassets/Icons/copy.imageset/\345\244\215\345\210\266@3x.png" diff --git a/Neuron/Assets.xcassets/Icons/copy_address.imageset/Contents.json b/Cyton/Assets.xcassets/Icons/copy_address.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Icons/copy_address.imageset/Contents.json rename to Cyton/Assets.xcassets/Icons/copy_address.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Icons/copy_address.imageset/copy_address@2x.png b/Cyton/Assets.xcassets/Icons/copy_address.imageset/copy_address@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/copy_address.imageset/copy_address@2x.png rename to Cyton/Assets.xcassets/Icons/copy_address.imageset/copy_address@2x.png diff --git a/Neuron/Assets.xcassets/Icons/copy_address.imageset/copy_address@3x.png b/Cyton/Assets.xcassets/Icons/copy_address.imageset/copy_address@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/copy_address.imageset/copy_address@3x.png rename to Cyton/Assets.xcassets/Icons/copy_address.imageset/copy_address@3x.png diff --git a/Neuron/Assets.xcassets/Icons/currency_selected.imageset/Contents.json b/Cyton/Assets.xcassets/Icons/currency_selected.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Icons/currency_selected.imageset/Contents.json rename to Cyton/Assets.xcassets/Icons/currency_selected.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Icons/currency_selected.imageset/selected@2x.png b/Cyton/Assets.xcassets/Icons/currency_selected.imageset/selected@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/currency_selected.imageset/selected@2x.png rename to Cyton/Assets.xcassets/Icons/currency_selected.imageset/selected@2x.png diff --git a/Neuron/Assets.xcassets/Icons/currency_selected.imageset/selected@3x.png b/Cyton/Assets.xcassets/Icons/currency_selected.imageset/selected@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/currency_selected.imageset/selected@3x.png rename to Cyton/Assets.xcassets/Icons/currency_selected.imageset/selected@3x.png diff --git a/Neuron/Assets.xcassets/Icons/neuron_logo.imageset/Contents.json b/Cyton/Assets.xcassets/Icons/cyton_logo.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Icons/neuron_logo.imageset/Contents.json rename to Cyton/Assets.xcassets/Icons/cyton_logo.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Icons/neuron_logo.imageset/neuron_logo@2x.png b/Cyton/Assets.xcassets/Icons/cyton_logo.imageset/neuron_logo@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/neuron_logo.imageset/neuron_logo@2x.png rename to Cyton/Assets.xcassets/Icons/cyton_logo.imageset/neuron_logo@2x.png diff --git a/Neuron/Assets.xcassets/Icons/neuron_logo.imageset/neuron_logo@3x.png b/Cyton/Assets.xcassets/Icons/cyton_logo.imageset/neuron_logo@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/neuron_logo.imageset/neuron_logo@3x.png rename to Cyton/Assets.xcassets/Icons/cyton_logo.imageset/neuron_logo@3x.png diff --git a/Neuron/Assets.xcassets/Icons/eth_logo.imageset/Contents.json b/Cyton/Assets.xcassets/Icons/eth_logo.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Icons/eth_logo.imageset/Contents.json rename to Cyton/Assets.xcassets/Icons/eth_logo.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Icons/eth_logo.imageset/eth_logo.png b/Cyton/Assets.xcassets/Icons/eth_logo.imageset/eth_logo.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/eth_logo.imageset/eth_logo.png rename to Cyton/Assets.xcassets/Icons/eth_logo.imageset/eth_logo.png diff --git a/Neuron/Assets.xcassets/Icons/eth_logo.imageset/eth_logo@2x.png b/Cyton/Assets.xcassets/Icons/eth_logo.imageset/eth_logo@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/eth_logo.imageset/eth_logo@2x.png rename to Cyton/Assets.xcassets/Icons/eth_logo.imageset/eth_logo@2x.png diff --git a/Neuron/Assets.xcassets/Icons/eth_logo.imageset/eth_logo@3x.png b/Cyton/Assets.xcassets/Icons/eth_logo.imageset/eth_logo@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/eth_logo.imageset/eth_logo@3x.png rename to Cyton/Assets.xcassets/Icons/eth_logo.imageset/eth_logo@3x.png diff --git a/Neuron/Assets.xcassets/Icons/eth_test.imageset/Contents.json b/Cyton/Assets.xcassets/Icons/eth_test.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Icons/eth_test.imageset/Contents.json rename to Cyton/Assets.xcassets/Icons/eth_test.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Icons/eth_test.imageset/ETH_test.png b/Cyton/Assets.xcassets/Icons/eth_test.imageset/ETH_test.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/eth_test.imageset/ETH_test.png rename to Cyton/Assets.xcassets/Icons/eth_test.imageset/ETH_test.png diff --git a/Neuron/Assets.xcassets/Icons/eth_test.imageset/ETH_test@2x.png b/Cyton/Assets.xcassets/Icons/eth_test.imageset/ETH_test@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/eth_test.imageset/ETH_test@2x.png rename to Cyton/Assets.xcassets/Icons/eth_test.imageset/ETH_test@2x.png diff --git a/Neuron/Assets.xcassets/Icons/eth_test.imageset/ETH_test@3x.png b/Cyton/Assets.xcassets/Icons/eth_test.imageset/ETH_test@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/eth_test.imageset/ETH_test@3x.png rename to Cyton/Assets.xcassets/Icons/eth_test.imageset/ETH_test@3x.png diff --git a/Neuron/Assets.xcassets/Icons/icon_changepassword_info.imageset/Contents.json b/Cyton/Assets.xcassets/Icons/icon_changepassword_info.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Icons/icon_changepassword_info.imageset/Contents.json rename to Cyton/Assets.xcassets/Icons/icon_changepassword_info.imageset/Contents.json diff --git "a/Neuron/Assets.xcassets/Icons/icon_changepassword_info.imageset/\350\255\246\345\221\212.png" "b/Cyton/Assets.xcassets/Icons/icon_changepassword_info.imageset/\350\255\246\345\221\212.png" similarity index 100% rename from "Neuron/Assets.xcassets/Icons/icon_changepassword_info.imageset/\350\255\246\345\221\212.png" rename to "Cyton/Assets.xcassets/Icons/icon_changepassword_info.imageset/\350\255\246\345\221\212.png" diff --git a/Neuron/Assets.xcassets/Icons/icon_refresh.imageset/Contents.json b/Cyton/Assets.xcassets/Icons/icon_refresh.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Icons/icon_refresh.imageset/Contents.json rename to Cyton/Assets.xcassets/Icons/icon_refresh.imageset/Contents.json diff --git "a/Neuron/Assets.xcassets/Icons/icon_refresh.imageset/\345\210\267\346\226\260.png" "b/Cyton/Assets.xcassets/Icons/icon_refresh.imageset/\345\210\267\346\226\260.png" similarity index 100% rename from "Neuron/Assets.xcassets/Icons/icon_refresh.imageset/\345\210\267\346\226\260.png" rename to "Cyton/Assets.xcassets/Icons/icon_refresh.imageset/\345\210\267\346\226\260.png" diff --git a/Neuron/Assets.xcassets/Icons/icon_wallet_add.imageset/Contents.json b/Cyton/Assets.xcassets/Icons/icon_wallet_add.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Icons/icon_wallet_add.imageset/Contents.json rename to Cyton/Assets.xcassets/Icons/icon_wallet_add.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Icons/icon_wallet_add.imageset/Group 3.png b/Cyton/Assets.xcassets/Icons/icon_wallet_add.imageset/Group 3.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/icon_wallet_add.imageset/Group 3.png rename to Cyton/Assets.xcassets/Icons/icon_wallet_add.imageset/Group 3.png diff --git a/Neuron/Assets.xcassets/Icons/icon_wallet_qrcode.imageset/Contents.json b/Cyton/Assets.xcassets/Icons/icon_wallet_qrcode.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Icons/icon_wallet_qrcode.imageset/Contents.json rename to Cyton/Assets.xcassets/Icons/icon_wallet_qrcode.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Icons/icon_wallet_qrcode.imageset/Group 6.png b/Cyton/Assets.xcassets/Icons/icon_wallet_qrcode.imageset/Group 6.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/icon_wallet_qrcode.imageset/Group 6.png rename to Cyton/Assets.xcassets/Icons/icon_wallet_qrcode.imageset/Group 6.png diff --git a/Neuron/Assets.xcassets/Icons/icon_wallet_switch.imageset/Contents.json b/Cyton/Assets.xcassets/Icons/icon_wallet_switch.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Icons/icon_wallet_switch.imageset/Contents.json rename to Cyton/Assets.xcassets/Icons/icon_wallet_switch.imageset/Contents.json diff --git "a/Neuron/Assets.xcassets/Icons/icon_wallet_switch.imageset/\345\210\207\346\215\242 (2).png" "b/Cyton/Assets.xcassets/Icons/icon_wallet_switch.imageset/\345\210\207\346\215\242 (2).png" similarity index 100% rename from "Neuron/Assets.xcassets/Icons/icon_wallet_switch.imageset/\345\210\207\346\215\242 (2).png" rename to "Cyton/Assets.xcassets/Icons/icon_wallet_switch.imageset/\345\210\207\346\215\242 (2).png" diff --git a/Neuron/Assets.xcassets/Icons/icon_wallet_trans.imageset/Contents.json b/Cyton/Assets.xcassets/Icons/icon_wallet_trans.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Icons/icon_wallet_trans.imageset/Contents.json rename to Cyton/Assets.xcassets/Icons/icon_wallet_trans.imageset/Contents.json diff --git "a/Neuron/Assets.xcassets/Icons/icon_wallet_trans.imageset/\345\275\242\347\212\266.png" "b/Cyton/Assets.xcassets/Icons/icon_wallet_trans.imageset/\345\275\242\347\212\266.png" similarity index 100% rename from "Neuron/Assets.xcassets/Icons/icon_wallet_trans.imageset/\345\275\242\347\212\266.png" rename to "Cyton/Assets.xcassets/Icons/icon_wallet_trans.imageset/\345\275\242\347\212\266.png" diff --git a/Neuron/Assets.xcassets/Icons/import_wallet.imageset/Contents.json b/Cyton/Assets.xcassets/Icons/import_wallet.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Icons/import_wallet.imageset/Contents.json rename to Cyton/Assets.xcassets/Icons/import_wallet.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Icons/import_wallet.imageset/importWallet@2x.png b/Cyton/Assets.xcassets/Icons/import_wallet.imageset/importWallet@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/import_wallet.imageset/importWallet@2x.png rename to Cyton/Assets.xcassets/Icons/import_wallet.imageset/importWallet@2x.png diff --git a/Neuron/Assets.xcassets/Icons/import_wallet.imageset/importWallet@3x.png b/Cyton/Assets.xcassets/Icons/import_wallet.imageset/importWallet@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/import_wallet.imageset/importWallet@3x.png rename to Cyton/Assets.xcassets/Icons/import_wallet.imageset/importWallet@3x.png diff --git a/Neuron/Assets.xcassets/Icons/neuron_nervos.imageset/Contents.json b/Cyton/Assets.xcassets/Icons/neuron_nervos.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Icons/neuron_nervos.imageset/Contents.json rename to Cyton/Assets.xcassets/Icons/neuron_nervos.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Icons/neuron_nervos.imageset/neuron_nervos@2x.png b/Cyton/Assets.xcassets/Icons/neuron_nervos.imageset/neuron_nervos@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/neuron_nervos.imageset/neuron_nervos@2x.png rename to Cyton/Assets.xcassets/Icons/neuron_nervos.imageset/neuron_nervos@2x.png diff --git a/Neuron/Assets.xcassets/Icons/neuron_nervos.imageset/neuron_nervos@3x.png b/Cyton/Assets.xcassets/Icons/neuron_nervos.imageset/neuron_nervos@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/neuron_nervos.imageset/neuron_nervos@3x.png rename to Cyton/Assets.xcassets/Icons/neuron_nervos.imageset/neuron_nervos@3x.png diff --git a/Neuron/Assets.xcassets/Icons/qr_code.imageset/Contents.json b/Cyton/Assets.xcassets/Icons/qr_code.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Icons/qr_code.imageset/Contents.json rename to Cyton/Assets.xcassets/Icons/qr_code.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Icons/qr_code.imageset/qrCode.png b/Cyton/Assets.xcassets/Icons/qr_code.imageset/qrCode.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/qr_code.imageset/qrCode.png rename to Cyton/Assets.xcassets/Icons/qr_code.imageset/qrCode.png diff --git a/Neuron/Assets.xcassets/Icons/qr_code.imageset/qrCode@2x.png b/Cyton/Assets.xcassets/Icons/qr_code.imageset/qrCode@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/qr_code.imageset/qrCode@2x.png rename to Cyton/Assets.xcassets/Icons/qr_code.imageset/qrCode@2x.png diff --git a/Neuron/Assets.xcassets/Icons/qr_code.imageset/qrCode@3x.png b/Cyton/Assets.xcassets/Icons/qr_code.imageset/qrCode@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/qr_code.imageset/qrCode@3x.png rename to Cyton/Assets.xcassets/Icons/qr_code.imageset/qrCode@3x.png diff --git a/Neuron/Assets.xcassets/Icons/search_left.imageset/Contents.json b/Cyton/Assets.xcassets/Icons/search_left.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Icons/search_left.imageset/Contents.json rename to Cyton/Assets.xcassets/Icons/search_left.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Icons/search_left.imageset/search_left.png b/Cyton/Assets.xcassets/Icons/search_left.imageset/search_left.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/search_left.imageset/search_left.png rename to Cyton/Assets.xcassets/Icons/search_left.imageset/search_left.png diff --git a/Neuron/Assets.xcassets/Icons/search_left.imageset/search_left@2x.png b/Cyton/Assets.xcassets/Icons/search_left.imageset/search_left@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/search_left.imageset/search_left@2x.png rename to Cyton/Assets.xcassets/Icons/search_left.imageset/search_left@2x.png diff --git a/Neuron/Assets.xcassets/Icons/search_left.imageset/search_left@3x.png b/Cyton/Assets.xcassets/Icons/search_left.imageset/search_left@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/search_left.imageset/search_left@3x.png rename to Cyton/Assets.xcassets/Icons/search_left.imageset/search_left@3x.png diff --git a/Cyton/Assets.xcassets/Icons/select_chain.imageset/Contents.json b/Cyton/Assets.xcassets/Icons/select_chain.imageset/Contents.json new file mode 100644 index 00000000..98e8436c --- /dev/null +++ b/Cyton/Assets.xcassets/Icons/select_chain.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "select_chain@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "select_chain@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Cyton/Assets.xcassets/Icons/select_chain.imageset/select_chain@2x.png b/Cyton/Assets.xcassets/Icons/select_chain.imageset/select_chain@2x.png new file mode 100644 index 00000000..cb5f4f05 Binary files /dev/null and b/Cyton/Assets.xcassets/Icons/select_chain.imageset/select_chain@2x.png differ diff --git a/Cyton/Assets.xcassets/Icons/select_chain.imageset/select_chain@3x.png b/Cyton/Assets.xcassets/Icons/select_chain.imageset/select_chain@3x.png new file mode 100644 index 00000000..227beb48 Binary files /dev/null and b/Cyton/Assets.xcassets/Icons/select_chain.imageset/select_chain@3x.png differ diff --git a/Neuron/Assets.xcassets/Icons/select_on.imageset/Contents.json b/Cyton/Assets.xcassets/Icons/select_on.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Icons/select_on.imageset/Contents.json rename to Cyton/Assets.xcassets/Icons/select_on.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Icons/select_on.imageset/select_on.png b/Cyton/Assets.xcassets/Icons/select_on.imageset/select_on.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/select_on.imageset/select_on.png rename to Cyton/Assets.xcassets/Icons/select_on.imageset/select_on.png diff --git a/Neuron/Assets.xcassets/Icons/select_on.imageset/select_on@2x.png b/Cyton/Assets.xcassets/Icons/select_on.imageset/select_on@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/select_on.imageset/select_on@2x.png rename to Cyton/Assets.xcassets/Icons/select_on.imageset/select_on@2x.png diff --git a/Neuron/Assets.xcassets/Icons/select_on.imageset/select_on@3x.png b/Cyton/Assets.xcassets/Icons/select_on.imageset/select_on@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/select_on.imageset/select_on@3x.png rename to Cyton/Assets.xcassets/Icons/select_on.imageset/select_on@3x.png diff --git a/Neuron/Assets.xcassets/Icons/state_off.imageset/Contents.json b/Cyton/Assets.xcassets/Icons/state_off.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Icons/state_off.imageset/Contents.json rename to Cyton/Assets.xcassets/Icons/state_off.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Icons/state_off.imageset/state_off.png b/Cyton/Assets.xcassets/Icons/state_off.imageset/state_off.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/state_off.imageset/state_off.png rename to Cyton/Assets.xcassets/Icons/state_off.imageset/state_off.png diff --git a/Neuron/Assets.xcassets/Icons/state_off.imageset/state_off@2x.png b/Cyton/Assets.xcassets/Icons/state_off.imageset/state_off@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/state_off.imageset/state_off@2x.png rename to Cyton/Assets.xcassets/Icons/state_off.imageset/state_off@2x.png diff --git a/Neuron/Assets.xcassets/Icons/state_off.imageset/state_off@3x.png b/Cyton/Assets.xcassets/Icons/state_off.imageset/state_off@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/state_off.imageset/state_off@3x.png rename to Cyton/Assets.xcassets/Icons/state_off.imageset/state_off@3x.png diff --git a/Neuron/Assets.xcassets/Icons/state_on.imageset/Contents.json b/Cyton/Assets.xcassets/Icons/state_on.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Icons/state_on.imageset/Contents.json rename to Cyton/Assets.xcassets/Icons/state_on.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Icons/state_on.imageset/state_on.png b/Cyton/Assets.xcassets/Icons/state_on.imageset/state_on.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/state_on.imageset/state_on.png rename to Cyton/Assets.xcassets/Icons/state_on.imageset/state_on.png diff --git a/Neuron/Assets.xcassets/Icons/state_on.imageset/state_on@2x.png b/Cyton/Assets.xcassets/Icons/state_on.imageset/state_on@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/state_on.imageset/state_on@2x.png rename to Cyton/Assets.xcassets/Icons/state_on.imageset/state_on@2x.png diff --git a/Neuron/Assets.xcassets/Icons/state_on.imageset/state_on@3x.png b/Cyton/Assets.xcassets/Icons/state_on.imageset/state_on@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/state_on.imageset/state_on@3x.png rename to Cyton/Assets.xcassets/Icons/state_on.imageset/state_on@3x.png diff --git a/Neuron/Assets.xcassets/Icons/success.imageset/Contents.json b/Cyton/Assets.xcassets/Icons/success.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Icons/success.imageset/Contents.json rename to Cyton/Assets.xcassets/Icons/success.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Icons/success.imageset/success@2x.png b/Cyton/Assets.xcassets/Icons/success.imageset/success@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/success.imageset/success@2x.png rename to Cyton/Assets.xcassets/Icons/success.imageset/success@2x.png diff --git a/Neuron/Assets.xcassets/Icons/success.imageset/success@3x.png b/Cyton/Assets.xcassets/Icons/success.imageset/success@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/success.imageset/success@3x.png rename to Cyton/Assets.xcassets/Icons/success.imageset/success@3x.png diff --git a/Neuron/Assets.xcassets/Icons/transaction_failed.imageset/Contents.json b/Cyton/Assets.xcassets/Icons/transaction_failed.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Icons/transaction_failed.imageset/Contents.json rename to Cyton/Assets.xcassets/Icons/transaction_failed.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Icons/transaction_failed.imageset/transaction_failed@2x.png b/Cyton/Assets.xcassets/Icons/transaction_failed.imageset/transaction_failed@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/transaction_failed.imageset/transaction_failed@2x.png rename to Cyton/Assets.xcassets/Icons/transaction_failed.imageset/transaction_failed@2x.png diff --git a/Neuron/Assets.xcassets/Icons/transaction_failed.imageset/transaction_failed@3x.png b/Cyton/Assets.xcassets/Icons/transaction_failed.imageset/transaction_failed@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/transaction_failed.imageset/transaction_failed@3x.png rename to Cyton/Assets.xcassets/Icons/transaction_failed.imageset/transaction_failed@3x.png diff --git a/Neuron/Assets.xcassets/Icons/transaction_success.imageset/Contents.json b/Cyton/Assets.xcassets/Icons/transaction_success.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Icons/transaction_success.imageset/Contents.json rename to Cyton/Assets.xcassets/Icons/transaction_success.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Icons/transaction_success.imageset/transaction_success@2x.png b/Cyton/Assets.xcassets/Icons/transaction_success.imageset/transaction_success@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/transaction_success.imageset/transaction_success@2x.png rename to Cyton/Assets.xcassets/Icons/transaction_success.imageset/transaction_success@2x.png diff --git a/Neuron/Assets.xcassets/Icons/transaction_success.imageset/transaction_success@3x.png b/Cyton/Assets.xcassets/Icons/transaction_success.imageset/transaction_success@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/transaction_success.imageset/transaction_success@3x.png rename to Cyton/Assets.xcassets/Icons/transaction_success.imageset/transaction_success@3x.png diff --git a/Neuron/Assets.xcassets/Icons/transferring.imageset/Contents.json b/Cyton/Assets.xcassets/Icons/transferring.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Icons/transferring.imageset/Contents.json rename to Cyton/Assets.xcassets/Icons/transferring.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Icons/transferring.imageset/transferring@2x.png b/Cyton/Assets.xcassets/Icons/transferring.imageset/transferring@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/transferring.imageset/transferring@2x.png rename to Cyton/Assets.xcassets/Icons/transferring.imageset/transferring@2x.png diff --git a/Neuron/Assets.xcassets/Icons/transferring.imageset/transferring@3x.png b/Cyton/Assets.xcassets/Icons/transferring.imageset/transferring@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/transferring.imageset/transferring@3x.png rename to Cyton/Assets.xcassets/Icons/transferring.imageset/transferring@3x.png diff --git a/Neuron/Assets.xcassets/Icons/tx_status.imageset/Contents.json b/Cyton/Assets.xcassets/Icons/tx_status.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Icons/tx_status.imageset/Contents.json rename to Cyton/Assets.xcassets/Icons/tx_status.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Icons/tx_status.imageset/Oval 3.png b/Cyton/Assets.xcassets/Icons/tx_status.imageset/Oval 3.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/tx_status.imageset/Oval 3.png rename to Cyton/Assets.xcassets/Icons/tx_status.imageset/Oval 3.png diff --git a/Neuron/Assets.xcassets/Icons/tx_status.imageset/Oval 3@2x.png b/Cyton/Assets.xcassets/Icons/tx_status.imageset/Oval 3@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/tx_status.imageset/Oval 3@2x.png rename to Cyton/Assets.xcassets/Icons/tx_status.imageset/Oval 3@2x.png diff --git a/Neuron/Assets.xcassets/Icons/tx_status.imageset/Oval 3@3x.png b/Cyton/Assets.xcassets/Icons/tx_status.imageset/Oval 3@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/tx_status.imageset/Oval 3@3x.png rename to Cyton/Assets.xcassets/Icons/tx_status.imageset/Oval 3@3x.png diff --git a/Neuron/Assets.xcassets/Icons/tx_success.imageset/Contents.json b/Cyton/Assets.xcassets/Icons/tx_success.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Icons/tx_success.imageset/Contents.json rename to Cyton/Assets.xcassets/Icons/tx_success.imageset/Contents.json diff --git "a/Neuron/Assets.xcassets/Icons/tx_success.imageset/\346\210\220\345\212\237.png" "b/Cyton/Assets.xcassets/Icons/tx_success.imageset/\346\210\220\345\212\237.png" similarity index 100% rename from "Neuron/Assets.xcassets/Icons/tx_success.imageset/\346\210\220\345\212\237.png" rename to "Cyton/Assets.xcassets/Icons/tx_success.imageset/\346\210\220\345\212\237.png" diff --git "a/Neuron/Assets.xcassets/Icons/tx_success.imageset/\346\210\220\345\212\237@2x.png" "b/Cyton/Assets.xcassets/Icons/tx_success.imageset/\346\210\220\345\212\237@2x.png" similarity index 100% rename from "Neuron/Assets.xcassets/Icons/tx_success.imageset/\346\210\220\345\212\237@2x.png" rename to "Cyton/Assets.xcassets/Icons/tx_success.imageset/\346\210\220\345\212\237@2x.png" diff --git "a/Neuron/Assets.xcassets/Icons/tx_success.imageset/\346\210\220\345\212\237@3x.png" "b/Cyton/Assets.xcassets/Icons/tx_success.imageset/\346\210\220\345\212\237@3x.png" similarity index 100% rename from "Neuron/Assets.xcassets/Icons/tx_success.imageset/\346\210\220\345\212\237@3x.png" rename to "Cyton/Assets.xcassets/Icons/tx_success.imageset/\346\210\220\345\212\237@3x.png" diff --git a/Neuron/Assets.xcassets/Icons/wallet_detail.imageset/Contents.json b/Cyton/Assets.xcassets/Icons/wallet_detail.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Icons/wallet_detail.imageset/Contents.json rename to Cyton/Assets.xcassets/Icons/wallet_detail.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Icons/wallet_detail.imageset/wallet_detail@2x.png b/Cyton/Assets.xcassets/Icons/wallet_detail.imageset/wallet_detail@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/wallet_detail.imageset/wallet_detail@2x.png rename to Cyton/Assets.xcassets/Icons/wallet_detail.imageset/wallet_detail@2x.png diff --git a/Neuron/Assets.xcassets/Icons/wallet_detail.imageset/wallet_detail@3x.png b/Cyton/Assets.xcassets/Icons/wallet_detail.imageset/wallet_detail@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/wallet_detail.imageset/wallet_detail@3x.png rename to Cyton/Assets.xcassets/Icons/wallet_detail.imageset/wallet_detail@3x.png diff --git a/Neuron/Assets.xcassets/Icons/wallet_switch_arrow.imageset/Contents.json b/Cyton/Assets.xcassets/Icons/wallet_switch_arrow.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Icons/wallet_switch_arrow.imageset/Contents.json rename to Cyton/Assets.xcassets/Icons/wallet_switch_arrow.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Icons/wallet_switch_arrow.imageset/wallet_switch@2x.png b/Cyton/Assets.xcassets/Icons/wallet_switch_arrow.imageset/wallet_switch@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/wallet_switch_arrow.imageset/wallet_switch@2x.png rename to Cyton/Assets.xcassets/Icons/wallet_switch_arrow.imageset/wallet_switch@2x.png diff --git a/Neuron/Assets.xcassets/Icons/wallet_switch_arrow.imageset/wallet_switch@3x.png b/Cyton/Assets.xcassets/Icons/wallet_switch_arrow.imageset/wallet_switch@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/wallet_switch_arrow.imageset/wallet_switch@3x.png rename to Cyton/Assets.xcassets/Icons/wallet_switch_arrow.imageset/wallet_switch@3x.png diff --git a/Neuron/Assets.xcassets/Icons/warn.imageset/Contents.json b/Cyton/Assets.xcassets/Icons/warn.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Icons/warn.imageset/Contents.json rename to Cyton/Assets.xcassets/Icons/warn.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Icons/warn.imageset/warn@2x.png b/Cyton/Assets.xcassets/Icons/warn.imageset/warn@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/warn.imageset/warn@2x.png rename to Cyton/Assets.xcassets/Icons/warn.imageset/warn@2x.png diff --git a/Neuron/Assets.xcassets/Icons/warn.imageset/warn@3x.png b/Cyton/Assets.xcassets/Icons/warn.imageset/warn@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Icons/warn.imageset/warn@3x.png rename to Cyton/Assets.xcassets/Icons/warn.imageset/warn@3x.png diff --git a/Neuron/Assets.xcassets/Launch Screen/Contents.json b/Cyton/Assets.xcassets/Launch Screen/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Launch Screen/Contents.json rename to Cyton/Assets.xcassets/Launch Screen/Contents.json diff --git a/Cyton/Assets.xcassets/Launch Screen/launch_icon.imageset/Contents.json b/Cyton/Assets.xcassets/Launch Screen/launch_icon.imageset/Contents.json new file mode 100644 index 00000000..9997c874 --- /dev/null +++ b/Cyton/Assets.xcassets/Launch Screen/launch_icon.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "launch_icon@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "launch_icon@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Cyton/Assets.xcassets/Launch Screen/launch_icon.imageset/launch_icon@2x.png b/Cyton/Assets.xcassets/Launch Screen/launch_icon.imageset/launch_icon@2x.png new file mode 100644 index 00000000..59d1445c Binary files /dev/null and b/Cyton/Assets.xcassets/Launch Screen/launch_icon.imageset/launch_icon@2x.png differ diff --git a/Cyton/Assets.xcassets/Launch Screen/launch_icon.imageset/launch_icon@3x.png b/Cyton/Assets.xcassets/Launch Screen/launch_icon.imageset/launch_icon@3x.png new file mode 100644 index 00000000..eee17d6c Binary files /dev/null and b/Cyton/Assets.xcassets/Launch Screen/launch_icon.imageset/launch_icon@3x.png differ diff --git a/Neuron/Assets.xcassets/NavigationBar/Contents.json b/Cyton/Assets.xcassets/NavigationBar/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/NavigationBar/Contents.json rename to Cyton/Assets.xcassets/NavigationBar/Contents.json diff --git a/Neuron/Assets.xcassets/NavigationBar/add_wallet_icon.imageset/Contents.json b/Cyton/Assets.xcassets/NavigationBar/add_wallet_icon.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/NavigationBar/add_wallet_icon.imageset/Contents.json rename to Cyton/Assets.xcassets/NavigationBar/add_wallet_icon.imageset/Contents.json diff --git "a/Neuron/Assets.xcassets/NavigationBar/add_wallet_icon.imageset/\346\267\273\345\212\240 \345\212\240\345\217\267 \346\227\240\350\276\271\346\241\206.png" "b/Cyton/Assets.xcassets/NavigationBar/add_wallet_icon.imageset/\346\267\273\345\212\240 \345\212\240\345\217\267 \346\227\240\350\276\271\346\241\206.png" similarity index 100% rename from "Neuron/Assets.xcassets/NavigationBar/add_wallet_icon.imageset/\346\267\273\345\212\240 \345\212\240\345\217\267 \346\227\240\350\276\271\346\241\206.png" rename to "Cyton/Assets.xcassets/NavigationBar/add_wallet_icon.imageset/\346\267\273\345\212\240 \345\212\240\345\217\267 \346\227\240\350\276\271\346\241\206.png" diff --git a/Neuron/Assets.xcassets/Launch Screen/launch_icon.imageset/Contents.json b/Cyton/Assets.xcassets/NavigationBar/icon_share.imageset/Contents.json similarity index 77% rename from Neuron/Assets.xcassets/Launch Screen/launch_icon.imageset/Contents.json rename to Cyton/Assets.xcassets/NavigationBar/icon_share.imageset/Contents.json index c595e1b5..e021396b 100644 --- a/Neuron/Assets.xcassets/Launch Screen/launch_icon.imageset/Contents.json +++ b/Cyton/Assets.xcassets/NavigationBar/icon_share.imageset/Contents.json @@ -6,12 +6,12 @@ }, { "idiom" : "universal", - "filename" : "launchIcon@2x.png", + "filename" : "分享-top@2x.png", "scale" : "2x" }, { "idiom" : "universal", - "filename" : "launchIcon@3x.png", + "filename" : "分享-top@3x.png", "scale" : "3x" } ], diff --git "a/Cyton/Assets.xcassets/NavigationBar/icon_share.imageset/\345\210\206\344\272\253-top@2x.png" "b/Cyton/Assets.xcassets/NavigationBar/icon_share.imageset/\345\210\206\344\272\253-top@2x.png" new file mode 100644 index 00000000..8b07a674 Binary files /dev/null and "b/Cyton/Assets.xcassets/NavigationBar/icon_share.imageset/\345\210\206\344\272\253-top@2x.png" differ diff --git "a/Cyton/Assets.xcassets/NavigationBar/icon_share.imageset/\345\210\206\344\272\253-top@3x.png" "b/Cyton/Assets.xcassets/NavigationBar/icon_share.imageset/\345\210\206\344\272\253-top@3x.png" new file mode 100644 index 00000000..d4686c74 Binary files /dev/null and "b/Cyton/Assets.xcassets/NavigationBar/icon_share.imageset/\345\210\206\344\272\253-top@3x.png" differ diff --git a/Neuron/Assets.xcassets/NavigationBar/nav_add_asset.imageset/Contents.json b/Cyton/Assets.xcassets/NavigationBar/nav_add_asset.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/NavigationBar/nav_add_asset.imageset/Contents.json rename to Cyton/Assets.xcassets/NavigationBar/nav_add_asset.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/NavigationBar/nav_add_asset.imageset/nav_addAsset@2x.png b/Cyton/Assets.xcassets/NavigationBar/nav_add_asset.imageset/nav_addAsset@2x.png similarity index 100% rename from Neuron/Assets.xcassets/NavigationBar/nav_add_asset.imageset/nav_addAsset@2x.png rename to Cyton/Assets.xcassets/NavigationBar/nav_add_asset.imageset/nav_addAsset@2x.png diff --git a/Neuron/Assets.xcassets/NavigationBar/nav_add_asset.imageset/nav_addAsset@3x.png b/Cyton/Assets.xcassets/NavigationBar/nav_add_asset.imageset/nav_addAsset@3x.png similarity index 100% rename from Neuron/Assets.xcassets/NavigationBar/nav_add_asset.imageset/nav_addAsset@3x.png rename to Cyton/Assets.xcassets/NavigationBar/nav_add_asset.imageset/nav_addAsset@3x.png diff --git a/Neuron/Assets.xcassets/NavigationBar/nav_back.imageset/Contents.json b/Cyton/Assets.xcassets/NavigationBar/nav_back.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/NavigationBar/nav_back.imageset/Contents.json rename to Cyton/Assets.xcassets/NavigationBar/nav_back.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/NavigationBar/nav_back.imageset/back2.png b/Cyton/Assets.xcassets/NavigationBar/nav_back.imageset/back2.png similarity index 100% rename from Neuron/Assets.xcassets/NavigationBar/nav_back.imageset/back2.png rename to Cyton/Assets.xcassets/NavigationBar/nav_back.imageset/back2.png diff --git a/Neuron/Assets.xcassets/NavigationBar/nav_close.imageset/Contents.json b/Cyton/Assets.xcassets/NavigationBar/nav_close.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/NavigationBar/nav_close.imageset/Contents.json rename to Cyton/Assets.xcassets/NavigationBar/nav_close.imageset/Contents.json diff --git "a/Neuron/Assets.xcassets/NavigationBar/nav_close.imageset/\345\205\263\351\227\255 (1).png" "b/Cyton/Assets.xcassets/NavigationBar/nav_close.imageset/\345\205\263\351\227\255 (1).png" similarity index 100% rename from "Neuron/Assets.xcassets/NavigationBar/nav_close.imageset/\345\205\263\351\227\255 (1).png" rename to "Cyton/Assets.xcassets/NavigationBar/nav_close.imageset/\345\205\263\351\227\255 (1).png" diff --git a/Neuron/Assets.xcassets/NavigationBar/nav_darkback.imageset/Contents.json b/Cyton/Assets.xcassets/NavigationBar/nav_darkback.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/NavigationBar/nav_darkback.imageset/Contents.json rename to Cyton/Assets.xcassets/NavigationBar/nav_darkback.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/NavigationBar/nav_darkback.imageset/nav_darkback@2x.png b/Cyton/Assets.xcassets/NavigationBar/nav_darkback.imageset/nav_darkback@2x.png similarity index 100% rename from Neuron/Assets.xcassets/NavigationBar/nav_darkback.imageset/nav_darkback@2x.png rename to Cyton/Assets.xcassets/NavigationBar/nav_darkback.imageset/nav_darkback@2x.png diff --git a/Neuron/Assets.xcassets/NavigationBar/nav_darkback.imageset/nav_darkback@3x.png b/Cyton/Assets.xcassets/NavigationBar/nav_darkback.imageset/nav_darkback@3x.png similarity index 100% rename from Neuron/Assets.xcassets/NavigationBar/nav_darkback.imageset/nav_darkback@3x.png rename to Cyton/Assets.xcassets/NavigationBar/nav_darkback.imageset/nav_darkback@3x.png diff --git a/Neuron/Assets.xcassets/NavigationBar/nav_scan.imageset/Contents.json b/Cyton/Assets.xcassets/NavigationBar/nav_scan.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/NavigationBar/nav_scan.imageset/Contents.json rename to Cyton/Assets.xcassets/NavigationBar/nav_scan.imageset/Contents.json diff --git "a/Neuron/Assets.xcassets/NavigationBar/nav_scan.imageset/\346\211\253\347\240\201.png" "b/Cyton/Assets.xcassets/NavigationBar/nav_scan.imageset/\346\211\253\347\240\201.png" similarity index 100% rename from "Neuron/Assets.xcassets/NavigationBar/nav_scan.imageset/\346\211\253\347\240\201.png" rename to "Cyton/Assets.xcassets/NavigationBar/nav_scan.imageset/\346\211\253\347\240\201.png" diff --git a/Neuron/Assets.xcassets/NavigationBar/nav_switch_wallet.imageset/Contents.json b/Cyton/Assets.xcassets/NavigationBar/nav_switch_wallet.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/NavigationBar/nav_switch_wallet.imageset/Contents.json rename to Cyton/Assets.xcassets/NavigationBar/nav_switch_wallet.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/NavigationBar/nav_switch_wallet.imageset/switchWallet@2x.png b/Cyton/Assets.xcassets/NavigationBar/nav_switch_wallet.imageset/switchWallet@2x.png similarity index 100% rename from Neuron/Assets.xcassets/NavigationBar/nav_switch_wallet.imageset/switchWallet@2x.png rename to Cyton/Assets.xcassets/NavigationBar/nav_switch_wallet.imageset/switchWallet@2x.png diff --git a/Neuron/Assets.xcassets/NavigationBar/nav_switch_wallet.imageset/switchWallet@3x.png b/Cyton/Assets.xcassets/NavigationBar/nav_switch_wallet.imageset/switchWallet@3x.png similarity index 100% rename from Neuron/Assets.xcassets/NavigationBar/nav_switch_wallet.imageset/switchWallet@3x.png rename to Cyton/Assets.xcassets/NavigationBar/nav_switch_wallet.imageset/switchWallet@3x.png diff --git a/Neuron/Assets.xcassets/NavigationBar/pull_down.imageset/Contents.json b/Cyton/Assets.xcassets/NavigationBar/pull_down.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/NavigationBar/pull_down.imageset/Contents.json rename to Cyton/Assets.xcassets/NavigationBar/pull_down.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/NavigationBar/pull_down.imageset/pull_down@2x.png b/Cyton/Assets.xcassets/NavigationBar/pull_down.imageset/pull_down@2x.png similarity index 100% rename from Neuron/Assets.xcassets/NavigationBar/pull_down.imageset/pull_down@2x.png rename to Cyton/Assets.xcassets/NavigationBar/pull_down.imageset/pull_down@2x.png diff --git a/Neuron/Assets.xcassets/NavigationBar/pull_down.imageset/pull_down@3x.png b/Cyton/Assets.xcassets/NavigationBar/pull_down.imageset/pull_down@3x.png similarity index 100% rename from Neuron/Assets.xcassets/NavigationBar/pull_down.imageset/pull_down@3x.png rename to Cyton/Assets.xcassets/NavigationBar/pull_down.imageset/pull_down@3x.png diff --git a/Neuron/Assets.xcassets/NavigationBar/search_dapp.imageset/Contents.json b/Cyton/Assets.xcassets/NavigationBar/search_dapp.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/NavigationBar/search_dapp.imageset/Contents.json rename to Cyton/Assets.xcassets/NavigationBar/search_dapp.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/NavigationBar/search_dapp.imageset/search_dapp@2x.png b/Cyton/Assets.xcassets/NavigationBar/search_dapp.imageset/search_dapp@2x.png similarity index 100% rename from Neuron/Assets.xcassets/NavigationBar/search_dapp.imageset/search_dapp@2x.png rename to Cyton/Assets.xcassets/NavigationBar/search_dapp.imageset/search_dapp@2x.png diff --git a/Neuron/Assets.xcassets/NavigationBar/search_dapp.imageset/search_dapp@3x.png b/Cyton/Assets.xcassets/NavigationBar/search_dapp.imageset/search_dapp@3x.png similarity index 100% rename from Neuron/Assets.xcassets/NavigationBar/search_dapp.imageset/search_dapp@3x.png rename to Cyton/Assets.xcassets/NavigationBar/search_dapp.imageset/search_dapp@3x.png diff --git a/Neuron/Assets.xcassets/NavigationBar/switch_wallet.imageset/Contents.json b/Cyton/Assets.xcassets/NavigationBar/switch_wallet.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/NavigationBar/switch_wallet.imageset/Contents.json rename to Cyton/Assets.xcassets/NavigationBar/switch_wallet.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/NavigationBar/switch_wallet.imageset/switch_wallet@2x.png b/Cyton/Assets.xcassets/NavigationBar/switch_wallet.imageset/switch_wallet@2x.png similarity index 100% rename from Neuron/Assets.xcassets/NavigationBar/switch_wallet.imageset/switch_wallet@2x.png rename to Cyton/Assets.xcassets/NavigationBar/switch_wallet.imageset/switch_wallet@2x.png diff --git a/Neuron/Assets.xcassets/NavigationBar/switch_wallet.imageset/switch_wallet@3x.png b/Cyton/Assets.xcassets/NavigationBar/switch_wallet.imageset/switch_wallet@3x.png similarity index 100% rename from Neuron/Assets.xcassets/NavigationBar/switch_wallet.imageset/switch_wallet@3x.png rename to Cyton/Assets.xcassets/NavigationBar/switch_wallet.imageset/switch_wallet@3x.png diff --git a/Neuron/Assets.xcassets/NavigationBar/switch_wallet_icon.imageset/Contents.json b/Cyton/Assets.xcassets/NavigationBar/switch_wallet_icon.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/NavigationBar/switch_wallet_icon.imageset/Contents.json rename to Cyton/Assets.xcassets/NavigationBar/switch_wallet_icon.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/NavigationBar/switch_wallet_icon.imageset/Shape.png b/Cyton/Assets.xcassets/NavigationBar/switch_wallet_icon.imageset/Shape.png similarity index 100% rename from Neuron/Assets.xcassets/NavigationBar/switch_wallet_icon.imageset/Shape.png rename to Cyton/Assets.xcassets/NavigationBar/switch_wallet_icon.imageset/Shape.png diff --git a/Neuron/Assets.xcassets/NavigationBar/wallet_qr_code.imageset/Contents.json b/Cyton/Assets.xcassets/NavigationBar/wallet_qr_code.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/NavigationBar/wallet_qr_code.imageset/Contents.json rename to Cyton/Assets.xcassets/NavigationBar/wallet_qr_code.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/NavigationBar/wallet_qr_code.imageset/walletQRCode@2x.png b/Cyton/Assets.xcassets/NavigationBar/wallet_qr_code.imageset/walletQRCode@2x.png similarity index 100% rename from Neuron/Assets.xcassets/NavigationBar/wallet_qr_code.imageset/walletQRCode@2x.png rename to Cyton/Assets.xcassets/NavigationBar/wallet_qr_code.imageset/walletQRCode@2x.png diff --git a/Neuron/Assets.xcassets/NavigationBar/wallet_qr_code.imageset/walletQRCode@3x.png b/Cyton/Assets.xcassets/NavigationBar/wallet_qr_code.imageset/walletQRCode@3x.png similarity index 100% rename from Neuron/Assets.xcassets/NavigationBar/wallet_qr_code.imageset/walletQRCode@3x.png rename to Cyton/Assets.xcassets/NavigationBar/wallet_qr_code.imageset/walletQRCode@3x.png diff --git a/Neuron/Assets.xcassets/Settings/Contents.json b/Cyton/Assets.xcassets/Settings/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Settings/Contents.json rename to Cyton/Assets.xcassets/Settings/Contents.json diff --git a/Neuron/Assets.xcassets/Settings/aboutus.imageset/Contents.json b/Cyton/Assets.xcassets/Settings/aboutus.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Settings/aboutus.imageset/Contents.json rename to Cyton/Assets.xcassets/Settings/aboutus.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Settings/aboutus.imageset/aboutus@2x.png b/Cyton/Assets.xcassets/Settings/aboutus.imageset/aboutus@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Settings/aboutus.imageset/aboutus@2x.png rename to Cyton/Assets.xcassets/Settings/aboutus.imageset/aboutus@2x.png diff --git a/Neuron/Assets.xcassets/Settings/aboutus.imageset/aboutus@3x.png b/Cyton/Assets.xcassets/Settings/aboutus.imageset/aboutus@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Settings/aboutus.imageset/aboutus@3x.png rename to Cyton/Assets.xcassets/Settings/aboutus.imageset/aboutus@3x.png diff --git a/Neuron/Assets.xcassets/Settings/cita.imageset/Contents.json b/Cyton/Assets.xcassets/Settings/cita.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Settings/cita.imageset/Contents.json rename to Cyton/Assets.xcassets/Settings/cita.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Settings/cita.imageset/cita@2x.png b/Cyton/Assets.xcassets/Settings/cita.imageset/cita@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Settings/cita.imageset/cita@2x.png rename to Cyton/Assets.xcassets/Settings/cita.imageset/cita@2x.png diff --git a/Neuron/Assets.xcassets/Settings/cita.imageset/cita@3x.png b/Cyton/Assets.xcassets/Settings/cita.imageset/cita@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Settings/cita.imageset/cita@3x.png rename to Cyton/Assets.xcassets/Settings/cita.imageset/cita@3x.png diff --git a/Neuron/Assets.xcassets/Settings/contactus.imageset/Contents.json b/Cyton/Assets.xcassets/Settings/contactus.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Settings/contactus.imageset/Contents.json rename to Cyton/Assets.xcassets/Settings/contactus.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Settings/contactus.imageset/contactus@2x.png b/Cyton/Assets.xcassets/Settings/contactus.imageset/contactus@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Settings/contactus.imageset/contactus@2x.png rename to Cyton/Assets.xcassets/Settings/contactus.imageset/contactus@2x.png diff --git a/Neuron/Assets.xcassets/Settings/contactus.imageset/contactus@3x.png b/Cyton/Assets.xcassets/Settings/contactus.imageset/contactus@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Settings/contactus.imageset/contactus@3x.png rename to Cyton/Assets.xcassets/Settings/contactus.imageset/contactus@3x.png diff --git a/Neuron/Assets.xcassets/Settings/currency.imageset/Contents.json b/Cyton/Assets.xcassets/Settings/currency.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Settings/currency.imageset/Contents.json rename to Cyton/Assets.xcassets/Settings/currency.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Settings/currency.imageset/currency@2x.png b/Cyton/Assets.xcassets/Settings/currency.imageset/currency@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Settings/currency.imageset/currency@2x.png rename to Cyton/Assets.xcassets/Settings/currency.imageset/currency@2x.png diff --git a/Neuron/Assets.xcassets/Settings/currency.imageset/currency@3x.png b/Cyton/Assets.xcassets/Settings/currency.imageset/currency@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Settings/currency.imageset/currency@3x.png rename to Cyton/Assets.xcassets/Settings/currency.imageset/currency@3x.png diff --git a/Neuron/Assets.xcassets/Settings/fingerprint_setup.imageset/Contents.json b/Cyton/Assets.xcassets/Settings/fingerprint_setup.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Settings/fingerprint_setup.imageset/Contents.json rename to Cyton/Assets.xcassets/Settings/fingerprint_setup.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Settings/fingerprint_setup.imageset/fingerprint_setup@2x.png b/Cyton/Assets.xcassets/Settings/fingerprint_setup.imageset/fingerprint_setup@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Settings/fingerprint_setup.imageset/fingerprint_setup@2x.png rename to Cyton/Assets.xcassets/Settings/fingerprint_setup.imageset/fingerprint_setup@2x.png diff --git a/Neuron/Assets.xcassets/Settings/fingerprint_setup.imageset/fingerprint_setup@3x.png b/Cyton/Assets.xcassets/Settings/fingerprint_setup.imageset/fingerprint_setup@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Settings/fingerprint_setup.imageset/fingerprint_setup@3x.png rename to Cyton/Assets.xcassets/Settings/fingerprint_setup.imageset/fingerprint_setup@3x.png diff --git a/Neuron/Assets.xcassets/Settings/forums.imageset/Contents.json b/Cyton/Assets.xcassets/Settings/forums.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Settings/forums.imageset/Contents.json rename to Cyton/Assets.xcassets/Settings/forums.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Settings/forums.imageset/Group 11@2x.png b/Cyton/Assets.xcassets/Settings/forums.imageset/Group 11@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Settings/forums.imageset/Group 11@2x.png rename to Cyton/Assets.xcassets/Settings/forums.imageset/Group 11@2x.png diff --git a/Neuron/Assets.xcassets/Settings/forums.imageset/Group 11@3x.png b/Cyton/Assets.xcassets/Settings/forums.imageset/Group 11@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Settings/forums.imageset/Group 11@3x.png rename to Cyton/Assets.xcassets/Settings/forums.imageset/Group 11@3x.png diff --git a/Neuron/Assets.xcassets/Settings/infua.imageset/Contents.json b/Cyton/Assets.xcassets/Settings/infua.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Settings/infua.imageset/Contents.json rename to Cyton/Assets.xcassets/Settings/infua.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Settings/infua.imageset/infua@2x.png b/Cyton/Assets.xcassets/Settings/infua.imageset/infua@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Settings/infua.imageset/infua@2x.png rename to Cyton/Assets.xcassets/Settings/infua.imageset/infua@2x.png diff --git a/Neuron/Assets.xcassets/Settings/infua.imageset/infua@3x.png b/Cyton/Assets.xcassets/Settings/infua.imageset/infua@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Settings/infua.imageset/infua@3x.png rename to Cyton/Assets.xcassets/Settings/infua.imageset/infua@3x.png diff --git a/Neuron/Assets.xcassets/Settings/nervos_network.imageset/Contents.json b/Cyton/Assets.xcassets/Settings/nervos_network.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Settings/nervos_network.imageset/Contents.json rename to Cyton/Assets.xcassets/Settings/nervos_network.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Settings/nervos_network.imageset/nervos_network@2x.png b/Cyton/Assets.xcassets/Settings/nervos_network.imageset/nervos_network@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Settings/nervos_network.imageset/nervos_network@2x.png rename to Cyton/Assets.xcassets/Settings/nervos_network.imageset/nervos_network@2x.png diff --git a/Neuron/Assets.xcassets/Settings/nervos_network.imageset/nervos_network@3x.png b/Cyton/Assets.xcassets/Settings/nervos_network.imageset/nervos_network@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Settings/nervos_network.imageset/nervos_network@3x.png rename to Cyton/Assets.xcassets/Settings/nervos_network.imageset/nervos_network@3x.png diff --git a/Neuron/Assets.xcassets/Settings/opensea.imageset/Contents.json b/Cyton/Assets.xcassets/Settings/opensea.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Settings/opensea.imageset/Contents.json rename to Cyton/Assets.xcassets/Settings/opensea.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Settings/opensea.imageset/openSea@2x.png b/Cyton/Assets.xcassets/Settings/opensea.imageset/openSea@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Settings/opensea.imageset/openSea@2x.png rename to Cyton/Assets.xcassets/Settings/opensea.imageset/openSea@2x.png diff --git a/Neuron/Assets.xcassets/Settings/opensea.imageset/openSea@3x.png b/Cyton/Assets.xcassets/Settings/opensea.imageset/openSea@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Settings/opensea.imageset/openSea@3x.png rename to Cyton/Assets.xcassets/Settings/opensea.imageset/openSea@3x.png diff --git a/Neuron/Assets.xcassets/Settings/peckshield.imageset/Contents.json b/Cyton/Assets.xcassets/Settings/peckshield.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Settings/peckshield.imageset/Contents.json rename to Cyton/Assets.xcassets/Settings/peckshield.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Settings/peckshield.imageset/peckshield@2x.png b/Cyton/Assets.xcassets/Settings/peckshield.imageset/peckshield@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Settings/peckshield.imageset/peckshield@2x.png rename to Cyton/Assets.xcassets/Settings/peckshield.imageset/peckshield@2x.png diff --git a/Neuron/Assets.xcassets/Settings/peckshield.imageset/peckshield@3x.png b/Cyton/Assets.xcassets/Settings/peckshield.imageset/peckshield@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Settings/peckshield.imageset/peckshield@3x.png rename to Cyton/Assets.xcassets/Settings/peckshield.imageset/peckshield@3x.png diff --git a/Neuron/Assets.xcassets/Settings/service_terms.imageset/Contents.json b/Cyton/Assets.xcassets/Settings/service_terms.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Settings/service_terms.imageset/Contents.json rename to Cyton/Assets.xcassets/Settings/service_terms.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Settings/service_terms.imageset/service_terms@2x.png b/Cyton/Assets.xcassets/Settings/service_terms.imageset/service_terms@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Settings/service_terms.imageset/service_terms@2x.png rename to Cyton/Assets.xcassets/Settings/service_terms.imageset/service_terms@2x.png diff --git a/Neuron/Assets.xcassets/Settings/service_terms.imageset/service_terms@3x.png b/Cyton/Assets.xcassets/Settings/service_terms.imageset/service_terms@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Settings/service_terms.imageset/service_terms@3x.png rename to Cyton/Assets.xcassets/Settings/service_terms.imageset/service_terms@3x.png diff --git a/Neuron/Assets.xcassets/Settings/source_code.imageset/Contents.json b/Cyton/Assets.xcassets/Settings/source_code.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Settings/source_code.imageset/Contents.json rename to Cyton/Assets.xcassets/Settings/source_code.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/Settings/source_code.imageset/source_code@2x.png b/Cyton/Assets.xcassets/Settings/source_code.imageset/source_code@2x.png similarity index 100% rename from Neuron/Assets.xcassets/Settings/source_code.imageset/source_code@2x.png rename to Cyton/Assets.xcassets/Settings/source_code.imageset/source_code@2x.png diff --git a/Neuron/Assets.xcassets/Settings/source_code.imageset/source_code@3x.png b/Cyton/Assets.xcassets/Settings/source_code.imageset/source_code@3x.png similarity index 100% rename from Neuron/Assets.xcassets/Settings/source_code.imageset/source_code@3x.png rename to Cyton/Assets.xcassets/Settings/source_code.imageset/source_code@3x.png diff --git a/Neuron/Assets.xcassets/TabBar/Contents.json b/Cyton/Assets.xcassets/TabBar/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/TabBar/Contents.json rename to Cyton/Assets.xcassets/TabBar/Contents.json diff --git a/Neuron/Assets.xcassets/TabBar/Main_off.imageset/Contents.json b/Cyton/Assets.xcassets/TabBar/Main_off.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/TabBar/Main_off.imageset/Contents.json rename to Cyton/Assets.xcassets/TabBar/Main_off.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/TabBar/Main_off.imageset/Main_off@2x.png b/Cyton/Assets.xcassets/TabBar/Main_off.imageset/Main_off@2x.png similarity index 100% rename from Neuron/Assets.xcassets/TabBar/Main_off.imageset/Main_off@2x.png rename to Cyton/Assets.xcassets/TabBar/Main_off.imageset/Main_off@2x.png diff --git a/Neuron/Assets.xcassets/TabBar/Main_off.imageset/Main_off@3x.png b/Cyton/Assets.xcassets/TabBar/Main_off.imageset/Main_off@3x.png similarity index 100% rename from Neuron/Assets.xcassets/TabBar/Main_off.imageset/Main_off@3x.png rename to Cyton/Assets.xcassets/TabBar/Main_off.imageset/Main_off@3x.png diff --git a/Neuron/Assets.xcassets/TabBar/Main_on.imageset/Contents.json b/Cyton/Assets.xcassets/TabBar/Main_on.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/TabBar/Main_on.imageset/Contents.json rename to Cyton/Assets.xcassets/TabBar/Main_on.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/TabBar/Main_on.imageset/Main_on@2x.png b/Cyton/Assets.xcassets/TabBar/Main_on.imageset/Main_on@2x.png similarity index 100% rename from Neuron/Assets.xcassets/TabBar/Main_on.imageset/Main_on@2x.png rename to Cyton/Assets.xcassets/TabBar/Main_on.imageset/Main_on@2x.png diff --git a/Neuron/Assets.xcassets/TabBar/Main_on.imageset/Main_on@3x.png b/Cyton/Assets.xcassets/TabBar/Main_on.imageset/Main_on@3x.png similarity index 100% rename from Neuron/Assets.xcassets/TabBar/Main_on.imageset/Main_on@3x.png rename to Cyton/Assets.xcassets/TabBar/Main_on.imageset/Main_on@3x.png diff --git a/Neuron/Assets.xcassets/TabBar/dapp_off.imageset/Contents.json b/Cyton/Assets.xcassets/TabBar/dapp_off.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/TabBar/dapp_off.imageset/Contents.json rename to Cyton/Assets.xcassets/TabBar/dapp_off.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/TabBar/dapp_off.imageset/dapp_off@2x.png b/Cyton/Assets.xcassets/TabBar/dapp_off.imageset/dapp_off@2x.png similarity index 100% rename from Neuron/Assets.xcassets/TabBar/dapp_off.imageset/dapp_off@2x.png rename to Cyton/Assets.xcassets/TabBar/dapp_off.imageset/dapp_off@2x.png diff --git a/Neuron/Assets.xcassets/TabBar/dapp_off.imageset/dapp_off@3x.png b/Cyton/Assets.xcassets/TabBar/dapp_off.imageset/dapp_off@3x.png similarity index 100% rename from Neuron/Assets.xcassets/TabBar/dapp_off.imageset/dapp_off@3x.png rename to Cyton/Assets.xcassets/TabBar/dapp_off.imageset/dapp_off@3x.png diff --git a/Neuron/Assets.xcassets/TabBar/dapp_on.imageset/Contents.json b/Cyton/Assets.xcassets/TabBar/dapp_on.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/TabBar/dapp_on.imageset/Contents.json rename to Cyton/Assets.xcassets/TabBar/dapp_on.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/TabBar/dapp_on.imageset/dapp_on@2x.png b/Cyton/Assets.xcassets/TabBar/dapp_on.imageset/dapp_on@2x.png similarity index 100% rename from Neuron/Assets.xcassets/TabBar/dapp_on.imageset/dapp_on@2x.png rename to Cyton/Assets.xcassets/TabBar/dapp_on.imageset/dapp_on@2x.png diff --git a/Neuron/Assets.xcassets/TabBar/dapp_on.imageset/dapp_on@3x.png b/Cyton/Assets.xcassets/TabBar/dapp_on.imageset/dapp_on@3x.png similarity index 100% rename from Neuron/Assets.xcassets/TabBar/dapp_on.imageset/dapp_on@3x.png rename to Cyton/Assets.xcassets/TabBar/dapp_on.imageset/dapp_on@3x.png diff --git a/Neuron/Assets.xcassets/TabBar/wallet_off.imageset/Contents.json b/Cyton/Assets.xcassets/TabBar/wallet_off.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/TabBar/wallet_off.imageset/Contents.json rename to Cyton/Assets.xcassets/TabBar/wallet_off.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/TabBar/wallet_off.imageset/wallet_off@2x.png b/Cyton/Assets.xcassets/TabBar/wallet_off.imageset/wallet_off@2x.png similarity index 100% rename from Neuron/Assets.xcassets/TabBar/wallet_off.imageset/wallet_off@2x.png rename to Cyton/Assets.xcassets/TabBar/wallet_off.imageset/wallet_off@2x.png diff --git a/Neuron/Assets.xcassets/TabBar/wallet_off.imageset/wallet_off@3x.png b/Cyton/Assets.xcassets/TabBar/wallet_off.imageset/wallet_off@3x.png similarity index 100% rename from Neuron/Assets.xcassets/TabBar/wallet_off.imageset/wallet_off@3x.png rename to Cyton/Assets.xcassets/TabBar/wallet_off.imageset/wallet_off@3x.png diff --git a/Neuron/Assets.xcassets/TabBar/wallet_on.imageset/Contents.json b/Cyton/Assets.xcassets/TabBar/wallet_on.imageset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/TabBar/wallet_on.imageset/Contents.json rename to Cyton/Assets.xcassets/TabBar/wallet_on.imageset/Contents.json diff --git a/Neuron/Assets.xcassets/TabBar/wallet_on.imageset/wallet_on@2x.png b/Cyton/Assets.xcassets/TabBar/wallet_on.imageset/wallet_on@2x.png similarity index 100% rename from Neuron/Assets.xcassets/TabBar/wallet_on.imageset/wallet_on@2x.png rename to Cyton/Assets.xcassets/TabBar/wallet_on.imageset/wallet_on@2x.png diff --git a/Neuron/Assets.xcassets/TabBar/wallet_on.imageset/wallet_on@3x.png b/Cyton/Assets.xcassets/TabBar/wallet_on.imageset/wallet_on@3x.png similarity index 100% rename from Neuron/Assets.xcassets/TabBar/wallet_on.imageset/wallet_on@3x.png rename to Cyton/Assets.xcassets/TabBar/wallet_on.imageset/wallet_on@3x.png diff --git a/Neuron/Assets.xcassets/Theme Colors/Contents.json b/Cyton/Assets.xcassets/Theme Colors/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Theme Colors/Contents.json rename to Cyton/Assets.xcassets/Theme Colors/Contents.json diff --git a/Neuron/Assets.xcassets/Theme Colors/Control/Contents.json b/Cyton/Assets.xcassets/Theme Colors/Control/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Theme Colors/Control/Contents.json rename to Cyton/Assets.xcassets/Theme Colors/Control/Contents.json diff --git a/Neuron/Assets.xcassets/Theme Colors/Control/control_disabled_bg_color.colorset/Contents.json b/Cyton/Assets.xcassets/Theme Colors/Control/control_disabled_bg_color.colorset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Theme Colors/Control/control_disabled_bg_color.colorset/Contents.json rename to Cyton/Assets.xcassets/Theme Colors/Control/control_disabled_bg_color.colorset/Contents.json diff --git a/Neuron/Assets.xcassets/Theme Colors/Control/control_disabled_title_color.colorset/Contents.json b/Cyton/Assets.xcassets/Theme Colors/Control/control_disabled_title_color.colorset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Theme Colors/Control/control_disabled_title_color.colorset/Contents.json rename to Cyton/Assets.xcassets/Theme Colors/Control/control_disabled_title_color.colorset/Contents.json diff --git a/Neuron/Assets.xcassets/Theme Colors/Neutral/Contents.json b/Cyton/Assets.xcassets/Theme Colors/Neutral/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Theme Colors/Neutral/Contents.json rename to Cyton/Assets.xcassets/Theme Colors/Neutral/Contents.json diff --git a/Neuron/Assets.xcassets/Theme Colors/Neutral/dark_bg_color.colorset/Contents.json b/Cyton/Assets.xcassets/Theme Colors/Neutral/dark_bg_color.colorset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Theme Colors/Neutral/dark_bg_color.colorset/Contents.json rename to Cyton/Assets.xcassets/Theme Colors/Neutral/dark_bg_color.colorset/Contents.json diff --git a/Neuron/Assets.xcassets/Theme Colors/Neutral/headline_color.colorset/Contents.json b/Cyton/Assets.xcassets/Theme Colors/Neutral/headline_color.colorset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Theme Colors/Neutral/headline_color.colorset/Contents.json rename to Cyton/Assets.xcassets/Theme Colors/Neutral/headline_color.colorset/Contents.json diff --git a/Neuron/Assets.xcassets/Theme Colors/Neutral/info_color.colorset/Contents.json b/Cyton/Assets.xcassets/Theme Colors/Neutral/info_color.colorset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Theme Colors/Neutral/info_color.colorset/Contents.json rename to Cyton/Assets.xcassets/Theme Colors/Neutral/info_color.colorset/Contents.json diff --git a/Neuron/Assets.xcassets/Theme Colors/Neutral/subhead_color.colorset/Contents.json b/Cyton/Assets.xcassets/Theme Colors/Neutral/subhead_color.colorset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Theme Colors/Neutral/subhead_color.colorset/Contents.json rename to Cyton/Assets.xcassets/Theme Colors/Neutral/subhead_color.colorset/Contents.json diff --git a/Neuron/Assets.xcassets/Theme Colors/Primary/Contents.json b/Cyton/Assets.xcassets/Theme Colors/Primary/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Theme Colors/Primary/Contents.json rename to Cyton/Assets.xcassets/Theme Colors/Primary/Contents.json diff --git a/Neuron/Assets.xcassets/Theme Colors/Primary/branding_color.colorset/Contents.json b/Cyton/Assets.xcassets/Theme Colors/Primary/branding_color.colorset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Theme Colors/Primary/branding_color.colorset/Contents.json rename to Cyton/Assets.xcassets/Theme Colors/Primary/branding_color.colorset/Contents.json diff --git a/Neuron/Assets.xcassets/Theme Colors/Primary/label_bg_color.colorset/Contents.json b/Cyton/Assets.xcassets/Theme Colors/Primary/label_bg_color.colorset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Theme Colors/Primary/label_bg_color.colorset/Contents.json rename to Cyton/Assets.xcassets/Theme Colors/Primary/label_bg_color.colorset/Contents.json diff --git a/Neuron/Assets.xcassets/Theme Colors/Primary/label_border_color.colorset/Contents.json b/Cyton/Assets.xcassets/Theme Colors/Primary/label_border_color.colorset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Theme Colors/Primary/label_border_color.colorset/Contents.json rename to Cyton/Assets.xcassets/Theme Colors/Primary/label_border_color.colorset/Contents.json diff --git a/Neuron/Assets.xcassets/Theme Colors/Primary/tint_color.colorset/Contents.json b/Cyton/Assets.xcassets/Theme Colors/Primary/tint_color.colorset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Theme Colors/Primary/tint_color.colorset/Contents.json rename to Cyton/Assets.xcassets/Theme Colors/Primary/tint_color.colorset/Contents.json diff --git a/Neuron/Assets.xcassets/Theme Colors/Secondary/Contents.json b/Cyton/Assets.xcassets/Theme Colors/Secondary/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Theme Colors/Secondary/Contents.json rename to Cyton/Assets.xcassets/Theme Colors/Secondary/Contents.json diff --git a/Neuron/Assets.xcassets/Theme Colors/Secondary/secondary_color.colorset/Contents.json b/Cyton/Assets.xcassets/Theme Colors/Secondary/secondary_color.colorset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Theme Colors/Secondary/secondary_color.colorset/Contents.json rename to Cyton/Assets.xcassets/Theme Colors/Secondary/secondary_color.colorset/Contents.json diff --git a/Neuron/Assets.xcassets/Theme Colors/Secondary/warning_bg_color.colorset/Contents.json b/Cyton/Assets.xcassets/Theme Colors/Secondary/warning_bg_color.colorset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Theme Colors/Secondary/warning_bg_color.colorset/Contents.json rename to Cyton/Assets.xcassets/Theme Colors/Secondary/warning_bg_color.colorset/Contents.json diff --git a/Neuron/Assets.xcassets/Theme Colors/Secondary/warning_color.colorset/Contents.json b/Cyton/Assets.xcassets/Theme Colors/Secondary/warning_color.colorset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Theme Colors/Secondary/warning_color.colorset/Contents.json rename to Cyton/Assets.xcassets/Theme Colors/Secondary/warning_color.colorset/Contents.json diff --git a/Neuron/Assets.xcassets/Theme Colors/Weak/Contents.json b/Cyton/Assets.xcassets/Theme Colors/Weak/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Theme Colors/Weak/Contents.json rename to Cyton/Assets.xcassets/Theme Colors/Weak/Contents.json diff --git a/Neuron/Assets.xcassets/Theme Colors/Weak/weak_1_color.colorset/Contents.json b/Cyton/Assets.xcassets/Theme Colors/Weak/weak_1_color.colorset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Theme Colors/Weak/weak_1_color.colorset/Contents.json rename to Cyton/Assets.xcassets/Theme Colors/Weak/weak_1_color.colorset/Contents.json diff --git a/Neuron/Assets.xcassets/Theme Colors/Weak/weak_2_color.colorset/Contents.json b/Cyton/Assets.xcassets/Theme Colors/Weak/weak_2_color.colorset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Theme Colors/Weak/weak_2_color.colorset/Contents.json rename to Cyton/Assets.xcassets/Theme Colors/Weak/weak_2_color.colorset/Contents.json diff --git a/Neuron/Assets.xcassets/Theme Colors/Weak/weak_3_color.colorset/Contents.json b/Cyton/Assets.xcassets/Theme Colors/Weak/weak_3_color.colorset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Theme Colors/Weak/weak_3_color.colorset/Contents.json rename to Cyton/Assets.xcassets/Theme Colors/Weak/weak_3_color.colorset/Contents.json diff --git a/Neuron/Assets.xcassets/Theme Colors/Weak/weak_4_color.colorset/Contents.json b/Cyton/Assets.xcassets/Theme Colors/Weak/weak_4_color.colorset/Contents.json similarity index 100% rename from Neuron/Assets.xcassets/Theme Colors/Weak/weak_4_color.colorset/Contents.json rename to Cyton/Assets.xcassets/Theme Colors/Weak/weak_4_color.colorset/Contents.json diff --git a/Cyton/Assets.xcassets/Transaction/Contents.json b/Cyton/Assets.xcassets/Transaction/Contents.json new file mode 100644 index 00000000..da4a164c --- /dev/null +++ b/Cyton/Assets.xcassets/Transaction/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Cyton/Assets.xcassets/Transaction/Details/Contents.json b/Cyton/Assets.xcassets/Transaction/Details/Contents.json new file mode 100644 index 00000000..da4a164c --- /dev/null +++ b/Cyton/Assets.xcassets/Transaction/Details/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Cyton/Assets.xcassets/Transaction/Details/icon_tx_details_chain_cita.imageset/Contents.json b/Cyton/Assets.xcassets/Transaction/Details/icon_tx_details_chain_cita.imageset/Contents.json new file mode 100644 index 00000000..f85c19b7 --- /dev/null +++ b/Cyton/Assets.xcassets/Transaction/Details/icon_tx_details_chain_cita.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "分组 5@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "分组 5@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git "a/Cyton/Assets.xcassets/Transaction/Details/icon_tx_details_chain_cita.imageset/\345\210\206\347\273\204 5@2x.png" "b/Cyton/Assets.xcassets/Transaction/Details/icon_tx_details_chain_cita.imageset/\345\210\206\347\273\204 5@2x.png" new file mode 100644 index 00000000..5f1a29ca Binary files /dev/null and "b/Cyton/Assets.xcassets/Transaction/Details/icon_tx_details_chain_cita.imageset/\345\210\206\347\273\204 5@2x.png" differ diff --git "a/Cyton/Assets.xcassets/Transaction/Details/icon_tx_details_chain_cita.imageset/\345\210\206\347\273\204 5@3x.png" "b/Cyton/Assets.xcassets/Transaction/Details/icon_tx_details_chain_cita.imageset/\345\210\206\347\273\204 5@3x.png" new file mode 100644 index 00000000..e9cac1ce Binary files /dev/null and "b/Cyton/Assets.xcassets/Transaction/Details/icon_tx_details_chain_cita.imageset/\345\210\206\347\273\204 5@3x.png" differ diff --git a/Cyton/Assets.xcassets/Transaction/Details/icon_tx_details_chain_eth.imageset/Bitmap@2x.png b/Cyton/Assets.xcassets/Transaction/Details/icon_tx_details_chain_eth.imageset/Bitmap@2x.png new file mode 100644 index 00000000..5e8152cc Binary files /dev/null and b/Cyton/Assets.xcassets/Transaction/Details/icon_tx_details_chain_eth.imageset/Bitmap@2x.png differ diff --git a/Cyton/Assets.xcassets/Transaction/Details/icon_tx_details_chain_eth.imageset/Bitmap@3x.png b/Cyton/Assets.xcassets/Transaction/Details/icon_tx_details_chain_eth.imageset/Bitmap@3x.png new file mode 100644 index 00000000..f4067a73 Binary files /dev/null and b/Cyton/Assets.xcassets/Transaction/Details/icon_tx_details_chain_eth.imageset/Bitmap@3x.png differ diff --git a/Cyton/Assets.xcassets/Transaction/Details/icon_tx_details_chain_eth.imageset/Contents.json b/Cyton/Assets.xcassets/Transaction/Details/icon_tx_details_chain_eth.imageset/Contents.json new file mode 100644 index 00000000..d6ddda13 --- /dev/null +++ b/Cyton/Assets.xcassets/Transaction/Details/icon_tx_details_chain_eth.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Bitmap@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "Bitmap@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Cyton/Assets.xcassets/Transaction/Details/icon_tx_details_copy.imageset/Contents.json b/Cyton/Assets.xcassets/Transaction/Details/icon_tx_details_copy.imageset/Contents.json new file mode 100644 index 00000000..9fc6dc32 --- /dev/null +++ b/Cyton/Assets.xcassets/Transaction/Details/icon_tx_details_copy.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "形状@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "形状@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git "a/Cyton/Assets.xcassets/Transaction/Details/icon_tx_details_copy.imageset/\345\275\242\347\212\266@2x.png" "b/Cyton/Assets.xcassets/Transaction/Details/icon_tx_details_copy.imageset/\345\275\242\347\212\266@2x.png" new file mode 100644 index 00000000..f12b441c Binary files /dev/null and "b/Cyton/Assets.xcassets/Transaction/Details/icon_tx_details_copy.imageset/\345\275\242\347\212\266@2x.png" differ diff --git "a/Cyton/Assets.xcassets/Transaction/Details/icon_tx_details_copy.imageset/\345\275\242\347\212\266@3x.png" "b/Cyton/Assets.xcassets/Transaction/Details/icon_tx_details_copy.imageset/\345\275\242\347\212\266@3x.png" new file mode 100644 index 00000000..ae2a602e Binary files /dev/null and "b/Cyton/Assets.xcassets/Transaction/Details/icon_tx_details_copy.imageset/\345\275\242\347\212\266@3x.png" differ diff --git a/Cyton/Assets.xcassets/Transaction/Send/Contents.json b/Cyton/Assets.xcassets/Transaction/Send/Contents.json new file mode 100644 index 00000000..da4a164c --- /dev/null +++ b/Cyton/Assets.xcassets/Transaction/Send/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Cyton/Assets.xcassets/Transaction/Send/icon_tx_send_selected.imageset/Contents.json b/Cyton/Assets.xcassets/Transaction/Send/icon_tx_send_selected.imageset/Contents.json new file mode 100644 index 00000000..dd146aa2 --- /dev/null +++ b/Cyton/Assets.xcassets/Transaction/Send/icon_tx_send_selected.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Path 21@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "Path 21@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Cyton/Assets.xcassets/Transaction/Send/icon_tx_send_selected.imageset/Path 21@2x.png b/Cyton/Assets.xcassets/Transaction/Send/icon_tx_send_selected.imageset/Path 21@2x.png new file mode 100644 index 00000000..3b9c92f0 Binary files /dev/null and b/Cyton/Assets.xcassets/Transaction/Send/icon_tx_send_selected.imageset/Path 21@2x.png differ diff --git a/Cyton/Assets.xcassets/Transaction/Send/icon_tx_send_selected.imageset/Path 21@3x.png b/Cyton/Assets.xcassets/Transaction/Send/icon_tx_send_selected.imageset/Path 21@3x.png new file mode 100644 index 00000000..9d2c4b2d Binary files /dev/null and b/Cyton/Assets.xcassets/Transaction/Send/icon_tx_send_selected.imageset/Path 21@3x.png differ diff --git a/Cyton/Assets.xcassets/Wallet/Contents.json b/Cyton/Assets.xcassets/Wallet/Contents.json new file mode 100644 index 00000000..da4a164c --- /dev/null +++ b/Cyton/Assets.xcassets/Wallet/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Cyton/Assets.xcassets/Wallet/Icon/Contents.json b/Cyton/Assets.xcassets/Wallet/Icon/Contents.json new file mode 100644 index 00000000..da4a164c --- /dev/null +++ b/Cyton/Assets.xcassets/Wallet/Icon/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Neuron/Assets.xcassets/Guide/guide_1.imageset/Contents.json b/Cyton/Assets.xcassets/Wallet/Icon/icon_wallet_selected.imageset/Contents.json similarity index 80% rename from Neuron/Assets.xcassets/Guide/guide_1.imageset/Contents.json rename to Cyton/Assets.xcassets/Wallet/Icon/icon_wallet_selected.imageset/Contents.json index 4c805ccb..f3670271 100644 --- a/Neuron/Assets.xcassets/Guide/guide_1.imageset/Contents.json +++ b/Cyton/Assets.xcassets/Wallet/Icon/icon_wallet_selected.imageset/Contents.json @@ -6,11 +6,12 @@ }, { "idiom" : "universal", - "filename" : "页面1.png", + "filename" : "勾@2x.png", "scale" : "2x" }, { "idiom" : "universal", + "filename" : "勾@3x.png", "scale" : "3x" } ], diff --git "a/Cyton/Assets.xcassets/Wallet/Icon/icon_wallet_selected.imageset/\345\213\276@2x.png" "b/Cyton/Assets.xcassets/Wallet/Icon/icon_wallet_selected.imageset/\345\213\276@2x.png" new file mode 100644 index 00000000..04310b5d Binary files /dev/null and "b/Cyton/Assets.xcassets/Wallet/Icon/icon_wallet_selected.imageset/\345\213\276@2x.png" differ diff --git "a/Cyton/Assets.xcassets/Wallet/Icon/icon_wallet_selected.imageset/\345\213\276@3x.png" "b/Cyton/Assets.xcassets/Wallet/Icon/icon_wallet_selected.imageset/\345\213\276@3x.png" new file mode 100644 index 00000000..b79f7647 Binary files /dev/null and "b/Cyton/Assets.xcassets/Wallet/Icon/icon_wallet_selected.imageset/\345\213\276@3x.png" differ diff --git a/Neuron/Assets.xcassets/Guide/guide_3.imageset/Contents.json b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_dog.imageset/Contents.json similarity index 80% rename from Neuron/Assets.xcassets/Guide/guide_3.imageset/Contents.json rename to Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_dog.imageset/Contents.json index ed520a1c..859aa491 100644 --- a/Neuron/Assets.xcassets/Guide/guide_3.imageset/Contents.json +++ b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_dog.imageset/Contents.json @@ -6,11 +6,12 @@ }, { "idiom" : "universal", - "filename" : "页面3.png", + "filename" : "狗@2x.png", "scale" : "2x" }, { "idiom" : "universal", + "filename" : "狗@3x.png", "scale" : "3x" } ], diff --git "a/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_dog.imageset/\347\213\227@2x.png" "b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_dog.imageset/\347\213\227@2x.png" new file mode 100644 index 00000000..0a5df98a Binary files /dev/null and "b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_dog.imageset/\347\213\227@2x.png" differ diff --git "a/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_dog.imageset/\347\213\227@3x.png" "b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_dog.imageset/\347\213\227@3x.png" new file mode 100644 index 00000000..3413a064 Binary files /dev/null and "b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_dog.imageset/\347\213\227@3x.png" differ diff --git a/Neuron/Assets.xcassets/Guide/guide_2.imageset/Contents.json b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_fish.imageset/Contents.json similarity index 80% rename from Neuron/Assets.xcassets/Guide/guide_2.imageset/Contents.json rename to Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_fish.imageset/Contents.json index c0d37313..c48f3000 100644 --- a/Neuron/Assets.xcassets/Guide/guide_2.imageset/Contents.json +++ b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_fish.imageset/Contents.json @@ -6,11 +6,12 @@ }, { "idiom" : "universal", - "filename" : "页面2.png", + "filename" : "鱼@2x.png", "scale" : "2x" }, { "idiom" : "universal", + "filename" : "鱼@3x.png", "scale" : "3x" } ], diff --git "a/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_fish.imageset/\351\261\274@2x.png" "b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_fish.imageset/\351\261\274@2x.png" new file mode 100644 index 00000000..6869350d Binary files /dev/null and "b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_fish.imageset/\351\261\274@2x.png" differ diff --git "a/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_fish.imageset/\351\261\274@3x.png" "b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_fish.imageset/\351\261\274@3x.png" new file mode 100644 index 00000000..a9a96c29 Binary files /dev/null and "b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_fish.imageset/\351\261\274@3x.png" differ diff --git a/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_fox.imageset/Contents.json b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_fox.imageset/Contents.json new file mode 100644 index 00000000..d2314934 --- /dev/null +++ b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_fox.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "狐狸@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "狐狸@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git "a/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_fox.imageset/\347\213\220\347\213\270@2x.png" "b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_fox.imageset/\347\213\220\347\213\270@2x.png" new file mode 100644 index 00000000..f73ca7c9 Binary files /dev/null and "b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_fox.imageset/\347\213\220\347\213\270@2x.png" differ diff --git "a/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_fox.imageset/\347\213\220\347\213\270@3x.png" "b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_fox.imageset/\347\213\220\347\213\270@3x.png" new file mode 100644 index 00000000..9564deac Binary files /dev/null and "b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_fox.imageset/\347\213\220\347\213\270@3x.png" differ diff --git a/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_owl.imageset/Contents.json b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_owl.imageset/Contents.json new file mode 100644 index 00000000..2d2cfda8 --- /dev/null +++ b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_owl.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "猫头鹰@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "猫头鹰@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git "a/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_owl.imageset/\347\214\253\345\244\264\351\271\260@2x.png" "b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_owl.imageset/\347\214\253\345\244\264\351\271\260@2x.png" new file mode 100644 index 00000000..d616fe99 Binary files /dev/null and "b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_owl.imageset/\347\214\253\345\244\264\351\271\260@2x.png" differ diff --git "a/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_owl.imageset/\347\214\253\345\244\264\351\271\260@3x.png" "b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_owl.imageset/\347\214\253\345\244\264\351\271\260@3x.png" new file mode 100644 index 00000000..e92fdc09 Binary files /dev/null and "b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_owl.imageset/\347\214\253\345\244\264\351\271\260@3x.png" differ diff --git a/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_parrot.imageset/Contents.json b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_parrot.imageset/Contents.json new file mode 100644 index 00000000..e075044f --- /dev/null +++ b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_parrot.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "鹦鹉@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "鹦鹉@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git "a/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_parrot.imageset/\351\271\246\351\271\211@2x.png" "b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_parrot.imageset/\351\271\246\351\271\211@2x.png" new file mode 100644 index 00000000..0b959aa6 Binary files /dev/null and "b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_parrot.imageset/\351\271\246\351\271\211@2x.png" differ diff --git "a/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_parrot.imageset/\351\271\246\351\271\211@3x.png" "b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_parrot.imageset/\351\271\246\351\271\211@3x.png" new file mode 100644 index 00000000..1d1c14d3 Binary files /dev/null and "b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_parrot.imageset/\351\271\246\351\271\211@3x.png" differ diff --git a/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_rat.imageset/Contents.json b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_rat.imageset/Contents.json new file mode 100644 index 00000000..74cdd8db --- /dev/null +++ b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_rat.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "老鼠@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "老鼠@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git "a/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_rat.imageset/\350\200\201\351\274\240@2x.png" "b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_rat.imageset/\350\200\201\351\274\240@2x.png" new file mode 100644 index 00000000..a24c113d Binary files /dev/null and "b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_rat.imageset/\350\200\201\351\274\240@2x.png" differ diff --git "a/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_rat.imageset/\350\200\201\351\274\240@3x.png" "b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_rat.imageset/\350\200\201\351\274\240@3x.png" new file mode 100644 index 00000000..9949cbf5 Binary files /dev/null and "b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_rat.imageset/\350\200\201\351\274\240@3x.png" differ diff --git a/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_squirrel.imageset/Contents.json b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_squirrel.imageset/Contents.json new file mode 100644 index 00000000..d0be9234 --- /dev/null +++ b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_squirrel.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "松鼠@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "松鼠@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git "a/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_squirrel.imageset/\346\235\276\351\274\240@2x.png" "b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_squirrel.imageset/\346\235\276\351\274\240@2x.png" new file mode 100644 index 00000000..ec818f09 Binary files /dev/null and "b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_squirrel.imageset/\346\235\276\351\274\240@2x.png" differ diff --git "a/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_squirrel.imageset/\346\235\276\351\274\240@3x.png" "b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_squirrel.imageset/\346\235\276\351\274\240@3x.png" new file mode 100644 index 00000000..2f99beeb Binary files /dev/null and "b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_squirrel.imageset/\346\235\276\351\274\240@3x.png" differ diff --git a/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_tiger.imageset/Contents.json b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_tiger.imageset/Contents.json new file mode 100644 index 00000000..872c1888 --- /dev/null +++ b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_tiger.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "老虎@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "老虎@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git "a/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_tiger.imageset/\350\200\201\350\231\216@2x.png" "b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_tiger.imageset/\350\200\201\350\231\216@2x.png" new file mode 100644 index 00000000..ae1389a6 Binary files /dev/null and "b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_tiger.imageset/\350\200\201\350\231\216@2x.png" differ diff --git "a/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_tiger.imageset/\350\200\201\350\231\216@3x.png" "b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_tiger.imageset/\350\200\201\350\231\216@3x.png" new file mode 100644 index 00000000..6a0e4ee1 Binary files /dev/null and "b/Cyton/Assets.xcassets/Wallet/Icon/wallet_icon_tiger.imageset/\350\200\201\350\231\216@3x.png" differ diff --git a/Cyton/Assets.xcassets/Wallet/Switch/Contents.json b/Cyton/Assets.xcassets/Wallet/Switch/Contents.json new file mode 100644 index 00000000..da4a164c --- /dev/null +++ b/Cyton/Assets.xcassets/Wallet/Switch/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Neuron/Assets.xcassets/Launch Screen/peckshield_launch.imageset/Contents.json b/Cyton/Assets.xcassets/Wallet/Switch/icon_add_wallet.imageset/Contents.json similarity index 90% rename from Neuron/Assets.xcassets/Launch Screen/peckshield_launch.imageset/Contents.json rename to Cyton/Assets.xcassets/Wallet/Switch/icon_add_wallet.imageset/Contents.json index 2c09ad6c..89d7362c 100644 --- a/Neuron/Assets.xcassets/Launch Screen/peckshield_launch.imageset/Contents.json +++ b/Cyton/Assets.xcassets/Wallet/Switch/icon_add_wallet.imageset/Contents.json @@ -2,7 +2,6 @@ "images" : [ { "idiom" : "universal", - "filename" : "Group@1x.png", "scale" : "1x" }, { diff --git a/Cyton/Assets.xcassets/Wallet/Switch/icon_add_wallet.imageset/Group@2x.png b/Cyton/Assets.xcassets/Wallet/Switch/icon_add_wallet.imageset/Group@2x.png new file mode 100644 index 00000000..4873305f Binary files /dev/null and b/Cyton/Assets.xcassets/Wallet/Switch/icon_add_wallet.imageset/Group@2x.png differ diff --git a/Cyton/Assets.xcassets/Wallet/Switch/icon_add_wallet.imageset/Group@3x.png b/Cyton/Assets.xcassets/Wallet/Switch/icon_add_wallet.imageset/Group@3x.png new file mode 100644 index 00000000..4fcf88dc Binary files /dev/null and b/Cyton/Assets.xcassets/Wallet/Switch/icon_add_wallet.imageset/Group@3x.png differ diff --git a/Neuron/Base.lproj/LaunchScreen.storyboard b/Cyton/Base.lproj/LaunchScreen.storyboard similarity index 100% rename from Neuron/Base.lproj/LaunchScreen.storyboard rename to Cyton/Base.lproj/LaunchScreen.storyboard diff --git a/Neuron/Base.lproj/Main.storyboard b/Cyton/Base.lproj/Main.storyboard similarity index 93% rename from Neuron/Base.lproj/Main.storyboard rename to Cyton/Base.lproj/Main.storyboard index 1cf01cc5..9958f198 100644 --- a/Neuron/Base.lproj/Main.storyboard +++ b/Cyton/Base.lproj/Main.storyboard @@ -13,7 +13,7 @@ - + @@ -29,10 +29,10 @@ - + - + @@ -52,7 +52,7 @@ - + @@ -71,7 +71,7 @@ - + @@ -105,7 +105,7 @@ - + diff --git a/Neuron/Constants/NibLoadable.swift b/Cyton/Constants/NibLoadable.swift similarity index 97% rename from Neuron/Constants/NibLoadable.swift rename to Cyton/Constants/NibLoadable.swift index a7afeaea..790c3360 100644 --- a/Neuron/Constants/NibLoadable.swift +++ b/Cyton/Constants/NibLoadable.swift @@ -1,6 +1,6 @@ // // NibLoadable.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/5/18. // Copyright © 2018年 cryptape. All rights reserved. diff --git a/Neuron/Constants/NotificationName.swift b/Cyton/Constants/NotificationName.swift similarity index 96% rename from Neuron/Constants/NotificationName.swift rename to Cyton/Constants/NotificationName.swift index e2f886d4..ec33cc4b 100644 --- a/Neuron/Constants/NotificationName.swift +++ b/Cyton/Constants/NotificationName.swift @@ -1,6 +1,6 @@ // // NotificationName.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/6/19. // Copyright © 2018年 cryptape. All rights reserved. diff --git a/Neuron/Constants/ServerAPI.swift b/Cyton/Constants/ServerAPI.swift similarity index 98% rename from Neuron/Constants/ServerAPI.swift rename to Cyton/Constants/ServerAPI.swift index 0d70eb0f..74f8ebcd 100644 --- a/Neuron/Constants/ServerAPI.swift +++ b/Cyton/Constants/ServerAPI.swift @@ -1,6 +1,6 @@ // // APIMacro.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/7/9. // Copyright © 2018年 cryptape. All rights reserved. diff --git a/Cyton/Constants/TokenMacro.swift b/Cyton/Constants/TokenMacro.swift new file mode 100644 index 00000000..a84c4fdc --- /dev/null +++ b/Cyton/Constants/TokenMacro.swift @@ -0,0 +1,14 @@ +// +// TokenMacro.swift +// Cyton +// +// Created by XiaoLu on 2018/8/1. +// Copyright © 2018年 cryptape. All rights reserved. +// + +import Foundation + +struct NativeDecimals { + /// ETH and CITA token decimals, default to 18 + static let nativeTokenDecimals = 18 +} diff --git a/Neuron/Constants/WKWebViewConfigConstants.swift b/Cyton/Constants/WKWebViewConfigConstants.swift similarity index 98% rename from Neuron/Constants/WKWebViewConfigConstants.swift rename to Cyton/Constants/WKWebViewConfigConstants.swift index f0dac00f..ec88f7be 100644 --- a/Neuron/Constants/WKWebViewConfigConstants.swift +++ b/Cyton/Constants/WKWebViewConfigConstants.swift @@ -1,6 +1,6 @@ // // WKWebViewConfigConstants.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/10/11. // Copyright © 2018 Cryptape. All rights reserved. diff --git a/Cyton/Cyton-Bridging-Header.h b/Cyton/Cyton-Bridging-Header.h new file mode 100644 index 00000000..fa05cd96 --- /dev/null +++ b/Cyton/Cyton-Bridging-Header.h @@ -0,0 +1,13 @@ +// +// Cyton-Bridging-Header.h +// Cyton +// +// Created by XiaoLu on 2018/5/18. +// Copyright © 2018年 cryptape. All rights reserved. +// + +#ifndef Cyton_Bridging_Header_h +#define Cyton_Bridging_Header_h + + +#endif /* Cyton_Bridging_Header_h */ diff --git a/Neuron/Neuron.entitlements b/Cyton/Cyton.entitlements similarity index 70% rename from Neuron/Neuron.entitlements rename to Cyton/Cyton.entitlements index 903def2a..0c67376e 100644 --- a/Neuron/Neuron.entitlements +++ b/Cyton/Cyton.entitlements @@ -1,8 +1,5 @@ - - aps-environment - development - + diff --git a/Neuron/Extensions/Foundation/BigUInt+Extension.swift b/Cyton/Extensions/Foundation/BigUInt+Extension.swift similarity index 56% rename from Neuron/Extensions/Foundation/BigUInt+Extension.swift rename to Cyton/Extensions/Foundation/BigUInt+Extension.swift index 91453f73..04b9b3f2 100644 --- a/Neuron/Extensions/Foundation/BigUInt+Extension.swift +++ b/Cyton/Extensions/Foundation/BigUInt+Extension.swift @@ -1,6 +1,6 @@ // // BigUInt+Extension.swift -// Neuron +// Cyton // // Created by James Chen on 2018/11/14. // Copyright © 2018 Cryptape. All rights reserved. @@ -58,8 +58,8 @@ extension BigUInt { return self / BigUInt(10).power(18) } - func weiToGwei() -> Double { - return Double.fromAmount(self, decimals: 9) + func toGweiText() -> String { + return toAmountText(9) } init?(string: String) { @@ -69,4 +69,30 @@ extension BigUInt { self.init(string) } } + + func toAmountText(_ decimals: Int = 18) -> String { + if self == 0 { return "0" } + if self > Int(0.00000001 * pow(10, Double(decimals))) { + let formattingDecimals = decimals < 8 ? decimals : 8 + return toDecimalNumber(decimals).formatterToString(formattingDecimals) + } else { + let numberText = toDecimalNumber(decimals).formatterToString(18) + let double = Double(numberText)! + return double.description + } + } + + func toDecimalNumber(_ decimals: Int = 18) -> NSDecimalNumber { + let text = Web3Utils.formatToPrecision(self, numberDecimals: decimals, formattingDecimals: decimals) + return NSDecimalNumber(string: text) + } + + func toDouble(_ decimals: Int = 18) -> Double { + return Double(toDecimalNumber(decimals).formatterToString(decimals)) ?? 0 + } + + static func parseToBigUInt(_ amount: String, _ decimals: Int = 18) -> BigUInt { + let formatText = NSDecimalNumber(string: amount).formatterToString(decimals) + return Web3Utils.parseToBigUInt(formatText, decimals: decimals) ?? 0 + } } diff --git a/Cyton/Extensions/Foundation/Double+Extension.swift b/Cyton/Extensions/Foundation/Double+Extension.swift new file mode 100644 index 00000000..6cf76f23 --- /dev/null +++ b/Cyton/Extensions/Foundation/Double+Extension.swift @@ -0,0 +1,16 @@ +// +// Double+Extension.swift +// Cyton +// +// Created by XiaoLu on 2018/9/25. +// Copyright © 2018年 Cryptape. All rights reserved. +// + +import UIKit +import BigInt + +extension Double { + var trailingZerosTrimmed: String { + return truncatingRemainder(dividingBy: 1) == 0 ? String(format: "%.0f", self) : String(self) + } +} diff --git a/Cyton/Extensions/Foundation/NSDecimalNumber+Extension.swift b/Cyton/Extensions/Foundation/NSDecimalNumber+Extension.swift new file mode 100644 index 00000000..f541639b --- /dev/null +++ b/Cyton/Extensions/Foundation/NSDecimalNumber+Extension.swift @@ -0,0 +1,30 @@ +// +// NSDecimalNumber+Extension.swift +// Cyton +// +// Created by 晨风 on 2018/12/5. +// Copyright © 2018 Cryptape. All rights reserved. +// + +import Foundation + +extension NSDecimalNumber { + func formatterToString( _ decimals: Int = 18) -> String { + let formatter = NumberFormatter() + formatter.numberStyle = .none + formatter.minimumIntegerDigits = 1 + formatter.minimumFractionDigits = 0 + formatter.maximumFractionDigits = decimals + formatter.roundingMode = .floor + return formatter.string(from: self) ?? "0" + } + + func currencyFormat() -> String { + let formatter = NumberFormatter() + formatter.numberStyle = .currency + formatter.locale = Locale(identifier: LocalCurrencyService.shared.getLocalCurrencySelect().identifier) + print(formatter.locale) + let text = formatter.string(from: self) ?? "0" + return text.replacingOccurrences(of: formatter.locale.currencySymbol!, with: "\(formatter.locale.currencySymbol!) ") + } +} diff --git a/Cyton/Extensions/Foundation/String+Error.swift b/Cyton/Extensions/Foundation/String+Error.swift new file mode 100644 index 00000000..fc326219 --- /dev/null +++ b/Cyton/Extensions/Foundation/String+Error.swift @@ -0,0 +1,12 @@ +// +// String+Error.swift +// Cyton +// +// Created by 翟泉 on 2019/1/17. +// Copyright © 2019 Cryptape. All rights reserved. +// + +import UIKit + +extension String : Error { +} diff --git a/Neuron/Extensions/Foundation/String+Extension.swift b/Cyton/Extensions/Foundation/String+Extension.swift similarity index 98% rename from Neuron/Extensions/Foundation/String+Extension.swift rename to Cyton/Extensions/Foundation/String+Extension.swift index 0805474d..fa91e03f 100644 --- a/Neuron/Extensions/Foundation/String+Extension.swift +++ b/Cyton/Extensions/Foundation/String+Extension.swift @@ -1,6 +1,6 @@ // // String+Extension.swift -// Neuron +// Cyton // // Created by Yate Fulham on 2018/08/23. // Copyright © 2018 Cryptape. All rights reserved. diff --git a/Neuron/Extensions/Foundation/UInt+Extension.swift b/Cyton/Extensions/Foundation/UInt+Extension.swift similarity index 97% rename from Neuron/Extensions/Foundation/UInt+Extension.swift rename to Cyton/Extensions/Foundation/UInt+Extension.swift index df9e4119..3ee111ea 100644 --- a/Neuron/Extensions/Foundation/UInt+Extension.swift +++ b/Cyton/Extensions/Foundation/UInt+Extension.swift @@ -1,6 +1,6 @@ // // UIntExtension.swift -// Neuron +// Cyton // // Created by 晨风 on 2018/10/24. // Copyright © 2018 Cryptape. All rights reserved. diff --git a/Cyton/Extensions/Foundation/Web3Error+Description.swift b/Cyton/Extensions/Foundation/Web3Error+Description.swift new file mode 100644 index 00000000..766c22ec --- /dev/null +++ b/Cyton/Extensions/Foundation/Web3Error+Description.swift @@ -0,0 +1,37 @@ +// +// Web3Error+Description.swift +// Cyton +// +// Created by 翟泉 on 2019/1/17. +// Copyright © 2019 Cryptape. All rights reserved. +// + +import UIKit +import Web3swift + +extension Web3Error : CustomStringConvertible { + public var description : String { + switch self { + case .transactionSerializationError: + return "Transaction Serialization Error" + case .connectionError: + return "Connection Error" + case .dataError: + return "Data Error" + case .walletError: + return "Wallet Error" + case .inputError(let desc): + return desc + case .nodeError(let desc): + return desc + case .processingError(let desc): + return desc + case .keystoreError(let err): + return err.localizedDescription + case .generalError(let err): + return err.localizedDescription + case .unknownError: + return "Unknown Error" + } + } +} diff --git a/Neuron/Extensions/UIKit/UIColor+Extension.swift b/Cyton/Extensions/UIKit/UIColor+Extension.swift similarity index 98% rename from Neuron/Extensions/UIKit/UIColor+Extension.swift rename to Cyton/Extensions/UIKit/UIColor+Extension.swift index 81dca154..8845c10a 100644 --- a/Neuron/Extensions/UIKit/UIColor+Extension.swift +++ b/Cyton/Extensions/UIKit/UIColor+Extension.swift @@ -1,6 +1,6 @@ // // UIColor+Extension.swift -// Neuron +// Cyton // // Created by James Chen on 2018/11/23. // Copyright © 2018 Cryptape. All rights reserved. diff --git a/Neuron/Extensions/UIKit/UIControl+Extension.swift b/Cyton/Extensions/UIKit/UIControl+Extension.swift similarity index 99% rename from Neuron/Extensions/UIKit/UIControl+Extension.swift rename to Cyton/Extensions/UIKit/UIControl+Extension.swift index 038c35ef..fa7c235c 100644 --- a/Neuron/Extensions/UIKit/UIControl+Extension.swift +++ b/Cyton/Extensions/UIKit/UIControl+Extension.swift @@ -1,6 +1,6 @@ // // UIControl+Extension.swift -// Neuron +// Cyton // // Created by 晨风 on 2018/10/16. // Copyright © 2018 Cryptape. All rights reserved. diff --git a/Neuron/Extensions/UIKit/UIStoryboard+Extension.swift b/Cyton/Extensions/UIKit/UIStoryboard+Extension.swift similarity index 97% rename from Neuron/Extensions/UIKit/UIStoryboard+Extension.swift rename to Cyton/Extensions/UIKit/UIStoryboard+Extension.swift index 309ee86a..aca8adf0 100644 --- a/Neuron/Extensions/UIKit/UIStoryboard+Extension.swift +++ b/Cyton/Extensions/UIKit/UIStoryboard+Extension.swift @@ -1,6 +1,6 @@ // // UIStoryboard+Extension.swift -// Neuron +// Cyton // // Created by 晨风 on 2018/10/8. // Copyright © 2018 Cryptape. All rights reserved. @@ -34,6 +34,7 @@ extension UIStoryboard { case sendTransaction case walletManagement case dAppBrowser + case transactionDetails var capitalized: String { let capital = String(rawValue.prefix(1)).uppercased() diff --git a/Neuron/Extensions/UIKit/UIView+Extension.swift b/Cyton/Extensions/UIKit/UIView+Extension.swift similarity index 99% rename from Neuron/Extensions/UIKit/UIView+Extension.swift rename to Cyton/Extensions/UIKit/UIView+Extension.swift index a226477f..52d58e11 100644 --- a/Neuron/Extensions/UIKit/UIView+Extension.swift +++ b/Cyton/Extensions/UIKit/UIView+Extension.swift @@ -1,6 +1,6 @@ // // CALayer+Extension.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/8/28. // Copyright © 2018年 Cryptape. All rights reserved. diff --git a/Cyton/Extensions/UIKit/URLRequest+Extension.swift b/Cyton/Extensions/UIKit/URLRequest+Extension.swift new file mode 100644 index 00000000..f5d39022 --- /dev/null +++ b/Cyton/Extensions/UIKit/URLRequest+Extension.swift @@ -0,0 +1,23 @@ +// +// URLRequest+Extension.swift +// Cyton +// +// Created by James Chen on 2018/12/06. +// Copyright © 2018 Cryptape. All rights reserved. +// + +import Foundation + +extension URLRequest { + static var acceptLanguage: String { + return Locale.preferredLanguages.joined(separator: ",") + } + + mutating func setAcceptLanguage() { + setValue(URLRequest.acceptLanguage, forHTTPHeaderField: "Accept-Language") + } + + var acceptLanguage: String { + return value(forHTTPHeaderField: "Accept-Language") ?? "" + } +} diff --git a/Neuron/Info.plist b/Cyton/Info.plist similarity index 96% rename from Neuron/Info.plist rename to Cyton/Info.plist index b8cd5f27..65f9f5f4 100644 --- a/Neuron/Info.plist +++ b/Cyton/Info.plist @@ -5,7 +5,7 @@ CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName - Neuron + Cyton CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier @@ -17,9 +17,9 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.7.0 + 0.7.1 CFBundleVersion - 7 + 35 ITSAppUsesNonExemptEncryption LSRequiresIPhoneOS diff --git a/Cyton/MainViewController.swift b/Cyton/MainViewController.swift new file mode 100644 index 00000000..73a36c32 --- /dev/null +++ b/Cyton/MainViewController.swift @@ -0,0 +1,40 @@ +// +// MainViewController.swift +// Cyton +// +// Created by XiaoLu on 2018/5/18. +// Copyright © 2018年 cryptape. All rights reserved. +// + +import UIKit +import RealmSwift + +class MainViewController: UITabBarController, UITabBarControllerDelegate { + override func viewDidLoad() { + super.viewDidLoad() + delegate = self + + applyStyle() + addDefaultTokenToRealm() + + viewControllers?[0].title = "DApp.Home".localized() + viewControllers?[1].title = "Wallet".localized() + viewControllers?[2].title = "Settings.Title".localized() + } + + func addDefaultTokenToRealm() { + guard let walletModel = AppModel.current.currentWallet else { + return + } + DefaultTokenAndChain().addDefaultTokenToWallet(wallet: walletModel) + } + + private func applyStyle() { + UITabBarItem.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor(named: "tint_color")!], for: .selected) + let navigationBarBackImage = UIImage(named: "nav_darkback")!.withRenderingMode(.alwaysOriginal) + UINavigationBar.appearance().backIndicatorImage = navigationBarBackImage + UINavigationBar.appearance().backIndicatorTransitionMaskImage = navigationBarBackImage + UIBarButtonItem.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.clear], for: .normal) + UIBarButtonItem.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.clear], for: .highlighted) + } +} diff --git a/Neuron/Models/Realm/AppModel.swift b/Cyton/Models/Realm/AppModel.swift similarity index 67% rename from Neuron/Models/Realm/AppModel.swift rename to Cyton/Models/Realm/AppModel.swift index dad954df..10ad0afc 100644 --- a/Neuron/Models/Realm/AppModel.swift +++ b/Cyton/Models/Realm/AppModel.swift @@ -1,6 +1,6 @@ // // AppModel.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/6/13. // Copyright © 2018年 cryptape. All rights reserved. @@ -15,12 +15,6 @@ class AppModel: Object { /// whole wallet list var wallets = List() - /// whole wallet extra asset token list not included in tokens-eth.json - var extraTokenList = List() - - /// storage of native tokens - var nativeTokenList = List() - static var current: AppModel { let realm = try! Realm() return realm.objects(AppModel.self).first ?? AppModel() diff --git a/Cyton/Models/Realm/ChainModel.swift b/Cyton/Models/Realm/ChainModel.swift new file mode 100644 index 00000000..39f2cc55 --- /dev/null +++ b/Cyton/Models/Realm/ChainModel.swift @@ -0,0 +1,39 @@ +// +// ChainModel.swift +// Cyton +// +// Created by XiaoLu on 2018/12/5. +// Copyright © 2018 Cryptape. All rights reserved. +// + +import Foundation +import RealmSwift + +class ChainModel: Object { + @objc dynamic var chainId = "" + @objc dynamic var chainName = "" + @objc dynamic var httpProvider = "" + @objc dynamic var nativeTokenIdentifier = "" + @objc dynamic var identifier = UUID().uuidString + + override class func primaryKey() -> String? { return "identifier" } + + var nativeToken: TokenModel { return (try! Realm()).object(ofType: TokenModel.self, forPrimaryKey: nativeTokenIdentifier)! } +} + +extension ChainModel { + static func identifier(for chainModel: ChainModel) -> String? { + let realm = try! Realm() + let chainList = realm.objects(ChainModel.self) + if let model = chainList.first(where: { $0 == chainModel }) { + return model.identifier + } + return nil + } +} + +extension ChainModel { + public static func == (lhs: ChainModel, rhs: ChainModel) -> Bool { + return lhs.chainId == rhs.chainId && lhs.chainName == rhs.chainName + } +} diff --git a/Neuron/Models/Realm/DAppModel.swift b/Cyton/Models/Realm/DAppModel.swift similarity index 97% rename from Neuron/Models/Realm/DAppModel.swift rename to Cyton/Models/Realm/DAppModel.swift index a4c5763b..a3880bf5 100644 --- a/Neuron/Models/Realm/DAppModel.swift +++ b/Cyton/Models/Realm/DAppModel.swift @@ -1,6 +1,6 @@ // // DAppModel.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/11/22. // Copyright © 2018 Cryptape. All rights reserved. diff --git a/Neuron/Models/Realm/RealmConfigurator.swift b/Cyton/Models/Realm/RealmConfigurator.swift similarity index 91% rename from Neuron/Models/Realm/RealmConfigurator.swift rename to Cyton/Models/Realm/RealmConfigurator.swift index 6229021f..2e38f986 100644 --- a/Neuron/Models/Realm/RealmConfigurator.swift +++ b/Cyton/Models/Realm/RealmConfigurator.swift @@ -1,6 +1,6 @@ // // RealmConfigurator.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/6/8. // Copyright © 2018年 cryptape. All rights reserved. @@ -10,7 +10,7 @@ import Foundation import RealmSwift class RealmConfigurator { - private static var schemaVersion: UInt64 = 7 + private static var schemaVersion: UInt64 = 16 static func configure() { var config = Realm.Configuration() diff --git a/Cyton/Models/Realm/TokenModel.swift b/Cyton/Models/Realm/TokenModel.swift new file mode 100644 index 00000000..2f891b20 --- /dev/null +++ b/Cyton/Models/Realm/TokenModel.swift @@ -0,0 +1,74 @@ +// +// TokenModel.swift +// Cyton +// +// Created by XiaoLu on 2018/7/2. +// Copyright © 2018年 cryptape. All rights reserved. +// + +import Foundation +import RealmSwift +import BigInt + +class TokenModel: Object { + @objc dynamic var name = "" + @objc dynamic var iconUrl: String? = "" + @objc dynamic var address = "" + @objc dynamic var decimals = 18 + @objc dynamic var symbol = "" + @objc dynamic var identifier = UUID().uuidString + + // defaults false, eth and RPC "getMateData" is true. + @objc dynamic var isNativeToken = false + @objc dynamic var chainIdentifier: String = "" + + var chain: ChainModel { + switch type { + case .ether, .erc20: + return EthereumNetwork().chain + case .cita, .citaErc20: + return (try! Realm()).object(ofType: ChainModel.self, forPrimaryKey: chainIdentifier)! + } + } + + override class func primaryKey() -> String? { return "identifier" } + + override static func ignoredProperties() -> [String] { return ["currencyAmount"] } +} + +extension TokenModel { + var type: TokenType { + if isNativeToken { + if chainIdentifier == "" && address == "" { + return .ether + } else { + return .cita + } + } else if chainIdentifier != "" && address != "" { + return .citaErc20 + } else { + return .erc20 + } + } + + var isEthereum: Bool { + return type == .ether || type == .erc20 + } +} + +extension TokenModel { + static func identifier(for tokenModel: TokenModel) -> String? { + return (try! Realm()).objects(TokenModel.self).first(where: { $0 == tokenModel })?.identifier + } +} + +extension TokenModel { + public static func == (lhs: TokenModel, rhs: TokenModel) -> Bool { + return lhs.symbol == rhs.symbol && lhs.name == rhs.name + } + + override func isEqual(_ object: Any?) -> Bool { + guard let object = object as? TokenModel else { return false } + return object.address == address + } +} diff --git a/Cyton/Models/Realm/WalletModel.swift b/Cyton/Models/Realm/WalletModel.swift new file mode 100644 index 00000000..091d8a8d --- /dev/null +++ b/Cyton/Models/Realm/WalletModel.swift @@ -0,0 +1,87 @@ +// +// WalletModel.swift +// Cyton +// +// Created by XiaoLu on 2018/6/6. +// Copyright © 2018年 cryptape. All rights reserved. +// + +import UIKit +import RealmSwift + +class WalletModel: Object { + @objc dynamic var name = "" + @objc dynamic var address = "" + @objc dynamic var iconName: String! + var selectedTokenList = List() + var tokenModelList = List() + var chainModelList = List() + var balanceList = List() + + var wallet: Wallet? { + return WalletManager.default.wallet(for: address) + } + + var icon: Icon { + get { + if let iconName = iconName { + return Icon(rawValue: iconName)! + } + try! (realm ?? Realm()).write { + self.icon = Icon.random() + } + return self.icon + } + set { + iconName = newValue.rawValue + } + } + + override static func primaryKey() -> String? { return "address" } +} + +class TokenBalance: Object { + @objc dynamic var identifier: String! // token identifier + @objc dynamic var value: String! // token balance +} + +extension WalletModel { + enum Icon: String, CaseIterable { + case dog + case fish + case owl + case parrot + case rat + case squirrel + case fox + case tiger + + var image: UIImage { + return UIImage(named: "wallet_icon_\(rawValue)")! + } + } +} + +extension WalletModel.Icon { + static func random() -> WalletModel.Icon { + let iconList = WalletModel.Icon.allCases + var useCount = [Int].init(repeating: 0, count: iconList.count) + try! Realm().objects(WalletModel.self).forEach { (wallet) in + guard let idx = iconList.firstIndex(where: { $0.rawValue == wallet.iconName }) else { return } + useCount[idx] += 1 + } + var minimumUsedCount = Int.max + var minimumUsedList = [WalletModel.Icon]() + for (idx, count) in useCount.enumerated() { + if count < minimumUsedCount { + minimumUsedCount = count + minimumUsedList.removeAll() + } + if count == minimumUsedCount { + minimumUsedList.append(iconList[idx]) + } + } + let randomIdx = Int.random(in: 0.. BigUInt? { + if let signal = refreshBalanceSignal { + signal.wait() + return self.balance + } + refreshBalanceSignal = DispatchGroup() + refreshBalanceSignal?.enter() + defer { + refreshBalanceSignal?.leave() + refreshBalanceSignal = nil + } + + switch type { + case .cita : + balance = try CITANetwork(url: chainHost).getBalance(walletAddress: walletAddress) + case .citaErc20 : + balance = try CITANetwork(url: chainHost).getErc20Balance(walletAddress: walletAddress, contractAddress: address) + case .ether: + balance = try EthereumBalanceLoader(web3: EthereumNetwork().getWeb3(), address: walletAddress).getBalance() + case .erc20: + balance = try EthereumBalanceLoader(web3: EthereumNetwork().getWeb3(), address: walletAddress).getTokenBalance(address: address) + } + refreshBalanceSignal?.leave() + refreshBalanceSignal = nil + return self.balance + } +} + +extension Token { + var tokenModel: TokenModel { + let realm = try! Realm() + return realm.object(ofType: TokenModel.self, forPrimaryKey: identifier)! + } + var walletModel: WalletModel { + return (try! Realm()).object(ofType: WalletModel.self, forPrimaryKey: walletAddress)! + } +} + +extension Token { + var nativeTokenSymbol: String { + switch type { + case .erc20, .citaErc20: + return tokenModel.chain.nativeToken.symbol + case .ether, .cita: + return symbol + } + } + var nativeToken: Token { + return tokenModel.chain.nativeToken.token + } +} + +extension Token: Equatable { + static func == (lhs: Token, rhs: Token) -> Bool { + return + lhs.type == rhs.type && + lhs.address == rhs.address && + lhs.symbol == rhs.symbol && + lhs.walletAddress == rhs.walletAddress + } +} + +extension TokenModel { + var token: Token { return Token(self) } +} diff --git a/Neuron/Models/TransactionDetails.swift b/Cyton/Models/TransactionDetails.swift similarity index 92% rename from Neuron/Models/TransactionDetails.swift rename to Cyton/Models/TransactionDetails.swift index 087b28b8..89cdc14f 100644 --- a/Neuron/Models/TransactionDetails.swift +++ b/Cyton/Models/TransactionDetails.swift @@ -1,6 +1,6 @@ // // TransactionDetails.swift -// Neuron +// Cyton // // Created by 晨风 on 2018/11/14. // Copyright © 2018 Cryptape. All rights reserved. @@ -28,6 +28,8 @@ class TransactionDetails: Codable { var blockNumber: BigUInt = 0 var status: TransactionState = .success var token: Token! + var gasPrice: BigUInt = 0 + var gasLimit: BigUInt = 0 enum CodingKeys: String, CodingKey { case hash @@ -73,3 +75,9 @@ class TransactionDetails: Codable { try container.encode("0x\(String(blockNumber, radix: 16))", forKey: .blockNumber) } } + +extension TransactionDetails { + var isContractCreation: Bool { + return to.count == 0 + } +} diff --git a/Neuron/Resource/currency.plist b/Cyton/Resource/currency.plist similarity index 77% rename from Neuron/Resource/currency.plist rename to Cyton/Resource/currency.plist index 2444de78..34642345 100644 --- a/Neuron/Resource/currency.plist +++ b/Cyton/Resource/currency.plist @@ -9,6 +9,8 @@ CNY symbol ¥ + identifier + zh_CN name @@ -17,6 +19,8 @@ USD symbol $ + identifier + zh-Hans_US name @@ -25,6 +29,8 @@ TWD symbol NT$ + identifier + zh-Hans_TW name @@ -33,6 +39,8 @@ HKD symbol HK$ + identifier + zh-Hans_HK name @@ -41,6 +49,8 @@ EUR symbol + identifier + zh-Hans_FR name @@ -49,6 +59,8 @@ RUB symbol + identifier + zh-Hans_RU diff --git a/Neuron/Resource/neuron.js b/Cyton/Resource/cyton.js similarity index 99% rename from Neuron/Resource/neuron.js rename to Cyton/Resource/cyton.js index e0f03caa..d0787c83 100755 --- a/Neuron/Resource/neuron.js +++ b/Cyton/Resource/cyton.js @@ -46323,7 +46323,7 @@ HookedWalletSubprovider.prototype.handleRequest = function(payload, next, end){ return - // adpter to appchain + // adpter to CITA case 'accounts': // process normally self.getAccounts(function(err, accounts){ @@ -46335,7 +46335,7 @@ HookedWalletSubprovider.prototype.handleRequest = function(payload, next, end){ case 'sendTransaction': console.log("sendTransaction") txParams = payload.params[0] - txParams.chainType = "AppChain" + txParams.chainType = "CITA" waterfall([ // (cb) => self.validateTransaction(txParams, cb), (cb) => self.processTransaction(txParams, cb), @@ -46344,7 +46344,7 @@ HookedWalletSubprovider.prototype.handleRequest = function(payload, next, end){ case 'signTransaction': txParams = payload.params[0] - txParams.chainType = "AppChain" + txParams.chainType = "CITA" waterfall([ // (cb) => self.validateTransaction(txParams, cb), (cb) => self.processSignTransaction(txParams, cb), @@ -46362,7 +46362,7 @@ HookedWalletSubprovider.prototype.handleRequest = function(payload, next, end){ from: address, data: message, }) - msgParams.chainType = "AppChain" + msgParams.chainType = "CITA" waterfall([ // (cb) => self.validateMessage(msgParams, cb), (cb) => self.processMessage(msgParams, cb), @@ -46370,10 +46370,10 @@ HookedWalletSubprovider.prototype.handleRequest = function(payload, next, end){ return // come from personal_sign of ethereum - case 'neuron_sign': + case 'cyton_sign': // process normally - const first_neuron = payload.params[1] - const second_neuron = payload.params[2] + const first_cyton = payload.params[1] + const second_cyton = payload.params[2] // We initially incorrectly ordered these parameters. // To gracefully respect users who adopted this API early, @@ -46382,7 +46382,7 @@ HookedWalletSubprovider.prototype.handleRequest = function(payload, next, end){ // // That means when the first param is definitely an address, // and the second param is definitely not, but is hex. - if (resemblesData(second_neuron) && resemblesAddress(first_neuron)) { + if (resemblesData(second_cyton) && resemblesAddress(first_cyton)) { let warning = `The eth_personalSign method requires params ordered ` warning += `[message, address]. This was previously handled incorrectly, ` warning += `and has been corrected automatically. ` @@ -46403,7 +46403,7 @@ HookedWalletSubprovider.prototype.handleRequest = function(payload, next, end){ from: address, data: message, }) - msgParams.chainType = "AppChain" + msgParams.chainType = "CITA" waterfall([ // (cb) => self.validatePersonalMessage(msgParams, cb), (cb) => self.processPersonalMessage(msgParams, cb), @@ -54051,12 +54051,12 @@ var callbacks = {}; var hookedSubProvider = void 0; var globalSyncOptions = {}; -var Neuron = { +var Cyton = { init: function init(rpcUrl, options, syncOptions) { var engine = new ProviderEngine(); var web3 = new Web3(engine); context.web3 = web3; - context.appchain = web3; + context.cita = web3; globalSyncOptions = syncOptions; @@ -54068,7 +54068,7 @@ var Neuron = { engine.on('error', function (err) { return console.error(err.stack); }); - engine.isNeuron = true; + engine.isCyton = true; engine.start(); return engine; @@ -54098,8 +54098,8 @@ var Neuron = { } }; -if (typeof context.Neuron === 'undefined') { - context.Neuron = Neuron; +if (typeof context.Cyton === 'undefined') { + context.Cyton = Cyton; } ProviderEngine.prototype.setHost = function (host) { @@ -54144,7 +54144,7 @@ ProviderEngine.prototype.send = function (payload) { // throw not-supported Error default: - var message = 'The Neuron Web3 object does not support synchronous methods like ' + payload.method + ' without a callback parameter.'; + var message = 'The Cyton Web3 object does not support synchronous methods like ' + payload.method + ' without a callback parameter.'; throw new Error(message); } // return the result @@ -54164,7 +54164,7 @@ ProviderEngine.prototype.isConnected = function () { }).result; }; -module.exports = Neuron; +module.exports = Cyton; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"web3":297,"web3-provider-engine":283,"web3-provider-engine/subproviders/cache.js":284,"web3-provider-engine/subproviders/filters.js":285,"web3-provider-engine/subproviders/hooked-wallet.js":286,"web3-provider-engine/subproviders/provider.js":287,"web3-provider-engine/subproviders/subscriptions.js":289}]},{},[349]); diff --git a/Neuron/Resource/dappOpration.js b/Cyton/Resource/dappOpration.js similarity index 100% rename from Neuron/Resource/dappOpration.js rename to Cyton/Resource/dappOpration.js diff --git a/Cyton/Resource/en.lproj/product_agreement.txt b/Cyton/Resource/en.lproj/product_agreement.txt new file mode 100644 index 00000000..5df61847 --- /dev/null +++ b/Cyton/Resource/en.lproj/product_agreement.txt @@ -0,0 +1,75 @@ +Last updated on: June 29, 2018 +Dear users: +The Nervos foundation (hereinafter referred to as "foundation" or "we") respects and protects the privacy of users (hereinafter referred to as "you" or "user"). When you use Cyton, the foundation will collect and use your personal information in accordance with this privacy policy (hereinafter referred to as "the policy"). +The foundation recommends that you read and understand the entire policy before using the product (hereafter referred to as "Cyton"), and that important information, including disclaimers, be bolded. The definition of key words in this policy is consistent with the foundation's Cyton service terms. +This policy can be updated online by the foundation at any time. Once the updated policy is published, it replaces the original policy. If you do not accept the modified clause, please immediately stop using Cyton. Once the revised policy is published in Cyton, it takes effect automatically. +You are aware that this policy and other relevant regulations apply to Cyton. Privacy policy of the other DApp developed by Foundation that Cyton links will be separately provided to you by the other DApp. + +I.What information do we collect from you +Please be aware that we collect the following information for your needs in the Cyton service and we take your privacy seriously. When we collect your information, we will strictly abide by the principle of "lawful, just and necessary". And you know that if you do not provide the relevant information needed for our services, your service experience in Cyton may be affected as a result. +1. For the purpose of Cyton service only, we will not collect your mobile device information, operation record, transaction record, wallet address, your name, bank card number, mobile phone number, email address and other personal information; The code used by Cyton will be open-sourced on Github.com to verify the above commitment. +2. For the purpose of optimizing application experience, collect anonymous access statistics, but they do not belong to your personal information. +3. What you know: your wallet password, private key, mnemonic word, and Keystore on the Cyton do not store or synchronize to the foundation server. The foundation does not provide a service for retrieving your wallet password, private key, mnemonic word, and Keystore. +4. In addition to the above content, when you use the Cyton specific function, you will be prompted for more personal information before collecting it. If you choose not to agree, you are deemed to have given up using the particular function of Cyton. +5. When you jump to another DApp developed by the Foundation or a DApp developed by a third party, the other or third party DApp will collect personal information from you with its own special terms and privacy scheme, and you need to make an independent judgment on whether to sign up to use the DApp. Cyton does not collect, retain, and use the personal information that the DApp collects from you. +6. To the extent permitted by laws and regulations, the foundation may collect and use your personal information without your authorization and consent: +(1) those related to national security and national defense security; +(2) relating to public safety, public health and major public interests; +(3) relating to criminal investigation, prosecution, trial and execution of judgment; +(4) the personal information collected is open to the public by yourself; +(5) collect your personal information from legally disclosed information, such as legitimate news reports, government information disclosure and other channels; +(6) necessary to maintain the security and compliance of the service, such as finding and handling failures of products and services; +(7) other circumstances stipulated by laws and regulations. + +II.How do we use your information +1. We will send you important notice in time, such as software update, service agreement and change of this policy. +2. We will provide you with the "fingerprint login" option in the Cyton's "system Settings" to allow you to easily and securely manage your crypto- tokens. Fingerprint information will remain local and Cyton will not collect and retain your fingerprint information. +3. Provisions of laws and regulations and requirements for cooperation with regulatory authorities. + +III.How do you control your information +You have the following independent control of your personal information in Cyton: +1. You can import your other wallets into Cyton by synchronizing your wallet, or import your wallet in Cyton into other crypto- token management wallets. Cyton will show you the information to import the wallet. +2. You are aware that you can modify your crypto-token type, transfer and collection activities through the "assets" section. +3. You know that when we collect information from you for a specific purpose, we will inform you in advance and you have the right to refuse. But at the same time, you know that when you choose to refuse to provide information about the service, you forgo using the relevant service at Cyton. +4. You know that you and we have no control over whether your transaction records are public or not, because based on the open source property of the blockchain transaction system, your transaction records are open and transparent in the whole blockchain system. +5. You know when you use the function of the Cyton to jump to the development of Foundation’s other DApp or third-party DApp, our "Cyton service agreement", and the Cyton privacy policy will no longer applicable, for your personal information about you on the DApp control problem, we recommend that you read before using the DApp and to understand its privacy rules and the user service agreement, etc. +6.You have the right to ask us to update, change, and delete your information collected by Cyton. +7. You are aware that we may collect your information in accordance with the requirements of article 1, section 6 of this policy without obtaining your prior authorization consent. + +IV.We may share or transmit your information +1. User personal information collected and generated by the foundation within the territory of the People's Republic of China will be stored on servers within the territory of the People's Republic of China. If the foundation really needs to transmit your personal information to overseas, it will obtain your authorization in advance, carry out cross-border data transmission in accordance with the requirements of relevant laws, regulations and policies, and perform the confidentiality obligation on your personal information. +2. The foundation will not share or transfer your personal information to any third party without your prior consent, unless: +(1) obtain your express consent or authorization in advance; +(2) the personal information collected is open to the public by yourself; +(3) the personal information collected is collected from the information disclosed legally, such as legal news reports, government information disclosure and other channels; +(4) sharing with the foundation's affiliates, we will only share the necessary user information and will be bound by the stated purpose in this privacy clause; +(5) to be provided in accordance with applicable laws and regulations, requirements of legal procedures, and requirements of administrative or judicial authorities; +(6) when merger or acquisition is involved, if personal information transfer is involved, the foundation will require the recipient of personal information to continue to be bound by this policy. + +V. How do we protect your information +1. If the Foundation ceases operation, the Foundation will stop the activity of collecting your personal information in time, put the notification of the cessation on the Cyton, and delete or anonymize your personal information held for a reasonable period of time. +2. In order to protect your personal information, the Foundation will adopt data security technical measures, improve internal compliance level, increase internal employee information security training, and set up security access rights for relevant data to protect your privacy information. +3. We will send you information about information security in the Cyton "message center" and periodically update your wallet usage and information protection information on the Cyton "help center" section for your reference. + +VI. The protection of minors +We have the following special agreements on the protection of minors under the age of 18: +1. Minors shall use Foundation services under the guidance of their parents or legal guardians. +2. Parents and legal guardians of minors shall instruct minors in the use of Cyton on the premise of reading the policy, the Cyton service terms and our other relevant rules. +3. The privacy and security of minors' personal information will be protected in accordance with national laws and regulations. + +VII. Disclaimer +1. Please note that when you access the third-party DApp via Cyton links, the privacy policy issued by the third-party DApp will apply. The third-party DApp's collection and use of your personal information is not controlled by the Foundation and is not subject to this policy. The Foundation cannot guarantee that the third-party DApp will take personal information protection measures as required by the Foundation. +2. You should carefully select and use third-party DApp and properly protect your personal information. The Foundation shall not be responsible for the privacy protection of other third-party DApp. +3. Please note that when you use the Cyton access Foundation's other DApp, the privacy policy issued by that other DApp will apply. The DApp's collection and use of your personal information is not subject to this policy. +4. The foundation shall, as far as possible, take reasonable security measures to protect your personal information at the current technical level to avoid information leakage, tampering or damage. The Foundation uses wireless to transmit data, so it cannot guarantee the privacy and security of transmitting data over the wireless network. + +VIII. Miscellaneous +1. You need to fully understand and comply with all relevant laws, regulations and rules regarding your jurisdiction and use of foundation services. +2. During the use of the foundation services, if you encounter any problems with the use of personal information, you can contact us by submitting feedback in Cyton. +3. You can view this policy and the foundation's other service rules in Cyton. We encourage you to check the foundation's service protocol and privacy policy every time you visit Cyton. +4. Any translated version of this policy is provided for the convenience of users only, and there is no intention to modify the terms of this policy. If there is a conflict between the Chinese version and the non-chinese version of this policy, the Chinese version shall prevail. +5. This policy shall apply from June 29, 2018. + +For matters not covered by this policy, you shall comply with the announcement and relevant rules updated by the foundation from time to time. + +Nervos foundation diff --git a/Cyton/Resource/guide_image/en.lproj/guide_page_1@2x.png b/Cyton/Resource/guide_image/en.lproj/guide_page_1@2x.png new file mode 100644 index 00000000..f4a0df40 Binary files /dev/null and b/Cyton/Resource/guide_image/en.lproj/guide_page_1@2x.png differ diff --git a/Cyton/Resource/guide_image/en.lproj/guide_page_1@3x.png b/Cyton/Resource/guide_image/en.lproj/guide_page_1@3x.png new file mode 100644 index 00000000..21d6c0d3 Binary files /dev/null and b/Cyton/Resource/guide_image/en.lproj/guide_page_1@3x.png differ diff --git a/Cyton/Resource/guide_image/en.lproj/guide_page_2@2x.png b/Cyton/Resource/guide_image/en.lproj/guide_page_2@2x.png new file mode 100644 index 00000000..4e07cf2b Binary files /dev/null and b/Cyton/Resource/guide_image/en.lproj/guide_page_2@2x.png differ diff --git a/Cyton/Resource/guide_image/en.lproj/guide_page_2@3x.png b/Cyton/Resource/guide_image/en.lproj/guide_page_2@3x.png new file mode 100644 index 00000000..20328964 Binary files /dev/null and b/Cyton/Resource/guide_image/en.lproj/guide_page_2@3x.png differ diff --git a/Cyton/Resource/guide_image/en.lproj/guide_page_3@2x.png b/Cyton/Resource/guide_image/en.lproj/guide_page_3@2x.png new file mode 100644 index 00000000..b02951c9 Binary files /dev/null and b/Cyton/Resource/guide_image/en.lproj/guide_page_3@2x.png differ diff --git a/Cyton/Resource/guide_image/en.lproj/guide_page_3@3x.png b/Cyton/Resource/guide_image/en.lproj/guide_page_3@3x.png new file mode 100644 index 00000000..a64ff4ec Binary files /dev/null and b/Cyton/Resource/guide_image/en.lproj/guide_page_3@3x.png differ diff --git a/Cyton/Resource/guide_image/zh-Hans.lproj/guide_page_1@2x.png b/Cyton/Resource/guide_image/zh-Hans.lproj/guide_page_1@2x.png new file mode 100644 index 00000000..6eb469d3 Binary files /dev/null and b/Cyton/Resource/guide_image/zh-Hans.lproj/guide_page_1@2x.png differ diff --git a/Cyton/Resource/guide_image/zh-Hans.lproj/guide_page_1@3x.png b/Cyton/Resource/guide_image/zh-Hans.lproj/guide_page_1@3x.png new file mode 100644 index 00000000..f16597fc Binary files /dev/null and b/Cyton/Resource/guide_image/zh-Hans.lproj/guide_page_1@3x.png differ diff --git a/Cyton/Resource/guide_image/zh-Hans.lproj/guide_page_2@2x.png b/Cyton/Resource/guide_image/zh-Hans.lproj/guide_page_2@2x.png new file mode 100644 index 00000000..057d35a6 Binary files /dev/null and b/Cyton/Resource/guide_image/zh-Hans.lproj/guide_page_2@2x.png differ diff --git a/Cyton/Resource/guide_image/zh-Hans.lproj/guide_page_2@3x.png b/Cyton/Resource/guide_image/zh-Hans.lproj/guide_page_2@3x.png new file mode 100644 index 00000000..223cc105 Binary files /dev/null and b/Cyton/Resource/guide_image/zh-Hans.lproj/guide_page_2@3x.png differ diff --git a/Cyton/Resource/guide_image/zh-Hans.lproj/guide_page_3@2x.png b/Cyton/Resource/guide_image/zh-Hans.lproj/guide_page_3@2x.png new file mode 100644 index 00000000..23b69de0 Binary files /dev/null and b/Cyton/Resource/guide_image/zh-Hans.lproj/guide_page_3@2x.png differ diff --git a/Cyton/Resource/guide_image/zh-Hans.lproj/guide_page_3@3x.png b/Cyton/Resource/guide_image/zh-Hans.lproj/guide_page_3@3x.png new file mode 100644 index 00000000..fd58286c Binary files /dev/null and b/Cyton/Resource/guide_image/zh-Hans.lproj/guide_page_3@3x.png differ diff --git a/Neuron/Resource/init.js b/Cyton/Resource/init.js similarity index 84% rename from Neuron/Resource/init.js rename to Cyton/Resource/init.js index 3ffe0521..aa8ebd10 100644 --- a/Neuron/Resource/init.js +++ b/Cyton/Resource/init.js @@ -1,21 +1,21 @@ function executeCallback (id, error, value) { - Neuron.executeCallback(id, error, value) + Cyton.executeCallback(id, error, value) } function onSignSuccessful(id, value) { console.log("onSignSuccessful", value) - Neuron.executeCallback(id, null, value) + Cyton.executeCallback(id, null, value) } function onSignError(id, error) { - Neuron.executeCallback(id, error, null) + Cyton.executeCallback(id, error, null) } -window.Neuron.init(rpcURL, { +window.Cyton.init(rpcURL, { getAccounts: function (cb) { cb(null, [addressHex]) }, processTransaction: function (tx, cb){ console.log('signing a transaction', tx) const { id = 8888 } = tx - Neuron.addCallback(id, cb) + Cyton.addCallback(id, cb) var data = tx.data || null; var nonce = tx.nonce || -1; @@ -39,21 +39,21 @@ window.Neuron.init(rpcURL, { console.log('signMessage', msgParams) const { data, chainType } = msgParams const { id = 8888 } = msgParams - Neuron.addCallback(id, cb) + Cyton.addCallback(id, cb) webkit.messageHandlers.signMessage.postMessage({"name": "signMessage","chainType": chainType, "object": { data }, id: id}) }, signPersonalMessage: function (msgParams, cb) { console.log('signPersonalMessage', msgParams) const { data, chainType } = msgParams const { id = 8888 } = msgParams - Neuron.addCallback(id, cb) + Cyton.addCallback(id, cb) webkit.messageHandlers.signPersonalMessage.postMessage({"name": "signPersonalMessage","chainType": chainType, "object": { data }, id: id}) }, signTypedMessage: function (msgParams, cb) { console.log('signTypedMessage ', msgParams) const { data } = msgParams const { id = 8888 } = msgParams - Neuron.addCallback(id, cb) + Cyton.addCallback(id, cb) webkit.messageHandlers.signTypedMessage.postMessage({"name": "signTypedMessage","chainType": chainType, "object": { data }, id: id}) } }, { @@ -61,7 +61,7 @@ window.Neuron.init(rpcURL, { networkVersion: chainID }) window.web3.setProvider = function () { - console.debug('Neuron Wallet - overrode web3.setProvider') + console.debug('Cyton Wallet - overrode web3.setProvider') } window.web3.version.getNetwork = function(cb) { @@ -74,10 +74,10 @@ window.web3.eth.defaultAccount = addressHex window.isNervosReady = true window.isMetaMask = true -window.neuron = Object() -window.neuron.getAccount = function() { +window.cyton = Object() +window.cyton.getAccount = function() { return addressHex } -window.neuron.getAccounts = function() { +window.cyton.getAccounts = function() { return accounts.split(",") } diff --git a/Cyton/Resource/zh-Hans.lproj/product_agreement.txt b/Cyton/Resource/zh-Hans.lproj/product_agreement.txt new file mode 100644 index 00000000..646567f5 --- /dev/null +++ b/Cyton/Resource/zh-Hans.lproj/product_agreement.txt @@ -0,0 +1,230 @@ +最近更新于:2018年6月29日 +尊敬的用户: +Nervos基金会(以下简称“基金会”或“我们”)尊重并保护用户(以下简称“您”或“用户”)的隐私,您使用Cyton时,基金会将按照本隐私政策(以下简称“本政策”)收集、使用您的个人信息。 +基金会建议您在使用本产品(以下简称“Cyton”)之前仔细阅读并理解本政策全部内容, 针对免责声明等条款在内的重要信息将以加粗的形式体现。本政策有关关键词定义与基金会《Cyton服务协议》保持一致。 +本政策可由基金会在线随时更新,更新后的政策一旦公布即代替原来的政策,如果您不接受修改后的条款,请立即停止使用Cyton,您继续使用Cyton将被视为接受修改后的政策。经修改的政策一经在Cyton上公布,立即自动生效。 +您知悉本政策及其他有关规定适用于Cyton,Cyton上能链接的基金会所开发的DApp的隐私政策由该DApp另行向您提供。 +一、 我们收集您的哪些信息 +请您知悉,我们收集您的以下信息是出于满足您在Cyton服务需要的目的,且我们十分重视对您隐私的保护。在我们收集您的信息时,将严格遵守“合法、正当、必要”的原则。且您知悉,若您不提供我们服务所需的相关信息,您在Cyton的服务体验可能因此而受到影响。 +1. 仅为满足Cyton服务的目的,我们将不会收集您的移动设备信息、操作记录、交易记录、钱包地址、您的姓名、银行卡号、手机号码、邮件地址等个人信息;Cyton使用的代码将在Github上进行开源以验证以上承诺。 +2. Cyton仅为了优化应用体验的目的,收集匿名的访问统计数据,但是这些数据不属于您的个人信息。 +3. 您知悉:您在Cyton 上的钱包密码、私钥、助记词、Keystore并不存储或同步至基金会服务器。基金会不提供找回您的钱包密码、私钥、助记词、Keystore的服务。 +4. 除上述内容之外,您知悉在您使用Cyton特定功能时,我们将在收集您的个人信息前向您作出特别提示,要求向您收集更多的个人信息。如您选择不同意,则视为您放弃使用Cyton该特定功能。 +5. 当您跳转到基金会开发的DApp或者第三方开发的DApp后,该DApp会以他自己特有的条款和隐私方案向您收集个人信息,您需要独立作出判断是否签约使用该DApp。Cyton不收集、留存和使用该DApp向您收集的个人信息。 +6. 在法律法规允许的范围内,基金会可能会在以下情形中收集并使用您的个人信息无需征得您的授权同意: +(1) 与国家安全、国防安全有关的; +(2) 与公共安全、公共卫生、重大公共利益有关的; +(3) 与犯罪侦查、起诉、审判和判决执行等有关的; +(4) 所收集的个人信息是您自行向社会公众公开的; +(5) 从合法公开披露的信息中收集您的个人信息,如合法的新闻报道,政府信息公开等渠道; +(6) 用于维护服务的安全和合规所必需的,例如发现、处理产品和服务的故障; +(7) 法律法规规定的其他情形。 +二、 我们如何使用您的信息 +1. 我们将向您及时发送重要通知,如软件更新、服务协议及本政策条款的变更。 +2. 我们将在Cyton的“系统设置”中为您提供“指纹登录”选项,让您方便且更安全地管理您的数字代币;指纹信息将保留在本地,Cyton不会采集和留存您的指纹信息。 +3. 法律法规规定及与监管机构配合的要求。 +三、 您如何控制自己的信息 +您在Cyton中拥有以下对您个人信息自主控制权: +1. 您可以通过同步钱包的方式,将您的其他钱包导入Cyton中,或者将您在Cyton的钱包导入到其他数字代币管理钱包中。Cyton将向您显示导入钱包的信息。 +2. 您知悉您可以通过“资产”版块内容修改您的数字代币种类、进行转账及收款等活动。 +3. 您知悉当我们出于特定目的向您收集信息时,我们会提前给予您通知,您有权选择拒绝。但同时您知悉,当您选择拒绝提供有关信息时,即表示您放弃使用Cyton的有关服务。 +4. 您知悉,您及我们对于您交易记录是否公开并没有控制权,因为基于区块链交易系统的开源属性,您的交易记录在整个区块链系统中公开透明。 +5. 您知悉当您使用Cyton的功能跳转至基金会开发的DApp或第三方DApp之后,我们的《Cyton服务协议》、《Cyton隐私政策》将不再适用,针对您在该DApp上对您个人信息的控制权问题,我们建议您在使用该DApp之前详细阅读并了解其隐私规则和有关用户服务协议等内容。 +6. 您有权要求我们更新、更改、删除Cyton收集的您的有关信息。 +7. 您知悉我们可以根据本政策第一条第6款的要求收集您的信息而无需获得您的授权同意。 +四、 我们可能分享或传输您的信息 +1. 基金会在中华人民共和国境内收集和产生的用户个人信息将存储在中华人民共和国境内的服务器上。若基金会确需向境外传输您的个人信息,将在事前获得您的授权,且按照有关法律法规政策的要求进行跨境数据传输,并对您的个人信息履行保密义务。 +2. 未经您事先同意,基金会不会将您的个人信息向任何第三方共享或转让,但以下情况除外: +(1) 事先获得您明确的同意或授权; +(2) 所收集的个人信息是您自行向社会公众公开的; +(3) 所收集的个人信息系从合法公开披露的信息中收集,如合法的新闻报道,政府信息公开等渠道; +(4) 与基金会的关联方共享,我们只会共享必要的用户信息,且受本隐私条款中所声明的目的的约束; +(5) 根据适用的法律法规、法律程序的要求、行政机关或司法机关的要求进行提供; +(6) 在涉及合并、收购时,如涉及到个人信息转让,基金会将要求个人信息接收方继续接受本政策的约束。 +五、 我们如何保护您的信息 +1. 如基金会停止运营,基金会将及时停止继续收集您个人信息的活动,将停止运营的通知公告在Cyton上,并对所持有的您的个人信息在合理期限内进行删除或匿名化处理。 +2. 为了保护您的个人信息,基金会将采取数据安全技术措施,提升内部合规水平,增加内部员工信息安全培训,并对相关数据设置安全访问权限等方式安全保护您的隐私信息。 +3. 我们将在Cyton“消息中心”中向您发送有关信息安全的消息,并不时在Cyton“帮助中心”版块更新钱包使用及信息保护的资料,供您参考。 +六、 对未成年人的保护 +我们对保护未满18周岁的未成年人做出如下特别约定: +1. 未成年人应当在父母或监护人指导下使用基金会相关服务。 +2. 未成年人的父母和监护人应当在阅读本政策、《Cyton服务协议》及我们的其他有关规则的前提下,指导未成年人使用Cyton。 +3. Cyton将根据国家相关法律法规的规定保护未成年人的个人信息的保密性及安全性。 +七、 免责声明 +1. 请您注意,您通过Cyton接入第三方DApp后,将适用该第三方DApp发布的隐私政策。该第三方DApp对您个人信息的收集和使用不为基金会所控制,也不受本政策的约束。基金会无法保证第三方DApp一定会按照基金会的要求采取个人信息保护措施。 +2. 您应审慎选择和使用第三方DApp,并妥善保护好您的个人信息,基金会对其他第三方DApp的隐私保护不负任何责任。 +3. 请您注意,您通过Cyton接入基金会开发的DApp后,将适用该DApp发布的隐私政策。该DApp对您个人信息的收集和使用不受本政策的约束。 +4. 基金会将在现有技术水平条件下尽可能采取合理的安全措施来保护您的个人信息,以避免信息的泄露、篡改或者毁损。基金会系利用无线方式传输数据,因此,基金会无法确保通过无线网络传输数据的隐私性和安全性。 +八、 其他 +1. 您需全面了解并遵守您所在司法辖区与使用基金会服务所有相关法律、法规及规则。 +2. 您在使用基金会服务过程中,如遇到任何有关个人信息使用的问题,您可以通过在Cyton提交反馈等方式联系我们。 +3. 您可以在Cyton中查看本政策及基金会其他服务规则。我们鼓励您在每次访问Cyton时都查阅基金会的服务协议及隐私政策。 +4. 本政策的任何译文版本仅为方便用户而提供,无意对本政策的条款进行修改。如果本政策的中文版本与非中文版本之间存在冲突,应以中文版本为准。 +5. 本政策自2018年6月29日起适用。 +本政策未尽事宜,您需遵守基金会不时更新的公告及相关规则。 +Nervos基金会 + + +《Cyton服务协议》 +最近更新于:2018年6月29日 +尊敬的用户: +感谢您选择Cyton服务。《Cyton服务协议》(以下简称“本协议”)由Nervos基金会(以下简称“基金会”或“我们”)和用户(以下简称“您”或“用户”)签订,本协议在您与基金会之间具有合同上的法律效力。 +基金会在此特别提醒您在使用Cyton(以下简称“Cyton” 或“本软件”)之前,请认真阅读《Cyton服务协议》及后文提到的相关协议,尤其是本协议规定的“免责及责任限制”等条款将以加粗的形式突出体现,确保您充分理解本协议中各条款,并自主考虑风险。 +基金会在此特别提醒您,由于Cyton所使用的代码将在Github上开源,任何人都可能使用开源的Cyton代码,或自行修改后的代码,来打包形成软件。对于这些私自打包形成的软件,并非Cyton应用软件,不受本协议约束,基金会不承担任何责任。本协议只适用于使用基金会官方打包的安装包安装,得到基金会官方授权的Cyton应用软件。 + +一、 关于本协议的确认与接纳 +1. 您理解本协议及有关协议仅适用于Cyton应用本身,而不包括Cyton所能链接的基金会所自主开发和拥有的其他应用,也不包括任何第三方开发或拥有的应用。 +2. 您下载Cyton软件并创建或导入钱包,即视为您已经充分阅读并接受本协议全部条款,本协议立即生效,对双方具有约束力。 +3. 本协议可由基金会随时更新,经修改的协议一经在Cyton上公布,立即自动生效,恕不再另行通知。在基金会公布修改协议条款后,如果您不接受修改后的条款,请立即停止使用Cyton,您继续使用Cyton将被视为接受修改后的协议。 +4. 如果您未满18周岁,或者是无民事行为能力人或限制民事行为能力人,请在父母或监护人指导下使用Cyton。 +二、 定义 +1. Cyton:指由基金会基于Nervos网络和Ethereum网络开发的,向用户提供访问Nervos网络和Ethereum网络,以及保存Nervos网络和Ethereum网络加密数字资产的服务的钱包客户端,包括其他为方便用户使用相关系统而开发的辅助工具。 +2. 用户: +(1)用户必须是具备完全民事行为能力的自然人; +(2)若您为18周岁以下的未成年人使用Cyton服务,需要在您父母或监护人的指导下使用Cyton。无民事行为能力人使用Cyton或限制民事行为能力人超过其民事权利或行为能力范围从事交易的,造成的一切后果,Cyton有权要求您及您的父母或监护人负责。 +3. 创建或导入钱包:指您使用Cyton,确认履行本协议并创建或导入钱包的过程。 +4. 钱包密码:指您在创建Cyton钱包过程中,软件操作界面提示您填写的密码,该密码用于加密保护私钥。作为去中心化的应用,钱包密码不存储在您的这台移动设备或基金会的服务器,一旦丢失你需要借助明文私钥或助记词重置新密码。 +5. 信息提示:Cyton软件操作界面涉及的信息提示内容,建议用户按照相关步骤进行操作。 +6. 特定用户:指按照当地法律法规及政策规定必须要配合基金会履行个人信息披露义务的用户。 +7. 私钥:由私密随机字符构成,是用户拥有并使用数字代币的核心。 +8. 公钥:由私钥借助密码学原理单向推导生成,并用以生成区块链数字钱包地址,数字钱包地址即为公开收款地址。 +9. 助记词:由随机算法生成的若干个有序英文单词组成。助记词是私钥的易记录表现形式,方便用户备份保管。 +10. Keystore: 是私钥或助记词经过用户设置的钱包密码加密保存的文件形式,它只存储在您的这台移动设备中,不会同步至基金会服务器。 +11. 数字代币:指Cyton目前支持的数字代币种类,包括但不限于CKC、ETH、以太坊ERC20标准的代币、以太坊ERC721标准的代币等。 +12. 个人信息:指以电子或者其他方式记录的能够单独或者与其他信息结合识别用户个人身份的各种信息,包括但不限于自然人的姓名、出生日期、身份证件号码、个人生物识别信息、住址、电话号码、银行卡号、邮件地址、钱包地址、移动设备信息、操作记录、交易记录等,但不包括用户的钱包密码、私钥、助记词、Keystore。 +三、 服务内容 +1. 创建或导入钱包。对Cyton支持的数字代币,您可以使用Cyton生成新钱包或导入相关区块链系统的其它钱包工具生成的兼容钱包。 +2. 转账、收款。您可以使用Cyton的转账、收款功能进行数字代币的操作。转账是指付款方利用收款方的区块链地址进行转账操作,实际的转账、收款行为均在相关区块链系统(而非Cyton)发生。 +3. 管理数字资产。您可以使用Cyton添加、保管并移除Cyton所支持的数字代币。 +5. 浏览DApp。用户通过在Cyton上的链接,可以跳转至DApp并使用该DApp(包括基金会自己的DApp和第三方DApp)提供的服务。 +6. 暂停服务。您知悉基于区块链系统交易“不可撤销”的属性,我们不能为您暂停或撤销转账交易等操作,但在行政机关指令等紧急情况等下,我们可以暂停或者限制某位用户对Cyton软件的操作。 +7. 其他基金会认为有必要提供的服务。 +用户接受基金会提供的上述服务时应了解以下常见问题: +1. 秉承着区块链的去中心化特点,并为了保护用户的数字代币安全,基金会提供的是去中心化服务,与银行业金融机构提供的中心化金融服务具有根本性区别。用户了解,基金会不提供以下服务: +(1)行情查看; +(2)存储用户的钱包密码(即用户创建/导入钱包时设置的密码)、私钥、助记词、Keystore; +(3)找回用户的钱包密码、私钥、助记词、Keystore; +(4)冻结钱包; +(5)挂失钱包; +(6)恢复钱包; +(7)交易回滚; +(8)交易记录(用户进行的成功的交易记录将被记录在区块链系统账本上,Cyton自身不提供历史交易数据访问服务)。 +2. 由于基金会不提供上述服务,因此用户应当自行保管含有Cyton的移动设备及其关键芯片和硬件、备份Cyton、备份钱包密码、助记词、私钥及Keystore。如用户遗失移动设备、删除且未备份Cyton、删除且未备份钱包、钱包被盗或遗忘钱包密码、私钥、助记词、Keystore,基金会均无法还原钱包或找回钱包密码、私钥、助记词、Keystore;如用户进行交易时误操作(例如输错转账地址),基金会亦无法取消交易。 +3. 基金会和Cyton所能够提供的数字代币管理服务并未包括所有已存在的数字代币,请勿通过Cyton操作任何Cyton不支持的数字代币。 +4. Cyton仅是用户的数字代币管理工具,并非交易所或交易平台。虽然本协议将多次提及“交易”,其行为泛指用户使用Cyton进行的转账和收款操作,这与交易所或交易平台上进行的“交易”有本质区别。 +5. Cyton上集成的DApp包括基金会自主拥有的DApp和第三方平台提供的DApp。对于Cyton上每个基金会自己开发和拥有的DApp,都会有独立的用户协议和数据隐私政策,用户应当独立作出判断是否进行签约使用。对于第三方平台提供的DApp,Cyton仅为用户进入DApp提供区块链浏览器。用户在第三方DApp上接受服务或进行交易前应自行判断和评估该第三方DApp提供的服务或交易是否存在风险,基金会和Cyton不承担任何质量和责任担保义务。 +四、 您的权利义务 +(一)创建或导入钱包 +1. 创建或导入钱包:您有权在您的移动设备上通过Cyton创建和/或导入钱包,有权设定钱包的钱包密码等信息,并有权通过Cyton应用程序,使用自己的钱包在区块链上进行转账和收款等交易。 +2. 身份验证:按照有关法律法规和政策要求和可能产生的要求变化,特定用户在使用Cyton提供的有关服务时,应当按照Cyton的提示通过基金会另行开发的KYC应用程序或者第三方开发KYC应用程序及时完成相关身份验证,要求您提交包括但不限于您的姓名、身份证号码、手机号码、银行卡号信息等个人信息;Cyton自身不会采集和留存以上任何个人信息。未通过以上身份验证的特定用户将无法使用有关服务,因特定用户拖延造成的损失由您自行承担。 +3. 基金会可能为不同的终端设备开发不同的软件版本,您应当根据实际需要选择下载合适的版本进行安装。如果您从未经合法授权的第三方获取本软件或与本软件名称相同的安装程序,基金会将无法保证该软件能否正常使用,也无法保证其安全性,因此造成的损失由您自行承担。 +4. 本软件新版本发布后,旧版软件可能无法使用。基金会不保证旧版软件的安全性、继续可用性及提供相应的客户服务。请您随时核对并下载最新版本。 +(二)使用 +1. 用户应自行妥善保管移动设备、钱包密码、私钥、助记词、Keystore等信息。基金会不负责为用户保管以上信息。因您遗失移动设备、主动或被动泄露、遗忘钱包密码、私钥、助记词、Keystore或遭受他人攻击、诈骗等所引起的一切风险、责任、损失、费用应由您自行承担。 +2. 遵循信息提示。您了解并同意遵循Cyton对您做出的信息提示,按照信息提示的内容进行操作,否则,由此引起的一切风险、责任、损失、费用等应由您自行承担。 +3. 您知悉并理解Cyton没有义务对链接的任何非Cyton应用自身部分的,特别是第三方提供的DApp服务或交易履行尽职调查义务,您应当理性做出交易、投资决策并自主承担相应的交易、投资风险。 +4. 积极完成身份验证。当Cyton合理认为您的交易行为或交易情况出现异常的,或认为您的身份信息存在疑点的,或Cyton认为应核对您身份证件或其他必要文件的情形时,请您积极配合Cyton核对您的有效身份证件或其他必要文件,及时完成相关的身份验证。 +5. 转账。 +(1)您理解基于区块链操作的“不可撤销”属性,当您使用Cyton转账功能时,您应当自行承担因您操作失误而导致的后果(包括但不限于因您输错转账地址、您自身选择转账节点服务器的问题)。 +(2)您知悉在使用Cyton服务时,以下情况的出现可能导致转账“交易失败”或“打包超时”: +a) 钱包余额不足; +b) 交易矿工费不足; +c) 区块链执行合约代码失败; +d) 网络、设备等技术故障; +e) 区块链网络拥堵、故障等原因引起交易被抛弃。 +(4)您知悉Cyton仅向您提供转账工具,在您使用Cyton完成转账后,基金会即完成了当次服务的所有义务,基金会对其他纠纷争议,不负担任何义务。 +6. 合法合规。您知悉在Cyton进行操作时或进行交易时,您应当遵循有关法律法规、国家政策的要求。 +7. 公告通知。Cyton会以网站公告、电子邮件、发送短信、电话、消息中心信息、弹窗提示或客户端通知等方式向您发送通知,例如通知您交易进展情况,或者提示您进行相关操作,请您及时予以关注。 +8. 服务费用与纳税义务: +(1)Cyton暂时不向您收取任何形式的服务费或手续费,将来需对某些服务进行收费时将另行约定或公布规则; +(2)您使用Cyton进行转账时应支付矿工费,金额由您自行决定。矿工费由相关区块链系统收取; +(3)您知悉在特定情况下,因为您所处的环境及网络状态不稳定,导致您的转账操作未完成时,亦会被相关区块链系统收取矿工费; +(4)您因在Cyton进行交易而发生的所有应纳税负及其它方面的费用均由您负责支付。 +五、 风险提示 +1. 您了解并知悉,由于数字代币领域的法律法规政策尚未健全,该领域的数字代币可能会产生无法兑现、技术不稳定等重大风险。且数字代币的价格波动幅度远高于其他金融资产。我们谨慎提醒您应当根据自身财务状况和风险偏好,理性选择持有或处置任何一种数字代币。Cyton不提供行情报价服务。 +2. 在使用Cyton服务时,若您或您的相对方未遵从本协议或相关网站说明、交易、支付页面中之操作提示、规则,Cyton并不保证交易会顺利完成,且Cyton不承担损害赔偿责任。若发生前述情形,而款项已先行入账您的或您的交易方的Cyton钱包或第三方钱包,您理解区块链操作具有的“不可逆”属性,以及相关交易具有“不可撤销”的特征,由您及您的相对方自行承担相应的风险后果。 +3. 在您使用Cyton集成的基金会开发的DApp或第三方DApp服务或进行交易时,为了您的利益,基金会建议您仔细阅读本协议及Cyton提示,了解交易对象及产品信息,谨慎评估风险后再采取行动。所有您在基金会开发的DApp或第三方DApp进行的交易行为系您的个人行为,有约束力的合同关系在您和您的相对方之间按照特定的DApp的协议内容和隐私条件订立,与Cyton和本协议无关。Cyton和基金会对因您的以上交易行为所引起的一切风险、责任、损失、费用不应因本协议的履行承担任何责任。 +4. 您在交易过程中应当自行判断对方是否为完全民事行为能力人并自行决定是否与对方进行交易或转账给对方等,且您自行承担与此相关的所有风险。 +5. 在转账过程中,如果出现“交易失败”、“打包超时”等类似的异常信息提示时,您应通过相关区块链系统的官方途径或其他的区块链查询工具进行再次确认,以避免重复转账;否则,由此所引起的一切损失和费用应由您自行承担。 +6. 您理解当您在Cyton上创建或导入钱包之后,您的Keystore、私钥、助记词等信息仅存储在当前的这台移动设备中,不存储在Cyton或基金会的服务器上。您可以按照Cyton提供的操作指南采取同步钱包等方式更换移动设备。但若您未保存或备份钱包密码、私钥、助记词、Keystore等信息且在您移动设备丢失的情况下,您的数字代币将因此丢失,基金会无法为您找回,您需自行承担相应损失。若您在导出、保存或备份钱包密码、私钥、助记词、Keystore等信息的时候泄密,或保存或备份上述信息的设备或服务器被黑客攻击或控制等情况下,您的数字代币将因此丢失,基金会无法为您找回,您需自行承担相应损失。 +7. 我们建议您在创建或导入钱包时对您钱包的钱包密码、私钥、助记词及Keystore等信息做好安全备份。我们提请您注意,请不要采用以下备份方式:截图、邮件、记事本、短信、微信、QQ等电子备份方式。我们建议您在纸质记事本上抄写助记词和Keystore等信息,同时您亦可将电子数据保管至密码管理器。 +8. 我们建议您在安全的网络环境和安全的硬件设备中使用Cyton,确保您的移动设备没有越狱或Root, 以避免可能存在的安全隐患 +9. 请您在使用我们的服务过程中,警惕非Cyton官方的诈骗行为。一旦发现此类行为,我们鼓励您第一时间告知我们。 +六、 服务的变更、中断、终止 +1. 您同意基金会为保证自主业务经营权可以暂时提供部分服务功能,或于将来暂停部分服务功能或开通新的服务功能。当任何功能减少或者增加或者变化时,只要您仍然使用基金会提供的服务,表示您仍然同意本协议或者本协议修正后的条款。 +2. 您理解存在如下情形时,基金会将暂停提供服务: +(1)因设备、区块链系统维修、升级、故障和通信中断等技术原因而中断业务; +(2)因台风、地震、海啸、洪水、停电、战争或恐怖袭击等不可抗力因素,病毒、木马、黑客攻击、系统不稳定或政府行为等原因,造成基金会系统不能提供服务或基金会合理认为继续提供服务会有较大风险的; +(3)发生基金会无法控制或合理预见的其他情形。 +3. 当您出现如下情况时,基金会可单方面中止或终止您使用Cyton的部分或全部功能: +(1)用户死亡; +(2)盗用他人的钱包信息或移动设备; +(3)填写个人信息时提供虚假信息; +(4)拒绝基金会为提升Cyton功能而发起的强制更新操作; +(5)将Cyton用于违法或犯罪活动; +(6)妨碍其他用户正常使用; +(7)伪称基金会的工作人员或管理人员; +(8)攻击、侵入、更改或以任何其他方式威胁基金会计算机系统的正常运作; +(9)利用Cyton宣传垃圾广告; +(10)散布谣言,损害基金会和Cyton商誉; +(11)违法行为,其他违反本协议的行为,及基金会合理认为应当暂停功能的情形。 +4. 当您与基金会之间的服务关系变更、中断、终止时,您仍有权在合理时间内导出您钱包等信息。 +七、 您合法使用基金会服务的承诺 +1. 您应遵守中华人民共和国相关法律法规及您所居住的国家或地区的法律法规,不得将Cyton用于任何非法目的,也不得以任何非法方式使用基金会服务。 +2. 您不得利用Cyton从事违法或犯罪的行为,包括但不限于: +(1)反对宪法所确定的基本原则,危害国家安全、泄漏国家秘密、颠覆国家政权、破坏国家统一的; +(2)从事任何违法犯罪行为,包括但不限于洗钱、非法集资等; +(3)通过使用任何自动化程序、软件、引擎、网络爬虫、网页分析工具、数据挖掘工具或类似工具,接入基金会服务、收集或处理基金会所提供的内容,干预或试图干预任何用户或任何其他方式接入基金会服务的行为; +(4)提供赌博资讯或以任何方式引诱他人参与赌博; +(5)侵入他人Cyton钱包盗取数字代币; +(6)进行与交易对方宣称的交易内容不符的交易,或不真实的交易; +(7)从事任何侵害或可能侵害Cyton服务系统、数据之行为; +(8)其他违法以及基金会有正当理由认为不适当的行为; +(9)不得嵌入恶意代码、重打包,不得通过程序手段窃取用户私钥和用户信息等。 +3. 您理解并同意,如因您违反有关法律(包括但不限于海关及税务方面的监管规定)或者本协议之规定,使基金会遭受任何损失、受到任何第三方的索赔或任何行政管理部门的处罚,您应对基金会进行赔偿,包括合理的律师费用。 +4. 您承诺按时缴纳基金会的服务费用(如有),否则基金会有权暂停或中止对您提供的服务。 +八、 隐私条款 +1. 基金会十分重视对用户隐私的保护,相关隐私保护政策请参考基金会公布并不时更新的《Cyton隐私政策》。 +九、 免责及责任限制 +1. 基金会仅对本协议中所列明的义务承担责任。 +2. 您理解和同意,在法律所允许的范围内,基金会只能按照现有的技术水平和条件提供服务。因下列原因导致Cyton无法正常提供服务,基金会不承担责任: +(1)Cyton系统停机维护或升级; +(2)因台风、地震、洪水、雷电或恐怖袭击等不可抗力原因; +(3)您的移动设备软硬件和通信线路、供电线路出现故障的; +(4)您操作不当或未通过基金会授权或认可的方式使用基金会服务的; +(5)因病毒、木马、恶意程序攻击、网络拥堵、系统不稳定、系统或设备故障、通讯故障、电力故障、银行等原因或政府行为等原因; +(6)非因基金会的原因而引起的任何其它原因。 +3. 基金会对以下情形不承担责任: +(1)因用户遗失移动设备、删除且未备份Cyton、删除且未备份钱包、钱包被盗或遗忘钱包密码、私钥、助记词、Keystore而导致的数字代币丢失; +(2)因用户自行泄露钱包密码、私钥、助记词、Keystore,或借用、转让或授权他人使用自己的移动设备或Cyton钱包,或未通过基金会官方渠道下载Cyton应用程序或其他不安全的方式使用Cyton应用程序导致的数字代币丢失; +(3)因用户误操作(包括但不限于您输错转账地址、您自身选择转账节点服务器的问题)导致的数字代币丢失; +(4)因用户不理解区块链技术的性质而进行误操作导致的数字代币丢失; +(5)因时间滞后、区块链系统不稳定等原因导致基金会拷贝用户在区块链上的交易记录发生偏差; +(6)用户在第三方DApp上操作产生的风险和后果。 +4. 您理解Cyton仅作为您数字代币管理的工具。基金会不能控制第三方DApp提供的产品及服务的质量、安全或合法性,信息的真实性或准确性,以及相对方履行其在与您签订的协议项下的各项义务的能力。所有您在第三方DApp进行的交易行为系您的个人行为,有约束力的合同关系在您和您的相对方之间建立,与Cyton无关。基金会提醒您应该通过自己的谨慎判断确定登录DApp及相关信息的真实性、合法性和有效性。您与任何第三方交易所产生的风险亦应由您自行承担。 +5. 基金会可能同时为您及您的交易对手方提供服务,您同意对基金会可能存在的该等行为予以明确豁免任何实际或潜在的利益冲突,并不得以此来主张基金会在提供服务时存在法律上的瑕疵,也不因此而加重基金会的责任或注意义务。 +6. 基金会不提供以下形式的保证: +(1)基金会服务将符合您的全部需求; +(2)您经由基金会服务取得的任何技术、产品、服务、资讯将符合您的期望; +(3)基金会从第三方交易所抓取的数字代币市场交易行情等信息的及时性、准确性、完整性、可靠性做出保证; +(4)您在Cyton上的交易各方会及时履行其在与您达成的交易协议中各项义务。 +7. 您理解Cyton仅作为用户管理数字代币、显示交易信息的工具,基金会不提供法律、税务或投资建议等服务。您应当自行向法律、税务、投资方面的专业人士寻求建议,且您在使用我们服务过程中所遭受的投资损失、数据损失等,基金会概不负责。 +8. 您理解根据有关中国政策法规的要求,我们可能不时更改我们的用户准入标准,限定向某一特定群体提供服务的范围和方式等。 +十、 完整协议 +1. 本协议由《Cyton服务协议》、《Cyton隐私政策》及基金会不时公布的各项规则(包括“帮助中心”的内容)组成。 +2. 本协议部分内容被有管辖权的法院认定为违反或无效的,不因此影响其他内容的效力。 +3. 本协议的任何译文版本仅为方便用户而提供,无意对本协议的条款进行修改。如果本协议的中文版本与非中文版本之间存在冲突,应以中文版本为准。 +十一、 知识产权保护 +1. Cyton系基金会开发并拥有知识产权的应用程序。Cyton中显示的任何内容(包括本协议、公告、文章、视频、音频、图片、档案、资讯、资料、商标或标识)的知识产权归基金会或第三方权利人所有。用户仅可为持有和管理数字代币之目的使用Cyton应用程序及其中的内容。未经基金会或第三方权利人的事先书面同意,任何人不得擅自使用、修改、反向编译、复制、公开传播、改变、散布、发行或公开发表上述应用程序及内容。 +十二、 法律适用与争议解决 +1. 本协议及其修订版之效力、解释、变更、执行与争议解决均适用中华人民共和国香港特别行政区法律,如无相关法律规定,则应当适用国际商业惯例和(或)行业惯例。 +2.凡因本合同所引起的或与之相关的任何争议、纠纷、分歧或索赔,包括合同的存在、效力、解释、履行、违反或终止,或因本合同引起的或与之相关的任何非合同性争议,均应提交由香港国际仲裁中心管理的仲裁,并按照提交仲裁通知时有效的《香港国际仲裁中心机构仲裁规则》最终解决。本仲裁条款适用的法律为香港特别行政区法律。仲裁地应为香港特别行政区。仲裁员人数为三名。仲裁程序应按照中文来进行。 + +十三、 其他 +1. 您需全面了解并遵守您所在司法辖区与使用基金会服务所有相关法律、法规及规则。 +2. 您在使用基金会服务过程中,如遇到任何问题,您可以通过在Cyton提交反馈等方式联系我们。 +3. 您可以在Cyton中查看本协议。 基金会鼓励您在每次访问Cyton时都查阅基金会的服务协议。 +4. 本协议自2018年6月29日起适用。 +本协议未尽事宜,您需遵守基金会不时更新的公告及相关规则。 +Nervos基金会 + diff --git a/Neuron/Sections/Authentication/AuthDeviceViewController.swift b/Cyton/Sections/Authentication/AuthDeviceViewController.swift similarity index 99% rename from Neuron/Sections/Authentication/AuthDeviceViewController.swift rename to Cyton/Sections/Authentication/AuthDeviceViewController.swift index 30be7cd3..22669e74 100644 --- a/Neuron/Sections/Authentication/AuthDeviceViewController.swift +++ b/Cyton/Sections/Authentication/AuthDeviceViewController.swift @@ -1,6 +1,6 @@ // // TouchIDAuthenticationViewController.swift -// Neuron +// Cyton // // Created by 晨风 on 2018/10/8. // Copyright © 2018 Cryptape. All rights reserved. diff --git a/Neuron/Sections/Authentication/AuthPasswordViewController.swift b/Cyton/Sections/Authentication/AuthPasswordViewController.swift similarity index 94% rename from Neuron/Sections/Authentication/AuthPasswordViewController.swift rename to Cyton/Sections/Authentication/AuthPasswordViewController.swift index fa67db6e..154090b6 100644 --- a/Neuron/Sections/Authentication/AuthPasswordViewController.swift +++ b/Cyton/Sections/Authentication/AuthPasswordViewController.swift @@ -1,6 +1,6 @@ // // PasswordAuthenticationViewController.swift -// Neuron +// Cyton // // Created by 晨风 on 2018/10/8. // Copyright © 2018 Cryptape. All rights reserved. @@ -26,7 +26,8 @@ class AuthPasswordViewController: UIViewController, AuthenticationMode, UITextFi super.viewDidLoad() currentWallet = AppModel.current.currentWallet passwordTextField.placeholder = "Authentication.walletPassword".localized() - confirmButton.setTitle("Authentication.confirmPassword".localized(), for: .normal) + confirmButton.setTitle("Common.confirm".localized(), for: .normal) + selectWalletButton.setTitle("SwitchWallet.title".localized(), for: .normal) } @IBAction func selectWallet(_ sender: Any) { diff --git a/Neuron/Sections/Authentication/AuthSelectWalletViewController.swift b/Cyton/Sections/Authentication/AuthSelectWalletViewController.swift similarity index 96% rename from Neuron/Sections/Authentication/AuthSelectWalletViewController.swift rename to Cyton/Sections/Authentication/AuthSelectWalletViewController.swift index 256700e9..15fed51a 100644 --- a/Neuron/Sections/Authentication/AuthSelectWalletViewController.swift +++ b/Cyton/Sections/Authentication/AuthSelectWalletViewController.swift @@ -1,6 +1,6 @@ // // AuthSelectWalletViewController.swift -// Neuron +// Cyton // // Created by 晨风 on 2018/10/9. // Copyright © 2018 Cryptape. All rights reserved. @@ -35,7 +35,7 @@ class AuthSelectWalletViewController: UITableViewController { override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: AuthSelectWalletTableViewCell.self)) as! AuthSelectWalletTableViewCell let wallet = wallets[indexPath.row] - cell.iconImageView.image = UIImage(data: wallet.iconData) + cell.iconImageView.image = wallet.icon.image cell.nameLabel.text = wallet.name cell.addressLabel.text = wallet.address return cell diff --git a/Neuron/Sections/Authentication/Authentication.storyboard b/Cyton/Sections/Authentication/Authentication.storyboard similarity index 99% rename from Neuron/Sections/Authentication/Authentication.storyboard rename to Cyton/Sections/Authentication/Authentication.storyboard index 099a81cd..69df2af1 100644 --- a/Neuron/Sections/Authentication/Authentication.storyboard +++ b/Cyton/Sections/Authentication/Authentication.storyboard @@ -1,5 +1,5 @@ - + @@ -297,6 +297,7 @@ + diff --git a/Neuron/Sections/Authentication/AuthenticationService.swift b/Cyton/Sections/Authentication/AuthenticationService.swift similarity index 99% rename from Neuron/Sections/Authentication/AuthenticationService.swift rename to Cyton/Sections/Authentication/AuthenticationService.swift index 316f5906..93519c43 100644 --- a/Neuron/Sections/Authentication/AuthenticationService.swift +++ b/Cyton/Sections/Authentication/AuthenticationService.swift @@ -1,6 +1,6 @@ // // AuthenticationService.swift -// Neuron +// Cyton // // Created by 晨风 on 2018/10/8. // Copyright © 2018 Cryptape. All rights reserved. diff --git a/Neuron/Sections/Authentication/AuthenticationViewController.swift b/Cyton/Sections/Authentication/AuthenticationViewController.swift similarity index 96% rename from Neuron/Sections/Authentication/AuthenticationViewController.swift rename to Cyton/Sections/Authentication/AuthenticationViewController.swift index e3f34db4..4afa4f9a 100644 --- a/Neuron/Sections/Authentication/AuthenticationViewController.swift +++ b/Cyton/Sections/Authentication/AuthenticationViewController.swift @@ -1,6 +1,6 @@ // // AuthenticationViewController.swift -// Neuron +// Cyton // // Created by 晨风 on 2018/10/8. // Copyright © 2018 Cryptape. All rights reserved. @@ -32,6 +32,7 @@ class AuthenticationViewController: UIViewController, AuthenticationDelegate { otherTitleLabel.isHidden = true switchImageView.isHidden = true } + otherTitleLabel.text = "Authentication.otherMode".localized() } override func viewWillAppear(_ animated: Bool) { diff --git a/Neuron/Sections/Authentication/OpenAuthViewController.swift b/Cyton/Sections/Authentication/OpenAuthViewController.swift similarity index 90% rename from Neuron/Sections/Authentication/OpenAuthViewController.swift rename to Cyton/Sections/Authentication/OpenAuthViewController.swift index ca9f39bd..e70e0447 100644 --- a/Neuron/Sections/Authentication/OpenAuthViewController.swift +++ b/Cyton/Sections/Authentication/OpenAuthViewController.swift @@ -1,6 +1,6 @@ // // OpenAuthViewController.swift -// Neuron +// Cyton // // Created by 晨风 on 2018/10/16. // Copyright © 2018 Cryptape. All rights reserved. @@ -13,6 +13,7 @@ class OpenAuthViewController: UIViewController { @IBOutlet weak var iconView: UIImageView! @IBOutlet weak var messageLabel: UILabel! @IBOutlet weak var confirmButton: UIButton! + @IBOutlet weak var cancelButton: UIButton! override func viewDidLoad() { super.viewDidLoad() if AuthenticationService.shared.biometryType == .faceID { @@ -24,6 +25,7 @@ class OpenAuthViewController: UIViewController { messageLabel.text = "Authentication.openTouchIdAuthDesc".localized() confirmButton.setTitle("Authentication.openTouchIdAuth".localized(), for: .normal) } + cancelButton.setTitle("Authentication.notOpen".localized(), for: .normal) } @IBAction func confrim(_ sender: Any) { diff --git a/Neuron/Sections/Common/BaseNavigationController.swift b/Cyton/Sections/Common/BaseNavigationController.swift similarity index 97% rename from Neuron/Sections/Common/BaseNavigationController.swift rename to Cyton/Sections/Common/BaseNavigationController.swift index 2a1311d5..c3690e5b 100644 --- a/Neuron/Sections/Common/BaseNavigationController.swift +++ b/Cyton/Sections/Common/BaseNavigationController.swift @@ -1,6 +1,6 @@ // // BaseNavigationController.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/5/18. // Copyright © 2018年 cryptape. All rights reserved. diff --git a/Neuron/Sections/Common/DesignableButton.swift b/Cyton/Sections/Common/DesignableButton.swift similarity index 97% rename from Neuron/Sections/Common/DesignableButton.swift rename to Cyton/Sections/Common/DesignableButton.swift index 584a64db..963e395d 100644 --- a/Neuron/Sections/Common/DesignableButton.swift +++ b/Cyton/Sections/Common/DesignableButton.swift @@ -1,6 +1,6 @@ // // DesignableButton.swift -// Neuron +// Cyton // // Created by 晨风 on 2018/11/20. // Copyright © 2018 Cryptape. All rights reserved. diff --git a/Neuron/Sections/Common/DesignableGradientView.swift b/Cyton/Sections/Common/DesignableGradientView.swift similarity index 99% rename from Neuron/Sections/Common/DesignableGradientView.swift rename to Cyton/Sections/Common/DesignableGradientView.swift index 255b506a..9201fca3 100644 --- a/Neuron/Sections/Common/DesignableGradientView.swift +++ b/Cyton/Sections/Common/DesignableGradientView.swift @@ -1,6 +1,6 @@ // // DesignableGradientView.swift -// Neuron +// Cyton // // Created by 晨风 on 2018/11/20. // Copyright © 2018 Cryptape. All rights reserved. diff --git a/Neuron/Sections/Common/NEPickerView.swift b/Cyton/Sections/Common/NEPickerView.swift similarity index 99% rename from Neuron/Sections/Common/NEPickerView.swift rename to Cyton/Sections/Common/NEPickerView.swift index 1039caf3..0d52fba9 100644 --- a/Neuron/Sections/Common/NEPickerView.swift +++ b/Cyton/Sections/Common/NEPickerView.swift @@ -1,6 +1,6 @@ // // NEPickerView.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/5/30. // Copyright © 2018年 cryptape. All rights reserved. diff --git a/Neuron/Sections/Common/PageItems/ModifyWalletNamePageItem.swift b/Cyton/Sections/Common/PageItems/ModifyWalletNamePageItem.swift similarity index 85% rename from Neuron/Sections/Common/PageItems/ModifyWalletNamePageItem.swift rename to Cyton/Sections/Common/PageItems/ModifyWalletNamePageItem.swift index d019e6a2..bf729db4 100644 --- a/Neuron/Sections/Common/PageItems/ModifyWalletNamePageItem.swift +++ b/Cyton/Sections/Common/PageItems/ModifyWalletNamePageItem.swift @@ -1,6 +1,6 @@ // // ModifyWalletNamePageItem.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/11/21. // Copyright © 2018 Cryptape. All rights reserved. @@ -21,7 +21,7 @@ class ModifyWalletNamePageItem: BLTNPageItem { } } - static func create(title: String = "请输入钱包名称", actionButtonTitle: String = "确认修改") -> ModifyWalletNamePageItem { + static func create(title: String = "Wallet.Details.ChangeName.inputName".localized(), actionButtonTitle: String = "Common.confirm".localized()) -> ModifyWalletNamePageItem { let item = ModifyWalletNamePageItem(title: title) item.appearance = PageItemAppearance.default item.descriptionText = "" @@ -31,7 +31,7 @@ class ModifyWalletNamePageItem: BLTNPageItem { override func makeViewsUnderDescription(with interfaceBuilder: BLTNInterfaceBuilder) -> [UIView]? { if walletNameField == nil { - walletNameField = interfaceBuilder.makeTextField(placeholder: "请输入钱包名称", returnKey: .done, delegate: self) + walletNameField = interfaceBuilder.makeTextField(placeholder: "Wallet.Details.ChangeName.inputName".localized(), returnKey: .done, delegate: self) walletNameField.isSecureTextEntry = false } return [walletNameField] @@ -62,7 +62,7 @@ class ModifyWalletNamePageItem: BLTNPageItem { return true } } else { - errorMessage = "请输入钱包名称" + errorMessage = "Wallet.Details.ChangeName.inputName".localized() return false } } diff --git a/Neuron/Sections/Common/PageItems/PageItemAppearance.swift b/Cyton/Sections/Common/PageItems/PageItemAppearance.swift similarity index 97% rename from Neuron/Sections/Common/PageItems/PageItemAppearance.swift rename to Cyton/Sections/Common/PageItems/PageItemAppearance.swift index c9a9ba61..464413f2 100644 --- a/Neuron/Sections/Common/PageItems/PageItemAppearance.swift +++ b/Cyton/Sections/Common/PageItems/PageItemAppearance.swift @@ -1,6 +1,6 @@ // // PageItemAppearance.swift -// Neuron +// Cyton // // Created by James Chen on 2018/11/19. // Copyright © 2018 Cryptape. All rights reserved. diff --git a/Neuron/Sections/Common/PageItems/PasswordPageItem.swift b/Cyton/Sections/Common/PageItems/PasswordPageItem.swift similarity index 84% rename from Neuron/Sections/Common/PageItems/PasswordPageItem.swift rename to Cyton/Sections/Common/PageItems/PasswordPageItem.swift index f2bfc59d..43855123 100644 --- a/Neuron/Sections/Common/PageItems/PasswordPageItem.swift +++ b/Cyton/Sections/Common/PageItems/PasswordPageItem.swift @@ -1,6 +1,6 @@ // // PasswordPageItem.swift -// Neuron +// Cyton // // Created by James Chen on 2018/11/19. // Copyright © 2018 Cryptape. All rights reserved. @@ -23,7 +23,7 @@ class PasswordPageItem: BLTNPageItem { } } - static func create(title: String = "请输入钱包密码", actionButtonTitle: String = "确认发送") -> PasswordPageItem { + static func create(title: String = "Wallet.Details.ChangePassword.inputPassword".localized(), actionButtonTitle: String = "Common.confirm".localized()) -> PasswordPageItem { let item = PasswordPageItem(title: title) item.appearance = PageItemAppearance.default item.descriptionText = "" @@ -33,7 +33,7 @@ class PasswordPageItem: BLTNPageItem { override func makeViewsUnderDescription(with interfaceBuilder: BLTNInterfaceBuilder) -> [UIView]? { if passwordField == nil { - passwordField = interfaceBuilder.makeTextField(placeholder: "请输入钱包密码", returnKey: .done, delegate: self) + passwordField = interfaceBuilder.makeTextField(placeholder: "Wallet.Details.ChangePassword.inputPassword".localized(), returnKey: .done, delegate: self) passwordField.isSecureTextEntry = true } return [passwordField] @@ -65,7 +65,7 @@ class PasswordPageItem: BLTNPageItem { if isInputValid(text: passwordField.text) { return true } else { - errorMessage = "请输入密码" + errorMessage = "Wallet.Details.ChangePassword.inputPassword".localized() return false } } diff --git a/Neuron/Sections/Common/PageItems/SendTransactionSummaryView.xib b/Cyton/Sections/Common/PageItems/SendTransactionSummaryView.xib similarity index 94% rename from Neuron/Sections/Common/PageItems/SendTransactionSummaryView.xib rename to Cyton/Sections/Common/PageItems/SendTransactionSummaryView.xib index 886b7057..6fafe8d4 100644 --- a/Neuron/Sections/Common/PageItems/SendTransactionSummaryView.xib +++ b/Cyton/Sections/Common/PageItems/SendTransactionSummaryView.xib @@ -36,17 +36,17 @@ - + @@ -76,7 +76,7 @@ - + @@ -152,7 +152,7 @@ - + @@ -294,7 +294,7 @@ - + @@ -328,7 +328,7 @@ - + @@ -339,9 +339,9 @@ @@ -415,20 +415,17 @@ - @@ -451,20 +449,17 @@ - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + diff --git a/Neuron/Sections/Dapp/WebView/DappViewController.swift b/Cyton/Sections/DApp/WebView/DappViewController.swift similarity index 88% rename from Neuron/Sections/Dapp/WebView/DappViewController.swift rename to Cyton/Sections/DApp/WebView/DappViewController.swift index 6eaf556b..fa3d7b90 100644 --- a/Neuron/Sections/Dapp/WebView/DappViewController.swift +++ b/Cyton/Sections/DApp/WebView/DappViewController.swift @@ -1,6 +1,6 @@ // // DappViewController.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/5/18. // Copyright © 2018年 cryptape. All rights reserved. @@ -9,11 +9,13 @@ import UIKit import WebKit import JavaScriptCore +import Alamofire /// DApp Home class DappViewController: UIViewController, WKUIDelegate, ErrorOverlayPresentable { private let webView = WKWebView(frame: .zero) private var mainUrl = URL(string: "https://dapp.cryptape.com")! + let netState = NetworkReachabilityManager() override func viewDidLoad() { super.viewDidLoad() @@ -29,10 +31,11 @@ class DappViewController: UIViewController, WKUIDelegate, ErrorOverlayPresentabl return } self.removeOverlay() - self.webView.load(URLRequest(url: self.mainUrl)) + self.loadRequest() } - webView.load(URLRequest(url: mainUrl)) + loadRequest() + monitorNetwork() } private func addWebView() { @@ -59,6 +62,25 @@ class DappViewController: UIViewController, WKUIDelegate, ErrorOverlayPresentabl webView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true webView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true } + + private func loadRequest() { + var request = URLRequest(url: mainUrl) + request.setAcceptLanguage() + webView.load(request) + } + + func monitorNetwork() { + netState?.listener = { state in + switch state { + case .unknown, .notReachable: + break + case .reachable: + self.removeOverlay() + self.loadRequest() + self.netState?.stopListening() + } + } + } } // MARK: - User agent, JS, CSS style, etc. @@ -104,9 +126,10 @@ extension DappViewController: WKNavigationDelegate { let error = error as NSError errorOverlaycontroller.style = .networkFail if error.code == -1009 { - errorOverlaycontroller.messageLabel.text = "Common.Connection.ConnectionLost".localized() + netState?.startListening() + errorOverlaycontroller.messageLabel.text = "Common.Connection.LoseConnect".localized() } else { - errorOverlaycontroller.messageLabel.text = "Common.Connection.FailToLoadPage".localized() + errorOverlaycontroller.messageLabel.text = "Common.Connection.LoadFaild".localized() } showOverlay() } diff --git a/Neuron/Sections/Dapp/WebView/MessageSignController.swift b/Cyton/Sections/DApp/WebView/MessageSignController.swift similarity index 92% rename from Neuron/Sections/Dapp/WebView/MessageSignController.swift rename to Cyton/Sections/DApp/WebView/MessageSignController.swift index 72523a21..5fd6622c 100644 --- a/Neuron/Sections/Dapp/WebView/MessageSignController.swift +++ b/Cyton/Sections/DApp/WebView/MessageSignController.swift @@ -1,6 +1,6 @@ // // MessageSignController.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/5/30. // Copyright © 2018年 cryptape. All rights reserved. @@ -8,7 +8,7 @@ import UIKit import BLTNBoard -import AppChain +import CITA protocol MessageSignControllerDelegate: class { func messageSignCallBackWebView(id: Int, value: String, error: DAppError?) @@ -17,7 +17,6 @@ protocol MessageSignControllerDelegate: class { class MessageSignController: UIViewController { var dappCommonModel: DAppCommonModel! weak var delegate: MessageSignControllerDelegate? - private var chainType: ChainType = .appChain private lazy var messagePageItem: SignMessagePageItem = { return SignMessagePageItem.create() @@ -39,11 +38,9 @@ class MessageSignController: UIViewController { super.viewDidLoad() let dataText: String - if dappCommonModel.chainType == "AppChain" { - chainType = .appChain - dataText = dappCommonModel.appChain?.data ?? "" + if dappCommonModel.chainType == .cita { + dataText = dappCommonModel.cita?.data ?? "" } else { - chainType = .eth dataText = dappCommonModel.eth?.data ?? "" } messagePageItem.descriptionText = String(decoding: Data.fromHex(dataText)!, as: UTF8.self) @@ -96,9 +93,9 @@ class MessageSignController: UIViewController { private extension MessageSignController { func signMessage(password: String) { - switch chainType { - case .appChain: - appChainSign(password: password) + switch dappCommonModel.chainType { + case .cita: + citaSign(password: password) case .eth: ethSign(password: password) } @@ -115,10 +112,10 @@ private extension MessageSignController { } } - func appChainSign(password: String) { + func citaSign(password: String) { switch dappCommonModel.name { case .signMessage: - appChainSignMessage(password: password) + citaSignMessage(password: password) default: break } @@ -166,7 +163,7 @@ private extension MessageSignController { } } - func appChainSignMessage(password: String) { + func citaSignMessage(password: String) { DispatchQueue.global().async { do { let messageData = Data.fromHex(self.dappCommonModel.eth?.data ?? "") ?? Data() diff --git a/Neuron/Sections/Dapp/WebView/SearchAppController.swift b/Cyton/Sections/DApp/WebView/SearchAppController.swift similarity index 95% rename from Neuron/Sections/Dapp/WebView/SearchAppController.swift rename to Cyton/Sections/DApp/WebView/SearchAppController.swift index 1ae14417..84b0ecef 100644 --- a/Neuron/Sections/Dapp/WebView/SearchAppController.swift +++ b/Cyton/Sections/DApp/WebView/SearchAppController.swift @@ -1,6 +1,6 @@ // // SearchAppController.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/5/18. // Copyright © 2018年 cryptape. All rights reserved. @@ -20,6 +20,7 @@ class SearchAppController: UITableViewController, ErrorOverlayPresentable { override func viewDidLoad() { super.viewDidLoad() + textField.placeholder = "DApp.Search.TextFieldPlaceholder".localized() setUpNavigationTitleView() } @@ -118,7 +119,7 @@ class SearchAppController: UITableViewController, ErrorOverlayPresentable { } override func tableView(_ tableView: UITableView, titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) -> String? { - return "删除" + return "DApp.Search.DeleteHistory".localized() } } @@ -135,7 +136,7 @@ extension SearchAppController: QRCodeViewControllerDelegate, UITextFieldDelegate if codeResult.count != 0 { dealWithUrl(urlString: codeResult) } else { - Toast.showToast(text: "扫描结果为空") + Toast.showToast(text: "Common.Connection.ScanEmpty".localized()) } } diff --git a/Neuron/Sections/Dapp/WebView/WKWebViewConfiguration.swift b/Cyton/Sections/DApp/WebView/WKWebViewConfiguration.swift similarity index 92% rename from Neuron/Sections/Dapp/WebView/WKWebViewConfiguration.swift rename to Cyton/Sections/DApp/WebView/WKWebViewConfiguration.swift index 9879b425..881a581d 100644 --- a/Neuron/Sections/Dapp/WebView/WKWebViewConfiguration.swift +++ b/Cyton/Sections/DApp/WebView/WKWebViewConfiguration.swift @@ -1,6 +1,6 @@ // // WKWebViewConfiguration.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/10/11. // Copyright © 2018 Cryptape. All rights reserved. @@ -21,9 +21,9 @@ extension WKWebViewConfiguration { } var js = "" - if let neuronPath = Bundle.main.path(forResource: "neuron", ofType: "js") { + if let cytonPath = Bundle.main.path(forResource: "cyton", ofType: "js") { do { - js += try String(contentsOfFile: neuronPath) + js += try String(contentsOfFile: cytonPath) } catch { } } diff --git a/Neuron/Sections/Guide/Guide.storyboard b/Cyton/Sections/Guide/Guide.storyboard similarity index 68% rename from Neuron/Sections/Guide/Guide.storyboard rename to Cyton/Sections/Guide/Guide.storyboard index 5d184255..0228160e 100644 --- a/Neuron/Sections/Guide/Guide.storyboard +++ b/Cyton/Sections/Guide/Guide.storyboard @@ -6,6 +6,7 @@ + @@ -13,7 +14,7 @@ - + @@ -29,38 +30,22 @@ - + - - - - - + + + - - @@ -125,6 +110,8 @@ + + @@ -136,32 +123,16 @@ - + - - - + + - - - - - - + + @@ -169,34 +140,48 @@ - - - + + 最近更新于:2018年6月29日 尊敬的用户: -Nervos基金会(以下简称“基金会”或“我们”)尊重并保护用户(以下简称“您”或“用户”)的隐私,您使用Neuron时,基金会将按照本隐私政策(以下简称“本政策”)收集、使用您的个人信息。 -基金会建议您在使用本产品(以下简称“Neuron”)之前仔细阅读并理解本政策全部内容, 针对免责声明等条款在内的重要信息将以加粗的形式体现。本政策有关关键词定义与基金会《Neuron服务协议》保持一致。 +Nervos基金会(以下简称“基金会”或“我们”)尊重并保护用户(以下简称“您”或“用户”)的隐私,您使用Cyton时,基金会将按照本隐私政策(以下简称“本政策”)收集、使用您的个人信息。 +基金会建议您在使用本产品(以下简称“NCyton”)之前仔细阅读并理解本政策全部内容, 针对免责声明等条款在内的重要信息将以加粗的形式体现。本政策有关关键词定义与基金会《NCyton服务协议》保持一致。 ... - + + + + + + + + + + + + + + + + + + + + + + @@ -226,12 +233,20 @@ Nervos基金会(以下简称“基金会”或“我们”)尊重并保护 + + + + + + - + + + @@ -256,7 +271,9 @@ Nervos基金会(以下简称“基金会”或“我们”)尊重并保护 - - + + + + diff --git a/Neuron/Sections/Guide/GuideCollectionViewCell.swift b/Cyton/Sections/Guide/GuideCollectionViewCell.swift similarity index 71% rename from Neuron/Sections/Guide/GuideCollectionViewCell.swift rename to Cyton/Sections/Guide/GuideCollectionViewCell.swift index 471dcd40..edcfc70f 100644 --- a/Neuron/Sections/Guide/GuideCollectionViewCell.swift +++ b/Cyton/Sections/Guide/GuideCollectionViewCell.swift @@ -1,6 +1,6 @@ // // GuideCollectionViewCell.swift -// Neuron +// Cyton // // Created by 晨风 on 2018/10/10. // Copyright © 2018 Cryptape. All rights reserved. @@ -9,7 +9,5 @@ import UIKit class GuideCollectionViewCell: UICollectionViewCell { - @IBOutlet weak var titleLabel: UILabel! - @IBOutlet weak var subTitleLabel: UILabel! @IBOutlet weak var imageView: UIImageView! } diff --git a/Neuron/Sections/Guide/GuideService.swift b/Cyton/Sections/Guide/GuideService.swift similarity index 99% rename from Neuron/Sections/Guide/GuideService.swift rename to Cyton/Sections/Guide/GuideService.swift index 23e8b85d..d7e85834 100644 --- a/Neuron/Sections/Guide/GuideService.swift +++ b/Cyton/Sections/Guide/GuideService.swift @@ -1,6 +1,6 @@ // // GuideService.swift -// Neuron +// Cyton // // Created by 晨风 on 2018/10/11. // Copyright © 2018 Cryptape. All rights reserved. diff --git a/Neuron/Sections/Guide/GuideViewController.swift b/Cyton/Sections/Guide/GuideViewController.swift similarity index 70% rename from Neuron/Sections/Guide/GuideViewController.swift rename to Cyton/Sections/Guide/GuideViewController.swift index 5f96e7d8..6ec5d05f 100644 --- a/Neuron/Sections/Guide/GuideViewController.swift +++ b/Cyton/Sections/Guide/GuideViewController.swift @@ -1,6 +1,6 @@ // // GuideViewController.swift -// Neuron +// Cyton // // Created by 晨风 on 2018/10/10. // Copyright © 2018 Cryptape. All rights reserved. @@ -11,24 +11,18 @@ import UIKit private var GuideOnceTokenAssiciationKey = 0 class GuideViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { - struct GuideItem { - let title: String - let subTitle: String - let imageName: String - } - - private let items = [ - GuideItem(title: "甄选全球最新DAPP", subTitle: "一应俱全", imageName: "guide_1"), - GuideItem(title: "多重安全算法保护", subTitle: "钱包秘钥惟您掌握", imageName: "guide_2"), - GuideItem(title: "开启区块链之旅", subTitle: "探索无限可能", imageName: "guide_3") - ] + private let items = ["guide_page_1", "guide_page_2", "guide_page_3"] - @IBOutlet weak var collectionView: UICollectionView! - @IBOutlet weak var pageControl: UIPageControl! + @IBOutlet private weak var collectionView: UICollectionView! + @IBOutlet private weak var pageControl: UIPageControl! + @IBOutlet private weak var createWalletButton: UIButton! + @IBOutlet private weak var importWalletButton: UIButton! override func viewDidLoad() { super.viewDidLoad() + createWalletButton.setTitle("Guide.createWallet".localized(), for: .normal) + importWalletButton.setTitle("Guide.existingWallet".localized(), for: .normal) DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { self.showProductAgreementView() } @@ -53,10 +47,7 @@ class GuideViewController: UIViewController, UICollectionViewDataSource, UIColle func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: GuideCollectionViewCell.self), for: indexPath) as! GuideCollectionViewCell - cell.titleLabel.text = items[indexPath.row].title - cell.subTitleLabel.text = items[indexPath.row].subTitle - cell.imageView.image = UIImage(named: items[indexPath.row].imageName) - cell.backgroundColor = indexPath.row == 3 ? UIColor.clear : UIColor.white + cell.imageView.image = UIImage(named: items[indexPath.row]) return cell } diff --git a/Neuron/Sections/Guide/ProductAgreementViewController.swift b/Cyton/Sections/Guide/ProductAgreementViewController.swift similarity index 56% rename from Neuron/Sections/Guide/ProductAgreementViewController.swift rename to Cyton/Sections/Guide/ProductAgreementViewController.swift index 1e93eb78..443b70fc 100644 --- a/Neuron/Sections/Guide/ProductAgreementViewController.swift +++ b/Cyton/Sections/Guide/ProductAgreementViewController.swift @@ -1,6 +1,6 @@ // // ProductAgreementViewController.swift -// Neuron +// Cyton // // Created by 晨风 on 2018/10/10. // Copyright © 2018 Cryptape. All rights reserved. @@ -13,21 +13,28 @@ class ProductAgreementViewController: UIViewController { case agreement = "ProductAgreementUserDefaultsKey" } - @IBOutlet weak var confirmButton: UIButton! - @IBOutlet weak var textView: UITextView! - @IBOutlet weak var checkButton: UIButton! + @IBOutlet private weak var titleLabel: UILabel! + @IBOutlet private weak var confirmButton: UIButton! + @IBOutlet private weak var textView: UITextView! + @IBOutlet private weak var checkLabel: UILabel! + @IBOutlet private weak var checkLabelHeight: NSLayoutConstraint! var isAgree: Bool = false { didSet { + let attach = NSTextAttachment() if isAgree { confirmButton.isEnabled = true confirmButton.setTitleColor(UIColor(red: 54/255.0, green: 59/255.0, blue: 255/255.0, alpha: 1.0), for: .normal) - checkButton.setImage(UIImage(named: "icon_check_yes"), for: .normal) + attach.image = UIImage(named: "icon_check_yes") } else { confirmButton.isEnabled = false confirmButton.setTitleColor(UIColor(red: 233/255.0, green: 235/255.0, blue: 240/255.0, alpha: 1.0), for: .normal) - checkButton.setImage(UIImage(named: "icon_check_no"), for: .normal) + attach.image = UIImage(named: "icon_check_no") } + attach.bounds = CGRect(x: 0, y: 0, width: 14, height: 14) + let attributedText = NSMutableAttributedString(attributedString: checkLabel.attributedText!) + attributedText.replaceCharacters(in: NSRange(location: 0, length: 1), with: NSAttributedString(attachment: attach)) + checkLabel.attributedText = attributedText } } @@ -39,10 +46,33 @@ class ProductAgreementViewController: UIViewController { super.viewDidLoad() setupTextView() isAgree = false + titleLabel.text = "Guide.cytonServiceAgreement".localized() + confirmButton.setTitle("Guide.continue".localized(), for: .normal) + + let attach = NSTextAttachment() + attach.image = UIImage(named: "icon_check_no") + attach.bounds = CGRect(x: 0, y: 0, width: 14, height: 14) + + let attributedText = NSMutableAttributedString(string: " " + "Guide.agreementOfConsent".localized()) + attributedText.addAttribute(NSAttributedString.Key.baselineOffset, value: 3, range: NSRange(location: 0, length: attributedText.string.count)) + attributedText.insert(NSAttributedString(attachment: attach), at: 0) + checkLabel.attributedText = attributedText + checkLabelHeight.constant = checkLabel.textRect(forBounds: CGRect(x: 0, y: 0, width: checkLabel.bounds.size.width, height: 60), limitedToNumberOfLines: 0).size.height + 12 + + let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(ProductAgreementViewController.agreement(_:))) + checkLabel.addGestureRecognizer(tapGestureRecognizer) + checkLabel.accessibilityValue = "ckeckLabel" + checkLabel.accessibilityLabel = "ckeckLabel" + checkLabel.accessibilityIdentifier = "ckeckLabel" + } + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + textView.contentOffset = CGPoint.zero } func setupTextView() { - let text = try! String(contentsOfFile: Bundle.main.path(forResource: "ProductAgreement", ofType: "txt")!) + let text = try! String(contentsOfFile: Bundle.main.path(forResource: "product_agreement", ofType: "txt")!) textView.text = text let attributedText = NSMutableAttributedString(attributedString: textView.attributedText) var searchRange = Range(uncheckedBounds: (text.startIndex, text.endIndex)) diff --git a/Neuron/Sections/Settings/AboutUs.storyboard b/Cyton/Sections/Settings/AboutUs.storyboard similarity index 95% rename from Neuron/Sections/Settings/AboutUs.storyboard rename to Cyton/Sections/Settings/AboutUs.storyboard index da3ee0d3..67d4d1b1 100644 --- a/Neuron/Sections/Settings/AboutUs.storyboard +++ b/Cyton/Sections/Settings/AboutUs.storyboard @@ -12,7 +12,7 @@ - + @@ -27,7 +27,7 @@ - + @@ -39,7 +39,7 @@ - + + + + + + @@ -265,12 +271,12 @@ - + + - - + diff --git a/Neuron/Sections/Settings/AboutUsViewController.swift b/Cyton/Sections/Settings/AboutUsViewController.swift similarity index 63% rename from Neuron/Sections/Settings/AboutUsViewController.swift rename to Cyton/Sections/Settings/AboutUsViewController.swift index 484bb4d2..e60d062b 100644 --- a/Neuron/Sections/Settings/AboutUsViewController.swift +++ b/Cyton/Sections/Settings/AboutUsViewController.swift @@ -1,6 +1,6 @@ // // AboutUsViewController.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/9/7. // Copyright © 2018年 Cryptape. All rights reserved. @@ -11,16 +11,28 @@ import SafariServices class AboutUsViewController: UITableViewController { @IBOutlet private weak var versionLabel: UILabel! + @IBOutlet weak var sourceCodeLabel: UILabel! + @IBOutlet weak var servicePrivacyLabel: UILabel! + @IBOutlet weak var infuaDetailLabel: UILabel! + @IBOutlet weak var openSeaDetailLabel: UILabel! + @IBOutlet weak var peckShieldDetailLabel: UILabel! + @IBOutlet weak var citaDetailLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() title = "Settings.About.AboutUs".localized() + sourceCodeLabel.text = "Settings.About.SourceCode".localized() + servicePrivacyLabel.text = "Settings.About.ServicePrivacy".localized() + infuaDetailLabel.text = "Settings.About.InfuaDetail".localized() + openSeaDetailLabel.text = "Settings.About.OpenSea".localized() + peckShieldDetailLabel.text = "Settings.About.PeckShield".localized() + citaDetailLabel.text = "Settings.About.Cita".localized() setVersionLabel() } private var projectGithubUrls = [ - "https://github.com/cryptape/neuron-ios", - "https://docs.nervos.org/neuron-android/#/product-agreement" + "https://github.com/cryptape/cyton-ios", + "https://docs.nervos.org/cyton-android/#/product-agreement" ] private var secondSectionUrls = [ diff --git a/Neuron/Sections/Settings/CommonWebViewController.swift b/Cyton/Sections/Settings/CommonWebViewController.swift similarity index 99% rename from Neuron/Sections/Settings/CommonWebViewController.swift rename to Cyton/Sections/Settings/CommonWebViewController.swift index a9ba374e..79cc93d6 100644 --- a/Neuron/Sections/Settings/CommonWebViewController.swift +++ b/Cyton/Sections/Settings/CommonWebViewController.swift @@ -1,6 +1,6 @@ // // CommonWebViewController.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/7/8. // Copyright © 2018年 cryptape. All rights reserved. diff --git a/Neuron/Sections/Settings/CurrencyViewController.swift b/Cyton/Sections/Settings/CurrencyViewController.swift similarity index 96% rename from Neuron/Sections/Settings/CurrencyViewController.swift rename to Cyton/Sections/Settings/CurrencyViewController.swift index f6de143b..72515b0d 100644 --- a/Neuron/Sections/Settings/CurrencyViewController.swift +++ b/Cyton/Sections/Settings/CurrencyViewController.swift @@ -1,6 +1,6 @@ // // CurrencyViewController.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/8/24. // Copyright © 2018年 Cryptape. All rights reserved. @@ -13,7 +13,7 @@ class CurrencyViewController: UITableViewController { override func viewDidLoad() { super.viewDidLoad() - title = "默认货币单位" + title = "Settings.Currency.Title".localized() getCurrencyList() } diff --git a/Neuron/Sections/Settings/Settings.storyboard b/Cyton/Sections/Settings/Settings.storyboard similarity index 96% rename from Neuron/Sections/Settings/Settings.storyboard rename to Cyton/Sections/Settings/Settings.storyboard index 50c2e927..14a8a613 100644 --- a/Neuron/Sections/Settings/Settings.storyboard +++ b/Cyton/Sections/Settings/Settings.storyboard @@ -10,10 +10,10 @@ - + - + @@ -50,8 +50,9 @@ - + + + + + + + @@ -267,7 +273,7 @@ - + @@ -292,7 +298,7 @@ - + @@ -303,7 +309,7 @@ - + @@ -353,7 +359,7 @@ - + @@ -364,7 +370,7 @@ - + @@ -414,11 +420,11 @@ - + - - + + diff --git a/Neuron/Sections/Settings/SettingsViewController.swift b/Cyton/Sections/Settings/SettingsViewController.swift similarity index 72% rename from Neuron/Sections/Settings/SettingsViewController.swift rename to Cyton/Sections/Settings/SettingsViewController.swift index 3a64202e..e97abebe 100644 --- a/Neuron/Sections/Settings/SettingsViewController.swift +++ b/Cyton/Sections/Settings/SettingsViewController.swift @@ -1,6 +1,6 @@ // // SettingsViewController.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/5/28. // Copyright © 2018年 cryptape. All rights reserved. @@ -17,17 +17,30 @@ class SettingsViewController: UITableViewController { @IBOutlet weak var ethereumNetworkLabel: UILabel! @IBOutlet var authenticationSwitch: UISwitch! + @IBOutlet weak var currencyTitleLabel: UILabel! + @IBOutlet weak var touchIdLabel: UILabel! + @IBOutlet weak var switchEthLabel: UILabel! + @IBOutlet weak var aboutUsLabel: UILabel! + @IBOutlet weak var connectUsLabel: UILabel! + @IBOutlet weak var forumLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() + title = "Settings.Title".localized() + currencyTitleLabel.text = "Settings.CurrencyTitle".localized() + touchIdLabel.text = "Settings.TouchIdTitle".localized() + switchEthLabel.text = "Settings.SwitchNetwork.Title".localized() + aboutUsLabel.text = "Settings.About.AboutUs".localized() + connectUsLabel.text = "Settings.ConnectUs".localized() + forumLabel.text = "Settings.Forum".localized() } func getDataForUI() { if let walletModel = AppModel.current.currentWallet { nameLabel.text = walletModel.name addressLabel.text = walletModel.address - iconImageView.image = UIImage(data: walletModel.iconData) + iconImageView.image = walletModel.icon.image currencyLabel.text = LocalCurrencyService.shared.getLocalCurrencySelect().short - ethereumNetworkLabel.text = EthereumNetwork().currentNetwork.rawValue.capitalized + ethereumNetworkLabel.text = EthereumNetwork().networkType.chainName authenticationSwitch.isOn = AuthenticationService.shared.isEnable } } @@ -63,7 +76,7 @@ class SettingsViewController: UITableViewController { switch indexPath.row { case 1: UIPasteboard.general.string = "Nervos-Neuron" - Toast.showToast(text: "客服微信已复制") + Toast.showToast(text: "Settings.ConnectUs.CopyWechat".localized()) case 2: let safariController = SFSafariViewController(url: URL(string: "https://forums.nervos.org/")!) self.present(safariController, animated: true, completion: nil) diff --git a/Neuron/Sections/Settings/SwitchNetworkViewController.swift b/Cyton/Sections/Settings/SwitchNetworkViewController.swift similarity index 65% rename from Neuron/Sections/Settings/SwitchNetworkViewController.swift rename to Cyton/Sections/Settings/SwitchNetworkViewController.swift index 930e053b..cf2eff09 100644 --- a/Neuron/Sections/Settings/SwitchNetworkViewController.swift +++ b/Cyton/Sections/Settings/SwitchNetworkViewController.swift @@ -1,6 +1,6 @@ // // SwitchNetworkViewController.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/10/30. // Copyright © 2018 Cryptape. All rights reserved. @@ -9,23 +9,21 @@ import UIKit class SwitchNetworkViewController: UITableViewController { - var networks: [String] = [] - override func viewDidLoad() { super.viewDidLoad() - title = "切换以太坊网络" + title = "Settings.SwitchNetwork.Title".localized() tableView.reloadData() } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return EthereumNetwork.EthereumNetworkType.allValues.count + return EthereumNetwork.NetworkType.allCases.count } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "switchNetwork") as! SwitchNetworkTableViewCell - let network = EthereumNetwork.EthereumNetworkType.allValues[indexPath.row] - cell.networkLabel.text = network.capitalized - if EthereumNetwork().currentNetwork.rawValue == network { + let network = EthereumNetwork.NetworkType.allCases[indexPath.row] + cell.networkLabel.text = network.chainName + if EthereumNetwork().networkType == network { cell.selectImage.isHidden = false } else { cell.selectImage.isHidden = true @@ -35,8 +33,7 @@ class SwitchNetworkViewController: UITableViewController { override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { tableView.deselectRow(at: indexPath, animated: true) - EthereumNetwork().switchNetwork(EthereumNetwork.EthereumNetworkType.allValues[indexPath.row]) - NotificationCenter.default.post(name: .switchEthNetwork, object: nil) + EthereumNetwork().networkType = EthereumNetwork.NetworkType.allCases[indexPath.row] navigationController?.popViewController(animated: true) } } diff --git a/Neuron/Sections/Settings/TableViewCell/CurrencyTableViewCell.swift b/Cyton/Sections/Settings/TableViewCell/CurrencyTableViewCell.swift similarity index 96% rename from Neuron/Sections/Settings/TableViewCell/CurrencyTableViewCell.swift rename to Cyton/Sections/Settings/TableViewCell/CurrencyTableViewCell.swift index cd414b2b..a10ea54d 100644 --- a/Neuron/Sections/Settings/TableViewCell/CurrencyTableViewCell.swift +++ b/Cyton/Sections/Settings/TableViewCell/CurrencyTableViewCell.swift @@ -1,6 +1,6 @@ // // CurrencyTableViewCell.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/9/6. // Copyright © 2018年 Cryptape. All rights reserved. diff --git a/Neuron/Sections/Settings/TableViewCell/SettingAuthenticationTableViewCell.swift b/Cyton/Sections/Settings/TableViewCell/SettingAuthenticationTableViewCell.swift similarity index 96% rename from Neuron/Sections/Settings/TableViewCell/SettingAuthenticationTableViewCell.swift rename to Cyton/Sections/Settings/TableViewCell/SettingAuthenticationTableViewCell.swift index 409f62e0..ea148684 100644 --- a/Neuron/Sections/Settings/TableViewCell/SettingAuthenticationTableViewCell.swift +++ b/Cyton/Sections/Settings/TableViewCell/SettingAuthenticationTableViewCell.swift @@ -1,6 +1,6 @@ // // SettingAuthenticationTableViewCell.swift -// Neuron +// Cyton // // Created by 晨风 on 2018/10/9. // Copyright © 2018 Cryptape. All rights reserved. diff --git a/Neuron/Sections/Settings/TableViewCell/SettingCurrencyTableViewCell.swift b/Cyton/Sections/Settings/TableViewCell/SettingCurrencyTableViewCell.swift similarity index 95% rename from Neuron/Sections/Settings/TableViewCell/SettingCurrencyTableViewCell.swift rename to Cyton/Sections/Settings/TableViewCell/SettingCurrencyTableViewCell.swift index 78ccec1a..555c13b3 100644 --- a/Neuron/Sections/Settings/TableViewCell/SettingCurrencyTableViewCell.swift +++ b/Cyton/Sections/Settings/TableViewCell/SettingCurrencyTableViewCell.swift @@ -1,6 +1,6 @@ // // SettingCurrencyTableViewCell.swift -// Neuron +// Cyton // // Created by 晨风 on 2018/10/9. // Copyright © 2018 Cryptape. All rights reserved. diff --git a/Neuron/Sections/Settings/TableViewCell/SwitchNetworkTableViewCell.swift b/Cyton/Sections/Settings/TableViewCell/SwitchNetworkTableViewCell.swift similarity index 96% rename from Neuron/Sections/Settings/TableViewCell/SwitchNetworkTableViewCell.swift rename to Cyton/Sections/Settings/TableViewCell/SwitchNetworkTableViewCell.swift index 6b61ba57..be2e002f 100644 --- a/Neuron/Sections/Settings/TableViewCell/SwitchNetworkTableViewCell.swift +++ b/Cyton/Sections/Settings/TableViewCell/SwitchNetworkTableViewCell.swift @@ -1,6 +1,6 @@ // // SwitchNetworkTableViewCell.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/10/30. // Copyright © 2018 Cryptape. All rights reserved. diff --git a/Cyton/Sections/Transaction/Details/TransactionDetails.storyboard b/Cyton/Sections/Transaction/Details/TransactionDetails.storyboard new file mode 100644 index 00000000..5b627c26 --- /dev/null +++ b/Cyton/Sections/Transaction/Details/TransactionDetails.storyboard @@ -0,0 +1,557 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Cyton/Sections/Transaction/Details/TransactionDetailsParamBuilder.swift b/Cyton/Sections/Transaction/Details/TransactionDetailsParamBuilder.swift new file mode 100644 index 00000000..3ec63531 --- /dev/null +++ b/Cyton/Sections/Transaction/Details/TransactionDetailsParamBuilder.swift @@ -0,0 +1,102 @@ +// +// TransactionDetailsParamBuilder.swift +// Cyton +// +// Created by 晨风 on 2018/12/18. +// Copyright © 2018 Cryptape. All rights reserved. +// + +import UIKit + +class TransactionDetailsParamBuilder { + let tx: TransactionDetails + var tokenIcon: String! + var status: String! + var amount: String! + var date: String! + var from: String! + var to: String! + var txDetailsUrl: URL! + var hash: String! + var network: String! + var block: String! + var txFee: String! + var gasPrice: String! + var gasLimit: String! + var gasUsed: String! + + init(tx: TransactionDetails) { + self.tx = tx + buildBaseInfo() + buildTxFee() + buildMoreInfo() + } + + func buildBaseInfo() { + tokenIcon = tx.token.iconUrl + switch tx.status { + case .success: + status = tx.isContractCreation ? "Transaction.Details.contractCreationSuccess".localized() : "TransactionStatus.success".localized() + if tx.token.type == .cita || tx.token.type == .citaErc20 { + if tx.token.chainId == "1" { + txDetailsUrl = URL(string: "https://microscope.cryptape.com/#/transaction/\(tx.hash)")! + } + } else { + txDetailsUrl = EthereumNetwork().host().appendingPathComponent("/tx/\(tx.hash)") + } + case .pending: + status = tx.isContractCreation ? "Transaction.Details.contractCreationPending".localized() : "TransactionStatus.pending".localized() + case .failure: + status = tx.isContractCreation ? "Transaction.Details.contractCreationFailure".localized() : "TransactionStatus.failure".localized() + } + + if tx.from.lowercased() == tx.token.walletAddress.lowercased() || + tx.from == tx.to { + amount = "-\(tx.value.toAmountText(tx.token.decimals)) \(tx.token.symbol)" + } else { + amount = "+\(tx.value.toAmountText(tx.token.decimals)) \(tx.token.symbol)" + } + + date = { + let dateformatter = DateFormatter() + dateformatter.dateFormat = "yyyy/MM/dd HH:mm:ss" + return dateformatter.string(from: tx.date) + }() + from = tx.from + to = tx.to.count > 0 ? tx.to : "Contract Created" + } + + func buildMoreInfo() { + if tx.status == .success { + hash = tx.hash + block = "\(tx.blockNumber)" + } + switch tx.token.type { + case .ether, .erc20: + network = EthereumNetwork().networkType.chainName + case .cita, .citaErc20: + network = tx.token.chainName + } + } + + func buildTxFee() { + if tx.status == .success || tx.status == .pending { + if let etherTx = tx as? EthereumTransactionDetails { + txFee = (etherTx.gasUsed * etherTx.gasPrice).toAmountText() + " ETH" + gasPrice = "\(etherTx.gasPrice.toGweiText()) Gwei" + } else if let citaTx = tx as? CITATransactionDetails { + let quotaPrice = GasPriceFetcher().quotaPrice(rpcNode: citaTx.token.chainHost) + gasPrice = "\(quotaPrice.toAmountText()) NATT" + txFee = ((citaTx.quotaUsed > 0 ? citaTx.quotaUsed : citaTx.gasLimit) * quotaPrice).toAmountText() + " NATT" + } + } + gasLimit = tx.status == .pending ? "\(tx.gasLimit)" : nil + if tx.status == .success { + if let etherTx = tx as? EthereumTransactionDetails { + gasUsed = "\(etherTx.gasUsed)" + } else if let citaTx = tx as? CITATransactionDetails { + gasUsed = "\(citaTx.quotaUsed)" + } + } + } +} diff --git a/Cyton/Sections/Transaction/Details/TransactionDetailsViewController.swift b/Cyton/Sections/Transaction/Details/TransactionDetailsViewController.swift new file mode 100644 index 00000000..73a954fc --- /dev/null +++ b/Cyton/Sections/Transaction/Details/TransactionDetailsViewController.swift @@ -0,0 +1,200 @@ +// +// TransactionDetailsViewController.swift +// Cyton +// +// Created by 晨风 on 2018/12/6. +// Copyright © 2018 Cryptape. All rights reserved. +// + +import UIKit +import SafariServices +import Social + +class TransactionDetailsViewController: UITableViewController { + private struct ItemAction { + var indexPath: IndexPath + var action: () -> Void + } + + @IBOutlet private weak var tokenIconView: UIImageView! + @IBOutlet private weak var statusLabel: UILabel! + @IBOutlet private weak var amountLabel: UILabel! + @IBOutlet private weak var dateLabel: UILabel! + @IBOutlet private weak var paymentAddressTitleLabel: UILabel! + @IBOutlet private weak var paymentAddressLabel: UILabel! + @IBOutlet private weak var receiptAddressTitleLabel: UILabel! + @IBOutlet private weak var receiptAddressLabel: UILabel! + @IBOutlet private weak var chainIconView: UIImageView! + @IBOutlet private weak var blockchainBrowserLabel: UILabel! + @IBOutlet private weak var hashTitleLabel: UILabel! + @IBOutlet private weak var hashLabel: UILabel! + @IBOutlet private weak var chainNetworkTitleLable: UILabel! + @IBOutlet private weak var chainNetworkLabel: UILabel! + @IBOutlet private weak var blockTitleLabel: UILabel! + @IBOutlet private weak var blockLabel: UILabel! + @IBOutlet private weak var gasFeeTitleLabel: UILabel! + @IBOutlet private weak var gasFeeLabel: UILabel! + @IBOutlet private weak var gasPriceTitleLabel: UILabel! + @IBOutlet private weak var gasPriceLabel: UILabel! + @IBOutlet private weak var gasUsedTitleLabel: UILabel! + @IBOutlet private weak var gasUsedLabel: UILabel! + @IBOutlet private weak var gasLimitTitleLabel: UILabel! + @IBOutlet private weak var gasLimitLabel: UILabel! + @IBOutlet private weak var statusWidthLayout: NSLayoutConstraint! + @IBOutlet private weak var shareBarButtonItem: UIBarButtonItem! + private var paramBuilder: TransactionDetailsParamBuilder! + private var hiddenItems = [(Int, Int)]() + private var itemActions = [ItemAction]() + var transaction: TransactionDetails! + + override func viewDidLoad() { + super.viewDidLoad() + title = "Transaction.Details.title".localized() + paymentAddressTitleLabel.text = "Transaction.Details.paymentAddress".localized() + ":" + receiptAddressTitleLabel.text = "Transaction.Details.receiptAddress".localized() + ":" + blockchainBrowserLabel.text = "Transaction.Details.blockchainBrowserDesc".localized() + hashTitleLabel.text = "Transaction.Details.hash".localized() + ":" + chainNetworkTitleLable.text = "Transaction.Details.chainNetwork".localized() + ":" + blockTitleLabel.text = "Transaction.Details.block".localized() + ":" + gasFeeTitleLabel.text = "Transaction.Details.gasFee".localized() + ":" + + navigationItem.rightBarButtonItem = nil + setupTxFeeTitle() + Toast.showHUD() + DispatchQueue.global().async { + self.paramBuilder = TransactionDetailsParamBuilder(tx: self.transaction) + DispatchQueue.main.async { + Toast.hideHUD() + self.setupUI() + self.tableView.reloadData() + } + } + // Item actions + itemActions.append(ItemAction(indexPath: IndexPath(row: 1, section: 0), action: { [weak self] in + UIPasteboard.general.string = self?.transaction.from + Toast.showToast(text: "Wallet.QRCode.copySuccess".localized()) + })) + itemActions.append(ItemAction(indexPath: IndexPath(row: 2, section: 0), action: { [weak self] in + UIPasteboard.general.string = self?.transaction.to + Toast.showToast(text: "Wallet.QRCode.copySuccess".localized()) + })) + itemActions.append(ItemAction(indexPath: IndexPath(row: 0, section: 1), action: { [weak self] in + UIPasteboard.general.string = self?.transaction.hash + Toast.showToast(text: "Wallet.QRCode.copySuccess".localized()) + })) + itemActions.append(ItemAction(indexPath: IndexPath(row: 3, section: 0), action: { [weak self] in + let safariController = SFSafariViewController(url: self!.paramBuilder.txDetailsUrl) + self!.present(safariController, animated: true, completion: nil) + })) + } + + func setupUI() { + setupTxStatus() + tokenIconView.sd_setImage(with: URL(string: paramBuilder.tokenIcon), placeholderImage: UIImage(named: "eth_logo")) + amountLabel.text = paramBuilder.amount + dateLabel.text = paramBuilder.date + paymentAddressLabel.text = paramBuilder.from + receiptAddressLabel.text = paramBuilder.to + + if paramBuilder.txDetailsUrl == nil { + hiddenItems.append((0, 3)) // block chain network + navigationItem.rightBarButtonItem = nil + } else { + navigationItem.rightBarButtonItem = shareBarButtonItem + } + if let hash = paramBuilder.hash { + hashLabel.text = hash + } else { + hiddenItems.append((1, 0)) // hash + } + chainNetworkLabel.text = paramBuilder.network + if let block = paramBuilder.block { + blockLabel.text = block + } else { + hiddenItems.append((1, 2)) // block + } + if let txFee = paramBuilder.txFee { + gasFeeLabel.text = txFee + } else { + hiddenItems.append((1, 3)) // gas fee + } + if let gasPrice = paramBuilder.gasPrice { + gasPriceLabel.text = gasPrice + } else { + hiddenItems.append((1, 4)) // gas price + } + if let gasUsed = paramBuilder.gasUsed { + gasUsedLabel.text = gasUsed + } else { + hiddenItems.append((1, 5)) // gas used + } + if let gasLimit = paramBuilder.gasLimit { + gasLimitLabel.text = gasLimit + } else { + hiddenItems.append((1, 6)) // gas limit + } + } + + func setupTxStatus() { + switch transaction.status { + case .success: + statusLabel.text = transaction.isContractCreation ? "Transaction.Details.contractCreationSuccess".localized() : "TransactionStatus.success".localized() + statusLabel.backgroundColor = UIColor(named: "secondary_color")?.withAlphaComponent(0.2) + statusLabel.textColor = UIColor(named: "secondary_color") + case .pending: + statusLabel.text = transaction.isContractCreation ? "Transaction.Details.contractCreationPending".localized() : "TransactionStatus.pending".localized() + statusLabel.backgroundColor = UIColor(named: "warning_bg_color") + statusLabel.textColor = UIColor(named: "warning_color") + case .failure: + statusLabel.text = transaction.isContractCreation ? "Transaction.Details.contractCreationFailure".localized() : "TransactionStatus.failure".localized() + statusLabel.backgroundColor = UIColor(hex: "FF706B", alpha: 0.2) + statusLabel.textColor = UIColor(hex: "FF706B") + } + statusWidthLayout.constant = statusLabel.textRect(forBounds: CGRect(x: 0, y: 0, width: 200, height: 20), limitedToNumberOfLines: 1).size.width + 24 + } + + func setupTxFeeTitle() { + switch transaction.token.type { + case .ether, .erc20: + chainIconView.image = UIImage(named: "icon_tx_details_chain_eth") + gasUsedTitleLabel.text = "Gas Used:" + gasPriceTitleLabel.text = "Gas Price:" + gasLimitTitleLabel.text = "Gas Limit:" + case .cita, .citaErc20: + chainIconView.image = UIImage(named: "icon_tx_details_chain_cita") + gasUsedTitleLabel.text = "Quota Used:" + gasPriceTitleLabel.text = "Quota Price:" + gasLimitTitleLabel.text = "Quota Limit:" + } + } + + @IBAction func share(_ sender: Any) { + let controller = UIActivityViewController(activityItems: [paramBuilder.txDetailsUrl], applicationActivities: nil) + controller.excludedActivityTypes = [.markupAsPDF, .mail, .openInIBooks, .print, .addToReadingList, .assignToContact] + present(controller, animated: true, completion: nil) + } +} + +extension TransactionDetailsViewController { + override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + if paramBuilder == nil || hiddenItems.contains(where: { $0.0 == indexPath.section && $0.1 == indexPath.row }) { + return 0.0 + } else { + return super.tableView(tableView, heightForRowAt: indexPath) + } + } + + override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { + cell.isHidden = cell.bounds.height == 0.0 + } + + override func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool { + return itemActions.contains(where: { $0.indexPath == indexPath }) + } + + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + tableView.deselectRow(at: indexPath, animated: true) + guard let itemAction = itemActions.first(where: { $0.indexPath == indexPath }) else { return } + itemAction.action() + } +} diff --git a/Neuron/Sections/Transaction/TransactionHistory.storyboard b/Cyton/Sections/Transaction/History/TransactionHistory.storyboard similarity index 97% rename from Neuron/Sections/Transaction/TransactionHistory.storyboard rename to Cyton/Sections/Transaction/History/TransactionHistory.storyboard index 31cb3b01..16f08c03 100644 --- a/Neuron/Sections/Transaction/TransactionHistory.storyboard +++ b/Cyton/Sections/Transaction/History/TransactionHistory.storyboard @@ -108,10 +108,10 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -444,22 +410,32 @@ - - + + + + + + + + + + + + - + - + @@ -488,8 +464,9 @@ - + + diff --git a/Neuron/Sections/Transaction/SendTransactionViewController.swift b/Cyton/Sections/Transaction/Send/SendTransactionViewController.swift similarity index 53% rename from Neuron/Sections/Transaction/SendTransactionViewController.swift rename to Cyton/Sections/Transaction/Send/SendTransactionViewController.swift index 4a401a01..380e026d 100644 --- a/Neuron/Sections/Transaction/SendTransactionViewController.swift +++ b/Cyton/Sections/Transaction/Send/SendTransactionViewController.swift @@ -1,6 +1,6 @@ // // SendTransactionViewController.swift -// Neuron +// Cyton // // Created by 晨风 on 2018/10/30. // Copyright © 2018 Cryptape. All rights reserved. @@ -9,76 +9,9 @@ import UIKit import BLTNBoard import BigInt -import AppChain -import Web3swift -import EthereumAddress +import CITA import RealmSwift - -protocol TransactonSender { - var paramBuilder: TransactionParamBuilder! { get set } - func sendEthereumTransaction(password: String) throws -> TxHash - func sendAppChainTransaction(password: String) throws -> TxHash -} - -extension TransactonSender { - func sendEthereumTransaction(password: String) throws -> TxHash { - let keystore = WalletManager.default.keystore(for: paramBuilder.from) - let web3 = EthereumNetwork().getWeb3() - web3.addKeystoreManager(KeystoreManager([keystore])) - - if paramBuilder.tokenType == .ether { - let sender = try EthereumTxSender(web3: web3, from: paramBuilder.from) - return try sender.sendETH( - to: paramBuilder.to, - value: paramBuilder.value, - gasLimit: paramBuilder.gasLimit, - gasPrice: BigUInt(paramBuilder.gasPrice), - data: paramBuilder.data, - password: password - ) - } else { - let sender = try EthereumTxSender(web3: web3, from: paramBuilder.from) - // TODO: estimate gas - return try sender.sendToken( - to: paramBuilder.to, - value: paramBuilder.value, - gasLimit: paramBuilder.gasLimit, - gasPrice: BigUInt(paramBuilder.gasPrice), - contractAddress: paramBuilder.contractAddress, - password: password - ) - } - } - - func sendAppChainTransaction(password: String) throws -> TxHash { - let appChain: AppChain - if paramBuilder.rpcNode.isEmpty { - appChain = AppChainNetwork.appChain() - } else { - guard let appChainUrl = URL(string: paramBuilder.rpcNode) else { - throw SendTransactionError.invalidAppChainNode - } - appChain = AppChainNetwork.appChain(url: appChainUrl) - } - if paramBuilder.tokenType == .appChain { - let sender = try AppChainTxSender( - appChain: appChain, - walletManager: WalletManager.default, - from: paramBuilder.from - ) - return try sender.send( - to: paramBuilder.to, - value: paramBuilder.value, - quota: paramBuilder.gasLimit, - data: paramBuilder.data, - chainId: BigUInt(paramBuilder.chainId)!, - password: password - ) - } else { - return "" // TODO: AppChainErc20 not implemented yet. - } - } -} +import Web3swift class SendTransactionViewController: UITableViewController, TransactonSender { @IBOutlet private weak var walletIconView: UIImageView! @@ -89,6 +22,11 @@ class SendTransactionViewController: UITableViewController, TransactonSender { @IBOutlet private weak var gasCostLabel: UILabel! @IBOutlet private weak var addressTextField: UITextField! @IBOutlet weak var tokenLabel: UILabel! + @IBOutlet weak var tokenTitleLabel: UILabel! + @IBOutlet weak var amountTitleLabel: UILabel! + @IBOutlet weak var addressTitleLabel: UILabel! + @IBOutlet weak var gasCostTitleLabel: UILabel! + @IBOutlet weak var nextButton: UIButton! var paramBuilder: TransactionParamBuilder! var enableSwitchToken = false @@ -103,30 +41,33 @@ class SendTransactionViewController: UITableViewController, TransactonSender { summaryPageItem.actionHandler = { item in item.manager?.displayNextItem() } - return BLTNItemManager(rootItem: summaryPageItem) }() - var token: TokenModel! + var token: Token! var recipientAddress: String! override func viewDidLoad() { super.viewDidLoad() + tokenTitleLabel.text = "Transaction.Send.txToken".localized() + amountTitleLabel.text = "Transaction.Send.txAmount".localized() + amountTextField.placeholder = "Transaction.Send.inputAmount".localized() + addressTitleLabel.text = "Transaction.Send.receiptAddress".localized() + addressTextField.placeholder = "Transaction.Send.receiptAddress".localized() + gasCostTitleLabel.text = "Transaction.Send.gasFee".localized() + nextButton.setTitle("Common.next".localized(), for: .normal) if enableSwitchToken && token == nil { - token = AppModel.current.nativeTokenList.first + token = AppModel.current.currentWallet!.selectedTokenList.first?.token } createParamBuilder() } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { - if segue.identifier == "TransactionGasPriceViewController" { - let controller = segue.destination as! TransactionGasPriceViewController - controller.param = paramBuilder - } else if segue.identifier == "switchToken" { + if segue.identifier == "switchToken" { let controller = segue.destination as! TransactionSwitchTokenViewController - controller.currentToken = token + controller.currentToken = token.tokenModel controller.delegate = self } else if segue.identifier == String(describing: TransactionGasCostViewController.self) { let controller = segue.destination as! TransactionGasCostViewController @@ -137,19 +78,8 @@ class SendTransactionViewController: UITableViewController, TransactonSender { @IBAction func next(_ sender: Any) { view.endEditing(true) - let amount = Double(amountTextField.text!) ?? 0.0 - paramBuilder.value = amount.toAmount() + paramBuilder.value = BigUInt.parseToBigUInt(amountTextField.text!, token.decimals) paramBuilder.to = addressTextField.text! - paramBuilder.amount = amount - - if token.type == .erc20 { - let realm = try! Realm() - let ether = realm.objects(TokenModel.self).first(where: { $0.type == .ether })! - if ether.tokenBalance < paramBuilder.txFeeNatural { - Toast.showToast(text: "请确保账户剩余\(token.gasSymbol)高于矿工费用,以便顺利完成转账~") - return - } - } if isEffectiveTransferInfo { summaryPageItem.update(paramBuilder) @@ -165,40 +95,32 @@ class SendTransactionViewController: UITableViewController, TransactonSender { } @IBAction func transactionAvailableBalance() { - // TODO: FIXME: erc20 token requires ETH balance for tx fee switch token.type { - case .ether, .appChain: - let balance = NSDecimalNumber(string: String(token.tokenBalance)) - let txFee = NSDecimalNumber(string: String(paramBuilder.txFeeNatural)) - let amount = balance.subtracting(txFee) - if amount.doubleValue < 0 { - Toast.showToast(text: "请确保账户剩余\(token.gasSymbol)高于矿工费用,以便顺利完成转账~") + case .ether, .cita: + if paramBuilder.txFee > paramBuilder.tokenBalance { + Toast.showToast(text: String(format: "Transaction.Send.balanceNotSufficient".localized(), token.nativeTokenSymbol)) return } - amountTextField.text = amount.stringValue - paramBuilder.value = amount.doubleValue.toAmount(token.decimals) - case .erc20: - let realm = try! Realm() - let ether = realm.objects(TokenModel.self).first(where: { $0.type == .ether })! - if ether.tokenBalance < paramBuilder.txFeeNatural { - Toast.showToast(text: "请确保账户剩余\(token.gasSymbol)高于矿工费用,以便顺利完成转账~") + let amount = paramBuilder.tokenBalance - paramBuilder.txFee + let amountText = amount.toDecimalNumber(token.decimals).formatterToString(8) + amountTextField.text = amountText + case .erc20, .citaErc20: + if token.nativeToken.balance ?? 0 < paramBuilder.txFee { + Toast.showToast(text: String(format: "Transaction.Send.balanceNotSufficient".localized(), token.nativeTokenSymbol)) return } - let amount = token.tokenBalance - amountTextField.text = "\(amount)" - paramBuilder.value = amount.toAmount(token.decimals) - default: - break + amountTextField.text = (token.balance ?? 0).toDecimalNumber(token.decimals).formatterToString(8) } } func setupUI() { let wallet = AppModel.current.currentWallet! - title = "\(token.symbol)转账" - walletIconView.image = UIImage(data: wallet.iconData) + title = String(format: "Transaction.Send.title".localized(), token.symbol) + + walletIconView.image = wallet.icon.image walletNameLabel.text = wallet.name walletAddressLabel.text = wallet.address - tokenBalanceButton.setTitle("\(token.tokenBalance.decimal) \(token.symbol)", for: .normal) + tokenBalanceButton.setTitle("\((token.balance ?? 0).toAmountText(token.decimals)) \(token.symbol)", for: .normal) addressTextField.text = paramBuilder.to tokenLabel.text = token.symbol @@ -206,10 +128,10 @@ class SendTransactionViewController: UITableViewController, TransactonSender { } private func updateGasCost() { - gasCostLabel.text = "\(paramBuilder.txFeeNatural.decimal) \(paramBuilder.nativeCoinSymbol)" - if paramBuilder.tokenPrice > 0 { - let amount = paramBuilder.txFeeNatural * paramBuilder.tokenPrice - gasCostLabel.text! += "≈ \(paramBuilder.currencySymbol) " + String(format: "%.2lf", amount) + gasCostLabel.text = "\(paramBuilder.txFeeText) \(paramBuilder.nativeCoinSymbol)" + if paramBuilder.nativeTokenPrice > 0 { + let amount = paramBuilder.txFee.toDecimalNumber().multiplying(by: NSDecimalNumber(value: paramBuilder.nativeTokenPrice)) + gasCostLabel.text! += " ≈ \(amount.currencyFormat())" } } @@ -234,17 +156,20 @@ private extension SendTransactionViewController { func sendTransaction(password: String) { DispatchQueue.global().async { do { + guard let wallet = AppModel.current.currentWallet?.wallet else { return } + guard WalletManager.default.verifyPassword(wallet: wallet, password: password) else { + throw "WalletManager.Error.invalidPassword".localized() + } + if self.paramBuilder.tokenType == .ether || self.paramBuilder.tokenType == .erc20 { _ = try self.sendEthereumTransaction(password: password) } else { - _ = try self.sendAppChainTransaction(password: password) + _ = try self.sendCITATransaction(password: password) } - DispatchQueue.main.async { // TODO: send back txHash? - let successPageItem = SuccessPageItem.create(title: "交易已发送") + let successPageItem = SuccessPageItem.create(title: "DApp.Contract.TransactionSend".localized()) successPageItem.actionHandler = { item in - self.track() item.manager?.dismissBulletin(animated: true) self.navigationController?.popViewController(animated: true) } @@ -258,7 +183,13 @@ private extension SendTransactionViewController { /// create a new item. Note this would leave more than one password item in the stack. let passwordPageItem = self.createPasswordPageItem() self.bulletinManager.push(item: passwordPageItem) - passwordPageItem.errorMessage = error.localizedDescription + if let error = error as? Web3Error { + passwordPageItem.errorMessage = error.description.localized() + } else if let error = error as? String { + passwordPageItem.errorMessage = error + } else { + passwordPageItem.errorMessage = "交易失败" + } } } } @@ -266,39 +197,27 @@ private extension SendTransactionViewController { var isEffectiveTransferInfo: Bool { guard Address.isValid(paramBuilder.to) && paramBuilder.to != "0x" else { - Toast.showToast(text: "您的地址错误,请重新输入") + Toast.showToast(text: "Transaction.Send.addressError".localized()) return false } - // TODO: FIXME: erc20 requires eth balance as tx fee - if paramBuilder.hasSufficientBalance { - return true + if token.type == .erc20 || token.type == .citaErc20 { + if token.nativeToken.balance ?? 0 < paramBuilder.txFee { + Toast.showToast(text: String(format: "Transaction.Send.balanceNotSufficient".localized(), paramBuilder.nativeCoinSymbol)) + return false + } } - if paramBuilder.tokenBalance <= BigUInt(0) { - Toast.showToast(text: "请确保账户剩余\(token.gasSymbol)高于矿工费用,以便顺利完成转账~") - return false - } - let alert = UIAlertController(title: "您输入的金额超过您的余额,是否全部转出?", message: "", preferredStyle: .alert) - alert.addAction(UIAlertAction(title: "确认", style: .default, handler: { (_) in + guard !paramBuilder.hasSufficientBalance else { return true } + + let alert = UIAlertController(title: "Transaction.Send.transactionAvailableBalance".localized(), message: "", preferredStyle: .alert) + alert.addAction(UIAlertAction(title: "Common.confirm".localized(), style: .default, handler: { (_) in self.transactionAvailableBalance() })) - alert.addAction(UIAlertAction(title: "取消", style: .destructive, handler: { (_) in - })) + alert.addAction(UIAlertAction(title: "Common.cancel".localized(), style: .destructive)) present(alert, animated: true, completion: nil) return false } - - func track() { - SensorsAnalytics.Track.transaction( - chainType: paramBuilder.chainId, - currencyType: paramBuilder.symbol, - currencyNumber: Double(amountTextField.text ?? "0")!, - receiveAddress: addressTextField.text ?? "", - outcomeAddress: AppModel.current.currentWallet!.address, - transactionType: .normal - ) - } } extension SendTransactionViewController { @@ -349,7 +268,7 @@ extension SendTransactionViewController: TransactionSwitchTokenViewControllerDel } override func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool { - return !(indexPath.row == 3 && paramBuilder.tokenType == .appChain) + return indexPath.row == 0 || indexPath.row == 3 } override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { @@ -362,18 +281,10 @@ extension SendTransactionViewController: TransactionSwitchTokenViewControllerDel } else { cell.isHidden = false } - - if indexPath.row == 3 { - if paramBuilder.tokenType == .appChain { - cell.accessoryType = .none - } else { - cell.accessoryType = .disclosureIndicator - } - } } - func switchToken(switchToken: TransactionSwitchTokenViewController, didSwitchToToken token: TokenModel) { - self.token = token + func switchToken(switchToken: TransactionSwitchTokenViewController, didSwitchToToken tokenModel: TokenModel) { + self.token = tokenModel.token tableView.reloadData() observers.forEach { (observe) in @@ -386,10 +297,10 @@ extension SendTransactionViewController: TransactionSwitchTokenViewControllerDel private func createParamBuilder() { paramBuilder = TransactionParamBuilder(token: token) - observers.append(paramBuilder.observe(\.txFeeNatural, options: [.initial]) { (_, _) in + observers.append(paramBuilder.observe(\.txFeeText, options: [.initial]) { (_, _) in self.updateGasCost() }) - observers.append(paramBuilder.observe(\.tokenPrice, options: [.initial]) { [weak self](_, _) in + observers.append(paramBuilder.observe(\.nativeTokenPrice, options: [.initial]) { [weak self](_, _) in self?.updateGasCost() }) paramBuilder.from = AppModel.current.currentWallet!.address diff --git a/Cyton/Sections/Transaction/Send/TransactionGasCostViewController.swift b/Cyton/Sections/Transaction/Send/TransactionGasCostViewController.swift new file mode 100644 index 00000000..1c1b0fb7 --- /dev/null +++ b/Cyton/Sections/Transaction/Send/TransactionGasCostViewController.swift @@ -0,0 +1,201 @@ +// +// TransactionGasCostViewController.swift +// Cyton +// +// Created by 晨风 on 2018/11/23. +// Copyright © 2018 Cryptape. All rights reserved. +// + +import UIKit +import BigInt +import Web3swift + +class TransactionGasCostViewController: UITableViewController { + @IBOutlet private weak var gasPriceTitleLabel: UILabel! + @IBOutlet private weak var gasLimitTitleLabel: UILabel! + @IBOutlet private weak var gasPriceTextField: UITextField! + @IBOutlet private weak var gasLimitTextField: UITextField! + @IBOutlet private weak var gasCostLabel: UILabel! + @IBOutlet private weak var gasCostDescLabel: UILabel! + @IBOutlet private weak var inputDataTextView: UITextView! + @IBOutlet private weak var dataTextPlaceholderLabel: UILabel! + @IBOutlet private weak var confirmButton: UIButton! + @IBOutlet private weak var gasCostTitleLabel: UILabel! + @IBOutlet private weak var extenDataTitleLabel: UILabel! + @IBOutlet private weak var descLabel: UILabel! + @IBOutlet private weak var hexHighlightView: UIView! + @IBOutlet private weak var utf8HighlightView: UIView! + @IBOutlet private weak var dataTextView: UITextView! + @IBOutlet private weak var gasPriceSymbolLabel: UILabel! + @IBOutlet private weak var gasPriceSymbolWidthLayout: NSLayoutConstraint! + private var paramBuilder: TransactionParamBuilder! + private var observers = [NSKeyValueObservation]() + private let minGasPrice = 1.0 + var dataString: String? + var param: TransactionParamBuilder! + + override func viewDidLoad() { + super.viewDidLoad() + title = "Transaction.Send.gasCostSetting".localized() + extenDataTitleLabel.text = "Transaction.Send.extenData".localized() + descLabel.text = "Transaction.Send.gasCostSettingDesc".localized() + confirmButton.setTitle("Common.confirm".localized(), for: .normal) + gasPriceTextField.placeholder = "Transaction.Send.input".localized() + gasLimitTextField.placeholder = "Transaction.Send.input".localized() + dataTextPlaceholderLabel.text = "Transaction.Send.inputHexData".localized() + + paramBuilder = TransactionParamBuilder(builder: param) + observers.append(paramBuilder.observe(\.txFeeText, options: [.initial]) { [weak self](_, _) in + self?.updateGasCost() + }) + observers.append(param.observe(\.nativeTokenPrice, options: [.initial]) { [weak self](_, _) in + self?.updateGasCost() + }) + let hexText = paramBuilder.data.toHexString() + if hexText.lengthOfBytes(using: .utf8) > 0 { + inputDataTextView.text = hexText.addHexPrefix() + dataTextPlaceholderLabel.isHidden = inputDataTextView.text.lengthOfBytes(using: .utf8) > 0 + } + dataString != nil ? switchDataToHex() : nil + } + + // MARK: Action + + @IBAction func switchDataToHex() { + hexHighlightView.backgroundColor = UIColor(named: "tint_color") + utf8HighlightView.backgroundColor = UIColor(named: "weak_1_color") + dataTextView.text = dataString + } + + @IBAction func switchDataToUtf8() { + hexHighlightView.backgroundColor = UIColor(named: "weak_1_color") + utf8HighlightView.backgroundColor = UIColor(named: "tint_color") + dataTextView.text = String(decoding: Data.fromHex(dataString!)!, as: UTF8.self) + } + + @IBAction func confirm() { + UIApplication.shared.keyWindow?.endEditing(true) + if paramBuilder.tokenType == .ether || paramBuilder.tokenType == .erc20 { + let gasPrice = Double(gasPriceTextField.text!)! + if gasPrice < minGasPrice { + Toast.showToast(text: "Transaction.Send.gasPriceSettingIsTooLow".localized()) + return + } + if paramBuilder.data.count > 0 { + let estimateGasLimit = paramBuilder.estimateGasLimit() + if paramBuilder.gasLimit < UInt(estimateGasLimit) { + Toast.showToast(text: "Transaction.Send.gasLimitSettingIsTooLow".localized()) + return + } + } else { + if paramBuilder.gasLimit < GasCalculator.defaultGasLimit { + Toast.showToast(text: "Transaction.Send.gasLimitSettingIsTooLow".localized()) + return + } + } + } else if paramBuilder.tokenType == .cita || paramBuilder.tokenType == .citaErc20 { + gasPriceTextField.isEnabled = false + if paramBuilder.gasLimit < paramBuilder.estimateGasLimit() { + Toast.showToast(text: "Transaction.Send.quotaLimitSettingIsTooLow".localized()) + return + } + } + param.gasPrice = paramBuilder.gasPrice + param.gasLimit = paramBuilder.gasLimit + if var dataText = inputDataTextView.text { + dataText = dataText.removeHexPrefix() + if !CharacterSet(charactersIn: "0123456789ABCDEFabcdef").isSuperset(of: CharacterSet(charactersIn: dataText)) { + Toast.showToast(text: "Transaction.Send.inputHexData".localized()) + return + } + param.data = Data(hex: dataText) + } + navigationController?.popViewController(animated: true) + } + + private func updateGasCost() { + switch paramBuilder.tokenType { + case .cita, .citaErc20: + gasPriceTextField.text = paramBuilder.gasPrice.toAmountText(paramBuilder.nativeTokenDecimals) + gasPriceSymbolLabel.text = "NATT" + gasPriceTextField.isEnabled = false + gasPriceTitleLabel.text = "Quota Price" + gasLimitTitleLabel.text = "Quota Limit" + gasCostTitleLabel.text = "Transaction.Send.quotaCost".localized() + case .ether, .erc20: + gasPriceTextField.text = paramBuilder.gasPrice.toGweiText() + gasPriceSymbolLabel.text = "Gwei" + gasPriceTitleLabel.text = "Gas Price" + gasLimitTitleLabel.text = "Gas Limit" + gasCostTitleLabel.text = "Transaction.Send.gasCost".localized() + } + gasPriceSymbolWidthLayout.constant = gasPriceSymbolLabel.textRect(forBounds: CGRect(x: 0, y: 0, width: 100, height: 20), limitedToNumberOfLines: 1).size.width + + gasLimitTextField.text = paramBuilder.gasLimit.description + gasCostLabel.text = "\(paramBuilder.txFeeText) \(paramBuilder.nativeCoinSymbol)" + gasCostDescLabel.text = "≈\(gasLimitTitleLabel.text!)(\(gasLimitTextField.text!))*\(gasPriceTitleLabel.text!)(\(gasPriceTextField.text!) \(gasPriceSymbolLabel.text!))" + if paramBuilder.nativeTokenPrice > 0 { + let amount = paramBuilder.txFee.toDecimalNumber().multiplying(by: NSDecimalNumber(value: paramBuilder.nativeTokenPrice)) + gasCostLabel.text = gasCostLabel.text! + " ≈ \(amount.currencyFormat())" + } + } + + override func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool { + return false + } +} + +extension TransactionGasCostViewController: UITextFieldDelegate { + func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { + var character = "0123456789" + if textField.text!.contains(".") { + character += "." + } + guard CharacterSet(charactersIn: character).isSuperset(of: CharacterSet(charactersIn: string)) else { + return false + } + return true + } + + func textFieldDidEndEditing(_ textField: UITextField) { + if textField == gasPriceTextField { + paramBuilder.gasPrice = BigUInt.parseToBigUInt(gasPriceTextField.text!, 9) + } else if textField == gasLimitTextField { + paramBuilder.gasLimit = BigUInt(string: gasLimitTextField.text!) ?? GasCalculator.defaultGasLimit + } + } +} + +extension TransactionGasCostViewController: UITextPasteDelegate { +} + +extension TransactionGasCostViewController { + override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + if indexPath.row == 4 { + if dataString == nil { + return 0.0 + } + } + if indexPath.row == 3 { + if paramBuilder.tokenType == .erc20 || paramBuilder.tokenType == .citaErc20 || dataString != nil { + return 0.0 + } + } + return super.tableView(tableView, heightForRowAt: indexPath) + } + + override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { + cell.isHidden = cell.bounds.size.height == 0.0 + } +} + +extension TransactionGasCostViewController: UITextViewDelegate { + func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { + let character = "0123456789abcdefABCDEFxX" + guard CharacterSet(charactersIn: character).isSuperset(of: CharacterSet(charactersIn: text)) else { + return false + } + dataTextPlaceholderLabel.isHidden = textView.text.count + (text.count - range.length) > 0 + return true + } +} diff --git a/Neuron/Sections/Transaction/TransactionParamBuilder.swift b/Cyton/Sections/Transaction/Send/TransactionParamBuilder.swift similarity index 66% rename from Neuron/Sections/Transaction/TransactionParamBuilder.swift rename to Cyton/Sections/Transaction/Send/TransactionParamBuilder.swift index 1452a4a5..06dbbaf1 100644 --- a/Neuron/Sections/Transaction/TransactionParamBuilder.swift +++ b/Cyton/Sections/Transaction/Send/TransactionParamBuilder.swift @@ -1,6 +1,6 @@ // // TransactionParamBuilder.swift -// Neuron +// Cyton // // Created by 晨风 on 2018/10/31. // Copyright © 2018 Cryptape. All rights reserved. @@ -10,25 +10,26 @@ import Foundation import BigInt import Web3swift import EthereumAddress +import RealmSwift /// Prepare tx params. class TransactionParamBuilder: NSObject { - var from: String = "" + var tokenIdentifier = "" + var from = "" var to = "" var value: BigUInt = 0 var data = Data() var contractAddress = "" var chainId = "" - var amount = 0.0 - var fetchedGasPrice: BigUInt = 1 // Fetched from node as recommended gas price - var gasPrice: BigUInt = 1 { + var fetchedGasPrice: BigUInt = BigUInt.parseToBigUInt("1", 9) // Fetched from node as recommended gas price + var gasPrice: BigUInt = BigUInt.parseToBigUInt("1", 9) { didSet { rebuildGasCalculator() } } - var gasLimit: UInt64 = GasCalculator.defaultGasLimit { + var gasLimit: BigUInt = GasCalculator.defaultGasLimit { didSet { rebuildGasCalculator() } @@ -39,13 +40,13 @@ class TransactionParamBuilder: NSObject { } @objc dynamic - private(set) var txFeeNatural: Double = 0 + private(set) var txFeeText: String = "0" var tokenBalance: BigUInt = 0 - var balance: Double = 0 @objc dynamic - private(set) var tokenPrice: Double = 0 + private(set) var nativeTokenPrice: Double = 0 + private(set) var nativeTokenDecimals = 18 private(set) var currencySymbol = "" @@ -53,11 +54,9 @@ class TransactionParamBuilder: NSObject { /// when sending ERC20. UI layer should check that. var hasSufficientBalance: Bool { switch tokenType { - case .ether, .appChain: - let amount = NSDecimalNumber(string: self.amount.description).adding(NSDecimalNumber(string: txFeeNatural.description)) - let balance = NSDecimalNumber(string: self.balance.description) - return balance.doubleValue >= amount.doubleValue - case .erc20, .appChainErc20: + case .ether, .cita: + return tokenBalance >= value + txFee + case .erc20, .citaErc20: return tokenBalance >= value } } @@ -70,25 +69,34 @@ class TransactionParamBuilder: NSObject { private var gasCalculator = GasCalculator() - init(token: TokenModel) { + init(token: Token, gasPrice: BigUInt? = nil, gasLimit: BigUInt? = nil) { + tokenIdentifier = token.identifier tokenType = token.type - rpcNode = token.chainHosts + rpcNode = token.chainHost decimals = token.decimals chainId = token.chainId contractAddress = token.address symbol = token.symbol - nativeCoinSymbol = token.gasSymbol - tokenBalance = token.tokenBalance.toAmount(token.decimals) - balance = token.tokenBalance + nativeCoinSymbol = token.nativeTokenSymbol + tokenBalance = token.balance ?? 0 super.init() - fetchGasPrice() - fetchGasLimit() - fetchTokenPrice(token: token) + if let gasPrice = gasPrice { + self.gasPrice = gasPrice + } else { + fetchGasPrice() + } + if let gasLimit = gasLimit { + self.gasLimit = gasLimit + } else { + fetchGasLimit() + } + fetchNativeTokenPrice(token: token) } init(builder: TransactionParamBuilder) { + tokenIdentifier = builder.tokenIdentifier tokenType = builder.tokenType rpcNode = builder.rpcNode decimals = builder.decimals @@ -97,18 +105,18 @@ class TransactionParamBuilder: NSObject { symbol = builder.symbol nativeCoinSymbol = builder.nativeCoinSymbol tokenBalance = builder.tokenBalance - balance = builder.balance super.init() gasPrice = builder.gasPrice gasLimit = builder.gasLimit from = builder.from to = builder.to - tokenPrice = builder.tokenPrice + data = builder.data + nativeTokenPrice = builder.nativeTokenPrice currencySymbol = builder.currencySymbol rebuildGasCalculator() } - func estimateGasLimit() -> UInt64 { + func estimateGasLimit() -> BigUInt { switch tokenType { case .erc20, .ether: var options = TransactionOptions.defaultOptions @@ -118,7 +126,7 @@ class TransactionParamBuilder: NSObject { let contract = EthereumNetwork().getWeb3().contract(Web3Utils.erc20ABI, at: EthereumAddress(from)!) let trans = contract!.method(transactionOptions: options)! let estimateGasLimit = (try? trans.estimateGas(transactionOptions: options)) ?? BigUInt(GasCalculator.defaultGasLimit) - return UInt64(estimateGasLimit) + return estimateGasLimit default: return GasCalculator.defaultGasLimit } @@ -133,7 +141,7 @@ class TransactionParamBuilder: NSObject { switch tokenType { case .ether, .erc20: GasPriceFetcher().fetchGasPrice(then: fetched) - case .appChain, .appChainErc20: + case .cita, .citaErc20: GasPriceFetcher().fetchQuotaPrice(rpcNode: rpcNode, then: fetched) } } @@ -141,21 +149,23 @@ class TransactionParamBuilder: NSObject { // TODO: implement estimate gas private func fetchGasLimit() { switch tokenType { - case .ether, .appChain: + case .ether, .cita: gasLimit = GasCalculator.defaultGasLimit - case .erc20, .appChainErc20: + case .erc20: gasLimit = 100_000 + case .citaErc20: + gasLimit = 200_000 } } - private func fetchTokenPrice(token: TokenModel) { + private func fetchNativeTokenPrice(token: Token) { let currency = LocalCurrencyService.shared.getLocalCurrencySelect() - let symbol = token.symbol + let tokenSymbol: String = token.nativeTokenSymbol currencySymbol = currency.symbol DispatchQueue.global().async { - if let price = TokenPriceLoader().getPrice(symbol: symbol, currency: currency.short) { + if let price = TokenPriceLoader().getPrice(symbol: tokenSymbol, currency: currency.short) { DispatchQueue.main.async { - self.tokenPrice = price + self.nativeTokenPrice = price } } } @@ -163,6 +173,6 @@ class TransactionParamBuilder: NSObject { private func rebuildGasCalculator() { gasCalculator = GasCalculator(gasPrice: gasPrice, gasLimit: gasLimit) - txFeeNatural = gasCalculator.txFeeNatural + txFeeText = gasCalculator.txFee.toAmountText() } } diff --git a/Neuron/Sections/Transaction/TransactionSwitchTokenViewController.swift b/Cyton/Sections/Transaction/Send/TransactionSwitchTokenViewController.swift similarity index 82% rename from Neuron/Sections/Transaction/TransactionSwitchTokenViewController.swift rename to Cyton/Sections/Transaction/Send/TransactionSwitchTokenViewController.swift index e4a9ba8b..c1e4790b 100644 --- a/Neuron/Sections/Transaction/TransactionSwitchTokenViewController.swift +++ b/Cyton/Sections/Transaction/Send/TransactionSwitchTokenViewController.swift @@ -1,6 +1,6 @@ // // SendTransactionSwitchTokenViewController.swift -// Neuron +// Cyton // // Created by 晨风 on 2018/11/21. // Copyright © 2018 Cryptape. All rights reserved. @@ -9,21 +9,22 @@ import UIKit protocol TransactionSwitchTokenViewControllerDelegate: NSObjectProtocol { - func switchToken(switchToken: TransactionSwitchTokenViewController, didSwitchToToken token: TokenModel) + func switchToken(switchToken: TransactionSwitchTokenViewController, didSwitchToToken tokenModel: TokenModel) } class TransactionSwitchTokenViewController: UIViewController { - @IBOutlet weak var backgroundView: UIView! - @IBOutlet weak var contentView: UIView! - @IBOutlet weak var tableView: UITableView! + @IBOutlet private weak var backgroundView: UIView! + @IBOutlet private weak var contentView: UIView! + @IBOutlet private weak var tableView: UITableView! + @IBOutlet private weak var titleLabel: UILabel! private var tokens = [TokenModel]() var currentToken: TokenModel! weak var delegate: TransactionSwitchTokenViewControllerDelegate? override func viewDidLoad() { super.viewDidLoad() - tokens += AppModel.current.nativeTokenList - tokens += AppModel.current.currentWallet!.selectTokenList + tokens = AppModel.current.currentWallet!.selectedTokenList.map({ $0 }) + titleLabel.text = "Transaction.Send.txTokens".localized() } override func viewWillAppear(_ animated: Bool) { @@ -49,7 +50,7 @@ class TransactionSwitchTokenViewController: UIViewController { }) } - @IBAction func confirm() { + func confirm() { delegate?.switchToken(switchToken: self, didSwitchToToken: currentToken) dismiss() } @@ -68,11 +69,7 @@ extension TransactionSwitchTokenViewController: UITableViewDataSource, UITableVi func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { guard let cell = cell as? TransactionSwitchTokenTableViewCell else { return } - if tokens[indexPath.row].symbol == currentToken.symbol { - cell.tokenLabel.textColor = UIColor(red: 72/255.0, green: 109/255.0, blue: 255/255.0, alpha: 1.0) - } else { - cell.tokenLabel.textColor = UIColor(red: 36/255.0, green: 43/255.0, blue: 67/255.0, alpha: 1.0) - } + cell.selectedView.isHidden = tokens[indexPath.row].symbol != currentToken.symbol } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { @@ -84,9 +81,11 @@ extension TransactionSwitchTokenViewController: UITableViewDataSource, UITableVi self.tableView(tableView, willDisplay: tableView.cellForRow(at: indexPath)!, forRowAt: indexPath) } self.tableView(tableView, willDisplay: tableView.cellForRow(at: indexPath)!, forRowAt: indexPath) + confirm() } } class TransactionSwitchTokenTableViewCell: UITableViewCell { @IBOutlet weak var tokenLabel: UILabel! + @IBOutlet weak var selectedView: UIImageView! } diff --git a/Cyton/Sections/Transaction/Send/TransactonSender.swift b/Cyton/Sections/Transaction/Send/TransactonSender.swift new file mode 100644 index 00000000..f7e7d942 --- /dev/null +++ b/Cyton/Sections/Transaction/Send/TransactonSender.swift @@ -0,0 +1,108 @@ +// +// TransactonSender.swift +// Cyton +// +// Created by 晨风 on 2018/12/4. +// Copyright © 2018 Cryptape. All rights reserved. +// + +import UIKit +import BigInt +import CITA +import Web3swift + +protocol TransactonSender { + var token: Token! { get set } + var paramBuilder: TransactionParamBuilder! { get set } + func sendEthereumTransaction(password: String) throws -> TxHash + func sendCITATransaction(password: String) throws -> TxHash +} + +extension TransactonSender { + func sendEthereumTransaction(password: String) throws -> TxHash { + let keystore = WalletManager.default.keystore(for: paramBuilder.from) + let web3 = EthereumNetwork().getWeb3() + web3.addKeystoreManager(KeystoreManager([keystore])) + + if paramBuilder.tokenType == .ether { + let sender = try EthereumTxSender(web3: web3, from: paramBuilder.from) + let txhash = try sender.sendETH( + to: paramBuilder.to, + value: paramBuilder.value, + gasLimit: paramBuilder.gasLimit, + gasPrice: BigUInt(paramBuilder.gasPrice), + data: paramBuilder.data, + password: password + ) + recordEthereumTx(txhash: txhash) + return txhash + } else { + let sender = try EthereumTxSender(web3: web3, from: paramBuilder.from) + let txhash = try sender.sendToken( + to: paramBuilder.to, + value: paramBuilder.value, + gasLimit: paramBuilder.gasLimit, + gasPrice: BigUInt(paramBuilder.gasPrice), + contractAddress: paramBuilder.contractAddress, + password: password + ) + recordEthereumTx(txhash: txhash) + return txhash + } + } + + func sendCITATransaction(password: String) throws -> TxHash { + let cita: CITA + if paramBuilder.rpcNode.isEmpty { + cita = CITANetwork().cita + } else { + guard let citaUrl = URL(string: paramBuilder.rpcNode) else { + throw SendTransactionError.invalidCITANode + } + cita = CITANetwork(url: citaUrl).cita + } + let sender = try CITATxSender( + cita: cita, + walletManager: WalletManager.default, + from: paramBuilder.from + ) + if paramBuilder.tokenType == .cita { + let result = try sender.send( + to: paramBuilder.to, + value: paramBuilder.value, + quota: paramBuilder.gasLimit, + data: paramBuilder.data, + chainId: BigUInt(paramBuilder.chainId)!, + password: password + ) + recordCITATx(txhash: result.0, validUntilBlock: result.1) + return result.0 + } else { + let result = try sender.sendERC20( + to: paramBuilder.to, + contract: paramBuilder.contractAddress, + value: paramBuilder.value, + quota: paramBuilder.gasLimit, + chainId: BigUInt(paramBuilder.chainId)!, + password: password) + recordCITATx(txhash: result.0, validUntilBlock: result.1) + return result.0 + } + } + + func recordEthereumTx(txhash: String) { + EthereumLocalTxPool.pool.insertLocalTx(localTx: EthereumLocalTx( + token: token.tokenModel, txHash: txhash, + from: paramBuilder.from, to: paramBuilder.to, value: paramBuilder.value, + gasPrice: paramBuilder.gasPrice, gasLimit: paramBuilder.gasLimit + )) + } + + func recordCITATx(txhash: String, validUntilBlock: BigUInt) { + CITALocalTxPool.pool.insertLocalTx(localTx: CITALocalTx( + token: token.tokenModel, txHash: txhash, validUntilBlock: validUntilBlock, + from: paramBuilder.from, to: paramBuilder.to, value: paramBuilder.value, + quotaPrice: paramBuilder.gasPrice, quotaLimit: paramBuilder.gasLimit + )) + } +} diff --git a/Neuron/Sections/Wallet/AddWallet/AddWallet.storyboard b/Cyton/Sections/Wallet/AddWallet/AddWallet.storyboard similarity index 96% rename from Neuron/Sections/Wallet/AddWallet/AddWallet.storyboard rename to Cyton/Sections/Wallet/AddWallet/AddWallet.storyboard index 92b8b2d7..4465a803 100644 --- a/Neuron/Sections/Wallet/AddWallet/AddWallet.storyboard +++ b/Cyton/Sections/Wallet/AddWallet/AddWallet.storyboard @@ -6,6 +6,7 @@ + @@ -29,7 +30,7 @@ - + @@ -61,7 +62,6 @@ - @@ -124,6 +124,12 @@ + + + + + + @@ -359,13 +365,15 @@ + + - + @@ -575,11 +583,16 @@ + + + + + - + @@ -600,7 +613,7 @@ - + @@ -786,12 +799,17 @@ + + + + + - + @@ -801,19 +819,19 @@ - + - + - + @@ -965,7 +983,12 @@ + + + + + @@ -1105,6 +1128,11 @@ + + + + + @@ -1157,6 +1185,9 @@ + + + @@ -1167,5 +1198,8 @@ + + + diff --git a/Neuron/Sections/Wallet/AddWallet/CreateWalletController.swift b/Cyton/Sections/Wallet/AddWallet/CreateWalletController.swift similarity index 75% rename from Neuron/Sections/Wallet/AddWallet/CreateWalletController.swift rename to Cyton/Sections/Wallet/AddWallet/CreateWalletController.swift index b81d9b99..eb44c5c1 100644 --- a/Neuron/Sections/Wallet/AddWallet/CreateWalletController.swift +++ b/Cyton/Sections/Wallet/AddWallet/CreateWalletController.swift @@ -1,6 +1,6 @@ // // CreatWalletController.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/5/25. // Copyright © 2018年 cryptape. All rights reserved. @@ -9,16 +9,25 @@ import UIKit class CreateWalletController: UITableViewController { - - @IBOutlet weak var nextButton: UIButton! var name: String? = "" var password: String? = "" var confirmPassword: String? = "" + @IBOutlet private weak var nextButton: UIButton! + @IBOutlet private weak var passwordWarningLabel: UILabel! + @IBOutlet private weak var passwordDescLabel: UILabel! + @IBOutlet private weak var nameTextField: UITextField! + @IBOutlet private weak var passwordTextField: UITextField! + @IBOutlet private weak var rePasswordTextField: UITextField! override func viewDidLoad() { super.viewDidLoad() - - title = "创建钱包" + title = "Wallet.Create.createWallet".localized() + passwordWarningLabel.text = "Wallet.Create.passwordWarning".localized() + nameTextField.placeholder = "Wallet.Create.walletName".localized() + passwordTextField.placeholder = "Wallet.Create.setPassword".localized() + rePasswordTextField.placeholder = "Wallet.Create.rePassword".localized() + nextButton.setTitle("Common.next".localized(), for: .normal) + passwordDescLabel.text = "Wallet.Create.passwordDesc".localized() } override func viewWillAppear(_ animated: Bool) { @@ -74,7 +83,7 @@ class CreateWalletController: UITableViewController { func canProceedNextStep() -> Bool { if password != confirmPassword { - Toast.showToast(text: "两次密码不一致") + Toast.showToast(text: "Wallet.Create.passwordInconsistent".localized()) return false } if case .invalid(let reason) = WalletNameValidator.validate(walletName: name ?? "") { diff --git a/Cyton/Sections/Wallet/AddWallet/CreateWalletGuideViewController.swift b/Cyton/Sections/Wallet/AddWallet/CreateWalletGuideViewController.swift new file mode 100644 index 00000000..cee7a994 --- /dev/null +++ b/Cyton/Sections/Wallet/AddWallet/CreateWalletGuideViewController.swift @@ -0,0 +1,24 @@ +// +// AddWalletGuideViewController.swift +// Cyton +// +// Created by 晨风 on 2018/12/14. +// Copyright © 2018 Cryptape. All rights reserved. +// + +import UIKit + +class CreateWalletGuideViewController: UIViewController { + @IBOutlet private weak var warningLabel: UILabel! + @IBOutlet private weak var descLabel: UILabel! + @IBOutlet private weak var createWalletButton: UIButton! + @IBOutlet private weak var importWalletButton: UIButton! + + override func viewDidLoad() { + super.viewDidLoad() + warningLabel.text = "Wallet.Create.warning".localized() + descLabel.text = "Wallet.Create.desc".localized() + createWalletButton.setTitle("Wallet.Create.createWallet".localized(), for: .normal) + importWalletButton.setTitle("Wallet.Import.title".localized(), for: .normal) + } +} diff --git a/Neuron/Sections/Wallet/AddWallet/GenerateMnemonicController.swift b/Cyton/Sections/Wallet/AddWallet/GenerateMnemonicController.swift similarity index 64% rename from Neuron/Sections/Wallet/AddWallet/GenerateMnemonicController.swift rename to Cyton/Sections/Wallet/AddWallet/GenerateMnemonicController.swift index e7cec9c8..910fb851 100644 --- a/Neuron/Sections/Wallet/AddWallet/GenerateMnemonicController.swift +++ b/Cyton/Sections/Wallet/AddWallet/GenerateMnemonicController.swift @@ -1,6 +1,6 @@ // // GenerateMnemonicController.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/6/1. // Copyright © 2018年 cryptape. All rights reserved. @@ -12,12 +12,23 @@ class GenerateMnemonicController: UIViewController, NoScreenshot, EnterBackOverl var password = "" var walletModel = WalletModel() var mnemonic = "" - @IBOutlet weak var mnemonicTextView: UITextView! + @IBOutlet private weak var mnemonicTextView: UITextView! + @IBOutlet private weak var nextButton: UIButton! + @IBOutlet private weak var mnemonicWarnTitleLabel: UILabel! + @IBOutlet private weak var mnemonicWarnLabel1: UILabel! + @IBOutlet private weak var mnemonicWarnLabel2: UILabel! + @IBOutlet private weak var mnemonicWarnLabel3: UILabel! override func viewDidLoad() { super.viewDidLoad() + title = "Wallet.Create.backupMnemonic".localized() + nextButton.setTitle("Common.next".localized(), for: .normal) + mnemonicWarnTitleLabel.text = "Wallet.Create.mnemonicWarnTitle".localized() + mnemonicWarnLabel1.text = "Wallet.Create.mnemonicWarn1".localized() + mnemonicWarnLabel2.text = "Wallet.Create.mnemonicWarn2".localized() + mnemonicWarnLabel3.text = "Wallet.Create.mnemonicWarn3".localized() + mnemonicTextView.text = mnemonic - title = "备份助记词" setupEnterBackOverlay() } @@ -36,7 +47,7 @@ class GenerateMnemonicController: UIViewController, NoScreenshot, EnterBackOverl override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) - showNoScreenshotAlert(titile: "禁止截屏!", message: "拥有助记词就能完全控制该地址下的资产,建议抄写并放在安全的地方!") + showNoScreenshotAlert(titile: "NoScreenshot.title".localized(), message: "NoScreenshot.mnemonicMessage".localized()) } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { @@ -62,11 +73,11 @@ class GenerateMnemonicController: UIViewController, NoScreenshot, EnterBackOverl } @objc func clickBackBarButton() { - let alert = UIAlertController(title: nil, message: "距离开启您的安全区块链账户还差最后一步,是否继续", preferredStyle: .alert) - alert.addAction(UIAlertAction(title: "确认", style: .default, handler: { (_) in + let alert = UIAlertController(title: nil, message: "Wallet.Create.backCreateWalletAlert".localized(), preferredStyle: .alert) + alert.addAction(UIAlertAction(title: "Common.confirm".localized(), style: .default, handler: { (_) in alert.dismiss(animated: true, completion: nil) })) - alert.addAction(UIAlertAction(title: "拒绝", style: .destructive, handler: { (_) in + alert.addAction(UIAlertAction(title: "Common.reject".localized(), style: .destructive, handler: { (_) in alert.dismiss(animated: false, completion: nil) self.navigationController?.popViewController(animated: true) })) diff --git a/Neuron/Sections/Wallet/AddWallet/VerifyMnemonicViewController.swift b/Cyton/Sections/Wallet/AddWallet/VerifyMnemonicViewController.swift similarity index 84% rename from Neuron/Sections/Wallet/AddWallet/VerifyMnemonicViewController.swift rename to Cyton/Sections/Wallet/AddWallet/VerifyMnemonicViewController.swift index 734bef32..08fe009a 100644 --- a/Neuron/Sections/Wallet/AddWallet/VerifyMnemonicViewController.swift +++ b/Cyton/Sections/Wallet/AddWallet/VerifyMnemonicViewController.swift @@ -1,6 +1,6 @@ // // VerifyMnemonicViewController.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/6/1. // Copyright © 2018年 cryptape. All rights reserved. @@ -9,7 +9,6 @@ import UIKit import Web3swift import EthereumAddress -import IGIdenticon import RealmSwift class VerifyMnemonicViewController: UIViewController, ButtonTagViewDelegate, ButtonTagUpViewDelegate, NoScreenshot, EnterBackOverlayPresentable { @@ -26,17 +25,20 @@ class VerifyMnemonicViewController: UIViewController, ButtonTagViewDelegate, But } var walletModel = WalletModel() + @IBOutlet weak var inputMnemonicTitleLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() - title = "确认助记词" + title = "Wallet.Create.confirmMnemonic".localized() + inputMnemonicTitleLabel.text = "Wallet.Create.confirmMnemonicDesc".localized() + didDrawSubViews() setupEnterBackOverlay() } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) - showNoScreenshotAlert(titile: "禁止截屏!", message: "拥有助记词就能完全控制该地址下的资产,建议抄写并放在安全的地方!") + showNoScreenshotAlert(titile: "NoScreenshot.title".localized(), message: "NoScreenshot.mnemonicMessage".localized()) } func didDrawSubViews() { @@ -54,9 +56,10 @@ class VerifyMnemonicViewController: UIViewController, ButtonTagViewDelegate, But sureButton.frame = CGRect(x: 15, y: showView.frame.origin.y + showView.frame.size.height + 20, width: screenSize.width - 30, height: 44) sureButton.backgroundColor = UIColor(named: "control_disabled_bg_color") // TODO: should use isEnabled property sureButton.setTitleColor(UIColor(named: "control_disabled_title_color"), for: .normal) - sureButton.setTitle("完成备份", for: .normal) + sureButton.setTitle("Wallet.Create.backupCompleted".localized(), for: .normal) sureButton.addTarget(self, action: #selector(didCompletBackupMnemonic), for: .touchUpInside) sureButton.layer.cornerRadius = 5 + sureButton.accessibilityValue = "confirmButton" view.addSubview(sureButton) } @@ -88,7 +91,7 @@ class VerifyMnemonicViewController: UIViewController, ButtonTagViewDelegate, But @objc func didCompletBackupMnemonic() { if selectArray.count != titleArr.count { - Toast.showToast(text: "助记词验证失败") + Toast.showToast(text: "Wallet.Create.mnemonicValidationFailed".localized()) return } let originalMnemonic = titleArr.joined() @@ -97,7 +100,7 @@ class VerifyMnemonicViewController: UIViewController, ButtonTagViewDelegate, But if success { importWallet(mnemonic: mnemonic!, password: password) } else { - Toast.showToast(text: "助记词验证失败") + Toast.showToast(text: "Wallet.Create.mnemonicValidationFailed".localized()) } } @@ -111,14 +114,13 @@ class VerifyMnemonicViewController: UIViewController, ButtonTagViewDelegate, But } func importWallet(mnemonic: String, password: String) { - Toast.showHUD(text: "钱包创建中...") + Toast.showHUD(text: "Wallet.Create.walletCreation".localized()) DispatchQueue.global(qos: .userInitiated).async { do { let wallet = try WalletManager.default.importMnemonic(mnemonic: mnemonic, password: password) DispatchQueue.main.async { Toast.hideHUD() self.walletModel.address = EthereumAddress.toChecksumAddress(wallet.address)! - SensorsAnalytics.Track.createWallet(address: self.walletModel.address) self.saveWalletToRealm() } } catch let error { @@ -132,15 +134,14 @@ class VerifyMnemonicViewController: UIViewController, ButtonTagViewDelegate, But private func saveWalletToRealm() { let appModel = AppModel.current - let iconImage = GitHubIdenticon().icon(from: walletModel.address.lowercased(), size: CGSize(width: 60, height: 60)) - walletModel.iconData = iconImage!.pngData() let realm = try! Realm() try! realm.write { appModel.currentWallet = walletModel appModel.wallets.append(walletModel) realm.add(appModel) } + DefaultTokenAndChain().addDefaultTokenToWallet(wallet: walletModel) navigationController?.popToRootViewController(animated: true) - Toast.showToast(text: "创建成功") + Toast.showToast(text: "Wallet.Create.createSuccess".localized()) } } diff --git a/Cyton/Sections/Wallet/Assets/AddAssetController.swift b/Cyton/Sections/Wallet/Assets/AddAssetController.swift new file mode 100644 index 00000000..7e704651 --- /dev/null +++ b/Cyton/Sections/Wallet/Assets/AddAssetController.swift @@ -0,0 +1,221 @@ +// +// AddAssetController.swift +// Cyton +// +// Created by XiaoLu on 2018/5/24. +// Copyright © 2018年 cryptape. All rights reserved. +// + +import UIKit +import RealmSwift +import BLTNBoard + +class AddAssetController: UIViewController, UITableViewDelegate, UITableViewDataSource { + var tokenArray: [TokenModel] = [] + @IBOutlet private weak var searchButton: UIButton! + @IBOutlet private weak var tableView: UITableView! + @IBOutlet private weak var listSettingButton: DesignableButton! + private lazy var showTokenPageItem: ShowTokenPageItem = { + return ShowTokenPageItem.create() + }() + private lazy var bulletinManager: BLTNItemManager = { + return BLTNItemManager(rootItem: showTokenPageItem) + }() + + var chain = Chain() + var inputText = "" + + override func viewDidLoad() { + super.viewDidLoad() + title = "Assets.AddAssets.Title".localized() + searchButton.setTitle("Assets.AddAssets.Search".localized(), for: .normal) + listSettingButton.setTitle("Assets.AddAssets.ListSettings".localized(), for: .normal) + chain = Chain().defaultChain + } + + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + if segue.identifier == "switchChain" { + let switchChainViewController = segue.destination as! SwitchChainViewController + switchChainViewController.currentChain = chain + switchChainViewController.delegate = self + } + } + + @IBAction func searchTokenButton(_ sender: UIButton) { + if inputText.count == 0 { + Toast.showToast(text: "Assets.AddAssets.EmptyResult".localized()) + return + } + if chain.chainId == Chain().defaultChain.chainId { + ethereumERC20Token(contractAddress: inputText) + } else if chain.chainId == SwitchChainViewController().citaChainId { + citaNativeToken(nodeAddress: inputText) + } else { + citaERC20Token(chain: chain, contractAddress: inputText) + } + } + + func showTokenMessage(_ chainModel: ChainModel?, tokenModel: TokenModel) { + showTokenPageItem.actionHandler = { item in + item.manager?.displayActivityIndicator() + self.save(tokenModel: tokenModel, chainModel: chainModel) + } + showTokenPageItem.update(tokenModel: tokenModel) + bulletinManager.showBulletin(above: self) + } + + func save(tokenModel: TokenModel, chainModel: ChainModel?) { + do { + let realm = try Realm() + let wallet = AppModel.current.currentWallet! + var tokenModel = tokenModel + if let tokenIdentifier = TokenModel.identifier(for: tokenModel) { + tokenModel = realm.object(ofType: TokenModel.self, forPrimaryKey: tokenIdentifier)! + } else { + try realm.write { + realm.add(tokenModel, update: true) + } + } + + if !wallet.tokenModelList.contains(where: { $0 == tokenModel }) { + try realm.write { + wallet.tokenModelList.append(tokenModel) + wallet.selectedTokenList.append(tokenModel) + + if chainModel != nil { + realm.add(chainModel!, update: true) + if !wallet.chainModelList.contains(where: { $0 == chainModel }) { + wallet.chainModelList.append(chainModel!) + } + } + } + + let successPageItem = SuccessPageItem.create(title: "Assets.AddAssets.StoreSuccess".localized()) + successPageItem.actionHandler = { item in + self.bulletinManager.dismissBulletin() + self.navigationController?.popViewController(animated: true) + } + bulletinManager.push(item: successPageItem) + } else { + bulletinManager.dismissBulletin() + Toast.showToast(text: "Assets.AddAssets.AlreadyExist".localized()) + } + } catch { + bulletinManager.dismissBulletin() + Toast.showToast(text: "Assets.AddAssets.StoreFailed".localized()) + } + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return 2 + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + if indexPath.row == 0 { + let cell = tableView.dequeueReusableCell(withIdentifier: "selectChainTableViewCell") as! SelectChainTableViewCell + cell.detailTextLabel?.text = chain.chainName + return cell + } else { + let cell = tableView.dequeueReusableCell(withIdentifier: "contractAddressTableViewCell") as! ContractAddressTableViewCell + cell.delegate = self + cell.contractAddressTextField.text = inputText + if chain.chainId == SwitchChainViewController().citaChainId { + cell.contractAddressTextField.placeholder = "Assets.AddAssets.NodeAddressPlaceHolder".localized() + cell.contractAddressLabel.text = "Assets.AddAssets.NodeAddress".localized() + } else { + cell.contractAddressLabel.text = "Assets.AddAssets.ContractAddress".localized() + cell.contractAddressTextField.placeholder = "Assets.AddAssets.ContractAddressPlaceHolder".localized() + } + return cell + } + } + + @IBAction func clickSelectChainButton(_ sender: UIButton) { + + } + + @IBAction func clickQRCodeButton(_ sender: UIButton) { + let qrCodeViewController = QRCodeViewController() + qrCodeViewController.delegate = self + self.navigationController?.pushViewController(qrCodeViewController, animated: true) + } + + func ethereumERC20Token(contractAddress: String) { + let walletAddress = AppModel.current.currentWallet!.address + Toast.showHUD() + DispatchQueue.global().async { [weak self] in + guard let self = self else { return } + let result = try? CustomERC20TokenService.searchTokenData(contractAddress: contractAddress, walletAddress: walletAddress) + DispatchQueue.main.async { + Toast.hideHUD() + if let result = result { + if !result.symbol.isEmpty { + self.showTokenMessage(nil, tokenModel: result) + } else { + Toast.showToast(text: "Assets.AddAssets.EmptySymbol".localized()) + } + } else { + Toast.showToast(text: "Assets.AddAssets.EmptyResult".localized()) + } + self.tableView.reloadData() + } + } + } + + func citaNativeToken(nodeAddress: String) { + Toast.showHUD() + DispatchQueue.global().async { [weak self] in + guard let self = self else { return } + let (tokenModel, chainModel) = AddCITAToken.nativeToken(nodeAddress: nodeAddress) + DispatchQueue.main.async { + Toast.hideHUD() + if tokenModel != nil && chainModel != nil { + self.showTokenMessage(chainModel!, tokenModel: tokenModel!) + } else { + Toast.showToast(text: "Assets.AddAssets.EmptyResult".localized()) + } + } + } + } + + func citaERC20Token(chain: Chain, contractAddress: String) { + Toast.showHUD() + DispatchQueue.global().async { [weak self] in + guard let self = self else { return } + let tokenModel = AddCITAToken.erc20Token(chain: chain, contractAddress: contractAddress) + DispatchQueue.main.async { + Toast.hideHUD() + if tokenModel != nil { + if tokenModel?.symbol.count == 0 { + Toast.showToast(text: "Assets.AddAssets.EmptySymbol".localized()) + } else { + self.showTokenMessage(nil, tokenModel: tokenModel!) + } + } else { + Toast.showToast(text: "Assets.AddAssets.EmptyResult".localized()) + } + } + } + } +} + +extension AddAssetController: QRCodeViewControllerDelegate { + func didBackQRCodeMessage(codeResult: String) { + inputText = codeResult.trimmingCharacters(in: .whitespaces) + tableView.reloadData() + } +} + +extension AddAssetController: ContractAddressTableViewCellDelegate { + func textFieldInput(text: String) { + let finalText = text.trimmingCharacters(in: .whitespaces) + inputText = finalText + } +} + +extension AddAssetController: SwitchChainViewControllerDelegate { + func callSelectChain(chain: Chain) { + self.chain = chain + tableView.reloadData() + } +} diff --git a/Cyton/Sections/Wallet/Assets/Assets.storyboard b/Cyton/Sections/Wallet/Assets/Assets.storyboard new file mode 100644 index 00000000..0f2b66f8 --- /dev/null +++ b/Cyton/Sections/Wallet/Assets/Assets.storyboard @@ -0,0 +1,481 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Cyton/Sections/Wallet/Assets/ManageAssetViewController.swift b/Cyton/Sections/Wallet/Assets/ManageAssetViewController.swift new file mode 100644 index 00000000..dde5b2d7 --- /dev/null +++ b/Cyton/Sections/Wallet/Assets/ManageAssetViewController.swift @@ -0,0 +1,126 @@ +// +// ManageAssetViewController.swift +// Cyton +// +// Created by XiaoLu on 2018/5/23. +// Copyright © 2018年 cryptape. All rights reserved. +// + +import UIKit +import RealmSwift + +class ManageAssetViewController: UITableViewController, AssetTableViewCellDelegate { + @IBOutlet private weak var rightBarButton: DesignableButton! + var tokenArray: List! + var selectArray: List! + var tempTokenArray: [TokenModel]! + var realm: Realm! + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + } + + override func viewDidLoad() { + super.viewDidLoad() + realm = try! Realm() + title = "Assets.AddAssets.ListSettings".localized() + rightBarButton.setTitle("Assets.AssetSetting.Edit".localized(), for: .normal) + rightBarButton.setTitle("Assets.AssetSetting.Complete".localized(), for: .selected) + tokenList() + } + + @IBAction func clickEditListButton(_ sender: DesignableButton) { + if sender.isSelected { + sender.isSelected = false + sortSelectTokenArray() + } else { + sender.isSelected = true + } + tableView.setEditing(sender.isSelected, animated: true) + } + + func sortSelectTokenArray() { + let tempArray = List() + tempArray.append(objectsIn: selectArray) + try! realm.write { + selectArray.removeAll() + tokenArray.removeAll() + tokenArray.append(objectsIn: tempTokenArray) + tempTokenArray.forEach({ (model) in + if let token = tempArray.first(where: { $0 == model }) { + selectArray.append(token) + } + }) + } + } + + func tokenList() { + let appModel = realm.objects(AppModel.self).first ?? AppModel() + tokenArray = appModel.currentWallet?.tokenModelList + selectArray = appModel.currentWallet?.selectedTokenList + tempTokenArray = tokenArray.map({ $0 }) + } + + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return tempTokenArray.count + } + + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "assetTableviewCell") as! AssetTableViewCell + cell.delegate = self + let tokenModel = tempTokenArray[indexPath.row] + cell.iconUrlStr = tokenModel.iconUrl + cell.symbolLabel.text = tokenModel.symbol + cell.addressLabel.text = tokenModel.address + cell.nameLabel.text = tokenModel.chain.chainName + cell.selectionStyle = .none + cell.isSelected = selectArray.contains(where: { $0 == tokenModel }) + return cell + } + + override func tableView(_ tableView: UITableView, willBeginEditingRowAt indexPath: IndexPath) { + let cell = tableView.cellForRow(at: indexPath) as! AssetTableViewCell + cell.setEditing(true, animated: true) + } + + override func tableView(_ tableView: UITableView, didEndEditingRowAt indexPath: IndexPath?) { + let cell = tableView.cellForRow(at: indexPath!) as! AssetTableViewCell + cell.setEditing(false, animated: true) + } + + override func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle { + return .none + } + + override func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool { + return false + } + + override func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) { + try! realm.write { + let object = tempTokenArray[sourceIndexPath.row] + tempTokenArray.remove(at: sourceIndexPath.row) + tempTokenArray.insert(object, at: destinationIndexPath.row) + } + } + + func assetTableViewCell(_ assetTableViewCell: UITableViewCell, isSelected: Bool) { + let index = tableView.indexPath(for: assetTableViewCell)! + let tokenModel = tempTokenArray[index.row] + try! realm.write { + if isSelected { + var insertIndex = 0 + for token in tempTokenArray { + if token == tokenModel { + break + } else if selectArray.contains(token) { + insertIndex += 1 + } + } + selectArray.insert(tokenModel, at: insertIndex) + } else { + selectArray.remove(at: selectArray.index(of: tokenModel)!) + } + } + } +} diff --git a/Cyton/Sections/Wallet/Assets/SwitchChainViewController.swift b/Cyton/Sections/Wallet/Assets/SwitchChainViewController.swift new file mode 100644 index 00000000..e3fbd4bf --- /dev/null +++ b/Cyton/Sections/Wallet/Assets/SwitchChainViewController.swift @@ -0,0 +1,127 @@ +// +// SwitchChainViewController.swift +// Cyton +// +// Created by XiaoLu on 2018/12/10. +// Copyright © 2018 Cryptape. All rights reserved. +// + +import UIKit +import RealmSwift + +protocol SwitchChainViewControllerDelegate: class { + func callSelectChain(chain: Chain) +} + +class SwitchChainViewController: UIViewController { + @IBOutlet private weak var backgroundView: UIView! + @IBOutlet private weak var contentView: UIView! + @IBOutlet private weak var titleLabel: UILabel! + @IBOutlet private weak var closeButton: UIButton! + @IBOutlet private weak var tableView: UITableView! + let ethereumChainId = "ethereumERC20"// switch chain work only + let citaChainId = "citaNative" + + var chains: [Chain] = [] + var currentChain: Chain! + weak var delegate: SwitchChainViewControllerDelegate? + + override func viewDidLoad() { + super.viewDidLoad() + titleLabel.text = "Assets.AddAssets.SwitchChainNetWorkTitle".localized() + getChainModelList() + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + backgroundView.alpha = 0.0 + contentView.transform = CGAffineTransform(translationX: 0, y: contentView.bounds.size.height) + UIView.animate(withDuration: CATransaction.animationDuration()) { + self.backgroundView.alpha = 1.0 + self.contentView.transform = CGAffineTransform.identity + } + } + + override func touchesEnded(_ touches: Set, with event: UIEvent?) { + dismiss() + } + + @IBAction func dismiss() { + UIView.animate(withDuration: CATransaction.animationDuration(), animations: { + self.backgroundView.alpha = 0.0 + self.contentView.transform = CGAffineTransform(translationX: 0, y: self.contentView.bounds.size.height) + }, completion: { (_) in + self.dismiss(animated: false, completion: nil) + }) + } + + func getChainModelList() { + let ethChain = Chain().defaultChain + let testChain = Chain(chainId: citaChainId, chainName: "Assets.AddAssets.CITANativeCoin".localized(), httpProvider: "") + chains += [ethChain, testChain] + let realm = try! Realm() + let chainResult = realm.objects(ChainModel.self) + chainResult.forEach { (model) in + let chain = Chain(chainModel: model) + chains.append(chain) + } + tableView.reloadData() + } +} + +extension SwitchChainViewController: UITableViewDelegate, UITableViewDataSource { + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return chains.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "switchChainTableViewCell") as! SwitchChainTableViewCell + cell.networkLabel.text = chains[indexPath.row].chainName + if currentChain.chainId == chains[indexPath.row].chainId { + cell.selectedImageView.isHidden = false + } else { + cell.selectedImageView.isHidden = true + } + return cell + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + currentChain = chains[indexPath.row] + delegate?.callSelectChain(chain: currentChain) + dismiss() + } + +} + +class SwitchChainTableViewCell: UITableViewCell { + @IBOutlet weak var networkLabel: UILabel! + @IBOutlet weak var selectedImageView: UIImageView! +} + +struct Chain { + var chainId = "" + var chainName = "" + var httpProvider = "" + + // first index chain default ethereum chain + var defaultChain: Chain { + return Chain(chainId: SwitchChainViewController().ethereumChainId, chainName: EthereumNetwork().networkType.chainName, httpProvider: EthereumNetwork().apiHost().absoluteString) + } + + init() { + } + + init(chainId: String, + chainName: String, + httpProvider: String) { + self.chainId = chainId + self.chainName = chainName + self.httpProvider = httpProvider + } + + init(chainModel: ChainModel) { + chainId = chainModel.chainId + chainName = chainModel.chainName + httpProvider = chainModel.httpProvider + } +} diff --git a/Neuron/Sections/Wallet/CustomView/ButtonTagUpView.swift b/Cyton/Sections/Wallet/CustomView/ButtonTagUpView.swift similarity index 99% rename from Neuron/Sections/Wallet/CustomView/ButtonTagUpView.swift rename to Cyton/Sections/Wallet/CustomView/ButtonTagUpView.swift index 583cd171..cd5ee889 100644 --- a/Neuron/Sections/Wallet/CustomView/ButtonTagUpView.swift +++ b/Cyton/Sections/Wallet/CustomView/ButtonTagUpView.swift @@ -1,6 +1,6 @@ // // ButtonTagUpView.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/6/1. // Copyright © 2018年 cryptape. All rights reserved. diff --git a/Neuron/Sections/Wallet/CustomView/ButtonTagView.swift b/Cyton/Sections/Wallet/CustomView/ButtonTagView.swift similarity index 99% rename from Neuron/Sections/Wallet/CustomView/ButtonTagView.swift rename to Cyton/Sections/Wallet/CustomView/ButtonTagView.swift index e3b6f6bd..7c48d74a 100644 --- a/Neuron/Sections/Wallet/CustomView/ButtonTagView.swift +++ b/Cyton/Sections/Wallet/CustomView/ButtonTagView.swift @@ -1,6 +1,6 @@ // // ButtonTagView.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/6/1. // Copyright © 2018年 cryptape. All rights reserved. diff --git a/Neuron/Sections/Wallet/TableViewCell/TokenTableViewCell.swift b/Cyton/Sections/Wallet/Home/TokenTableViewCell.swift similarity index 80% rename from Neuron/Sections/Wallet/TableViewCell/TokenTableViewCell.swift rename to Cyton/Sections/Wallet/Home/TokenTableViewCell.swift index 3a09a12c..75184d99 100644 --- a/Neuron/Sections/Wallet/TableViewCell/TokenTableViewCell.swift +++ b/Cyton/Sections/Wallet/Home/TokenTableViewCell.swift @@ -1,6 +1,6 @@ // // TokenTableViewCell.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/8/31. // Copyright © 2018年 Cryptape. All rights reserved. @@ -18,16 +18,16 @@ class TokenTableViewCell: UITableViewCell { var token: Token! { didSet { - iconView.sd_setImage(with: URL(string: token.iconUrl ?? ""), placeholderImage: UIImage(named: "eth_logo")) + iconView.sd_setImage(with: URL(string: token.iconUrl), placeholderImage: UIImage(named: "eth_logo")) symbolLabel.text = token.symbol symbolWidthConstraint.constant = symbolLabel.textRect(forBounds: CGRect(x: 0, y: 0, width: 150, height: 20), limitedToNumberOfLines: 1).size.width - if let balance = token.balance { - balanceLabel.text = balance.decimal + if let balance = token.balance, let balanceLabel = balanceLabel { + balanceLabel.text = balance.toAmountText(token.decimals) if balance > 0 { if let price = token.price { - let amount = price * balance + let amountNumber = balance.toDecimalNumber(token.decimals).multiplying(by: NSDecimalNumber(value: price)) let currency = LocalCurrencyService.shared.getLocalCurrencySelect() - amountLabel.text = "≈\(currency.symbol)" + String(format: "%.4lf", amount) + amountLabel.text = "≈\(currency.symbol)" + amountNumber.currencyFormat() } } } diff --git a/Neuron/Sections/Wallet/Home/Wallet.storyboard b/Cyton/Sections/Wallet/Home/Wallet.storyboard similarity index 96% rename from Neuron/Sections/Wallet/Home/Wallet.storyboard rename to Cyton/Sections/Wallet/Home/Wallet.storyboard index 2615e3fd..b643c26d 100644 --- a/Neuron/Sections/Wallet/Home/Wallet.storyboard +++ b/Cyton/Sections/Wallet/Home/Wallet.storyboard @@ -1,11 +1,12 @@ - + + @@ -13,7 +14,7 @@ - + @@ -24,7 +25,7 @@ - + @@ -94,12 +95,12 @@ - + - + @@ -132,26 +133,20 @@ - + - + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + diff --git a/Cyton/Services/CITA/CITA+AddToken.swift b/Cyton/Services/CITA/CITA+AddToken.swift new file mode 100644 index 00000000..1e4b9335 --- /dev/null +++ b/Cyton/Services/CITA/CITA+AddToken.swift @@ -0,0 +1,76 @@ +// +// CITA+AddToken.swift +// Cyton +// +// Created by XiaoLu on 2018/12/11. +// Copyright © 2018 Cryptape. All rights reserved. +// + +import Foundation +import RealmSwift + +class AddCITAToken { + static func nativeToken(nodeAddress: String) -> (TokenModel?, ChainModel?) { + if !nodeAddress.hasPrefix("http") { + return (nil, nil) + } + let cita = CITANetwork(url: URL(string: nodeAddress)).cita + guard let metaData = try? cita.rpc.getMetaData() else { + return (nil, nil) + } + let chainModel = ChainModel() + chainModel.chainId = metaData.chainId + chainModel.chainName = metaData.chainName + chainModel.httpProvider = nodeAddress + if let chainIndentifier = ChainModel.identifier(for: chainModel) { + chainModel.identifier = chainIndentifier + } + + let tokenModel = TokenModel() + tokenModel.address = "" + tokenModel.iconUrl = metaData.tokenAvatar + tokenModel.isNativeToken = true + tokenModel.name = metaData.tokenName + tokenModel.symbol = metaData.tokenSymbol + tokenModel.decimals = NativeDecimals.nativeTokenDecimals + tokenModel.chainIdentifier = chainModel.identifier + if let id = TokenModel.identifier(for: tokenModel) { + tokenModel.identifier = id + } + return (tokenModel, chainModel) + } + + static func erc20Token(chain: Chain, contractAddress: String) -> TokenModel? { + do { + let cita = CITANetwork(url: URL(string: chain.httpProvider)).cita + let erc20 = CITAERC20(cita: cita, contractAddress: contractAddress) + + guard let name = try erc20.name() else { + return nil + } + + guard let symbol = try erc20.symbol() else { + return TokenModel() + } + + guard let decimals = try erc20.decimals() else { + return nil + } + + let realm = try! Realm() + let result = realm.objects(ChainModel.self) + let chainModel = result.first(where: { $0.chainId == chain.chainId && $0.chainName == chain.chainName }) + + let tokenModel = TokenModel() + tokenModel.decimals = Int(decimals) + tokenModel.name = name + tokenModel.symbol = symbol + tokenModel.address = contractAddress + tokenModel.isNativeToken = false + tokenModel.chainIdentifier = chainModel!.identifier + return tokenModel + } catch { + return nil + } + } +} diff --git a/Cyton/Services/CITA/CITA+Balance.swift b/Cyton/Services/CITA/CITA+Balance.swift new file mode 100644 index 00000000..0bbed78c --- /dev/null +++ b/Cyton/Services/CITA/CITA+Balance.swift @@ -0,0 +1,21 @@ +// +// CITABalanceLoader.swift +// Cyton +// +// Created by XiaoLu on 2018/12/13. +// Copyright © 2018 Cryptape. All rights reserved. +// + +import Foundation +import CITA +import BigInt + +extension CITANetwork { + func getBalance(walletAddress: String) throws -> BigUInt { + return try cita.rpc.getBalance(address: walletAddress) + } + + func getErc20Balance(walletAddress: String, contractAddress: String) throws -> BigUInt { + return try CITAERC20(cita: cita, contractAddress: contractAddress).balance() ?? 0 + } +} diff --git a/Cyton/Services/CITA/CITA+ERC20.swift b/Cyton/Services/CITA/CITA+ERC20.swift new file mode 100644 index 00000000..9a5729d0 --- /dev/null +++ b/Cyton/Services/CITA/CITA+ERC20.swift @@ -0,0 +1,82 @@ +// +// CITA+ERC20.swift +// Cyton +// +// Created by XiaoLu on 2018/12/3. +// Copyright © 2018 Cryptape. All rights reserved. +// + +import Foundation +import CITA +import Web3swift +import EthereumAddress +import BigInt + +class CITAERC20 { + private let cita: CITA + private let contractAddress: String + private let contract: EthereumContract + + init(cita: CITA, contractAddress: String) { + self.cita = cita + self.contractAddress = contractAddress + self.contract = EthereumContract(Web3Utils.erc20ABI)! + } + + func name() throws -> String? { + let callRequest = CallRequest(from: AppModel.current.currentWallet?.address, to: self.contractAddress, data: getContractString("name()")) + let nameHex = try cita.rpc.call(request: callRequest) + let data = Data(hex: nameHex) + let result = contract.decodeReturnData("name", data: data) + return result?.first?.value as? String + } + + func decimals() throws -> BigUInt? { + let callRequest = CallRequest(from: nil, to: self.contractAddress, data: getContractString("decimals()")) + let decimalsHex = try cita.rpc.call(request: callRequest) + return decimalsHex.toBigUInt() + } + + func symbol() throws -> String? { + let callRequest = CallRequest(from: nil, to: self.contractAddress, data: getContractString("symbol()")) + let symbolHex = try cita.rpc.call(request: callRequest) + let data = Data(hex: symbolHex) + let result = contract.decodeReturnData("symbol", data: data) + return result?.first?.value as? String + } + + func balance() throws -> BigUInt? { + let walletAddress = AppModel.current.currentWallet!.address + let data = encodeInputs(method: "balanceOf", parameters: [walletAddress as AnyObject])! + let dataHex = data.toHexString().prefix(8) + let callRequest = CallRequest(from: walletAddress, to: contractAddress, data: String(dataHex).addHexPrefix() + String(repeating: "0", count: 24) + walletAddress.removeHexPrefix()) + let balanceHex = try cita.rpc.call(request: callRequest) + return balanceHex.toBigUInt() ?? 0 + } + + func transferData(to: String, amount: BigUInt) throws -> Data? { + guard let erc20Contract = EthereumContract(Web3Utils.erc20ABI, at: EthereumAddress(contractAddress)) else { + return nil + } + guard let to = EthereumAddress(to) else { return nil } + let data = encodeInputs(ethereumContract: erc20Contract, method: "transfer", parameters: [to, amount] as [AnyObject]) + return data + } + + func getContractString(_ string: String) -> String { + let data = string.data(using: .utf8)! + let sha3 = data.sha3(.keccak256) + let hexString = sha3.toHexString() + return String(hexString.prefix(8)).addHexPrefix() + } + + func encodeInputs(ethereumContract: EthereumContract = EthereumContract(Web3Utils.erc20ABI)!, method: String, parameters: [AnyObject] = [AnyObject]()) -> Data? { + let foundMethod = ethereumContract.methods.filter { (key, _) -> Bool in + return key == method + } + guard foundMethod.count == 1 else { return Data() } + let abiMethod = foundMethod[method] + return abiMethod?.encodeParameters(parameters) + } + +} diff --git a/Neuron/Services/AppChain/AppChain+TransactionDetails.swift b/Cyton/Services/CITA/CITA+TransactionDetails.swift similarity index 59% rename from Neuron/Services/AppChain/AppChain+TransactionDetails.swift rename to Cyton/Services/CITA/CITA+TransactionDetails.swift index 22b38f19..4549fc5f 100644 --- a/Neuron/Services/AppChain/AppChain+TransactionDetails.swift +++ b/Cyton/Services/CITA/CITA+TransactionDetails.swift @@ -1,6 +1,6 @@ // -// AppChain+TransactionDetails.swift -// Neuron +// CITA+TransactionDetails.swift +// Cyton // // Created by 晨风 on 2018/11/16. // Copyright © 2018 Cryptape. All rights reserved. @@ -9,18 +9,17 @@ import Foundation import BigInt import Alamofire -import AppChain +import CITA import PromiseKit -class AppChainTransactionDetails: TransactionDetails { - var content: String = "" +class CITATransactionDetails: TransactionDetails { var gasUsed: BigUInt = 0 var quotaUsed: BigUInt = 0 var chainId: Int = 0 var chainName: String = "" var errorMessage: String? - enum AppChainCodingKeys: String, CodingKey { + enum CITACodingKeys: String, CodingKey { case content case gasUsed case quotaUsed @@ -35,8 +34,7 @@ class AppChainTransactionDetails: TransactionDetails { required init(from decoder: Decoder) throws { try super.init(from: decoder) - let values = try decoder.container(keyedBy: AppChainCodingKeys.self) - content = (try? values.decode(String.self, forKey: .content)) ?? "" + let values = try decoder.container(keyedBy: CITACodingKeys.self) if let value = try? values.decode(String.self, forKey: .gasUsed) { gasUsed = BigUInt(string: value) ?? 0 } @@ -45,40 +43,48 @@ class AppChainTransactionDetails: TransactionDetails { } chainName = (try? values.decode(String.self, forKey: .chainName)) ?? "" chainId = (try? values.decode(Int.self, forKey: .chainId)) ?? 0 + errorMessage = try? values.decode(String.self, forKey: .errorMessage) + if errorMessage != nil { + status = .failure + } } } -private struct AppChainTransactionsResponse: Decodable { +private struct CITATransactionsResponse: Decodable { let result: Result struct Result: Decodable { let count: UInt - let transactions: [AppChainTransactionDetails] + let transactions: [CITATransactionDetails] } } -private struct AppChainTransactionResponse: Decodable { +private struct CITATransactionResponse: Decodable { let result: Result struct Result: Decodable { - let transaction: AppChainTransactionDetails? + let transaction: CITATransactionDetails? } } -class AppChainErc20TransactionDetails: AppChainTransactionDetails { +private struct CITAErc20TransactionsResponse: Decodable { + let result: Result + struct Result: Decodable { + let transfers: [CITATransactionDetails] + } } -extension AppChainNetwork { - func getTransactionHistory(walletAddress: String, page: UInt, pageSize: UInt) throws -> [AppChainTransactionDetails] { - let url = AppChainNetwork().host().appendingPathComponent("/api/transactions") +extension CITANetwork { + func getTransactionHistory(walletAddress: String, page: UInt, pageSize: UInt) throws -> [CITATransactionDetails] { + let url = host().appendingPathComponent("/api/transactions") let parameters: [String: Any] = [ "account": walletAddress.lowercased(), "page": page, "perPage": pageSize ] - return try Promise<[AppChainTransactionDetails]>.init { (resolver) in + return try Promise<[CITATransactionDetails]>.init { (resolver) in Alamofire.request(url, method: .get, parameters: parameters).responseJSON { (response) in do { guard let responseData = response.data else { throw TransactionHistoryError.networkFailure } - let response = try JSONDecoder().decode(AppChainTransactionsResponse.self, from: responseData) + let response = try JSONDecoder().decode(CITATransactionsResponse.self, from: responseData) let transactions = response.result.transactions resolver.fulfill(transactions) } catch { @@ -88,20 +94,20 @@ extension AppChainNetwork { }.wait() } - func getErc20TransactionHistory(walletAddress: String, tokenAddress: String, page: UInt, pageSize: UInt) throws -> [AppChainTransactionDetails] { - let url = AppChainNetwork().host().appendingPathComponent("/api/erc20/transfers") + func getErc20TransactionHistory(walletAddress: String, tokenAddress: String, page: UInt, pageSize: UInt) throws -> [CITATransactionDetails] { + let url = host().appendingPathComponent("/api/erc20/transfers") let parameters: [String: Any] = [ "account": walletAddress.lowercased(), "address": tokenAddress, "page": page, "perPage": pageSize ] - return try Promise<[AppChainTransactionDetails]>.init { (resolver) in + return try Promise<[CITATransactionDetails]>.init { (resolver) in Alamofire.request(url, method: .get, parameters: parameters).responseJSON { (response) in do { guard let responseData = response.data else { throw TransactionHistoryError.networkFailure } - let response = try JSONDecoder().decode(AppChainTransactionsResponse.self, from: responseData) - let transactions = response.result.transactions + let response = try JSONDecoder().decode(CITAErc20TransactionsResponse.self, from: responseData) + let transactions = response.result.transfers resolver.fulfill(transactions) } catch { resolver.reject(error) @@ -110,18 +116,13 @@ extension AppChainNetwork { }.wait() } - func getTransaction(txhash: String, account: String, from: String, to: String) throws -> AppChainTransactionDetails { - let url = AppChainNetwork().host().appendingPathComponent("/api/transactions/\(txhash)") - let parameters: [String: Any] = [ - "account": account, - "from": from, - "to": to - ] - return try Promise.init { (resolver) in - Alamofire.request(url, method: .get, parameters: parameters).responseData(completionHandler: { (response) in + func getTransaction(txhash: String) throws -> CITATransactionDetails { + let url = host().appendingPathComponent("/api/transactions/\(txhash)") + return try Promise.init { (resolver) in + Alamofire.request(url, method: .get, parameters: nil).responseData(completionHandler: { (response) in do { guard let responseData = response.data else { throw TransactionHistoryError.networkFailure } - let response = try JSONDecoder().decode(AppChainTransactionResponse.self, from: responseData) + let response = try JSONDecoder().decode(CITATransactionResponse.self, from: responseData) if let transaction = response.result.transaction { resolver.fulfill(transaction) } else { diff --git a/Cyton/Services/CITA/CITALocalTxPool.swift b/Cyton/Services/CITA/CITALocalTxPool.swift new file mode 100644 index 00000000..563abbb4 --- /dev/null +++ b/Cyton/Services/CITA/CITALocalTxPool.swift @@ -0,0 +1,201 @@ +// +// CitaLocalTxPool.swift +// Cyton +// +// Created by 晨风 on 2019/1/3. +// Copyright © 2019 Cryptape. All rights reserved. +// + +import UIKit +import RealmSwift +import BigInt +import CITA + +class CITALocalTx: Object { + @objc dynamic var token: TokenModel! + @objc dynamic var txHash = "" + @objc dynamic var from = "" + @objc dynamic var to = "" + @objc dynamic var value = "" + @objc dynamic var quotaPrice = "" + @objc dynamic var quotaLimit = "" + @objc dynamic var date = Date() + @objc dynamic private var statusValue: Int = TxStatus.pending.rawValue + @objc dynamic private var validUntilBlockText = "" + var status: TxStatus { + get { return TxStatus(rawValue: statusValue)! } + set { statusValue = newValue.rawValue } + } + var validUntilBlock: BigUInt { + get { return BigUInt(validUntilBlockText)! } + set { validUntilBlockText = String(newValue) } + } + + required convenience init(token: TokenModel, txHash: String, validUntilBlock: BigUInt, from: String, to: String, value: BigUInt, quotaPrice: BigUInt, quotaLimit: BigUInt) { + self.init() + self.token = token + self.txHash = txHash + self.validUntilBlock = validUntilBlock + self.from = from + self.to = to + self.value = String(value) + self.quotaPrice = String(quotaPrice) + self.quotaLimit = String(quotaLimit) + } + + @objc override class func primaryKey() -> String? { return "txHash" } + + enum TxStatus: Int { + case pending + case success + case failure + } +} + +class CITALocalTxPool: NSObject { + static let didUpdateTxStatus = Notification.Name("CITALocalTxPool.didUpdateTxStatus") + static let didAddLocalTx = Notification.Name("CITALocalTxPool.didAddLocalTx") + static let txKey = "tx" + static let pool = CITALocalTxPool() + + func register() {} + + func insertLocalTx(localTx: CITALocalTx) { + do { + let realm = try Realm() + try realm.write { + realm.add(localTx) + } + let tx = localTx.getTx() + DispatchQueue.main.async { + NotificationCenter.default.post(name: CITALocalTxPool.didAddLocalTx, object: nil, userInfo: [CITALocalTxPool.txKey: tx]) + } + } catch { + } + } + + func getTransactions(token: Token) -> [CITATransactionDetails] { + return (try! Realm()).objects(CITALocalTx.self).filter({ + $0.from == token.walletAddress && + $0.token.address == token.address + }).map({ $0.getTx() }) + } + + // MARK: - Private + private var observers = [NotificationToken]() + + private override init() { + super.init() + DispatchQueue.global().async { + self.checkLocalTxList() + } + let realm = try! Realm() + observers.append(realm.objects(CITALocalTx.self).observe { (change) in + switch change { + case .update(_, deletions: _, let insertions, modifications: _): + guard insertions.count > 0 else { return } + DispatchQueue.global().async { + self.checkLocalTxList() + } + default: + break + } + }) + } + + private var checking = false + private let timeInterval: TimeInterval = 4.0 + + @objc private func checkLocalTxList() { + NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(checkLocalTxList), object: nil) + guard checking == false else { return } + let realm = try! Realm() + let results = realm.objects(CITALocalTx.self).filter({ $0.status == .pending }) + guard results.count > 0 else { return } + checking = true + results.forEach { (localTx) in + guard localTx.status == .pending else { return } + self.checkLocalTxStatus(localTx: localTx) + } + checking = false + checkLocalTxList() + perform(#selector(checkLocalTxList), with: nil, afterDelay: timeInterval) + } + + private func checkLocalTxStatus(localTx: CITALocalTx) { + let cita = CITA(provider: HTTPProvider(URL(string: localTx.token.chain.httpProvider)!)!) + let realm = try! Realm() + do { + try realm.write { + if let receipt = localTx.transactionReceipt { + if receipt.errorMessage != nil { + localTx.status = .failure + } else { + if (try? CITANetwork().getTransaction(txhash: localTx.txHash)) != nil { + localTx.status = .success + } + } + } + let currentBlockNumber = try cita.rpc.blockNumber() + if localTx.status == .pending && localTx.validUntilBlock < BigUInt(currentBlockNumber) { + localTx.status = .failure + } + } + } catch { + } + if localTx.status == .success || localTx.status == .failure { + let tx = localTx.getTx() + DispatchQueue.main.async { + NotificationCenter.default.post(name: CITALocalTxPool.didUpdateTxStatus, object: nil, userInfo: [CITALocalTxPool.txKey: tx]) + } + if localTx.status == .success { + try? realm.write { + realm.delete(localTx) + } + } + } + } +} + +extension CITALocalTx { + func getTx() -> CITATransactionDetails { + let tx = CITATransactionDetails() + tx.token = Token(token, from) + tx.hash = txHash + tx.from = from + tx.to = to + tx.value = BigUInt(value) ?? 0 + tx.gasLimit = BigUInt(quotaLimit) ?? 0 + tx.date = date + tx.blockNumber = transactionReceipt?.blockNumber ?? 0 + tx.quotaUsed = transactionReceipt?.quotaUsed ?? 0 + switch status { + case .pending: + tx.status = .pending + case .success: + tx.status = .success + case .failure: + tx.status = .failure + } + return tx + } +} + +extension CITALocalTx { + private struct AssociatedKey { + static var transactionReceipt = 0 + } + + private var cita: CITA { + return CITA(provider: HTTPProvider(URL(string: token.chain.httpProvider)!)!) + } + + fileprivate var transactionReceipt: TransactionReceipt? { + if let transactionReceipt = objc_getAssociatedObject(self, &AssociatedKey.transactionReceipt) { + return transactionReceipt as? TransactionReceipt + } + let transactionReceipt = try? cita.rpc.getTransactionReceipt(txhash: txHash) + objc_setAssociatedObject(self, &AssociatedKey.transactionReceipt, transactionReceipt, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + return transactionReceipt + } +} diff --git a/Cyton/Services/CITA/CITANetwork.swift b/Cyton/Services/CITA/CITANetwork.swift new file mode 100644 index 00000000..f2d7f5b5 --- /dev/null +++ b/Cyton/Services/CITA/CITANetwork.swift @@ -0,0 +1,31 @@ +// +// CITANetwork.swift +// Cyton +// +// Created by XiaoLu on 2018/7/31. +// Copyright © 2018年 cryptape. All rights reserved. +// + +import Foundation +import CITA +import Alamofire + +struct CITANetwork { + static let defaultNode = "http://121.196.200.225:1337" + + func host() -> URL { + return URL(string: "https://microscope.cryptape.com:8888")! + } + + let cita: CITA + + init(url: URLConvertible? = defaultNode) { + let provider: HTTPProvider + if let urlstring = url, let url = try? urlstring.asURL() { + provider = HTTPProvider(url)! + } else { + provider = HTTPProvider(try! CITANetwork.defaultNode.asURL())! + } + cita = CITA(provider: provider) + } +} diff --git a/Cyton/Services/CITA/CITATxSender.swift b/Cyton/Services/CITA/CITATxSender.swift new file mode 100644 index 00000000..fb89c844 --- /dev/null +++ b/Cyton/Services/CITA/CITATxSender.swift @@ -0,0 +1,121 @@ +// +// CITATxSender.swift +// Cyton +// +// Created by James Chen on 2018/11/06. +// Copyright © 2018 Cryptape. All rights reserved. +// + +import Foundation +import CITA +import EthereumAddress +import BigInt + +class CITATxSender { + private let cita: CITA + private let walletManager: WalletManager + private let from: Address + + init(cita: CITA, walletManager: WalletManager, from: String) throws { + self.cita = cita + self.walletManager = walletManager + guard let fromAddress = Address(from) else { + throw SendTransactionError.invalidSourceAddress + } + self.from = fromAddress + } + + func send( + to: String, + value: BigUInt, + quota: BigUInt = GasCalculator.defaultGasLimit, + data: Data, + chainId: BigUInt, + password: String + ) throws -> (TxHash, BlockNumber) { + let destinationEthAddress = Address(to.addHexPrefix()) + if !to.isEmpty && destinationEthAddress == nil { + throw SendTransactionError.invalidDestinationAddress + } + + guard let meta = try? cita.rpc.getMetaData() else { + throw SendTransactionError.createTransactionIssue + } + guard let blockNumber = try? cita.rpc.blockNumber() else { + throw SendTransactionError.createTransactionIssue + } + if chainId.description != meta.chainId { + throw SendTransactionError.invalidChainId + } + + let transaction = Transaction( + to: destinationEthAddress, + nonce: UUID().uuidString, + quota: UInt64(UInt(quota)), + validUntilBlock: blockNumber + UInt64(88), + data: data, + value: value, + chainId: meta.chainId, + version: meta.version + ) + let signed = try sign(transaction: transaction, password: password) + return (try cita.rpc.sendRawTransaction(signedTx: signed), BigUInt(transaction.validUntilBlock)) + } + + func sendERC20( + to: String, + contract: String, + value: BigUInt, + quota: BigUInt = GasCalculator.defaultGasLimit, + chainId: BigUInt, + password: String + ) throws -> (TxHash, BlockNumber) { + let destinationEthAddress = Address(contract.addHexPrefix()) + if !contract.isEmpty && destinationEthAddress == nil { + throw SendTransactionError.invalidDestinationAddress + } + + guard let meta = try? cita.rpc.getMetaData() else { + throw SendTransactionError.createTransactionIssue + } + guard let blockNumber = try? cita.rpc.blockNumber() else { + throw SendTransactionError.createTransactionIssue + } + guard let data = try CITAERC20(cita: cita, contractAddress: contract).transferData(to: to, amount: value) else { + throw SendTransactionError.createTransactionIssue + } + + if chainId.description != meta.chainId { + throw SendTransactionError.invalidChainId + } + + let transaction = Transaction( + to: destinationEthAddress, + nonce: UUID().uuidString, + quota: UInt64(UInt(quota)), + validUntilBlock: blockNumber + UInt64(88), + data: data, + value: BigUInt(0), + chainId: meta.chainId, + version: meta.version + ) + let signed = try sign(transaction: transaction, password: password) + return (try cita.rpc.sendRawTransaction(signedTx: signed), BigUInt(transaction.validUntilBlock)) + } + + func sendToken(transaction: Transaction, password: String) throws -> TxHash { + let signed = try sign(transaction: transaction, password: password) + return try cita.rpc.sendRawTransaction(signedTx: signed) + } + + func sign(transaction: Transaction, password: String) throws -> String { + guard let wallet = walletManager.wallet(for: from.address) else { + throw SendTransactionError.noAvailableKeys + } + let privateKey = try walletManager.exportPrivateKey(wallet: wallet, password: password) + guard let signed = try? Signer().sign(transaction: transaction, with: privateKey) else { + throw SendTransactionError.signTXFailed + } + return signed + } +} diff --git a/Cyton/Services/Common/DefaultTokenAndChain.swift b/Cyton/Services/Common/DefaultTokenAndChain.swift new file mode 100644 index 00000000..7f933bb2 --- /dev/null +++ b/Cyton/Services/Common/DefaultTokenAndChain.swift @@ -0,0 +1,91 @@ +// +// DefaultTokenAndChain.swift +// Cyton +// +// Created by XiaoLu on 2018/12/6. +// Copyright © 2018 Cryptape. All rights reserved. +// + +import Foundation +import RealmSwift + +class DefaultTokenAndChain { + func addDefaultTokenToWallet(wallet: WalletModel) { + let walletRef = ThreadSafeReference(to: wallet) + DispatchQueue.global().async { + let realm = try! Realm() + guard let walletModel = realm.resolve(walletRef) else { + return + } + self.ethereum(wallet: walletModel) + self.testChain(chainHost: CITANetwork.defaultNode, wallet: walletModel) + self.testChain(chainHost: "http://testnet.mba.cmbchina.biz:1337", wallet: walletModel) + } + } + + func ethereum(wallet: WalletModel) { + let ethModel = TokenModel() + ethModel.address = "" + ethModel.decimals = NativeDecimals.nativeTokenDecimals + ethModel.iconUrl = "" + ethModel.isNativeToken = true + ethModel.name = "ethereum" + ethModel.symbol = "ETH" + if let id = TokenModel.identifier(for: ethModel) { + ethModel.identifier = id + } + + let realm = try! Realm() + try? realm.write { + realm.add(ethModel, update: true) + if !wallet.tokenModelList.contains(where: { $0 == ethModel }) { + wallet.tokenModelList.append(ethModel) + if !wallet.selectedTokenList.contains(where: { $0 == ethModel }) { + wallet.selectedTokenList.append(ethModel) + } + } + } + } + + func testChain(chainHost: String, wallet: WalletModel) { + do { + let metaData = try CITANetwork(url: URL(string: chainHost)).cita.rpc.getMetaData() + let tokenModel = TokenModel() + tokenModel.symbol = metaData.tokenSymbol + tokenModel.iconUrl = metaData.tokenAvatar + tokenModel.name = metaData.tokenName + tokenModel.isNativeToken = true + if let tokenIdentifier = TokenModel.identifier(for: tokenModel) { + tokenModel.identifier = tokenIdentifier + } + + let chainModel = ChainModel() + chainModel.chainId = metaData.chainId + chainModel.chainName = metaData.chainName + chainModel.httpProvider = chainHost + chainModel.nativeTokenIdentifier = tokenModel.identifier + if let chainIdentifier = ChainModel.identifier(for: chainModel) { + chainModel.identifier = chainIdentifier + } + tokenModel.chainIdentifier = chainModel.identifier + + let realm = try Realm() + try realm.write { + realm.add(tokenModel, update: true) + realm.add(chainModel, update: true) + if !wallet.chainModelList.contains(where: { $0 == chainModel }) { + wallet.chainModelList.append(chainModel) + } + if !wallet.tokenModelList.contains(where: { $0 == tokenModel }) { + wallet.tokenModelList.append(tokenModel) + if !wallet.selectedTokenList.contains(where: { $0 == tokenModel }) { + wallet.selectedTokenList.append(tokenModel) + } + } + } + } catch { + } + + } + +} diff --git a/Neuron/Services/Common/LocalCurrencyService.swift b/Cyton/Services/Common/LocalCurrencyService.swift similarity index 96% rename from Neuron/Services/Common/LocalCurrencyService.swift rename to Cyton/Services/Common/LocalCurrencyService.swift index 5930ae0c..25ee4c28 100644 --- a/Neuron/Services/Common/LocalCurrencyService.swift +++ b/Cyton/Services/Common/LocalCurrencyService.swift @@ -1,12 +1,12 @@ // // CurrencyService.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/9/6. // Copyright © 2018年 Cryptape. All rights reserved. // -import UIKit +import Foundation final class LocalCurrencyService { private let localCurrencyKey = "localCurrency" @@ -42,4 +42,5 @@ struct LocalCurrency: Codable { var name: String var short: String var symbol: String + var identifier: String } diff --git a/Neuron/Services/Common/SendTransactionError.swift b/Cyton/Services/Common/SendTransactionError.swift similarity index 92% rename from Neuron/Services/Common/SendTransactionError.swift rename to Cyton/Services/Common/SendTransactionError.swift index 4251e498..4cf7a69b 100644 --- a/Neuron/Services/Common/SendTransactionError.swift +++ b/Cyton/Services/Common/SendTransactionError.swift @@ -1,6 +1,6 @@ // // SendTransactionError.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/7/5. // Copyright © 2018年 cryptape. All rights reserved. @@ -14,7 +14,7 @@ enum SendTransactionError: String, LocalizedError { case invalidContractAddress case noAvailableKeys case createTransactionIssue - case invalidAppChainNode + case invalidCITANode case invalidChainId case signTXFailed diff --git a/Cyton/Services/Common/TaskThread.swift b/Cyton/Services/Common/TaskThread.swift new file mode 100644 index 00000000..01fec791 --- /dev/null +++ b/Cyton/Services/Common/TaskThread.swift @@ -0,0 +1,64 @@ +// +// TaskThread.swift +// Cyton +// +// Created by 晨风 on 2018/12/11. +// Copyright © 2018 Cryptape. All rights reserved. +// + +import UIKit + +class TaskThread: NSObject { + typealias Block = () -> Void + private(set) var thread: Thread? + + func perform(_ block: @escaping Block) { + guard let thread = thread else { return } + let task = Task(block: block) + let sel = #selector(TaskThread.taskHandler(task:)) + perform(sel, on: thread, with: task, waitUntilDone: false) + } + + func syncPerform(_ block: @escaping Block) { + guard let thread = thread else { return } + let task = Task(block: block) + let sel = #selector(TaskThread.taskHandler(task:)) + perform(sel, on: thread, with: task, waitUntilDone: true) + } + + @objc func run() { + guard thread == nil else { return } + let group = DispatchGroup() + let queue = DispatchQueue(label: "") + group.enter() + queue.async { + self.thread = Thread.current + self.runLoop = RunLoop.current + Thread.current.name = String(describing: TaskThread.self) + RunLoop.current.add(NSMachPort(), forMode: .default) + group.leave() + CFRunLoopRun() + } + group.wait() + } + + @objc func stop() { + guard thread != nil else { return } + thread = nil + if let runloop = runLoop?.getCFRunLoop() { + CFRunLoopStop(runloop) + } + } + + private var runLoop: RunLoop? + private class Task: NSObject { + let block: Block + init(block: @escaping Block) { + self.block = block + } + } + + @objc private func taskHandler(task: Task) { + task.block() + } +} diff --git a/Neuron/Services/Common/TokenPriceLoader.swift b/Cyton/Services/Common/TokenPriceLoader.swift similarity index 90% rename from Neuron/Services/Common/TokenPriceLoader.swift rename to Cyton/Services/Common/TokenPriceLoader.swift index 6bed3c69..e1f33636 100644 --- a/Neuron/Services/Common/TokenPriceLoader.swift +++ b/Cyton/Services/Common/TokenPriceLoader.swift @@ -1,13 +1,12 @@ // // TokenPriceLoader.swift -// Neuron +// Cyton // // Created by 晨风 on 2018/11/29. // Copyright © 2018 Cryptape. All rights reserved. // import UIKit -import RealmSwift import Alamofire import PromiseKit @@ -39,8 +38,10 @@ class TokenPriceLoader { private static var tokens = [Token]() - func getPrice(symbol: String, currency: String) -> Double? { + func getPrice(symbol: String, currency: String? = nil) -> Double? { + guard EthereumNetwork().networkType == .mainnet else { return nil } guard let tokenId = getTokenId(symbol: symbol) else { return nil } + let currency = currency ?? LocalCurrencyService.shared.getLocalCurrencySelect().short let url = URL(string: "https://api.coinmarketcap.com/v2/ticker/\(tokenId)/?convert=\(currency)")! return try? Promise.init { (resolver) in Alamofire.request(url).responseData { (response) in diff --git a/Neuron/Services/Ethereum/CustomERC20TokenService.swift b/Cyton/Services/Ethereum/CustomERC20TokenService.swift similarity index 88% rename from Neuron/Services/Ethereum/CustomERC20TokenService.swift rename to Cyton/Services/Ethereum/CustomERC20TokenService.swift index 2cc6d89b..3627a274 100644 --- a/Neuron/Services/Ethereum/CustomERC20TokenService.swift +++ b/Cyton/Services/Ethereum/CustomERC20TokenService.swift @@ -1,6 +1,6 @@ // // CustomERC20TokenService.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/7/5. // Copyright © 2018年 cryptape. All rights reserved. @@ -36,19 +36,16 @@ struct CustomERC20TokenService { throw CustomTokenError.badNameError } - if let symbol = callTransaction(contractAddress: contractAddress, walletAddress: walletAddress, method: "symbol") as? String { - tokenModel.symbol = symbol - } else { - throw CustomTokenError.badSymbolError - } + tokenModel.symbol = callTransaction(contractAddress: contractAddress, walletAddress: walletAddress, method: "symbol") as? String ?? "" if let decimals = callTransaction(contractAddress: contractAddress, walletAddress: walletAddress, method: "decimals") as? BigUInt { tokenModel.decimals = Int(decimals) } else { throw CustomTokenError.wrongBalanceError } - - guard !tokenModel.name.isEmpty, !tokenModel.symbol.isEmpty else { + tokenModel.address = contractAddress + tokenModel.isNativeToken = false + guard !tokenModel.name.isEmpty else { throw CustomTokenError.undefinedError } return tokenModel diff --git a/Neuron/Services/Ethereum/Ethereum+TransactionDetails.swift b/Cyton/Services/Ethereum/Ethereum+TransactionDetails.swift similarity index 68% rename from Neuron/Services/Ethereum/Ethereum+TransactionDetails.swift rename to Cyton/Services/Ethereum/Ethereum+TransactionDetails.swift index 8aecf03c..91df0191 100644 --- a/Neuron/Services/Ethereum/Ethereum+TransactionDetails.swift +++ b/Cyton/Services/Ethereum/Ethereum+TransactionDetails.swift @@ -1,6 +1,6 @@ // // Ethereum+TransactionDetails.swift -// Neuron +// Cyton // // Created by 晨风 on 2018/11/16. // Copyright © 2018 Cryptape. All rights reserved. @@ -17,16 +17,19 @@ class EthereumTransactionDetails: TransactionDetails { var blockHash: String = "" var transactionIndex: BigUInt = 0 var gas: BigUInt = 0 - var gasPrice: BigUInt = 0 + var gasUsed: BigUInt = 0 var input: String = "" var contractAddress: String = "" var cumulativeGasUsed: BigUInt = 0 - var gasUsed: BigUInt = 0 var confirmations: UInt = 0 var isError = false var txreceipt_status: Int = 0 + var tokenName: String = "" + var tokenSymbol: String = "" + var tokenDecimal: String = "" + enum EthereumCodingKeys: String, CodingKey { case timeStamp case nonce @@ -42,6 +45,10 @@ class EthereumTransactionDetails: TransactionDetails { case isError case txreceipt_status + + case tokenName + case tokenSymbol + case tokenDecimal } override init() { @@ -85,84 +92,6 @@ class EthereumTransactionDetails: TransactionDetails { if let value = try? values.decode(String.self, forKey: .txreceipt_status) { txreceipt_status = Int(value) ?? 0 } - } -} - -private struct EthereumTransactionsResponse: Decodable { - let status: String - let message: String - let result: [EthereumTransactionDetails] -} - -// MARK: - Erc20 transaction details -class Erc20TransactionDetails: TransactionDetails { - var nonce: BigUInt = 0 - var blockHash: String = "" - var contractAddress: String = "" - var tokenName: String = "" - var tokenSymbol: String = "" - var tokenDecimal: String = "" - var transactionIndex: BigUInt = 0 - var gas: BigUInt = 0 - var gasPrice: BigUInt = 0 - var gasUsed: BigUInt = 0 - var cumulativeGasUsed: BigUInt = 0 - var input: String = "" - var confirmations: UInt = 0 - - enum Erc20CodingKeys: String, CodingKey { - case timeStamp - case nonce - case blockHash - case contractAddress - case transactionIndex - case gas - case gasPrice - case gasUsed - case cumulativeGasUsed - case input - case confirmations - - case tokenName - case tokenSymbol - case tokenDecimal - } - - override init() { - super.init() - } - - required init(from decoder: Decoder) throws { - try super.init(from: decoder) - let values = try decoder.container(keyedBy: Erc20CodingKeys.self) - - if let value = try? values.decode(String.self, forKey: .timeStamp) { - date = Date(timeIntervalSince1970: TimeInterval(value) ?? 0.0) - } - if let value = try? values.decode(String.self, forKey: .nonce) { - nonce = BigUInt(string: value) ?? 0 - } - blockHash = (try? values.decode(String.self, forKey: .blockHash)) ?? "" - contractAddress = (try? values.decode(String.self, forKey: .contractAddress)) ?? "" - if let value = try? values.decode(String.self, forKey: .transactionIndex) { - transactionIndex = BigUInt(string: value) ?? 0 - } - if let value = try? values.decode(String.self, forKey: .gas) { - gas = BigUInt(string: value) ?? 0 - } - if let value = try? values.decode(String.self, forKey: .gasPrice) { - gasPrice = BigUInt(string: value) ?? 0 - } - if let value = try? values.decode(String.self, forKey: .gasUsed) { - gasUsed = BigUInt(string: value) ?? 0 - } - if let value = try? values.decode(String.self, forKey: .cumulativeGasUsed) { - cumulativeGasUsed = BigUInt(string: value) ?? 0 - } - input = (try? values.decode(String.self, forKey: .input)) ?? "" - if let value = try? values.decode(String.self, forKey: .confirmations) { - confirmations = UInt(value) ?? 0 - } tokenName = (try? values.decode(String.self, forKey: .tokenName)) ?? "" tokenSymbol = (try? values.decode(String.self, forKey: .tokenSymbol)) ?? "" @@ -170,16 +99,16 @@ class Erc20TransactionDetails: TransactionDetails { } } -private struct Erc20TransactionsResponse: Decodable { +private struct EthereumTransactionsResponse: Decodable { let status: String let message: String - let result: [Erc20TransactionDetails] + let result: [EthereumTransactionDetails] } // MARK: - Get transaction details extension EthereumNetwork { func getTransactionHistory(walletAddress: String, page: UInt, pageSize: UInt) throws -> [EthereumTransactionDetails] { - let url = EthereumNetwork().host().appendingPathComponent("/api") + let url = EthereumNetwork().apiHost().appendingPathComponent("/api") let parameters: [String: Any] = [ "apikey": ServerApi.etherScanKey, "module": "account", @@ -203,8 +132,8 @@ extension EthereumNetwork { }.wait() } - func getErc20TransactionHistory(walletAddress: String, tokenAddress: String, page: UInt, pageSize: UInt) throws -> [Erc20TransactionDetails] { - let url = EthereumNetwork().host().appendingPathComponent("/api") + func getErc20TransactionHistory(walletAddress: String, tokenAddress: String, page: UInt, pageSize: UInt) throws -> [EthereumTransactionDetails] { + let url = EthereumNetwork().apiHost().appendingPathComponent("/api") let parameters: [String: Any] = [ "apikey": ServerApi.etherScanKey, "module": "account", @@ -215,11 +144,11 @@ extension EthereumNetwork { "page": page, "offset": pageSize ] - return try Promise<[Erc20TransactionDetails]>.init { (resolver) in + return try Promise<[EthereumTransactionDetails]>.init { (resolver) in Alamofire.request(url, method: .get, parameters: parameters).responseJSON { (response) in do { guard let responseData = response.data else { throw TransactionHistoryError.networkFailure } - let response = try JSONDecoder().decode(Erc20TransactionsResponse.self, from: responseData) + let response = try JSONDecoder().decode(EthereumTransactionsResponse.self, from: responseData) let transactions = response.result resolver.fulfill(transactions) } catch { @@ -230,7 +159,7 @@ extension EthereumNetwork { } func getTransaction(txhash: String) throws -> EthereumTransactionDetails { - let url = EthereumNetwork().host().appendingPathComponent("/api") + let url = EthereumNetwork().apiHost().appendingPathComponent("/api") let parameters: [String: Any] = [ "apikey": ServerApi.etherScanKey, "module": "account", diff --git a/Neuron/Services/Ethereum/EthereumBalanceLoader.swift b/Cyton/Services/Ethereum/EthereumBalanceLoader.swift similarity index 98% rename from Neuron/Services/Ethereum/EthereumBalanceLoader.swift rename to Cyton/Services/Ethereum/EthereumBalanceLoader.swift index fe7bee03..b2e436ac 100644 --- a/Neuron/Services/Ethereum/EthereumBalanceLoader.swift +++ b/Cyton/Services/Ethereum/EthereumBalanceLoader.swift @@ -1,6 +1,6 @@ // // EthereumBalanceLoader.swift -// Neuron +// Cyton // // Created by 晨风 on 2018/11/29. // Copyright © 2018 Cryptape. All rights reserved. diff --git a/Cyton/Services/Ethereum/EthereumLocalTxPool.swift b/Cyton/Services/Ethereum/EthereumLocalTxPool.swift new file mode 100644 index 00000000..a6764bf4 --- /dev/null +++ b/Cyton/Services/Ethereum/EthereumLocalTxPool.swift @@ -0,0 +1,218 @@ +// +// EthereumLocalTxPool.swift +// Cyton +// +// Created by 晨风 on 2018/12/27. +// Copyright © 2018 Cryptape. All rights reserved. +// + +import Foundation +import RealmSwift +import Web3swift +import struct Web3swift.TransactionDetails +import BigInt + +class EthereumLocalTx: Object { + @objc dynamic var token: TokenModel! + @objc dynamic var txHash = "" + @objc dynamic var from = "" + @objc dynamic var to = "" + @objc dynamic var value = "" + @objc dynamic var gasPrice = "" + @objc dynamic var gasLimit = "" + @objc dynamic var date = Date() + @objc dynamic private var statusValue: Int = TxStatus.pending.rawValue + @objc dynamic private var ethereumNetworkValue: String = EthereumNetwork().networkType.rawValue + var ethereumNetwork: EthereumNetwork.NetworkType { + get { return EthereumNetwork.NetworkType(rawValue: ethereumNetworkValue)! } + set { ethereumNetworkValue = newValue.rawValue } + } + var status: TxStatus { + get { return TxStatus(rawValue: statusValue)! } + set { statusValue = newValue.rawValue } + } + + required convenience init(token: TokenModel, txHash: String, from: String, to: String, value: BigUInt, gasPrice: BigUInt, gasLimit: BigUInt) { + self.init() + self.token = token + self.txHash = txHash + self.from = from + self.to = to + self.value = String(value) + self.gasPrice = String(gasPrice) + self.gasLimit = String(gasLimit) + } + + @objc override class func primaryKey() -> String? { return "txHash" } + + enum TxStatus: Int { + case pending + case success + case failure + } +} + +class EthereumLocalTxPool: NSObject { + static let didUpdateTxStatus = Notification.Name("EthereumLocalTxPool.didUpdateTxStatus") + static let didAddLocalTx = Notification.Name("EthereumLocalTxPool.didAddLocalTx") + static let txKey = "tx" + static let pool = EthereumLocalTxPool() + + func register() {} + + func insertLocalTx(localTx: EthereumLocalTx) { + do { + let realm = try Realm() + try realm.write { + realm.add(localTx) + } + let tx = localTx.getTx() + DispatchQueue.main.async { + NotificationCenter.default.post(name: EthereumLocalTxPool.didAddLocalTx, object: nil, userInfo: [EthereumLocalTxPool.txKey: tx]) + } + } catch { + } + } + + func getTransactions(token: Token) -> [EthereumTransactionDetails] { + let ethereumNetwork = EthereumNetwork().networkType + return (try! Realm()).objects(EthereumLocalTx.self).filter({ + $0.from == token.walletAddress && + $0.token.address == token.address && + $0.ethereumNetwork == ethereumNetwork + }).map({ $0.getTx() }) + } + + // MARK: - Private + private var observers = [NotificationToken]() + + private override init() { + super.init() + DispatchQueue.global().async { + self.checkLocalTxList() + } + let realm = try! Realm() + observers.append(realm.objects(EthereumLocalTx.self).observe { (change) in + switch change { + case .update(_, deletions: _, let insertions, modifications: _): + guard insertions.count > 0 else { return } + DispatchQueue.global().async { + self.checkLocalTxList() + } + default: + break + } + }) + } + + private var checking = false + private let timeInterval: TimeInterval = 4.0 + + @objc private func checkLocalTxList() { + guard checking == false else { return } + NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(checkLocalTxList), object: nil) + let realm = try! Realm() + let results = realm.objects(EthereumLocalTx.self).filter({ $0.status == .pending }) + guard results.count > 0 else { return } + checking = true + results.forEach { (localTx) in + guard localTx.status == .pending else { return } + self.checkLocalTxStatus(localTx: localTx) + } + checking = false + checkLocalTxList() + perform(#selector(checkLocalTxList), with: nil, afterDelay: timeInterval) + } + + private func checkLocalTxStatus(localTx: EthereumLocalTx) { + guard let blockNumber = localTx.blockNumber else { return } + guard let currentBlockNumber = try? localTx.web3.eth.getBlockNumber() else { return } + let realm = try! Realm() + var status: EthereumLocalTx.TxStatus = .success + if localTx.transactionReceipt?.status == .ok { + if Int(currentBlockNumber) - Int(blockNumber) < 12 { + return + } + status = .success + } else if localTx.transactionReceipt?.status == .failed { + status = .failure + } + if localTx.status == .pending && localTx.date.timeIntervalSince1970 + 60*60*48 < Date().timeIntervalSince1970 { + status = .failure + } + + try? realm.write { + localTx.status = status + } + + if localTx.status == .success || localTx.status == .failure { + let tx = localTx.getTx() + DispatchQueue.main.async { + NotificationCenter.default.post(name: EthereumLocalTxPool.didUpdateTxStatus, object: nil, userInfo: [EthereumLocalTxPool.txKey: tx]) + } + } + } +} + +extension EthereumLocalTx { + private struct AssociatedKey { + static var transactionDetails: Int = 0 + static var transactionReceipt: Int = 0 + } + + fileprivate var transactionDetails: Web3swift.TransactionDetails? { + if let transactionDetails = objc_getAssociatedObject(self, &AssociatedKey.transactionDetails) { + return transactionDetails as? Web3swift.TransactionDetails + } + let transactionDetails = try? web3.eth.getTransactionDetails(txHash) + if transactionDetails?.blockNumber != nil { + objc_setAssociatedObject(self, &AssociatedKey.transactionDetails, transactionDetails, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + return transactionDetails + } + + fileprivate var transactionReceipt: Web3swift.TransactionReceipt? { + if let transactionReceipt = objc_getAssociatedObject(self, &AssociatedKey.transactionReceipt) { + return transactionReceipt as? Web3swift.TransactionReceipt + } + let transactionReceipt = try? web3.eth.getTransactionReceipt(txHash) + if transactionReceipt?.status == .ok || transactionReceipt?.status == .failed { + objc_setAssociatedObject(self, &AssociatedKey.transactionReceipt, transactionReceipt, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + return transactionReceipt + } + + fileprivate var blockNumber: BigUInt? { + return transactionDetails?.blockNumber + } + + fileprivate var web3: web3 { + return EthereumNetwork().getWeb3(networkType: ethereumNetwork) + } +} + +extension EthereumLocalTx { + func getTx() -> EthereumTransactionDetails { + let tx = EthereumTransactionDetails() + tx.gasUsed = BigUInt(gasLimit) ?? 0 + tx.contractAddress = token.address + tx.token = Token(token, from) + tx.hash = txHash + tx.from = from + tx.to = to + tx.value = BigUInt(value) ?? 0 + tx.gasPrice = BigUInt(gasPrice) ?? 0 + tx.gasLimit = BigUInt(gasLimit) ?? 0 + tx.date = date + tx.blockNumber = blockNumber ?? 0 + switch status { + case .pending: + tx.status = .pending + case .success: + tx.status = .success + case .failure: + tx.status = .failure + } + return tx + } +} diff --git a/Neuron/Services/Ethereum/EthereumMessageSigner.swift b/Cyton/Services/Ethereum/EthereumMessageSigner.swift similarity index 99% rename from Neuron/Services/Ethereum/EthereumMessageSigner.swift rename to Cyton/Services/Ethereum/EthereumMessageSigner.swift index e319a859..0094e558 100644 --- a/Neuron/Services/Ethereum/EthereumMessageSigner.swift +++ b/Cyton/Services/Ethereum/EthereumMessageSigner.swift @@ -1,6 +1,6 @@ // // EthereumMessageSigner.swift -// Neuron +// Cyton // // Created by James Chen on 2018/11/30. // Copyright © 2018 Cryptape. All rights reserved. diff --git a/Cyton/Services/Ethereum/EthereumNetwork.swift b/Cyton/Services/Ethereum/EthereumNetwork.swift new file mode 100644 index 00000000..1f9ee7ad --- /dev/null +++ b/Cyton/Services/Ethereum/EthereumNetwork.swift @@ -0,0 +1,95 @@ +// +// EthereumNetwork.swift +// Cyton +// +// Created by XiaoLu on 2018/7/6. +// Copyright © 2018年 cryptape. All rights reserved. +// + +import Foundation +import Web3swift +import RealmSwift + +class EthereumNetwork { + func getWeb3(networkType: NetworkType = EthereumNetwork().networkType) -> web3 { + switch networkType { + case .mainnet: + return Web3.InfuraMainnetWeb3() + case .rinkeby: + return Web3.InfuraRinkebyWeb3() + case .ropsten: + return Web3.InfuraRopstenWeb3() + case .kovan: + let infura = InfuraProvider(.Kovan)! + return web3(provider: infura) + } + } + + func apiHost() -> URL { + switch networkType { + case .mainnet: + return URL(string: "http://api.etherscan.io")! + case .rinkeby: + return URL(string: "http://api-rinkeby.etherscan.io")! + case .ropsten: + return URL(string: "http://api-ropsten.etherscan.io")! + case .kovan: + return URL(string: "http://api-kovan.etherscan.io")! + } + } + + func host() -> URL { + switch networkType { + case .mainnet: + return URL(string: "https://etherscan.io")! + case .rinkeby: + return URL(string: "https://rinkeby.etherscan.io")! + case .ropsten: + return URL(string: "https://ropsten.etherscan.io")! + case .kovan: + return URL(string: "https://kovan.etherscan.io")! + } + } + + enum NetworkType: String, CaseIterable { + case mainnet + case rinkeby + case ropsten + case kovan + + var chainName: String { + switch self { + case .mainnet: + return "Main Ethereum Network" + case .rinkeby: + return "Rinkeby Test Network" + case .ropsten: + return "Ropsten Test Network " + case .kovan: + return "Kovan Test Network" + } + } + } + + private let currentNetworkKey = "ethereumNetwork" + + var networkType: NetworkType { + get { + let network = UserDefaults.standard.string(forKey: currentNetworkKey) ?? "" + return NetworkType(rawValue: network) ?? .mainnet + } + set { + UserDefaults.standard.set(newValue.rawValue, forKey: currentNetworkKey) + NotificationCenter.default.post(name: .switchEthNetwork, object: nil) + } + } + + var chain: ChainModel { + let chainModel = ChainModel() + chainModel.chainId = "-1" + chainModel.chainName = networkType.chainName + chainModel.httpProvider = apiHost().absoluteString + chainModel.nativeTokenIdentifier = (try! Realm()).objects(TokenModel.self).first(where: { $0.symbol == "ETH" })!.identifier + return chainModel + } +} diff --git a/Cyton/Services/Ethereum/EthereumTokenProfileLoader.swift b/Cyton/Services/Ethereum/EthereumTokenProfileLoader.swift new file mode 100644 index 00000000..5f6189ae --- /dev/null +++ b/Cyton/Services/Ethereum/EthereumTokenProfileLoader.swift @@ -0,0 +1,47 @@ +// +// EthereumTokenProfileLoader.swift +// Cyton +// +// Created by 晨风 on 2018/12/20. +// Copyright © 2018 Cryptape. All rights reserved. +// + +import UIKit +import PromiseKit +import EthereumAddress +import Alamofire + +typealias TokenOverview = String +typealias TokenIconURL = String + +class EthereumTokenProfileLoader { + private struct TokenProfile: Decodable { + var overview: Overview? + } + private struct Overview: Decodable { + var zh: String? + var en: String? + } + + func loadTokenProfile(address: String) throws -> (TokenIconURL, TokenOverview) { + return try Promise<(TokenIconURL, TokenOverview)>.init { (resolver) in + guard address.count > 0, let address = EthereumAddress.toChecksumAddress(address) else { + resolver.fulfill(("", "TokenProfile.Ether.overview".localized())) + return + } + Alamofire.request("https://raw.githubusercontent.com/consenlabs/token-profile/master/erc20/\(address).json").responseData { (response) in + do { + guard let data = response.data else { throw response.error! } + let profile = try JSONDecoder().decode(TokenProfile.self, from: data) + if Locale.current.identifier.contains("zh") { + resolver.fulfill(("https://raw.githubusercontent.com/consenlabs/token-profile/master/images/\(address).png", profile.overview?.zh ?? "")) + } else { + resolver.fulfill(("https://raw.githubusercontent.com/consenlabs/token-profile/master/images/\(address).png", profile.overview?.en ?? "")) + } + } catch { + resolver.reject(error) + } + } + }.wait() + } +} diff --git a/Neuron/Services/Ethereum/EthereumTxSender.swift b/Cyton/Services/Ethereum/EthereumTxSender.swift similarity index 73% rename from Neuron/Services/Ethereum/EthereumTxSender.swift rename to Cyton/Services/Ethereum/EthereumTxSender.swift index e44812ff..d04fdc37 100644 --- a/Neuron/Services/Ethereum/EthereumTxSender.swift +++ b/Cyton/Services/Ethereum/EthereumTxSender.swift @@ -1,6 +1,6 @@ // // EthereumTxSender.swift -// Neuron +// Cyton // // Created by James Chen on 2018/11/06. // Copyright © 2018 Cryptape. All rights reserved. @@ -27,7 +27,7 @@ class EthereumTxSender { func sendETH( to: String, value: BigUInt, - gasLimit: UInt64 = GasCalculator.defaultGasLimit, + gasLimit: BigUInt = GasCalculator.defaultGasLimit, gasPrice: BigUInt, data: Data, password: String @@ -51,16 +51,13 @@ class EthereumTxSender { } transaction.transaction.value = value // Web3swift seems to be having bug setting value - let txHash = try transaction.sendPromise(password: password).wait().hash - let sentTransaction = SentTransaction(tokenType: .ether, from: from.address, to: to, value: value, txFee: gasPrice * BigUInt(gasLimit), txHash: txHash) - TransactionStatusManager.manager.insertTransaction(transaction: sentTransaction) - return txHash + return try transaction.sendPromise(password: password).wait().hash } func sendToken( to: String, value: BigUInt, - gasLimit: UInt64 = GasCalculator.defaultGasLimit, + gasLimit: BigUInt = GasCalculator.defaultGasLimit, gasPrice: BigUInt, contractAddress: String, password: String @@ -84,10 +81,6 @@ class EthereumTxSender { transaction.transactionOptions.gasLimit = .manual(BigUInt(gasLimit)) transaction.transactionOptions.gasPrice = .manual(gasPrice) - - let txHash = try transaction.sendPromise(password: password).wait().hash - let sentTransaction = SentTransaction(contractAddress: contractAddress, tokenType: .erc20, from: from.address, to: to, value: value, txFee: gasPrice * BigUInt(gasLimit), txHash: txHash) - TransactionStatusManager.manager.insertTransaction(transaction: sentTransaction) - return txHash + return try transaction.sendPromise(password: password).wait().hash } } diff --git a/Neuron/Services/Ethereum/NFTService.swift b/Cyton/Services/Ethereum/NFTService.swift similarity index 99% rename from Neuron/Services/Ethereum/NFTService.swift rename to Cyton/Services/Ethereum/NFTService.swift index 27a16827..ec0a1b1f 100644 --- a/Neuron/Services/Ethereum/NFTService.swift +++ b/Cyton/Services/Ethereum/NFTService.swift @@ -1,6 +1,6 @@ // // NFTService.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/9/11. // Copyright © 2018年 Cryptape. All rights reserved. diff --git a/Neuron/Services/WalletManager/WalletKeystoreManager.swift b/Cyton/Services/WalletManager/WalletKeystoreManager.swift similarity index 99% rename from Neuron/Services/WalletManager/WalletKeystoreManager.swift rename to Cyton/Services/WalletManager/WalletKeystoreManager.swift index 2e8d4707..6322fb1a 100644 --- a/Neuron/Services/WalletManager/WalletKeystoreManager.swift +++ b/Cyton/Services/WalletManager/WalletKeystoreManager.swift @@ -1,6 +1,6 @@ // // WalletKeystoreManager.swift -// Neuron +// Cyton // // Created by James Chen on 2018/10/31. // Copyright © 2018 Cryptape. All rights reserved. diff --git a/Neuron/Services/WalletManager/WalletManager+Errors.swift b/Cyton/Services/WalletManager/WalletManager+Errors.swift similarity index 98% rename from Neuron/Services/WalletManager/WalletManager+Errors.swift rename to Cyton/Services/WalletManager/WalletManager+Errors.swift index 18b81aa1..9544280e 100644 --- a/Neuron/Services/WalletManager/WalletManager+Errors.swift +++ b/Cyton/Services/WalletManager/WalletManager+Errors.swift @@ -1,6 +1,6 @@ // // WalletManager+Errors.swift -// Neuron +// Cyton // // Created by James Chen on 2018/11/03. // Copyright © 2018 Cryptape. All rights reserved. diff --git a/Neuron/Services/WalletManager/WalletManager.swift b/Cyton/Services/WalletManager/WalletManager.swift similarity index 99% rename from Neuron/Services/WalletManager/WalletManager.swift rename to Cyton/Services/WalletManager/WalletManager.swift index 958e9cbf..ab5b406e 100755 --- a/Neuron/Services/WalletManager/WalletManager.swift +++ b/Cyton/Services/WalletManager/WalletManager.swift @@ -1,6 +1,6 @@ // // WalletManager.swift -// Neuron +// Cyton // // diff --git a/Neuron/Utils/GasCalculator.swift b/Cyton/Utils/GasCalculator.swift similarity index 78% rename from Neuron/Utils/GasCalculator.swift rename to Cyton/Utils/GasCalculator.swift index 034e32bd..3831b787 100644 --- a/Neuron/Utils/GasCalculator.swift +++ b/Cyton/Utils/GasCalculator.swift @@ -1,13 +1,13 @@ // // GasCalculator.swift -// Neuron +// Cyton // // Created by James Chen on 2018/11/07. // Copyright © 2018 Cryptape. All rights reserved. // import Foundation -import AppChain +import CITA import BigInt /// Get current gas price and estimated gas, calculate gas, etc. @@ -15,12 +15,12 @@ import BigInt struct GasCalculator { // Default to 20 Gwei (which is not very reasonable when Ethereum is under congestion) static let defaultGasPrice = BigUInt(20).toWei(from: .gwei) - static let defaultGasLimit: UInt64 = 21_000 + static let defaultGasLimit: BigUInt = 21_000 var gasPrice: BigUInt - var gasLimit: UInt64 + var gasLimit: BigUInt - init(gasPrice: BigUInt = GasCalculator.defaultGasPrice, gasLimit: UInt64 = GasCalculator.defaultGasLimit) { + init(gasPrice: BigUInt = GasCalculator.defaultGasPrice, gasLimit: BigUInt = GasCalculator.defaultGasLimit) { self.gasPrice = gasPrice self.gasLimit = gasLimit } @@ -38,12 +38,12 @@ struct GasCalculator { /// - gasPrice: Gas price as GWei. /// - gasLimit: Gas limit. /// - Returns: Calculated tx fee with unit wei. - static func txFee(gasPrice: BigUInt, gasLimit: UInt64 = GasCalculator.defaultGasLimit) -> BigUInt { + static func txFee(gasPrice: BigUInt, gasLimit: BigUInt = GasCalculator.defaultGasLimit) -> BigUInt { return gasPrice * BigUInt(gasLimit) } /// Calculate tx fee (ETH) giving gas price and gas limit. - static func txFeeNatural(gasPrice: BigUInt, gasLimit: UInt64 = GasCalculator.defaultGasLimit) -> Double { + static func txFeeNatural(gasPrice: BigUInt, gasLimit: BigUInt = GasCalculator.defaultGasLimit) -> Double { let fee = txFee(gasPrice: gasPrice, gasLimit: gasLimit) return Double(Web3Utils.formatToEthereumUnits(fee, toUnits: .eth, decimals: 10)!)! } @@ -64,13 +64,7 @@ struct GasPriceFetcher { /// Get current quota price (CITA quota) func quotaPrice(rpcNode: String? = nil) -> BigUInt { do { - let appChain: AppChain - if let rpcNode = rpcNode, let rpcURL = URL(string: rpcNode) { - appChain = AppChainNetwork.appChain(url: rpcURL) - } else { - appChain = AppChainNetwork.appChain() - } - return try Utils.getQuotaPrice(appChain: appChain) + return try Utils.getQuotaPrice(cita: CITANetwork(url: rpcNode).cita) } catch { return GasCalculator.defaultGasPrice } diff --git a/Neuron/Utils/SkipBackupFiles.swift b/Cyton/Utils/SkipBackupFiles.swift similarity index 100% rename from Neuron/Utils/SkipBackupFiles.swift rename to Cyton/Utils/SkipBackupFiles.swift diff --git a/Neuron/Utils/UIKit/NoScreenshot.swift b/Cyton/Utils/UIKit/NoScreenshot.swift similarity index 85% rename from Neuron/Utils/UIKit/NoScreenshot.swift rename to Cyton/Utils/UIKit/NoScreenshot.swift index d4d55626..d50d962b 100644 --- a/Neuron/Utils/UIKit/NoScreenshot.swift +++ b/Cyton/Utils/UIKit/NoScreenshot.swift @@ -1,6 +1,6 @@ // // NoScreenshot.swift -// Neuron +// Cyton // // Created by 晨风 on 2018/10/9. // Copyright © 2018 Cryptape. All rights reserved. @@ -17,7 +17,7 @@ extension NoScreenshot where Self: UIViewController { guard objc_getAssociatedObject(self, &NoScreenshotOnceTokenAssiciationKey) == nil else { return } objc_setAssociatedObject(self, &NoScreenshotOnceTokenAssiciationKey, 2233, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) let alert = UIAlertController(title: titile, message: message, preferredStyle: .alert) - alert.addAction(UIAlertAction(title: "确定", style: .destructive, handler: nil)) + alert.addAction(UIAlertAction(title: "Common.confirm".localized(), style: .destructive, handler: nil)) present(alert, animated: true, completion: nil) } } diff --git a/Neuron/Utils/UIKit/Overlay.storyboard b/Cyton/Utils/UIKit/Overlay.storyboard similarity index 100% rename from Neuron/Utils/UIKit/Overlay.storyboard rename to Cyton/Utils/UIKit/Overlay.storyboard diff --git a/Neuron/Utils/UIKit/OverlayPresentable.swift b/Cyton/Utils/UIKit/OverlayPresentable.swift similarity index 94% rename from Neuron/Utils/UIKit/OverlayPresentable.swift rename to Cyton/Utils/UIKit/OverlayPresentable.swift index 71aca8ff..c7cb50fe 100644 --- a/Neuron/Utils/UIKit/OverlayPresentable.swift +++ b/Cyton/Utils/UIKit/OverlayPresentable.swift @@ -1,6 +1,6 @@ // // OverlayPresentable.swift -// Neuron +// Cyton // // Created by 晨风 on 2018/10/9. // Copyright © 2018 Cryptape. All rights reserved. @@ -52,13 +52,14 @@ class ErrorOverlayViewController: UIViewController { var style: Style = .networkFail { didSet { _ = view // load view + refreshButton.setTitle("Common.Connection.Refresh".localized(), for: .normal) if style == .networkFail { imageView.image = UIImage(named: "fail_icon") - messageLabel.text = "网络错误,请稍后再试" + messageLabel.text = "Common.NetworkError".localized() refreshButton.isHidden = false } else { imageView.image = UIImage(named: "blank_icon") - messageLabel.text = "空空如也" + messageLabel.text = "Common.DataEmpty".localized() refreshButton.isHidden = true } } diff --git a/Neuron/Utils/UIKit/Toast.swift b/Cyton/Utils/UIKit/Toast.swift similarity index 99% rename from Neuron/Utils/UIKit/Toast.swift rename to Cyton/Utils/UIKit/Toast.swift index ac2f9c12..d0019b7c 100644 --- a/Neuron/Utils/UIKit/Toast.swift +++ b/Cyton/Utils/UIKit/Toast.swift @@ -1,6 +1,6 @@ // // NeuLoad.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/6/6. // Copyright © 2018年 cryptape. All rights reserved. diff --git a/Neuron/Utils/UIKit/ToastActivityView.xib b/Cyton/Utils/UIKit/ToastActivityView.xib similarity index 100% rename from Neuron/Utils/UIKit/ToastActivityView.xib rename to Cyton/Utils/UIKit/ToastActivityView.xib diff --git a/Neuron/Utils/Validators/MnemonicValidator.swift b/Cyton/Utils/Validators/MnemonicValidator.swift similarity index 98% rename from Neuron/Utils/Validators/MnemonicValidator.swift rename to Cyton/Utils/Validators/MnemonicValidator.swift index 51722f6c..0a4bcfec 100644 --- a/Neuron/Utils/Validators/MnemonicValidator.swift +++ b/Cyton/Utils/Validators/MnemonicValidator.swift @@ -1,6 +1,6 @@ // // MnemonicValidator.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/11/28. // Copyright © 2018 Cryptape. All rights reserved. diff --git a/Neuron/Utils/Validators/PasswordValidator.swift b/Cyton/Utils/Validators/PasswordValidator.swift similarity index 99% rename from Neuron/Utils/Validators/PasswordValidator.swift rename to Cyton/Utils/Validators/PasswordValidator.swift index c7d1d55e..d33dda18 100644 --- a/Neuron/Utils/Validators/PasswordValidator.swift +++ b/Cyton/Utils/Validators/PasswordValidator.swift @@ -1,6 +1,6 @@ // // PasswordValidator.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/6/22. // Copyright © 2018年 cryptape. All rights reserved. diff --git a/Neuron/Utils/Validators/WalletNameValidator.swift b/Cyton/Utils/Validators/WalletNameValidator.swift similarity index 98% rename from Neuron/Utils/Validators/WalletNameValidator.swift rename to Cyton/Utils/Validators/WalletNameValidator.swift index a2b2f894..be4abaab 100644 --- a/Neuron/Utils/Validators/WalletNameValidator.swift +++ b/Cyton/Utils/Validators/WalletNameValidator.swift @@ -1,6 +1,6 @@ // // WalletNameValidator.swift -// Neuron +// Cyton // // Created by XiaoLu on 2018/10/14. // Copyright © 2018 Cryptape. All rights reserved. diff --git a/Neuron/Utils/Web3Utils.swift b/Cyton/Utils/Web3Utils.swift similarity index 80% rename from Neuron/Utils/Web3Utils.swift rename to Cyton/Utils/Web3Utils.swift index 5abd231b..71fc2a1b 100644 --- a/Neuron/Utils/Web3Utils.swift +++ b/Cyton/Utils/Web3Utils.swift @@ -1,6 +1,6 @@ // // Web3Utils.swift -// Neuron +// Cyton // // Created by James Chen on 2018/10/29. // Copyright © 2018 Cryptape. All rights reserved. @@ -8,7 +8,9 @@ import Foundation import Web3swift +import BigInt typealias Web3Utils = Web3swift.Web3Utils typealias TxHash = String +typealias BlockNumber = BigUInt diff --git a/Cyton/en.lproj/Localizable.strings b/Cyton/en.lproj/Localizable.strings new file mode 100644 index 00000000..3c63929c --- /dev/null +++ b/Cyton/en.lproj/Localizable.strings @@ -0,0 +1,363 @@ +/* + Localizable.strings + Cyton + + Created by James Chen on 2018/11/03. + Copyright © 2018 Cryptape. All rights reserved. +*/ + +// Common +// --------------------------------------------------------- +"Common.Connection.UserCancel" = "Canceled"; +"Common.Connection.ScanEmpty" = "QR Code failed"; +"Common.Connection.LoseConnect" = "The connection to the Internet is broken"; +"Common.Connection.LoadFaild" = "Failed to load the page"; +"Common.Connection.Refresh" = "Refresh"; +"Common.DataEmpty" = "Empty Data"; +"Common.NetworkError" = "Network error, please try again later"; +"Common.next" = "Continue"; +"Common.confirm" = "Confirm"; +"Common.cancel" = "Cancel"; +"Common.reject" = "Reject"; + +// DApp +// --------------------------------------------------------- +"DApp.Home" = "ÐApp"; +"DApp.Search.TextFieldPlaceholder" = "Explore the decentralized web"; +"DApp.Search.DeleteHistory" = "Delete"; + +// DApp Browser +// --------------------------------------------------------- +"DApp.Browser.InvalidLink" = "Invalid Address"; +"DApp.Browser.Collection" = "Add to Bookmark"; +"DApp.Browser.CollectSuccess" = "Added to Bookmark"; +"DApp.Browser.CollectFaild" = "Failed to add bookmark"; +"DApp.Browser.AlertTitle" = "Tips"; +"DApp.Browser.CheckNoAliPay" = "The Alipay client is not detected. Please try again after installation."; +"DApp.Browser.CheckNoWeChat" = "WeChat client is not detected, please try again after installation."; +"DApp.Browser.SignFaild" = "Signature failed"; +"DApp.Browser.PayFaild" = "Payment failed"; +"DApp.Browser.confirmSign" = "Signature Request"; +"DApp.Browser.MonitorDirectionFailed" = "Failed to monitor device direction"; +"DApp.Browser.MonitorGyroFailed" = "Failed to monitor gyroscope data"; + +// DApp Contract +// --------------------------------------------------------- +"DApp.Contract.TransactionSend" = "Transaction sent"; +"DApp.Details.Title" = "Transaction Detail"; + +// DApp Advanced +// --------------------------------------------------------- +"DApp.Advanced.ETHRecommend" = "Ethereum recommended"; +"DApp.Advanced.Gas" = "Gas Price"; +"DApp.Advanced.EmptyGasPrice" = "Please enter Gas Price"; +"DApp.Advanced.MinGasPrice" = "Gas Price too low, Please set above %@ GWei"; + +// DApp DAppTakePhoto +// --------------------------------------------------------- +"DApp.DAppTakePhoto.CameraPermissions" = "Please authorize camera access"; +"DApp.DAppTakePhoto.Open" = "Authorize"; +"DApp.DAppTakePhoto.NoAccess" = "No camera access,Please go to System Settings > Cyton > Camera,and authorize camera access"; + +// DApp MyDApp +// --------------------------------------------------------- +"DApp.MyDApp.Title" = "My ÐApp"; + +// DApp NFT +// --------------------------------------------------------- +"DApp.NFT.EmptyData" = "No Collectives Found"; +"DApp.NFT.Title" = "My Collectives"; +"DApp.NFT.DetailTitle" = "Collectibles Detail"; + +// DApp Transaction +// --------------------------------------------------------- +"DApp.SendTransactionError.emptyValue" = "Empty transfer amount"; +"DApp.SendTransactionError.emptyQuota" = "Empty transfer Quota"; +"DApp.SendTransactionError.emptyGasLimit" = "Empty Gas Limit"; +"DApp.SendTransactionError.emptyGasPrice" = "Empty Gas Price"; + +// Mnemonic Validator +// --------------------------------------------------------- +"MnemonicValidator.emptyMnemonic" = "Empty Mnemonic"; +"MnemonicValidator.invalidMnemonic" = "Invalid Mnemonic"; + +// Wallet Manager Errors +// --------------------------------------------------------- +"WalletManager.Error.invalidPassword" = "Invalid password"; +"WalletManager.Error.invalidPrivateKey" = "Invalid Private Key"; +"WalletManager.Error.invalidKeystore" = "Invalid Keystore"; +"WalletManager.Error.invalidMnemonic" = "Invalid Mnemonic"; +"WalletManager.Error.emptyMnemonic" = "Empty Mnemonic"; +"WalletManager.Error.accountAlreadyExists" = "You already have this wallet"; +"WalletManager.Error.accountNotFound" = "Wallet not found"; +"WalletManager.Error.failedToDeleteAccount" = "Failed to delete wallet"; +"WalletManager.Error.failedToUpdatePassword" = "Failed to update wallet password"; +"WalletManager.Error.failedToSaveKeystore" = "Failed to save the Keystore"; +"WalletManager.Error.unknown" = "Unknown error"; + +// Send Transactoin Error +// --------------------------------------------------------- +"SendTransactionError.invalidSourceAddress" = "Invalid source address"; +"SendTransactionError.invalidDestinationAddress" = "Invalid destination address"; +"SendTransactionError.invalidContractAddress" = "Invalid contract Address"; +"SendTransactionError.noAvailableKeys" = "Wallet not found"; +"SendTransactionError.createTransactionIssue" = "Failed to create transaction"; +"SendTransactionError.invalidChainId" = "Invalid chain ID"; +"SendTransactionError.signTXFailed" = "Failed to sign the transaction"; + +// Custom Token Error +// --------------------------------------------------------- +"CustomTokenError.wrongBalanceError" = "Wrong balance"; +"CustomTokenError.badNameError" = "Bad token name"; +"CustomTokenError.badSymbolError" = "Bad token symbol"; +"CustomTokenError.undefinedError" = "Undefined error"; + +// Sign Message Error +// --------------------------------------------------------- +"MessageSign.Error.walletNotFound" = "Wallet not found"; +"MessageSign.Error.signMessageFailed" = "Failed to sign the message"; + +// Wallet +// --------------------------------------------------------- +"Wallet" = "Wallet"; +"Wallet.token" = "Token"; +"Wallet.addToken" = "Add"; +"Wallet.transaction" = "Send"; +"Wallet.receipt" = "Receive"; +"Wallet.totalAmount" = "Total Assets"; +"Wallet.noAmount" = "No Assets"; +"Wallet.addWallet" = "Import Wallet"; + +// Wallet QRCode +// --------------------------------------------------------- +"Wallet.QRCode.desc" = "Please do not deposit any digital assets other than ETH and CITA to above address"; +"Wallet.QRCode.copy" = "Copy"; +"Wallet.QRCode.copySuccess" = "Address is copied to clipboard"; + +// Transaction History +// --------------------------------------------------------- +"Transaction.History.title" = "Transaction List"; +"TokenProfile.Ether.overview" = "Ethereum is a decentralized platform that runs smart contracts: applications that run exactly as programmed without any possibility of downtime, censorship, fraud or third-party interference."; +"Transaction.History.testTokenWarning" = "The token has no value and is only used for developer testing."; +"Transaction.History.details" = "Details >>"; + +// Transaction Status +// --------------------------------------------------------- +"TransactionStatus.success" = "Confirmed Transaction"; +"TransactionStatus.pending" = "Pending Transaction"; +"TransactionStatus.failure" = "Failed Transaction"; + +// Transaction Details +// --------------------------------------------------------- +"Transaction.Details.title" = "Transaction Details"; +"Transaction.Details.paymentAddress" = "From"; +"Transaction.Details.receiptAddress" = "To"; +"Transaction.Details.hash" = "TxID"; +"Transaction.Details.chainNetwork" = "Network"; +"Transaction.Details.block" = "Block"; +"Transaction.Details.gasFee" = "Miner Fee"; +"Transaction.Details.blockchainBrowserDesc" = "Go to the Blockchain Explore for more details"; +"Transaction.Details.contractCreationPending" = "Contract Creating"; +"Transaction.Details.contractCreationSuccess" = "Contract Created"; +"Transaction.Details.contractCreationFailure" = "Contract Creation failed"; + +// Send Transaction +// --------------------------------------------------------- +"Transaction.Send.balanceNotSufficient" = "Insufficient %@ Balance for miner fee"; +"Transaction.Send.addressError" = "Incorrect address:The address is usually a 42-bit character starting with 0x"; +"Transaction.Send.title" = "%@ Transfer"; +"Transaction.Send.transactionAvailableBalance" = "The amount you entered exceeds your account balance, are all transferred out?"; +"Transaction.Send.gasPriceSettingIsTooLow" = "Gas Price too low, Please set above the Recommend Gas Price"; +"Transaction.Send.gasLimitSettingIsTooLow" = "The Gas Price you entered is too low, please enter a reasonable value."; +"Transaction.Send.quotaLimitSettingIsTooLow" = "The Gas Limit you entered is too low, please enter a reasonable value."; +"Transaction.Send.gasCostSetting" = "Advanced"; +"Transaction.Send.gasCost" = "Gas Price"; +"Transaction.Send.quotaCost" = "Quota Price"; +"Transaction.Send.extenData" = "Data"; +"Transaction.Send.gasCostSettingDesc" = "The data will be uploaded to the blockchain and your data security will be guaranteed"; +"Transaction.Send.input" = "Please Enter"; +"Transaction.Send.inputHexData" = "Hexadecimal Data"; +"Transaction.Send.txToken" = "Transfer Token"; +"Transaction.Send.txAmount" = "Amount To Send"; +"Transaction.Send.inputAmount" = "Input Amount"; +"Transaction.Send.receiptAddress" = "To"; +"Transaction.Send.gasFee" = "Miner Fee"; +"Transaction.Send.txInfo" = "Payment Details"; +"Transaction.Send.confirmSendTx" = "Confirm"; +"Transaction.Send.txTokens" = "Tokens"; + +// Authentication +// --------------------------------------------------------- +"Authentication.clickFaceIdAuth" = "Click to verify Face ID"; +"Authentication.clickTouchIdAuth" = "Click to verify Touch ID"; +"Authentication.authFaceIdTitle" = "Please authenticate Face ID"; +"Authentication.authTouchIdTitle" = "Please authenticate Touch ID"; +"Authentication.otherMode" = "Other"; + +"Authentication.selectWallet" = "Select Wallet"; +"Authentication.walletPassword" = "Wallet Password"; +"Authentication.walletPasswordError" = "Incorrect Password"; + +"Authentication.openFaceIdAuthDesc" = "Please turn on Face ID to keep your assets safe"; +"Authentication.openFaceIdAuth" = "Turn on Face ID"; +"Authentication.openTouchIdAuthDesc" = "Please turn on Touch ID to keep your assets safe"; +"Authentication.openTouchIdAuth" = "Turn on Touch ID"; +"Authentication.notOpen" = "Not open yet"; + +"Authentication.Error.touchIDNotEnrolled" = "Touch ID is not set"; +"Authentication.Error.faceIDNotEnrolled" = "Face ID is not set"; +"Authentication.Error.faceIDNotAvailable" = "You have not set up your Touch ID. Please input password."; +"Authentication.Error.biometryLockout" = "Multiple verification failures, Please try again later"; +"Authentication.Error.authFailed" = "Verification failed, please re-verify"; + +// Guide +// --------------------------------------------------------- +"Guide.createWallet" = "Create Wallet"; +"Guide.existingWallet" = "Import Wallet"; +"Guide.cytonServiceAgreement" = "Cyton service agreement"; +"Guide.agreementOfConsent" = "I have carefully read and agree to the above terms and conditions."; +"Guide.continue" = "Continue"; + +// Create Wallet +// --------------------------------------------------------- +"Wallet.Create.warning" = "Backup Password!"; +"Wallet.Create.desc" = "Cyton will not store your password, please backup diligently."; + +"Wallet.Create.createWallet" = "Create Wallet"; +"Wallet.Create.passwordWarning" = "Your password will be required when sending digital assets or accessing confidential information."; +"Wallet.Create.walletName" = "Wallet Name"; +"Wallet.Create.setPassword" = "Password"; +"Wallet.Create.rePassword" = "Repeat Password"; +"Wallet.Create.passwordDesc" = "At least 8 characters three types of uppercase and lowercase alphabets, numbers, and special symbols!"; +"Wallet.Create.passwordInconsistent" = "Password don't match"; + +"Wallet.Create.backupMnemonic" = "Your Mnemonic"; +"Wallet.Create.mnemonicWarnTitle" = "Mnemonic will allow you to recover access to your wallet if your phone is lost or stolen."; +"Wallet.Create.mnemonicWarn1" = "- Anyone who has the mnemonic can transfer the corresponding digital assets"; +"Wallet.Create.mnemonicWarn2" = "- Don't email them or screenshot them."; +"Wallet.Create.mnemonicWarn3" = "- Carefully write down these 12 words or save them in your password manager."; +"Wallet.Create.backCreateWalletAlert" = "The last step to start your blockchain account! Do you want to continue?"; + +"Wallet.Create.confirmMnemonic" = "Verify Mnemonic"; +"Wallet.Create.confirmMnemonicDesc" = "Please click on the mnemonic in order to confirm that your backup mnemonic is correct."; +"Wallet.Create.backupCompleted" = "Confirm"; +"Wallet.Create.walletCreation" = "Wallet creating..."; +"Wallet.Create.mnemonicValidationFailed" = "Import Failed"; +"Wallet.Create.createSuccess" = "Wallet Created"; + +// Import Wallet +// --------------------------------------------------------- +"Wallet.Import.title" = "Import Wallet"; +"Wallet.Import.keystore" = "Keystore"; +"Wallet.Import.mnemonic" = "Mnemonic"; +"Wallet.Import.privatekey" = "Private Key"; +"NoScreenshot.importWalletMessage" = "Keystore,Mnemonic,Private Key gives full and unlimited access to your wallet."; +"Wallet.Import.inputWalletName" = "Wallet Name"; +"Wallet.Import.import" = "Import"; +"Wallet.Import.loading" = "Wallet Importing..."; +"Wallet.Import.walletAlreadyExists" = "Wallet Address is existed"; +"Wallet.Import.success" = "Wallet Imported"; +"Wallet.Import.setPassword" = "Set Password"; +"Wallet.Import.repeatPassword" = "Repeat Password"; +"Wallet.Import.setPasswordDesc" = "At least 8 characters, three types of uppercase and lowercase alphabets, numbers, and special symbols!"; +"Wallet.Import.inconsistentPasswords" = "Password don't match"; + +"Wallet.Import.inputKeystoreWarning" = "Please enter Keystore"; +"Wallet.Import.inputKeystore" = "Please enter Keystore"; +"Wallet.Import.inputWalletPassword" = "Password"; +"Wallet.Import.emptyKeystorePassword" = "Empty Password"; + +"Wallet.Import.inputMnemonicWarning" = "Please enter your mnemonics in order."; +"Wallet.Import.inputMnemonic" = "Please separate each Mnemonic with a space."; + +"Wallet.Import.inputPrivatekeyWarning" = "Please enter Private Key or scan it by QR code"; +"Wallet.Import.inputPrivatekey" = "Please enter Private Key."; + +// Wallet Details +// --------------------------------------------------------- +"Wallet.Details.ChangePassword.inputPassword" = "Password"; +"Wallet.Details.ChangeName.inputName" = "Wallet Name"; +"Wallet.Details.title" = "Manager"; +"Wallet.Details.deleteWallet" = "Delete Wallet"; +"Wallet.Details.confirmDeleteWallet" = "Confirm"; +"Wallet.Details.importKeystore" = "Export keystore"; +"Wallet.Details.deleteWalletSuccess" = "Wallet Deleted"; +"Wallet.Details.icon" = "Wallet Photo"; +"Wallet.Details.name" = "Wallet Name"; +"Wallet.Details.address" = "Wallet Address"; +"Wallet.Details.changePassword" = "Change Password"; +"Wallet.Details.exportKeystore" = "Export keystore"; +"Wallet.Details.delete" = "Delete Wallet"; +"Wallet.Details.ChangePassword.inputPassword" = "Password"; +"Wallet.Details.ChangePassword.inputNewPassword" = "New Password"; +"Wallet.Details.ChangePassword.repeatNewPassword" = "Repeat New Password"; +"Wallet.Details.ChangePassword.warning" = "Cyton will not store your password, please backup diligently."; +"Wallet.Details.ChangePassword.newPasswordIsSameAsOld" = "The password you entered is the same as the current password. Please re-enter"; +"Wallet.Details.ChangePassword.inconsistentPasswords" = "Password don't match"; +"Wallet.Details.ChangePassword.loading" = "Changing Password"; +"Wallet.Details.ChangePassword.success" = "Password Changed"; +"Wallet.Details.ExportKeystore.copy" = "Copy"; +"Wallet.Details.ExportKeystore.copySuccess" = "Keystore is copied to clipbord"; +"Wallet.Details.WalletIconPicker.title" = "Wallet Photo"; + +// No Screenshot +// --------------------------------------------------------- +"NoScreenshot.title" = "No screenshot!"; +"NoScreenshot.mnemonicMessage" = "Keep your 12-word Mnemonic Phrase safe. Anyone who has it can transfer the corresponding digital assets."; + +// Settings +// --------------------------------------------------------- +"Settings.Title" = "Me"; +"Settings.CurrencyTitle" = "Local Currency"; +"Settings.TouchIdTitle" = "Touch ID"; +"Settings.ConnectUs" = "Contact"; +"Settings.Forum" = "Forum"; +"Settings.ConnectUs.CopyWechat" = "WeChat is copied to clipbord"; + +// Settings: About U +// --------------------------------------------------------- +"Settings.About.AboutUs" = "About us"; +"Settings.About.SourceCode" = "Source Code"; +"Settings.About.ServicePrivacy" = "Terms of Use"; +"Settings.About.InfuaDetail" = "Provide access to Ethereum APIs"; +"Settings.About.OpenSea" = "Provide access to ERC721 assets APIs"; +"Settings.About.PeckShield" = "Provide security audits"; +"Settings.About.Cita" = "Blockchain Core"; + +// Settings: Currency +// --------------------------------------------------------- +"Settings.Currency.Title" = "Local Currency"; + +// Settings: Switch ETH Network +// --------------------------------------------------------- +"Settings.SwitchNetwork.Title" = "Network"; + +// Assets +// --------------------------------------------------------- +"Assets.AddAssets.Title" = "Add"; +"Assets.AddAssets.BlockChainNetwork" = "Blockchain"; +"Assets.AddAssets.ContractAddress" = "Contract Address"; +"Assets.AddAssets.NodeAddress" = "Node Address"; +"Assets.AddAssets.ContractAddressPlaceHolder" = "Enter"; +"Assets.AddAssets.NodeAddressPlaceHolder" = "Enter"; +"Assets.AddAssets.Search" = "Search"; +"Assets.AddAssets.EmptyResult" = "Incorrect contract address"; +"Assets.AddAssets.CITANativeCoin" = "CITA Native Token"; +"Assets.AddAssets.SwitchChainNetWorkTitle" = "Blockchain"; +"Assets.AddAssets.AlreadyExist" = "You have the token in your list."; +"Assets.AddAssets.StoreFailed" = "Failed to add token"; +"Assets.AddAssets.EmptySymbol" = "The token has no name and cannot be imported successfully!"; +"Assets.AddAssets.StoreSuccess" = "Token Added"; +"Assets.AddAssets.ListSettings" = "Setting"; +"Assets.AddAssets.TokenMessage" = "Token info"; +"Assets.AddAssets.TokenName" = "Token Name"; +"Assets.AddAssets.TokenSymbol" = "Token Symbol"; +"Assets.AddAssets.TokenDecimals" = "Decimal"; + +// Assets List Setting +"Assets.AssetSetting.Title" = "Setting"; +"Assets.AssetSetting.Complete" = "Done"; +"Assets.AssetSetting.Edit" = "Edit"; + +// Switch Wallet +"SwitchWallet.title" = "Switch Wallet"; diff --git a/Cyton/zh-Hans.lproj/Localizable.strings b/Cyton/zh-Hans.lproj/Localizable.strings new file mode 100644 index 00000000..3c84c793 --- /dev/null +++ b/Cyton/zh-Hans.lproj/Localizable.strings @@ -0,0 +1,363 @@ +/* + Localizable.strings + Cyton + + Created by James Chen on 2018/11/03. + Copyright © 2018 Cryptape. All rights reserved. +*/ + +// Common +// --------------------------------------------------------- +"Common.Connection.UserCancel" = "用户取消"; +"Common.Connection.ScanEmpty" = "扫描结果为空"; +"Common.Connection.LoseConnect" = "似乎已断开与互联网的连接"; +"Common.Connection.LoadFaild" = "页面加载失败"; +"Common.Connection.Refresh" = "刷新"; +"Common.DataEmpty" = "空空如也"; +"Common.NetworkError" = "网络错误,请稍后再试"; +"Common.next" = "下一步"; +"Common.confirm" = "确定"; +"Common.cancel" = "取消"; +"Common.reject" = "拒绝"; + +// DApp +// --------------------------------------------------------- +"DApp.Home" = "应用"; +"DApp.Search.TextFieldPlaceholder" = "请输入应用网址"; +"DApp.Search.DeleteHistory" = "删除"; + +// DApp Browser +// --------------------------------------------------------- +"DApp.Browser.InvalidLink" = "无效的链接地址"; +"DApp.Browser.Collection" = "收藏"; +"DApp.Browser.CollectSuccess" = "收藏成功"; +"DApp.Browser.CollectFaild" = "收藏失败"; +"DApp.Browser.AlertTitle" = "提示"; +"DApp.Browser.CheckNoAliPay" = "未检测到支付宝客户端,请安装后重试。"; +"DApp.Browser.CheckNoWeChat" = "未检测到微信客户端,请安装后重试。"; +"DApp.Browser.SignFaild" = "签名失败"; +"DApp.Browser.PayFaild" = "支付失败"; +"DApp.Browser.confirmSign" = "DApp签名信息确认"; +"DApp.Browser.MonitorDirectionFailed" = "监听设备方向失败"; +"DApp.Browser.MonitorGyroFailed" = "监听陀螺仪数据失败"; + +// DApp Contract +// --------------------------------------------------------- +"DApp.Contract.TransactionSend" = "交易已发送"; +"DApp.Contract.Title" = "交易详情"; + +// DApp Advanced +// --------------------------------------------------------- +"DApp.Advanced.ETHRecommend" = "以太坊推荐 "; +"DApp.Advanced.Gas" = "Gas费用"; +"DApp.Advanced.EmptyGasPrice" = "请输入GasPrice"; +"DApp.Advanced.MinGasPrice" = "请输入的GasPrice不小于%@ GWei"; + +// DApp DAppTakePhoto +// --------------------------------------------------------- +"DApp.DAppTakePhoto.CameraPermissions" = "拍照需要相机访问权限"; +"DApp.DAppTakePhoto.Open" = "开启"; +"DApp.DAppTakePhoto.NoAccess" = "无相机访问权限"; + +// DApp MyDApp +// --------------------------------------------------------- +"DApp.MyDApp.Title" = "我的ÐApp"; + +// DApp NFT +// --------------------------------------------------------- +"DApp.NFT.EmptyData" = "您还没有藏品数据"; +"DApp.NFT.Title" = "我的藏品"; +"DApp.NFT.DetailTitle" = "藏品详情"; + +// DApp Transaction +// --------------------------------------------------------- +"DApp.SendTransactionError.emptyValue" = "Transaction's value format error"; +"DApp.SendTransactionError.emptyQuota" = "Transaction's quota format error"; +"DApp.SendTransactionError.emptyGasLimit" = "Transaction's gas limit format error"; +"DApp.SendTransactionError.emptyGasPrice" = "Transaction's gas price format error"; + +// Mnemonic Validator +// --------------------------------------------------------- +"MnemonicValidator.emptyMnemonic" = "助记词不能为空"; +"MnemonicValidator.invalidMnemonic" = "助记词不正确"; + +// Wallet Manager Errors +// --------------------------------------------------------- +"WalletManager.Error.invalidPassword" = "密码不正确"; +"WalletManager.Error.invalidPrivateKey" = "私钥不正确"; +"WalletManager.Error.invalidKeystore" = "Keystore不正确"; +"WalletManager.Error.invalidMnemonic" = "助记词不正确"; +"WalletManager.Error.emptyMnemonic" = "助记词不能为空"; +"WalletManager.Error.accountAlreadyExists" = "该钱包已存在"; +"WalletManager.Error.accountNotFound" = "未找到该钱包"; +"WalletManager.Error.failedToDeleteAccount" = "删除钱包失败"; +"WalletManager.Error.failedToUpdatePassword" = "修改密码失败"; +"WalletManager.Error.failedToSaveKeystore" = "保存keystore失败"; +"WalletManager.Error.unknown" = "未知错误"; + +// Send Transactoin Error +// --------------------------------------------------------- +"SendTransactionError.invalidSourceAddress" = "发送地址不正确"; +"SendTransactionError.invalidDestinationAddress" = "接收地址不正确"; +"SendTransactionError.invalidContractAddress" = "合约地址不正确"; +"SendTransactionError.noAvailableKeys" = "未找到该钱包"; +"SendTransactionError.createTransactionIssue" = "创建交易失败"; +"SendTransactionError.invalidChainId" = "Chain ID不正确"; +"SendTransactionError.signTXFailed" = "交易签名失败"; + +// Custom Token Error +// --------------------------------------------------------- +"CustomTokenError.wrongBalanceError" = "余额不正确"; +"CustomTokenError.badNameError" = "Token名称不正确"; +"CustomTokenError.badSymbolError" = "Token symbol不正确"; +"CustomTokenError.undefinedError" = "未知错误"; + +// Sign Message Error +// --------------------------------------------------------- +"MessageSign.Error.walletNotFound" = "未找到该钱包"; +"MessageSign.Error.signMessageFailed" = "签名失败"; + +// Wallet +// --------------------------------------------------------- +"Wallet" = "钱包"; +"Wallet.token" = "代币"; +"Wallet.addToken" = "添加资产"; +"Wallet.transaction" = "转账"; +"Wallet.receipt" = "收款"; +"Wallet.totalAmount" = "总资产"; +"Wallet.noAmount" = "暂无资产"; +"Wallet.addWallet" = "添加钱包"; + +// Wallet QRCode +// --------------------------------------------------------- +"Wallet.QRCode.desc" = "此地址只接收CITA、以太坊Token,发送其他币种到此地址将不可找回"; +"Wallet.QRCode.copy" = "复制"; +"Wallet.QRCode.copySuccess" = "地址已经复制到粘贴板"; + +// Transaction History +// --------------------------------------------------------- +"Transaction.History.title" = "交易列表"; +"TokenProfile.Ether.overview" = "Ethereum是一个运行智能合约的去中心化平台,应用将完全按照程序运作,不存在任何欺诈,审查与第三方干预的可能。"; +"Transaction.History.testTokenWarning" = "该token无任何价值,仅做开发者测试使用"; +"Transaction.History.details" = "详情 >>"; + +// Transaction Status +// --------------------------------------------------------- +"TransactionStatus.success" = "交易成功"; +"TransactionStatus.pending" = "交易进行中"; +"TransactionStatus.failure" = "交易失败"; + +// Transaction Details +// --------------------------------------------------------- +"Transaction.Details.title" = "交易详情"; +"Transaction.Details.paymentAddress" = "付款地址"; +"Transaction.Details.receiptAddress" = "收款地址"; +"Transaction.Details.hash" = "交易流水号"; +"Transaction.Details.chainNetwork" = "区块链网络"; +"Transaction.Details.block" = "区块"; +"Transaction.Details.gasFee" = "矿工费用"; +"Transaction.Details.blockchainBrowserDesc" = "到区块链浏览器查看更多"; +"Transaction.Details.contractCreationPending" = "合约创建中"; +"Transaction.Details.contractCreationSuccess" = "合约创建成功"; +"Transaction.Details.contractCreationFailure" = "合约创建失败"; + +// Send Transaction +// --------------------------------------------------------- +"Transaction.Send.balanceNotSufficient" = "请确保账户剩余%@高于矿工费用,以便顺利完成转账~"; +"Transaction.Send.addressError" = "您的地址错误,请重新输入"; +"Transaction.Send.title" = "%@转账"; +"Transaction.Send.transactionAvailableBalance" = "您输入的金额超过您的余额,是否全部转出?"; +"Transaction.Send.gasPriceSettingIsTooLow" = "您的GasPrice设置过低,建议输入推荐值以快速转账"; +"Transaction.Send.gasLimitSettingIsTooLow" = "您输入的Gas Limit过低,请输入合理的数值"; +"Transaction.Send.quotaLimitSettingIsTooLow" = "您输入的Quota Limit过低,请输入合理的数值"; +"Transaction.Send.gasCostSetting" = "高级设置"; +"Transaction.Send.gasCost" = "Gas 费用"; +"Transaction.Send.quotaCost" = "Quota 费用"; +"Transaction.Send.extenData" = "包含数据"; +"Transaction.Send.gasCostSettingDesc" = "数据将上传至区块链,您的数据安全将得到一百分保障!"; +"Transaction.Send.input" = "请输入"; +"Transaction.Send.inputHexData" = "请输入十六进制数据"; +"Transaction.Send.txToken" = "转账币种"; +"Transaction.Send.txAmount" = "转账金额"; +"Transaction.Send.inputAmount" = "输入金额"; +"Transaction.Send.receiptAddress" = "收款地址"; +"Transaction.Send.gasFee" = "矿工费用"; +"Transaction.Send.txInfo" = "转账信息"; +"Transaction.Send.confirmSendTx" = "确认转账"; +"Transaction.Send.txTokens" = "转账币种"; + +// Authentication +// --------------------------------------------------------- +"Authentication.clickFaceIdAuth" = "点击进行验证 Face ID"; +"Authentication.clickTouchIdAuth" = "点击进行验证 Touch ID"; +"Authentication.authFaceIdTitle" = "请验证 Face ID"; +"Authentication.authTouchIdTitle" = "请验证 Touch ID"; +"Authentication.otherMode" = "其它验证方式"; + +"Authentication.selectWallet" = "选择钱包"; +"Authentication.walletPassword" = "钱包密码"; +"Authentication.walletPasswordError" = "密码不正确请重新输入"; + +"Authentication.openFaceIdAuthDesc" = "请开启刷脸验证,确保您的资产安全"; +"Authentication.openFaceIdAuth" = "开启刷脸验证"; +"Authentication.openTouchIdAuthDesc" = "请开启指纹验证,确保您的资产安全"; +"Authentication.openTouchIdAuth" = "开启指纹验证"; +"Authentication.notOpen" = "暂不开启"; + +"Authentication.Error.touchIDNotEnrolled" = "未设置 Touch ID"; +"Authentication.Error.faceIDNotEnrolled" = "未设置 Face ID"; +"Authentication.Error.faceIDNotAvailable" = "您的Face ID未开启,请输入密码登陆"; +"Authentication.Error.biometryLockout" = "多次验证失败被锁定"; +"Authentication.Error.authFailed" = "验证失败,请重新验证"; + +// Guide +// --------------------------------------------------------- +"Guide.createWallet" = "创建钱包"; +"Guide.existingWallet" = "已有钱包"; +"Guide.cytonServiceAgreement" = "Cyton服务协议"; +"Guide.agreementOfConsent" = "我以仔细阅读并同意以上条款"; +"Guide.continue" = "继续"; + +// Create Wallet +// --------------------------------------------------------- +"Wallet.Create.warning" = "没有「找回密码」!"; +"Wallet.Create.desc" = "您的钱包不会被保存在云端,无法提供找回服务,请您谨慎保管。"; + +"Wallet.Create.createWallet" = "创建钱包"; +"Wallet.Create.passwordWarning" = "此密码将被用于保护私钥和交易授权"; +"Wallet.Create.walletName" = "钱包名称"; +"Wallet.Create.setPassword" = "设定密码"; +"Wallet.Create.rePassword" = "重复密码"; +"Wallet.Create.passwordDesc" = "密码包含大写字母、小写字母、数字、特殊符号中的至少三类,且长度在8位以上。"; +"Wallet.Create.passwordInconsistent" = "两次密码不一致"; + +"Wallet.Create.backupMnemonic" = "备份助记词"; +"Wallet.Create.mnemonicWarnTitle" = "助记词将被用来恢复钱包或重置钱包密码"; +"Wallet.Create.mnemonicWarn1" = "- 如您的助记词被他人获取,您的财产可能受到损失"; +"Wallet.Create.mnemonicWarn2" = "- 不要截图或传送给他人"; +"Wallet.Create.mnemonicWarn3" = "- 推荐抄写并放在安全的地方"; +"Wallet.Create.backCreateWalletAlert" = "距离开启您的安全区块链账户还差最后一步,是否继续"; + +"Wallet.Create.confirmMnemonic" = "确认助记词"; +"Wallet.Create.confirmMnemonicDesc" = "请按顺序点击助记词,以确认你的备份助记词正确"; +"Wallet.Create.backupCompleted" = "完成备份"; +"Wallet.Create.walletCreation" = "钱包创建中..."; +"Wallet.Create.mnemonicValidationFailed" = "助记词验证失败"; +"Wallet.Create.createSuccess" = "创建成功"; + +// Import Wallet +// --------------------------------------------------------- +"Wallet.Import.title" = "导入钱包"; +"Wallet.Import.keystore" = "Keystore"; +"Wallet.Import.mnemonic" = "助记词"; +"Wallet.Import.privatekey" = "私钥"; +"NoScreenshot.importWalletMessage" = "keystore,助记词,私钥是打开您钱包的关键要素,请妥善保管!"; +"Wallet.Import.inputWalletName" = "输入钱包名称"; +"Wallet.Import.import" = "开始导入"; +"Wallet.Import.loading" = "导入钱包中"; +"Wallet.Import.walletAlreadyExists" = "已存在该钱包"; +"Wallet.Import.success" = "导入成功"; +"Wallet.Import.setPassword" = "设置密码"; +"Wallet.Import.repeatPassword" = "重复密码"; +"Wallet.Import.setPasswordDesc" = "密码包含大写字母、小写字母、数字、特殊符号的至少三类,且长度在8位以上!"; +"Wallet.Import.inconsistentPasswords" = "两次密码输入不一致"; + +"Wallet.Import.inputKeystoreWarning" = "粘贴以太坊Keystore内容至输入框,或通过扫描二维码输入。"; +"Wallet.Import.inputKeystore" = "请导入Keystore文本"; +"Wallet.Import.inputWalletPassword" = "输入密码"; +"Wallet.Import.emptyKeystorePassword" = "解锁密码不能为空"; + +"Wallet.Import.inputMnemonicWarning" = "请按顺序输入您的助记词。"; +"Wallet.Import.inputMnemonic" = "请按顺序输入您的助记词,按空格分隔"; + +"Wallet.Import.inputPrivatekeyWarning" = "请输入您的私钥,或通过二维码扫描输入。"; +"Wallet.Import.inputPrivatekey" = "请输入私钥原文"; + +// Wallet Details +// --------------------------------------------------------- +"Wallet.Details.ChangePassword.inputPassword" = "请输入钱包密码"; +"Wallet.Details.ChangeName.inputName" = "请输入钱包名称"; +"Wallet.Details.title" = "钱包管理"; +"Wallet.Details.deleteWallet" = "删除钱包"; +"Wallet.Details.confirmDeleteWallet" = "确认删除"; +"Wallet.Details.importKeystore" = "导出Keystore"; +"Wallet.Details.deleteWalletSuccess" = "删除成功"; +"Wallet.Details.icon" = "钱包头像"; +"Wallet.Details.name" = "钱包名称"; +"Wallet.Details.address" = "钱包地址"; +"Wallet.Details.changePassword" = "修改密码"; +"Wallet.Details.exportKeystore" = "导出Keystore"; +"Wallet.Details.delete" = "删除当前钱包"; +"Wallet.Details.ChangePassword.inputPassword" = "输入密码"; +"Wallet.Details.ChangePassword.inputNewPassword" = "输入新密码"; +"Wallet.Details.ChangePassword.repeatNewPassword" = "再次输入新密码"; +"Wallet.Details.ChangePassword.warning" = "钱包密码如丢失将无法找回,请您妥善保管密码"; +"Wallet.Details.ChangePassword.newPasswordIsSameAsOld" = "您输入的密码和原密码一致,请重新输入"; +"Wallet.Details.ChangePassword.inconsistentPasswords" = "两次新密码输入不一致"; +"Wallet.Details.ChangePassword.loading" = "修改密码中..."; +"Wallet.Details.ChangePassword.success" = "密码修改成功,请牢记!"; +"Wallet.Details.ExportKeystore.copy" = "复制"; +"Wallet.Details.ExportKeystore.copySuccess" = "Keystore已经复制到粘贴板"; +"Wallet.Details.WalletIconPicker.title" = "选择头像"; + +// No Screenshot +// --------------------------------------------------------- +"NoScreenshot.title" = "禁止截屏!"; +"NoScreenshot.mnemonicMessage" = "拥有助记词就能完全控制该地址下的资产,建议抄写并放在安全的地方!"; + +// Setting +// --------------------------------------------------------- +"Settings.Title" = "我"; +"Settings.CurrencyTitle" = "本地货币"; +"Settings.TouchIdTitle" = "指纹设置"; +"Settings.ConnectUs" = "联系我们"; +"Settings.Forum" = "论坛"; +"Settings.ConnectUs.CopyWechat" = "客服微信已复制"; + +// Settings: About U +// --------------------------------------------------------- +"Settings.About.AboutUs" = "About Us"; +"Settings.About.SourceCode" = "源代码"; +"Settings.About.ServicePrivacy" = "服务及隐私条款"; +"Settings.About.InfuaDetail" = "提供以太坊访问服务"; +"Settings.About.OpenSea" = "提供721数据服务"; +"Settings.About.PeckShield" = "提供代码安全审计服务"; +"Settings.About.Cita" = "区块链内核"; + +// Settings: Currency +// --------------------------------------------------------- +"Settings.Currency.Title" = "默认货币单位"; + +// Settings: Switch ETH Network +// --------------------------------------------------------- +"Settings.SwitchNetwork.Title" = "切换以太坊网络"; + +// Assets +// --------------------------------------------------------- +"Assets.AddAssets.Title" = "添加资产"; +"Assets.AddAssets.BlockChainNetwork" = "区块链网络"; +"Assets.AddAssets.ContractAddress" = "合约地址"; +"Assets.AddAssets.NodeAddress" = "节点地址"; +"Assets.AddAssets.ContractAddressPlaceHolder" = "请输入代币合约地址"; +"Assets.AddAssets.NodeAddressPlaceHolder" = "请输入节点地址"; +"Assets.AddAssets.Search" = "查询"; +"Assets.AddAssets.TokenMessage" = "代币信息"; +"Assets.AddAssets.CITANativeCoin" = "CITA 原生代币"; +"Assets.AddAssets.EmptyResult" = "请输入正确的合约地址"; +"Assets.AddAssets.EmptySymbol" = "您的代币没有名称,无法成功导入!"; +"Assets.AddAssets.AlreadyExist" = "您的列表已有该代币"; +"Assets.AddAssets.StoreFailed" = "代币添加失败"; +"Assets.AddAssets.StoreSuccess" = "代币添加成功"; +"Assets.AddAssets.SwitchChainNetWorkTitle" = "请选择区块链网络"; +"Assets.AddAssets.ListSettings" = "列表设置"; +"Assets.AddAssets.TokenName" = "代币名称"; +"Assets.AddAssets.TokenSymbol" = "代币缩写"; +"Assets.AddAssets.TokenDecimals" = "小数位数"; + +// Assets List Setting +"Assets.AssetSetting.Title" = "列表设置"; +"Assets.AssetSetting.Complete" = "完成"; +"Assets.AssetSetting.Edit" = "编辑"; + +// Switch Wallet +"SwitchWallet.title" = "切换钱包"; diff --git a/NeuronTests/NeuronTests.swift b/CytonTests/CytonTests.swift similarity index 55% rename from NeuronTests/NeuronTests.swift rename to CytonTests/CytonTests.swift index af1cb3e6..da6667c7 100644 --- a/NeuronTests/NeuronTests.swift +++ b/CytonTests/CytonTests.swift @@ -1,13 +1,13 @@ // -// NeuronTests.swift -// NeuronTests +// CytonTests.swift +// CytonTests // // Created by XiaoLu on 2018/5/18. // Copyright © 2018年 cryptape. All rights reserved. // import XCTest -@testable import Neuron +@testable import Cyton -class NeuronTests: XCTestCase { +class CytonTests: XCTestCase { } diff --git a/NeuronTests/Extensions/Foundation/BigUIntExtensionTests.swift b/CytonTests/Extensions/Foundation/BigUIntExtensionTests.swift similarity index 60% rename from NeuronTests/Extensions/Foundation/BigUIntExtensionTests.swift rename to CytonTests/Extensions/Foundation/BigUIntExtensionTests.swift index 1daf46d5..afbe31a6 100644 --- a/NeuronTests/Extensions/Foundation/BigUIntExtensionTests.swift +++ b/CytonTests/Extensions/Foundation/BigUIntExtensionTests.swift @@ -1,6 +1,6 @@ // // BigUIntExtensionTests.swift -// NeuronTests +// CytonTests // // Created by James Chen on 2018/11/14. // Copyright © 2018 Cryptape. All rights reserved. @@ -8,7 +8,7 @@ import XCTest import BigInt -@testable import Neuron +@testable import Cyton class BigUIntExtensionTests: XCTestCase { func testToWei() { @@ -92,15 +92,31 @@ class BigUIntExtensionTests: XCTestCase { ) } - func testWeiToGwei() { - XCTAssertEqual( - 20.5, - BigUInt("20500000000")!.weiToGwei() - ) - } - func testStringToBigUInt() { XCTAssertEqual(BigUInt(string: "96016"), 96016) XCTAssertEqual(BigUInt(string: "0x96016"), 614422) } + + func testAmountTextToBigUInt() { + XCTAssertEqual(BigUInt.parseToBigUInt("1.23", 4), 12_300) + XCTAssertEqual(BigUInt.parseToBigUInt("0.00045", 18), 450_000_000_000_000) + XCTAssertEqual(BigUInt.parseToBigUInt("1.23", 2), 123) + XCTAssertEqual(BigUInt.parseToBigUInt("1.2344", 2), 123) + XCTAssertEqual(BigUInt.parseToBigUInt("1.003", 2), 100) + } + + func testBigUIntToAmountText() { + XCTAssertEqual(BigUInt.parseToBigUInt("0.00032", 18).toDecimalNumber(18).formatterToString(18), "0.00032") + XCTAssertEqual(BigUInt.parseToBigUInt("0.000000089999", 18).toDecimalNumber(18).formatterToString(18), "0.000000089999") + XCTAssertEqual(BigUInt.parseToBigUInt("0.000000089999", 18).toAmountText(18), "0.00000008") + XCTAssertEqual(BigUInt.parseToBigUInt("0.00000000000234", 18).toAmountText(18), "2.34e-12") + XCTAssertEqual(BigUInt.parseToBigUInt("104.0040023089999", 18).toAmountText(18), "104.0040023") + } + + func testBigUIntToDouble() { + XCTAssertEqual(BigUInt.parseToBigUInt("0.00032", 18).toDouble(18), 0.00032) + XCTAssertEqual(BigUInt.parseToBigUInt("0.000000089999", 18).toDouble(18), 0.000000089999) + XCTAssertEqual(BigUInt.parseToBigUInt("2435.000000089999", 18).toDouble(18), 2435.000000089999) + XCTAssertEqual(BigUInt.parseToBigUInt("2435.1234", 18).toDouble(18), 2435.1234) + } } diff --git a/CytonTests/Extensions/Foundation/DoubleExtensionTests.swift b/CytonTests/Extensions/Foundation/DoubleExtensionTests.swift new file mode 100644 index 00000000..2e938311 --- /dev/null +++ b/CytonTests/Extensions/Foundation/DoubleExtensionTests.swift @@ -0,0 +1,19 @@ +// +// DoubleExtensionTests.swift +// CytonTests +// +// Created by 晨风 on 2018/11/8. +// Copyright © 2018 Cryptape. All rights reserved. +// + +import XCTest +import BigInt +@testable import Cyton + +class DoubleExtensionTests: XCTestCase { + func testClean() { + XCTAssertEqual(0.001000.trailingZerosTrimmed, "0.001") + XCTAssertEqual(2233.001000.trailingZerosTrimmed, "2233.001") + XCTAssertEqual(2233.0010010.trailingZerosTrimmed, "2233.001001") + } +} diff --git a/NeuronTests/Extensions/Foundation/UIntExtensionTests.swift b/CytonTests/Extensions/Foundation/UIntExtensionTests.swift similarity index 91% rename from NeuronTests/Extensions/Foundation/UIntExtensionTests.swift rename to CytonTests/Extensions/Foundation/UIntExtensionTests.swift index 6c35c353..f3ea005d 100644 --- a/NeuronTests/Extensions/Foundation/UIntExtensionTests.swift +++ b/CytonTests/Extensions/Foundation/UIntExtensionTests.swift @@ -1,13 +1,13 @@ // // UIntExtensionTests.swift -// NeuronTests +// CytonTests // // Created by 晨风 on 2018/10/24. // Copyright © 2018 Cryptape. All rights reserved. // import XCTest -@testable import Neuron +@testable import Cyton class UIntExtensionTests: XCTestCase { func testFromHex() { diff --git a/NeuronTests/Extensions/UIKit/UIStoryboardExtensionTests.swift b/CytonTests/Extensions/UIKit/UIStoryboardExtensionTests.swift similarity index 92% rename from NeuronTests/Extensions/UIKit/UIStoryboardExtensionTests.swift rename to CytonTests/Extensions/UIKit/UIStoryboardExtensionTests.swift index 0bdd3b37..e0b2070c 100644 --- a/NeuronTests/Extensions/UIKit/UIStoryboardExtensionTests.swift +++ b/CytonTests/Extensions/UIKit/UIStoryboardExtensionTests.swift @@ -1,13 +1,13 @@ // // UIStoryboardExtensionTests.swift -// NeuronTests +// CytonTests // // Created by James Chen on 2018/10/12. // Copyright © 2018 Cryptape. All rights reserved. // import XCTest -@testable import Neuron +@testable import Cyton class UIStoryboardExtensionTests: XCTestCase { func testCapitalized() { diff --git a/NeuronTests/Info.plist b/CytonTests/Info.plist similarity index 100% rename from NeuronTests/Info.plist rename to CytonTests/Info.plist diff --git a/NeuronTests/Service/WalletManager/WalletManagerTests.swift b/CytonTests/Service/WalletManager/WalletManagerTests.swift similarity index 99% rename from NeuronTests/Service/WalletManager/WalletManagerTests.swift rename to CytonTests/Service/WalletManager/WalletManagerTests.swift index b63e6bb9..e3dcbe7b 100644 --- a/NeuronTests/Service/WalletManager/WalletManagerTests.swift +++ b/CytonTests/Service/WalletManager/WalletManagerTests.swift @@ -1,13 +1,13 @@ // // WalletManagerTests.swift -// NeuronTests +// CytonTests // // Created by James Chen on 2018/10/19. // Copyright © 2018 Cryptape. All rights reserved. // import XCTest -@testable import Neuron +@testable import Cyton class WalletManagerTests: XCTestCase { let keyDirectory = FileManager.default.temporaryDirectory.appendingPathComponent("KeystoreTests") diff --git a/NeuronTests/Utils/GasCalculatorTests.swift b/CytonTests/Utils/GasCalculatorTests.swift similarity index 97% rename from NeuronTests/Utils/GasCalculatorTests.swift rename to CytonTests/Utils/GasCalculatorTests.swift index 03ee45d5..6d335843 100644 --- a/NeuronTests/Utils/GasCalculatorTests.swift +++ b/CytonTests/Utils/GasCalculatorTests.swift @@ -1,6 +1,6 @@ // // GasCalculatorTests.swift -// NeuronTests +// CytonTests // // Created by James Chen on 2018/11/07. // Copyright © 2018 Cryptape. All rights reserved. @@ -8,7 +8,7 @@ import XCTest import BigInt -@testable import Neuron +@testable import Cyton class GasCalculatorTests: XCTestCase { let doubleAccuracy = 0.0000001 diff --git a/NeuronTests/Utils/Validators/MnemonicValidatorTests.swift b/CytonTests/Utils/Validators/MnemonicValidatorTests.swift similarity index 98% rename from NeuronTests/Utils/Validators/MnemonicValidatorTests.swift rename to CytonTests/Utils/Validators/MnemonicValidatorTests.swift index 5aa2ea4f..def29b44 100644 --- a/NeuronTests/Utils/Validators/MnemonicValidatorTests.swift +++ b/CytonTests/Utils/Validators/MnemonicValidatorTests.swift @@ -1,13 +1,13 @@ // // MnemonicValidatorTests.swift -// NeuronTests +// CytonTests // // Created by XiaoLu on 2018/11/28. // Copyright © 2018 Cryptape. All rights reserved. // import XCTest -@testable import Neuron +@testable import Cyton class MnemonicValidatorTests: XCTestCase { func testEmptyMnemonic() { diff --git a/NeuronTests/Utils/Validators/PasswordValidatorTests.swift b/CytonTests/Utils/Validators/PasswordValidatorTests.swift similarity index 97% rename from NeuronTests/Utils/Validators/PasswordValidatorTests.swift rename to CytonTests/Utils/Validators/PasswordValidatorTests.swift index 85690c8d..3994c11e 100644 --- a/NeuronTests/Utils/Validators/PasswordValidatorTests.swift +++ b/CytonTests/Utils/Validators/PasswordValidatorTests.swift @@ -1,13 +1,13 @@ // // PasswordValidatorTests.swift -// NeuronTests +// CytonTests // // Created by James Chen on 2018/10/13. // Copyright © 2018 Cryptape. All rights reserved. // import XCTest -@testable import Neuron +@testable import Cyton class PasswordValidatorTests: XCTestCase { func testEmptyPassword() { diff --git a/NeuronTests/Utils/Validators/WalletNameValidatorTests.swift b/CytonTests/Utils/Validators/WalletNameValidatorTests.swift similarity index 95% rename from NeuronTests/Utils/Validators/WalletNameValidatorTests.swift rename to CytonTests/Utils/Validators/WalletNameValidatorTests.swift index 81860c32..2bb63e31 100644 --- a/NeuronTests/Utils/Validators/WalletNameValidatorTests.swift +++ b/CytonTests/Utils/Validators/WalletNameValidatorTests.swift @@ -1,6 +1,6 @@ // // WalletNameValidatorTests.swift -// NeuronTests +// CytonTests // // Created by XiaoLu on 2018/10/14. // Copyright © 2018 Cryptape. All rights reserved. @@ -8,7 +8,7 @@ import XCTest import RealmSwift -@testable import Neuron +@testable import Cyton class WalletNameValidatorTests: XCTestCase { func testEmptyWalletName() { @@ -34,7 +34,6 @@ class WalletNameValidatorTests: XCTestCase { let walletModel = WalletModel() walletModel.name = "ETH Wallet" walletModel.address = "0x6782CdeF6A4A056d412775EE6081d32B2bf90287" - walletModel.iconData = Data() let existence = appModel.wallets.contains(where: {$0.address == walletModel.address}) let realm = try! Realm() try! realm.write { diff --git a/NeuronUITests/NeuronUITests.swift b/CytonUITests/CytonUITests.swift similarity index 61% rename from NeuronUITests/NeuronUITests.swift rename to CytonUITests/CytonUITests.swift index 7d15d241..7df519a9 100644 --- a/NeuronUITests/NeuronUITests.swift +++ b/CytonUITests/CytonUITests.swift @@ -1,6 +1,6 @@ // -// NeuronUITests.swift -// NeuronUITests +// CytonUITests.swift +// CytonUITests // // Created by XiaoLu on 2018/5/18. // Copyright © 2018年 cryptape. All rights reserved. @@ -8,5 +8,5 @@ import XCTest -class NeuronUITests: XCTestCase { +class CytonUITests: XCTestCase { } diff --git a/NeuronUITests/Info.plist b/CytonUITests/Info.plist similarity index 100% rename from NeuronUITests/Info.plist rename to CytonUITests/Info.plist diff --git "a/Neuron/Assets.xcassets/Guide/guide_1.imageset/\351\241\265\351\235\2421.png" "b/Neuron/Assets.xcassets/Guide/guide_1.imageset/\351\241\265\351\235\2421.png" deleted file mode 100644 index a0c0ffce..00000000 Binary files "a/Neuron/Assets.xcassets/Guide/guide_1.imageset/\351\241\265\351\235\2421.png" and /dev/null differ diff --git "a/Neuron/Assets.xcassets/Guide/guide_2.imageset/\351\241\265\351\235\2422.png" "b/Neuron/Assets.xcassets/Guide/guide_2.imageset/\351\241\265\351\235\2422.png" deleted file mode 100644 index 545627a6..00000000 Binary files "a/Neuron/Assets.xcassets/Guide/guide_2.imageset/\351\241\265\351\235\2422.png" and /dev/null differ diff --git "a/Neuron/Assets.xcassets/Guide/guide_3.imageset/\351\241\265\351\235\2423.png" "b/Neuron/Assets.xcassets/Guide/guide_3.imageset/\351\241\265\351\235\2423.png" deleted file mode 100644 index c672db3a..00000000 Binary files "a/Neuron/Assets.xcassets/Guide/guide_3.imageset/\351\241\265\351\235\2423.png" and /dev/null differ diff --git a/Neuron/Assets.xcassets/Launch Screen/launch_icon.imageset/launchIcon@2x.png b/Neuron/Assets.xcassets/Launch Screen/launch_icon.imageset/launchIcon@2x.png deleted file mode 100644 index af18ed91..00000000 Binary files a/Neuron/Assets.xcassets/Launch Screen/launch_icon.imageset/launchIcon@2x.png and /dev/null differ diff --git a/Neuron/Assets.xcassets/Launch Screen/launch_icon.imageset/launchIcon@3x.png b/Neuron/Assets.xcassets/Launch Screen/launch_icon.imageset/launchIcon@3x.png deleted file mode 100644 index d80ba233..00000000 Binary files a/Neuron/Assets.xcassets/Launch Screen/launch_icon.imageset/launchIcon@3x.png and /dev/null differ diff --git a/Neuron/Assets.xcassets/Launch Screen/nervos_launch.imageset/Contents.json b/Neuron/Assets.xcassets/Launch Screen/nervos_launch.imageset/Contents.json deleted file mode 100644 index ca9a88c8..00000000 --- a/Neuron/Assets.xcassets/Launch Screen/nervos_launch.imageset/Contents.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "nervos_launch@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "filename" : "nervos_launch@3x.png", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/Neuron/Assets.xcassets/Launch Screen/nervos_launch.imageset/nervos_launch@2x.png b/Neuron/Assets.xcassets/Launch Screen/nervos_launch.imageset/nervos_launch@2x.png deleted file mode 100644 index 491a64be..00000000 Binary files a/Neuron/Assets.xcassets/Launch Screen/nervos_launch.imageset/nervos_launch@2x.png and /dev/null differ diff --git a/Neuron/Assets.xcassets/Launch Screen/nervos_launch.imageset/nervos_launch@3x.png b/Neuron/Assets.xcassets/Launch Screen/nervos_launch.imageset/nervos_launch@3x.png deleted file mode 100644 index 186bddf6..00000000 Binary files a/Neuron/Assets.xcassets/Launch Screen/nervos_launch.imageset/nervos_launch@3x.png and /dev/null differ diff --git a/Neuron/Assets.xcassets/Launch Screen/peckshield_launch.imageset/Group@1x.png b/Neuron/Assets.xcassets/Launch Screen/peckshield_launch.imageset/Group@1x.png deleted file mode 100644 index ed75f600..00000000 Binary files a/Neuron/Assets.xcassets/Launch Screen/peckshield_launch.imageset/Group@1x.png and /dev/null differ diff --git a/Neuron/Assets.xcassets/Launch Screen/peckshield_launch.imageset/Group@2x.png b/Neuron/Assets.xcassets/Launch Screen/peckshield_launch.imageset/Group@2x.png deleted file mode 100644 index 1c5a1ec1..00000000 Binary files a/Neuron/Assets.xcassets/Launch Screen/peckshield_launch.imageset/Group@2x.png and /dev/null differ diff --git a/Neuron/Assets.xcassets/Launch Screen/peckshield_launch.imageset/Group@3x.png b/Neuron/Assets.xcassets/Launch Screen/peckshield_launch.imageset/Group@3x.png deleted file mode 100644 index 8064e547..00000000 Binary files a/Neuron/Assets.xcassets/Launch Screen/peckshield_launch.imageset/Group@3x.png and /dev/null differ diff --git a/Neuron/Constants/TokenMacro.swift b/Neuron/Constants/TokenMacro.swift deleted file mode 100644 index 92426aaf..00000000 --- a/Neuron/Constants/TokenMacro.swift +++ /dev/null @@ -1,20 +0,0 @@ -// -// TokenMacro.swift -// Neuron -// -// Created by XiaoLu on 2018/8/1. -// Copyright © 2018年 cryptape. All rights reserved. -// - -import Foundation - -// TODO: do we really need this? -struct NativeChainId { - /// ETH mainnet chainId defined for Neuron - static let ethMainnetChainId = "-1" -} - -struct NativeDecimals { - /// ETH and AppChain token decimals, default to 18 - static let nativeTokenDecimals = 18 -} diff --git a/Neuron/Extensions/Foundation/Double+Extension.swift b/Neuron/Extensions/Foundation/Double+Extension.swift deleted file mode 100644 index 59874b4b..00000000 --- a/Neuron/Extensions/Foundation/Double+Extension.swift +++ /dev/null @@ -1,47 +0,0 @@ -// -// Double+Extension.swift -// Neuron -// -// Created by XiaoLu on 2018/9/25. -// Copyright © 2018年 Cryptape. All rights reserved. -// - -import UIKit -import BigInt - -extension Double { - var trailingZerosTrimmed: String { - return truncatingRemainder(dividingBy: 1) == 0 ? String(format: "%.0f", self) : String(self) - } - - /// Format to normal number string such as 3.1415926. - static var decimalFormatter: NumberFormatter = { - let formatter = NumberFormatter() - formatter.minimumIntegerDigits = 1 - formatter.minimumFractionDigits = 0 - formatter.maximumFractionDigits = 8 - formatter.roundingMode = .floor - return formatter - }() - - var decimal: String { - return Double.decimalFormatter.string(from: self as NSNumber)! - } - - func toAmount(_ decimals: Int = 18) -> BigUInt { - let stringValue = NSDecimalNumber(string: self.description).stringValue - return Web3Utils.parseToBigUInt(stringValue, decimals: decimals) ?? 0 - } - - func gweiToWei() -> BigUInt { - return toAmount(9) - } - - static func fromAmount(_ amount: BigUInt, decimals: Int = 18) -> Double { - if let value = Web3Utils.formatToPrecision(amount, numberDecimals: decimals, formattingDecimals: 8, fallbackToScientific: true) { - return Double(value) ?? 0 - } else { - return 0 - } - } -} diff --git a/Neuron/MainViewController.swift b/Neuron/MainViewController.swift deleted file mode 100644 index 4c363604..00000000 --- a/Neuron/MainViewController.swift +++ /dev/null @@ -1,85 +0,0 @@ -// -// MainViewController.swift -// Neuron -// -// Created by XiaoLu on 2018/5/18. -// Copyright © 2018年 cryptape. All rights reserved. -// - -import UIKit -import RealmSwift - -class MainViewController: UITabBarController, UITabBarControllerDelegate { - override func viewDidLoad() { - super.viewDidLoad() - - delegate = self - - applyStyle() - addNativeTokenMsgToRealm() - } - - // get native token for nervos 'just temporary' - func addNativeTokenMsgToRealm() { - let appModel = AppModel.current - let ethModel = TokenModel() - ethModel.address = "" - ethModel.chainId = NativeChainId.ethMainnetChainId - ethModel.chainName = "" - ethModel.decimals = NativeDecimals.nativeTokenDecimals - ethModel.iconUrl = "" - ethModel.isNativeToken = true - ethModel.name = "ethereum" - ethModel.symbol = "ETH" - - if let id = TokenModel.identifier(for: ethModel) { - ethModel.identifier = id - } - - let realm = try! Realm() - try? realm.write { - realm.add(ethModel, update: true) - if !appModel.nativeTokenList.contains(ethModel) { - appModel.nativeTokenList.append(ethModel) - realm.add(appModel) - } - } - - // Add mba token - DispatchQueue.global().async { - let mbaHost = "http://testnet.mba.cmbchina.biz:1337" - do { - let metaData = try AppChainNetwork.appChain(url: URL(string: mbaHost)!).rpc.getMetaData() - let realm = try Realm() - let appModel = realm.objects(AppModel.self).first! - guard !appModel.nativeTokenList.contains(where: { - $0.chainId == metaData.chainId && $0.chainHosts == mbaHost && $0.symbol == metaData.tokenSymbol - }) else { return } - - let tokenModel = TokenModel() - tokenModel.chainId = metaData.chainId - tokenModel.chainName = metaData.chainName - tokenModel.symbol = metaData.tokenSymbol - tokenModel.iconUrl = metaData.tokenAvatar - tokenModel.name = metaData.tokenName - tokenModel.chainHosts = mbaHost - tokenModel.isNativeToken = true - try realm.write { - appModel.nativeTokenList.append(tokenModel) - } - } catch { - } - } - } - - private func applyStyle() { - UITabBarItem.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor(named: "tint_color")!], for: .selected) - - let navigationBarBackImage = UIImage(named: "nav_darkback")!.withRenderingMode(.alwaysOriginal) - UINavigationBar.appearance().backIndicatorImage = navigationBarBackImage - UINavigationBar.appearance().backIndicatorTransitionMaskImage = navigationBarBackImage - - UIBarButtonItem.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.clear], for: .normal) - UIBarButtonItem.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.clear], for: .highlighted) - } -} diff --git a/Neuron/Models/Realm/TokenModel.swift b/Neuron/Models/Realm/TokenModel.swift deleted file mode 100644 index 4ed62493..00000000 --- a/Neuron/Models/Realm/TokenModel.swift +++ /dev/null @@ -1,101 +0,0 @@ -// -// TokenModel.swift -// Neuron -// -// Created by XiaoLu on 2018/7/2. -// Copyright © 2018年 cryptape. All rights reserved. -// - -import Foundation -import RealmSwift - -class TokenModel: Object, Decodable { - @objc dynamic var name = "" - @objc dynamic var iconUrl: String? = "" - @objc dynamic var address = "" - @objc dynamic var decimals = 18 - @objc dynamic var symbol = "" - @objc dynamic var chainName: String? = "" - @objc dynamic var chainId = "" - @objc dynamic var chainHosts = "" // manifest.json chainSet.values.first - @objc dynamic var identifier = UUID().uuidString - - // defaults false, eth and RPC "getMateData" is true. - @objc dynamic var isNativeToken = false // TODO: AppChain ERC20 should not be marked as native token. - - @objc dynamic var tokenBalance = 0.0 - var currencyAmount = "0" - - override class func primaryKey() -> String? { - return "identifier" - } - - override static func ignoredProperties() -> [String] { - return ["currencyAmount"] - } - - struct Logo: Decodable { - var src: String? - } - var logo: Logo? - - var type: TokenType { - if isNativeToken { - if chainId == NativeChainId.ethMainnetChainId { - return .ether - } else { - if address != "" { - return .appChainErc20 - } else { - return .appChain - } - } - } else { - return .erc20 - } - } - var gasSymbol: String { - switch type { - case .ether, .erc20: - return "ETH" - case .appChain, .appChainErc20: - return self.symbol - } - } - - var isEthereum: Bool { - return type == .ether || type == .erc20 - } - - enum CodingKeys: String, CodingKey { - case name - case address - case decimals - case symbol - case logo - } -} - -extension TokenModel { - static func identifier(for tokenModel: TokenModel) -> String? { - let appModel = AppModel.current - var tokenList: [TokenModel] = [] - tokenList += appModel.nativeTokenList - tokenList += appModel.extraTokenList - if let model = tokenList.first(where: { $0 == tokenModel }) { - return model.identifier - } - return nil - } -} - -extension TokenModel { - public static func == (lhs: TokenModel, rhs: TokenModel) -> Bool { - return lhs.chainId == rhs.chainId && lhs.symbol == rhs.symbol && lhs.name == rhs.name - } - - override func isEqual(_ object: Any?) -> Bool { - guard let object = object as? TokenModel else { return false } - return object.address == address - } -} diff --git a/Neuron/Models/Realm/WalletModel.swift b/Neuron/Models/Realm/WalletModel.swift deleted file mode 100644 index 975be426..00000000 --- a/Neuron/Models/Realm/WalletModel.swift +++ /dev/null @@ -1,25 +0,0 @@ -// -// WalletModel.swift -// Neuron -// -// Created by XiaoLu on 2018/6/6. -// Copyright © 2018年 cryptape. All rights reserved. -// - -import UIKit -import RealmSwift - -class WalletModel: Object { - @objc dynamic var name = "" - @objc dynamic var address = "" - @objc dynamic var iconData: Data! - var selectTokenList = List() - - var wallet: Wallet? { - return WalletManager.default.wallet(for: address) - } - - override static func primaryKey() -> String? { - return "address" - } -} diff --git a/Neuron/Models/Token.swift b/Neuron/Models/Token.swift deleted file mode 100644 index 9c56c36f..00000000 --- a/Neuron/Models/Token.swift +++ /dev/null @@ -1,105 +0,0 @@ -// -// Token.swift -// Neuron -// -// Created by 晨风 on 2018/11/20. -// Copyright © 2018 Cryptape. All rights reserved. -// - -import UIKit -import Web3swift -import BigInt -import EthereumAddress -import RealmSwift - -enum TokenType: String { - case ether - case erc20 - case appChain - case appChainErc20 -} - -class Token { - var name: String - var iconUrl: String? = "" - var address: String - var symbol: String - var chainName: String? = "" - var chainId: String - var chainHosts: String - var isNativeToken: Bool - var walletAddress = "" - var type: TokenType - var decimals = 18 - let identifier: String - - var tokenModel: TokenModel { - let realm = try! Realm() - return realm.object(ofType: TokenModel.self, forPrimaryKey: identifier)! - } - - private(set) var balance: Double? { - didSet { - try? tokenModel.realm!.write { - tokenModel.tokenBalance = balance ?? 0.0 - } - } - } - var price: Double? - - init(_ token: TokenModel) { - name = token.name - iconUrl = token.iconUrl - address = token.address - symbol = token.symbol - chainId = token.chainId - chainName = token.chainName - chainHosts = token.chainHosts - isNativeToken = token.isNativeToken - type = token.type - decimals = token.decimals - identifier = token.identifier - } - - // MARK: - balance - private var refreshBalanceSignal: DispatchGroup? - - @discardableResult func refreshBalance() throws -> Double? { - if let signal = refreshBalanceSignal { - signal.wait() - return self.balance - } - refreshBalanceSignal = DispatchGroup() - refreshBalanceSignal?.enter() - - defer { - refreshBalanceSignal?.leave() - refreshBalanceSignal = nil - } - - let balance: BigUInt - self.balance = nil - switch type { - case .appChain, .appChainErc20: - balance = try AppChainNetwork.appChain(url: URL(string: chainHosts)).rpc.getBalance(address: walletAddress) - case .ether: - balance = try EthereumBalanceLoader(web3: EthereumNetwork().getWeb3(), address: walletAddress).getBalance() - case .erc20: - balance = try EthereumBalanceLoader(web3: EthereumNetwork().getWeb3(), address: walletAddress).getTokenBalance(address: address) - } - self.balance = Double.fromAmount(balance, decimals: decimals) - refreshBalanceSignal?.leave() - refreshBalanceSignal = nil - return self.balance - } -} - -extension Token: Equatable { - static func == (lhs: Token, rhs: Token) -> Bool { - return - lhs.type == rhs.type && - lhs.address == rhs.address && - lhs.symbol == rhs.symbol && - lhs.walletAddress == rhs.walletAddress - } -} diff --git a/Neuron/Neuron-Bridging-Header.h b/Neuron/Neuron-Bridging-Header.h deleted file mode 100644 index 6e87911d..00000000 --- a/Neuron/Neuron-Bridging-Header.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// Neuron-Bridging-Header.h -// Neuron -// -// Created by XiaoLu on 2018/5/18. -// Copyright © 2018年 cryptape. All rights reserved. -// - -#ifndef Neuron_Bridging_Header_h -#define Neuron_Bridging_Header_h - - -#endif /* Neuron_Bridging_Header_h */ diff --git a/Neuron/Resource/ProductAgreement.txt b/Neuron/Resource/ProductAgreement.txt deleted file mode 100644 index a50ddd8a..00000000 --- a/Neuron/Resource/ProductAgreement.txt +++ /dev/null @@ -1,230 +0,0 @@ -最近更新于:2018年6月29日 -尊敬的用户: -Nervos基金会(以下简称“基金会”或“我们”)尊重并保护用户(以下简称“您”或“用户”)的隐私,您使用Neuron时,基金会将按照本隐私政策(以下简称“本政策”)收集、使用您的个人信息。 -基金会建议您在使用本产品(以下简称“Neuron”)之前仔细阅读并理解本政策全部内容, 针对免责声明等条款在内的重要信息将以加粗的形式体现。本政策有关关键词定义与基金会《Neuron服务协议》保持一致。 -本政策可由基金会在线随时更新,更新后的政策一旦公布即代替原来的政策,如果您不接受修改后的条款,请立即停止使用Neuron,您继续使用Neuron将被视为接受修改后的政策。经修改的政策一经在Neuron上公布,立即自动生效。 -您知悉本政策及其他有关规定适用于Neuron,Neuron上能链接的基金会所开发的DApp的隐私政策由该DApp另行向您提供。 -一、 我们收集您的哪些信息 -请您知悉,我们收集您的以下信息是出于满足您在Neuron服务需要的目的,且我们十分重视对您隐私的保护。在我们收集您的信息时,将严格遵守“合法、正当、必要”的原则。且您知悉,若您不提供我们服务所需的相关信息,您在Neuron的服务体验可能因此而受到影响。 -1. 仅为满足Neuron服务的目的,我们将不会收集您的移动设备信息、操作记录、交易记录、钱包地址、您的姓名、银行卡号、手机号码、邮件地址等个人信息;Neuron使用的代码将在Github上进行开源以验证以上承诺。 -2. Neuron仅为了优化应用体验的目的,收集匿名的访问统计数据,但是这些数据不属于您的个人信息。 -3. 您知悉:您在Neuron 上的钱包密码、私钥、助记词、Keystore并不存储或同步至基金会服务器。基金会不提供找回您的钱包密码、私钥、助记词、Keystore的服务。 -4. 除上述内容之外,您知悉在您使用Neuron特定功能时,我们将在收集您的个人信息前向您作出特别提示,要求向您收集更多的个人信息。如您选择不同意,则视为您放弃使用Neuron该特定功能。 -5. 当您跳转到基金会开发的DApp或者第三方开发的DApp后,该DApp会以他自己特有的条款和隐私方案向您收集个人信息,您需要独立作出判断是否签约使用该DApp。Neuron不收集、留存和使用该DApp向您收集的个人信息。 -6. 在法律法规允许的范围内,基金会可能会在以下情形中收集并使用您的个人信息无需征得您的授权同意: -(1) 与国家安全、国防安全有关的; -(2) 与公共安全、公共卫生、重大公共利益有关的; -(3) 与犯罪侦查、起诉、审判和判决执行等有关的; -(4) 所收集的个人信息是您自行向社会公众公开的; -(5) 从合法公开披露的信息中收集您的个人信息,如合法的新闻报道,政府信息公开等渠道; -(6) 用于维护服务的安全和合规所必需的,例如发现、处理产品和服务的故障; -(7) 法律法规规定的其他情形。 -二、 我们如何使用您的信息 -1. 我们将向您及时发送重要通知,如软件更新、服务协议及本政策条款的变更。 -2. 我们将在Neuron的“系统设置”中为您提供“指纹登录”选项,让您方便且更安全地管理您的数字代币;指纹信息将保留在本地,Neuron不会采集和留存您的指纹信息。 -3. 法律法规规定及与监管机构配合的要求。 -三、 您如何控制自己的信息 -您在Neuron中拥有以下对您个人信息自主控制权: -1. 您可以通过同步钱包的方式,将您的其他钱包导入Neuron中,或者将您在Neuron的钱包导入到其他数字代币管理钱包中。Neuron将向您显示导入钱包的信息。 -2. 您知悉您可以通过“资产”版块内容修改您的数字代币种类、进行转账及收款等活动。 -3. 您知悉当我们出于特定目的向您收集信息时,我们会提前给予您通知,您有权选择拒绝。但同时您知悉,当您选择拒绝提供有关信息时,即表示您放弃使用Neuron的有关服务。 -4. 您知悉,您及我们对于您交易记录是否公开并没有控制权,因为基于区块链交易系统的开源属性,您的交易记录在整个区块链系统中公开透明。 -5. 您知悉当您使用Neuron的功能跳转至基金会开发的DApp或第三方DApp之后,我们的《Neuron服务协议》、《Neuron隐私政策》将不再适用,针对您在该DApp上对您个人信息的控制权问题,我们建议您在使用该DApp之前详细阅读并了解其隐私规则和有关用户服务协议等内容。 -6. 您有权要求我们更新、更改、删除Neuron收集的您的有关信息。 -7. 您知悉我们可以根据本政策第一条第6款的要求收集您的信息而无需获得您的授权同意。 -四、 我们可能分享或传输您的信息 -1. 基金会在中华人民共和国境内收集和产生的用户个人信息将存储在中华人民共和国境内的服务器上。若基金会确需向境外传输您的个人信息,将在事前获得您的授权,且按照有关法律法规政策的要求进行跨境数据传输,并对您的个人信息履行保密义务。 -2. 未经您事先同意,基金会不会将您的个人信息向任何第三方共享或转让,但以下情况除外: -(1) 事先获得您明确的同意或授权; -(2) 所收集的个人信息是您自行向社会公众公开的; -(3) 所收集的个人信息系从合法公开披露的信息中收集,如合法的新闻报道,政府信息公开等渠道; -(4) 与基金会的关联方共享,我们只会共享必要的用户信息,且受本隐私条款中所声明的目的的约束; -(5) 根据适用的法律法规、法律程序的要求、行政机关或司法机关的要求进行提供; -(6) 在涉及合并、收购时,如涉及到个人信息转让,基金会将要求个人信息接收方继续接受本政策的约束。 -五、 我们如何保护您的信息 -1. 如基金会停止运营,基金会将及时停止继续收集您个人信息的活动,将停止运营的通知公告在Neuron上,并对所持有的您的个人信息在合理期限内进行删除或匿名化处理。 -2. 为了保护您的个人信息,基金会将采取数据安全技术措施,提升内部合规水平,增加内部员工信息安全培训,并对相关数据设置安全访问权限等方式安全保护您的隐私信息。 -3. 我们将在Neuron“消息中心”中向您发送有关信息安全的消息,并不时在Neuron“帮助中心”版块更新钱包使用及信息保护的资料,供您参考。 -六、 对未成年人的保护 -我们对保护未满18周岁的未成年人做出如下特别约定: -1. 未成年人应当在父母或监护人指导下使用基金会相关服务。 -2. 未成年人的父母和监护人应当在阅读本政策、《Neuron服务协议》及我们的其他有关规则的前提下,指导未成年人使用Neuron。 -3. Neuron将根据国家相关法律法规的规定保护未成年人的个人信息的保密性及安全性。 -七、 免责声明 -1. 请您注意,您通过Neuron接入第三方DApp后,将适用该第三方DApp发布的隐私政策。该第三方DApp对您个人信息的收集和使用不为基金会所控制,也不受本政策的约束。基金会无法保证第三方DApp一定会按照基金会的要求采取个人信息保护措施。 -2. 您应审慎选择和使用第三方DApp,并妥善保护好您的个人信息,基金会对其他第三方DApp的隐私保护不负任何责任。 -3. 请您注意,您通过Neuron接入基金会开发的DApp后,将适用该DApp发布的隐私政策。该DApp对您个人信息的收集和使用不受本政策的约束。 -4. 基金会将在现有技术水平条件下尽可能采取合理的安全措施来保护您的个人信息,以避免信息的泄露、篡改或者毁损。基金会系利用无线方式传输数据,因此,基金会无法确保通过无线网络传输数据的隐私性和安全性。 -八、 其他 -1. 您需全面了解并遵守您所在司法辖区与使用基金会服务所有相关法律、法规及规则。 -2. 您在使用基金会服务过程中,如遇到任何有关个人信息使用的问题,您可以通过在Neuron提交反馈等方式联系我们。 -3. 您可以在Neuron中查看本政策及基金会其他服务规则。我们鼓励您在每次访问Neuron时都查阅基金会的服务协议及隐私政策。 -4. 本政策的任何译文版本仅为方便用户而提供,无意对本政策的条款进行修改。如果本政策的中文版本与非中文版本之间存在冲突,应以中文版本为准。 -5. 本政策自2018年6月29日起适用。 -本政策未尽事宜,您需遵守基金会不时更新的公告及相关规则。 -Nervos基金会 - - -《Neuron服务协议》 -最近更新于:2018年6月29日 -尊敬的用户: -感谢您选择Neuron服务。《Neuron服务协议》(以下简称“本协议”)由Nervos基金会(以下简称“基金会”或“我们”)和用户(以下简称“您”或“用户”)签订,本协议在您与基金会之间具有合同上的法律效力。 -基金会在此特别提醒您在使用Neuron(以下简称“Neuron” 或“本软件”)之前,请认真阅读《Neuron服务协议》及后文提到的相关协议,尤其是本协议规定的“免责及责任限制”等条款将以加粗的形式突出体现,确保您充分理解本协议中各条款,并自主考虑风险。 -基金会在此特别提醒您,由于Neuron所使用的代码将在Github上开源,任何人都可能使用开源的Neuron代码,或自行修改后的代码,来打包形成软件。对于这些私自打包形成的软件,并非Neuron应用软件,不受本协议约束,基金会不承担任何责任。本协议只适用于使用基金会官方打包的安装包安装,得到基金会官方授权的Neuron应用软件。 - -一、 关于本协议的确认与接纳 -1. 您理解本协议及有关协议仅适用于Neuron应用本身,而不包括Neuron所能链接的基金会所自主开发和拥有的其他应用,也不包括任何第三方开发或拥有的应用。 -2. 您下载Neuron软件并创建或导入钱包,即视为您已经充分阅读并接受本协议全部条款,本协议立即生效,对双方具有约束力。 -3. 本协议可由基金会随时更新,经修改的协议一经在Neuron上公布,立即自动生效,恕不再另行通知。在基金会公布修改协议条款后,如果您不接受修改后的条款,请立即停止使用Neuron,您继续使用Neuron将被视为接受修改后的协议。 -4. 如果您未满18周岁,或者是无民事行为能力人或限制民事行为能力人,请在父母或监护人指导下使用Neuron。 -二、 定义 -1. Neuron:指由基金会基于Nervos网络和Ethereum网络开发的,向用户提供访问Nervos网络和Ethereum网络,以及保存Nervos网络和Ethereum网络加密数字资产的服务的钱包客户端,包括其他为方便用户使用相关系统而开发的辅助工具。 -2. 用户: -(1)用户必须是具备完全民事行为能力的自然人; -(2)若您为18周岁以下的未成年人使用Neuron服务,需要在您父母或监护人的指导下使用Neuron。无民事行为能力人使用Neuron或限制民事行为能力人超过其民事权利或行为能力范围从事交易的,造成的一切后果,Neuron有权要求您及您的父母或监护人负责。 -3. 创建或导入钱包:指您使用Neuron,确认履行本协议并创建或导入钱包的过程。 -4. 钱包密码:指您在创建Neuron钱包过程中,软件操作界面提示您填写的密码,该密码用于加密保护私钥。作为去中心化的应用,钱包密码不存储在您的这台移动设备或基金会的服务器,一旦丢失你需要借助明文私钥或助记词重置新密码。 -5. 信息提示:Neuron软件操作界面涉及的信息提示内容,建议用户按照相关步骤进行操作。 -6. 特定用户:指按照当地法律法规及政策规定必须要配合基金会履行个人信息披露义务的用户。 -7. 私钥:由私密随机字符构成,是用户拥有并使用数字代币的核心。 -8. 公钥:由私钥借助密码学原理单向推导生成,并用以生成区块链数字钱包地址,数字钱包地址即为公开收款地址。 -9. 助记词:由随机算法生成的若干个有序英文单词组成。助记词是私钥的易记录表现形式,方便用户备份保管。 -10. Keystore: 是私钥或助记词经过用户设置的钱包密码加密保存的文件形式,它只存储在您的这台移动设备中,不会同步至基金会服务器。 -11. 数字代币:指Neuron目前支持的数字代币种类,包括但不限于CKC、ETH、以太坊ERC20标准的代币、以太坊ERC721标准的代币等。 -12. 个人信息:指以电子或者其他方式记录的能够单独或者与其他信息结合识别用户个人身份的各种信息,包括但不限于自然人的姓名、出生日期、身份证件号码、个人生物识别信息、住址、电话号码、银行卡号、邮件地址、钱包地址、移动设备信息、操作记录、交易记录等,但不包括用户的钱包密码、私钥、助记词、Keystore。 -三、 服务内容 -1. 创建或导入钱包。对Neuron支持的数字代币,您可以使用Neuron生成新钱包或导入相关区块链系统的其它钱包工具生成的兼容钱包。 -2. 转账、收款。您可以使用Neuron的转账、收款功能进行数字代币的操作。转账是指付款方利用收款方的区块链地址进行转账操作,实际的转账、收款行为均在相关区块链系统(而非Neuron)发生。 -3. 管理数字资产。您可以使用Neuron添加、保管并移除Neuron所支持的数字代币。 -5. 浏览DApp。用户通过在Neuron上的链接,可以跳转至DApp并使用该DApp(包括基金会自己的DApp和第三方DApp)提供的服务。 -6. 暂停服务。您知悉基于区块链系统交易“不可撤销”的属性,我们不能为您暂停或撤销转账交易等操作,但在行政机关指令等紧急情况等下,我们可以暂停或者限制某位用户对Neuron软件的操作。 -7. 其他基金会认为有必要提供的服务。 -用户接受基金会提供的上述服务时应了解以下常见问题: -1. 秉承着区块链的去中心化特点,并为了保护用户的数字代币安全,基金会提供的是去中心化服务,与银行业金融机构提供的中心化金融服务具有根本性区别。用户了解,基金会不提供以下服务: -(1)行情查看; -(2)存储用户的钱包密码(即用户创建/导入钱包时设置的密码)、私钥、助记词、Keystore; -(3)找回用户的钱包密码、私钥、助记词、Keystore; -(4)冻结钱包; -(5)挂失钱包; -(6)恢复钱包; -(7)交易回滚; -(8)交易记录(用户进行的成功的交易记录将被记录在区块链系统账本上,Neuron自身不提供历史交易数据访问服务)。 -2. 由于基金会不提供上述服务,因此用户应当自行保管含有Neuron的移动设备及其关键芯片和硬件、备份Neuron、备份钱包密码、助记词、私钥及Keystore。如用户遗失移动设备、删除且未备份Neuron、删除且未备份钱包、钱包被盗或遗忘钱包密码、私钥、助记词、Keystore,基金会均无法还原钱包或找回钱包密码、私钥、助记词、Keystore;如用户进行交易时误操作(例如输错转账地址),基金会亦无法取消交易。 -3. 基金会和Neuron所能够提供的数字代币管理服务并未包括所有已存在的数字代币,请勿通过Neuron操作任何Neuron不支持的数字代币。 -4. Neuron仅是用户的数字代币管理工具,并非交易所或交易平台。虽然本协议将多次提及“交易”,其行为泛指用户使用Neuron进行的转账和收款操作,这与交易所或交易平台上进行的“交易”有本质区别。 -5. Neuron上集成的DApp包括基金会自主拥有的DApp和第三方平台提供的DApp。对于Neuron上每个基金会自己开发和拥有的DApp,都会有独立的用户协议和数据隐私政策,用户应当独立作出判断是否进行签约使用。对于第三方平台提供的DApp,Neuron仅为用户进入DApp提供区块链浏览器。用户在第三方DApp上接受服务或进行交易前应自行判断和评估该第三方DApp提供的服务或交易是否存在风险,基金会和Neuron不承担任何质量和责任担保义务。 -四、 您的权利义务 -(一)创建或导入钱包 -1. 创建或导入钱包:您有权在您的移动设备上通过Neuron创建和/或导入钱包,有权设定钱包的钱包密码等信息,并有权通过Neuron应用程序,使用自己的钱包在区块链上进行转账和收款等交易。 -2. 身份验证:按照有关法律法规和政策要求和可能产生的要求变化,特定用户在使用Neuron提供的有关服务时,应当按照Neuron的提示通过基金会另行开发的KYC应用程序或者第三方开发KYC应用程序及时完成相关身份验证,要求您提交包括但不限于您的姓名、身份证号码、手机号码、银行卡号信息等个人信息;Neuron自身不会采集和留存以上任何个人信息。未通过以上身份验证的特定用户将无法使用有关服务,因特定用户拖延造成的损失由您自行承担。 -3. 基金会可能为不同的终端设备开发不同的软件版本,您应当根据实际需要选择下载合适的版本进行安装。如果您从未经合法授权的第三方获取本软件或与本软件名称相同的安装程序,基金会将无法保证该软件能否正常使用,也无法保证其安全性,因此造成的损失由您自行承担。 -4. 本软件新版本发布后,旧版软件可能无法使用。基金会不保证旧版软件的安全性、继续可用性及提供相应的客户服务。请您随时核对并下载最新版本。 -(二)使用 -1. 用户应自行妥善保管移动设备、钱包密码、私钥、助记词、Keystore等信息。基金会不负责为用户保管以上信息。因您遗失移动设备、主动或被动泄露、遗忘钱包密码、私钥、助记词、Keystore或遭受他人攻击、诈骗等所引起的一切风险、责任、损失、费用应由您自行承担。 -2. 遵循信息提示。您了解并同意遵循Neuron对您做出的信息提示,按照信息提示的内容进行操作,否则,由此引起的一切风险、责任、损失、费用等应由您自行承担。 -3. 您知悉并理解Neuron没有义务对链接的任何非Neuron应用自身部分的,特别是第三方提供的DApp服务或交易履行尽职调查义务,您应当理性做出交易、投资决策并自主承担相应的交易、投资风险。 -4. 积极完成身份验证。当Neuron合理认为您的交易行为或交易情况出现异常的,或认为您的身份信息存在疑点的,或Neuron认为应核对您身份证件或其他必要文件的情形时,请您积极配合Neuron核对您的有效身份证件或其他必要文件,及时完成相关的身份验证。 -5. 转账。 -(1)您理解基于区块链操作的“不可撤销”属性,当您使用Neuron转账功能时,您应当自行承担因您操作失误而导致的后果(包括但不限于因您输错转账地址、您自身选择转账节点服务器的问题)。 -(2)您知悉在使用Neuron服务时,以下情况的出现可能导致转账“交易失败”或“打包超时”: -a) 钱包余额不足; -b) 交易矿工费不足; -c) 区块链执行合约代码失败; -d) 网络、设备等技术故障; -e) 区块链网络拥堵、故障等原因引起交易被抛弃。 -(4)您知悉Neuron仅向您提供转账工具,在您使用Neuron完成转账后,基金会即完成了当次服务的所有义务,基金会对其他纠纷争议,不负担任何义务。 -6. 合法合规。您知悉在Neuron进行操作时或进行交易时,您应当遵循有关法律法规、国家政策的要求。 -7. 公告通知。Neuron会以网站公告、电子邮件、发送短信、电话、消息中心信息、弹窗提示或客户端通知等方式向您发送通知,例如通知您交易进展情况,或者提示您进行相关操作,请您及时予以关注。 -8. 服务费用与纳税义务: -(1)Neuron暂时不向您收取任何形式的服务费或手续费,将来需对某些服务进行收费时将另行约定或公布规则; -(2)您使用Neuron进行转账时应支付矿工费,金额由您自行决定。矿工费由相关区块链系统收取; -(3)您知悉在特定情况下,因为您所处的环境及网络状态不稳定,导致您的转账操作未完成时,亦会被相关区块链系统收取矿工费; -(4)您因在Neuron进行交易而发生的所有应纳税负及其它方面的费用均由您负责支付。 -五、 风险提示 -1. 您了解并知悉,由于数字代币领域的法律法规政策尚未健全,该领域的数字代币可能会产生无法兑现、技术不稳定等重大风险。且数字代币的价格波动幅度远高于其他金融资产。我们谨慎提醒您应当根据自身财务状况和风险偏好,理性选择持有或处置任何一种数字代币。Neuron不提供行情报价服务。 -2. 在使用Neuron服务时,若您或您的相对方未遵从本协议或相关网站说明、交易、支付页面中之操作提示、规则,Neuron并不保证交易会顺利完成,且Neuron不承担损害赔偿责任。若发生前述情形,而款项已先行入账您的或您的交易方的Neuron钱包或第三方钱包,您理解区块链操作具有的“不可逆”属性,以及相关交易具有“不可撤销”的特征,由您及您的相对方自行承担相应的风险后果。 -3. 在您使用Neuron集成的基金会开发的DApp或第三方DApp服务或进行交易时,为了您的利益,基金会建议您仔细阅读本协议及Neuron提示,了解交易对象及产品信息,谨慎评估风险后再采取行动。所有您在基金会开发的DApp或第三方DApp进行的交易行为系您的个人行为,有约束力的合同关系在您和您的相对方之间按照特定的DApp的协议内容和隐私条件订立,与Neuron和本协议无关。Neuron和基金会对因您的以上交易行为所引起的一切风险、责任、损失、费用不应因本协议的履行承担任何责任。 -4. 您在交易过程中应当自行判断对方是否为完全民事行为能力人并自行决定是否与对方进行交易或转账给对方等,且您自行承担与此相关的所有风险。 -5. 在转账过程中,如果出现“交易失败”、“打包超时”等类似的异常信息提示时,您应通过相关区块链系统的官方途径或其他的区块链查询工具进行再次确认,以避免重复转账;否则,由此所引起的一切损失和费用应由您自行承担。 -6. 您理解当您在Neuron上创建或导入钱包之后,您的Keystore、私钥、助记词等信息仅存储在当前的这台移动设备中,不存储在Neuron或基金会的服务器上。您可以按照Neuron提供的操作指南采取同步钱包等方式更换移动设备。但若您未保存或备份钱包密码、私钥、助记词、Keystore等信息且在您移动设备丢失的情况下,您的数字代币将因此丢失,基金会无法为您找回,您需自行承担相应损失。若您在导出、保存或备份钱包密码、私钥、助记词、Keystore等信息的时候泄密,或保存或备份上述信息的设备或服务器被黑客攻击或控制等情况下,您的数字代币将因此丢失,基金会无法为您找回,您需自行承担相应损失。 -7. 我们建议您在创建或导入钱包时对您钱包的钱包密码、私钥、助记词及Keystore等信息做好安全备份。我们提请您注意,请不要采用以下备份方式:截图、邮件、记事本、短信、微信、QQ等电子备份方式。我们建议您在纸质记事本上抄写助记词和Keystore等信息,同时您亦可将电子数据保管至密码管理器。 -8. 我们建议您在安全的网络环境和安全的硬件设备中使用Neuron,确保您的移动设备没有越狱或Root, 以避免可能存在的安全隐患 -9. 请您在使用我们的服务过程中,警惕非Neuron官方的诈骗行为。一旦发现此类行为,我们鼓励您第一时间告知我们。 -六、 服务的变更、中断、终止 -1. 您同意基金会为保证自主业务经营权可以暂时提供部分服务功能,或于将来暂停部分服务功能或开通新的服务功能。当任何功能减少或者增加或者变化时,只要您仍然使用基金会提供的服务,表示您仍然同意本协议或者本协议修正后的条款。 -2. 您理解存在如下情形时,基金会将暂停提供服务: -(1)因设备、区块链系统维修、升级、故障和通信中断等技术原因而中断业务; -(2)因台风、地震、海啸、洪水、停电、战争或恐怖袭击等不可抗力因素,病毒、木马、黑客攻击、系统不稳定或政府行为等原因,造成基金会系统不能提供服务或基金会合理认为继续提供服务会有较大风险的; -(3)发生基金会无法控制或合理预见的其他情形。 -3. 当您出现如下情况时,基金会可单方面中止或终止您使用Neuron的部分或全部功能: -(1)用户死亡; -(2)盗用他人的钱包信息或移动设备; -(3)填写个人信息时提供虚假信息; -(4)拒绝基金会为提升Neuron功能而发起的强制更新操作; -(5)将Neuron用于违法或犯罪活动; -(6)妨碍其他用户正常使用; -(7)伪称基金会的工作人员或管理人员; -(8)攻击、侵入、更改或以任何其他方式威胁基金会计算机系统的正常运作; -(9)利用Neuron宣传垃圾广告; -(10)散布谣言,损害基金会和Neuron商誉; -(11)违法行为,其他违反本协议的行为,及基金会合理认为应当暂停功能的情形。 -4. 当您与基金会之间的服务关系变更、中断、终止时,您仍有权在合理时间内导出您钱包等信息。 -七、 您合法使用基金会服务的承诺 -1. 您应遵守中华人民共和国相关法律法规及您所居住的国家或地区的法律法规,不得将Neuron用于任何非法目的,也不得以任何非法方式使用基金会服务。 -2. 您不得利用Neuron从事违法或犯罪的行为,包括但不限于: -(1)反对宪法所确定的基本原则,危害国家安全、泄漏国家秘密、颠覆国家政权、破坏国家统一的; -(2)从事任何违法犯罪行为,包括但不限于洗钱、非法集资等; -(3)通过使用任何自动化程序、软件、引擎、网络爬虫、网页分析工具、数据挖掘工具或类似工具,接入基金会服务、收集或处理基金会所提供的内容,干预或试图干预任何用户或任何其他方式接入基金会服务的行为; -(4)提供赌博资讯或以任何方式引诱他人参与赌博; -(5)侵入他人Neuron钱包盗取数字代币; -(6)进行与交易对方宣称的交易内容不符的交易,或不真实的交易; -(7)从事任何侵害或可能侵害Neuron服务系统、数据之行为; -(8)其他违法以及基金会有正当理由认为不适当的行为; -(9)不得嵌入恶意代码、重打包,不得通过程序手段窃取用户私钥和用户信息等。 -3. 您理解并同意,如因您违反有关法律(包括但不限于海关及税务方面的监管规定)或者本协议之规定,使基金会遭受任何损失、受到任何第三方的索赔或任何行政管理部门的处罚,您应对基金会进行赔偿,包括合理的律师费用。 -4. 您承诺按时缴纳基金会的服务费用(如有),否则基金会有权暂停或中止对您提供的服务。 -八、 隐私条款 -1. 基金会十分重视对用户隐私的保护,相关隐私保护政策请参考基金会公布并不时更新的《Neuron隐私政策》。 -九、 免责及责任限制 -1. 基金会仅对本协议中所列明的义务承担责任。 -2. 您理解和同意,在法律所允许的范围内,基金会只能按照现有的技术水平和条件提供服务。因下列原因导致Neuron无法正常提供服务,基金会不承担责任: -(1)Neuron系统停机维护或升级; -(2)因台风、地震、洪水、雷电或恐怖袭击等不可抗力原因; -(3)您的移动设备软硬件和通信线路、供电线路出现故障的; -(4)您操作不当或未通过基金会授权或认可的方式使用基金会服务的; -(5)因病毒、木马、恶意程序攻击、网络拥堵、系统不稳定、系统或设备故障、通讯故障、电力故障、银行等原因或政府行为等原因; -(6)非因基金会的原因而引起的任何其它原因。 -3. 基金会对以下情形不承担责任: -(1)因用户遗失移动设备、删除且未备份Neuron、删除且未备份钱包、钱包被盗或遗忘钱包密码、私钥、助记词、Keystore而导致的数字代币丢失; -(2)因用户自行泄露钱包密码、私钥、助记词、Keystore,或借用、转让或授权他人使用自己的移动设备或Neuron钱包,或未通过基金会官方渠道下载Neuron应用程序或其他不安全的方式使用Neuron应用程序导致的数字代币丢失; -(3)因用户误操作(包括但不限于您输错转账地址、您自身选择转账节点服务器的问题)导致的数字代币丢失; -(4)因用户不理解区块链技术的性质而进行误操作导致的数字代币丢失; -(5)因时间滞后、区块链系统不稳定等原因导致基金会拷贝用户在区块链上的交易记录发生偏差; -(6)用户在第三方DApp上操作产生的风险和后果。 -4. 您理解Neuron仅作为您数字代币管理的工具。基金会不能控制第三方DApp提供的产品及服务的质量、安全或合法性,信息的真实性或准确性,以及相对方履行其在与您签订的协议项下的各项义务的能力。所有您在第三方DApp进行的交易行为系您的个人行为,有约束力的合同关系在您和您的相对方之间建立,与Neuron无关。基金会提醒您应该通过自己的谨慎判断确定登录DApp及相关信息的真实性、合法性和有效性。您与任何第三方交易所产生的风险亦应由您自行承担。 -5. 基金会可能同时为您及您的交易对手方提供服务,您同意对基金会可能存在的该等行为予以明确豁免任何实际或潜在的利益冲突,并不得以此来主张基金会在提供服务时存在法律上的瑕疵,也不因此而加重基金会的责任或注意义务。 -6. 基金会不提供以下形式的保证: -(1)基金会服务将符合您的全部需求; -(2)您经由基金会服务取得的任何技术、产品、服务、资讯将符合您的期望; -(3)基金会从第三方交易所抓取的数字代币市场交易行情等信息的及时性、准确性、完整性、可靠性做出保证; -(4)您在Neuron上的交易各方会及时履行其在与您达成的交易协议中各项义务。 -7. 您理解Neuron仅作为用户管理数字代币、显示交易信息的工具,基金会不提供法律、税务或投资建议等服务。您应当自行向法律、税务、投资方面的专业人士寻求建议,且您在使用我们服务过程中所遭受的投资损失、数据损失等,基金会概不负责。 -8. 您理解根据有关中国政策法规的要求,我们可能不时更改我们的用户准入标准,限定向某一特定群体提供服务的范围和方式等。 -十、 完整协议 -1. 本协议由《Neuron服务协议》、《Neuron隐私政策》及基金会不时公布的各项规则(包括“帮助中心”的内容)组成。 -2. 本协议部分内容被有管辖权的法院认定为违反或无效的,不因此影响其他内容的效力。 -3. 本协议的任何译文版本仅为方便用户而提供,无意对本协议的条款进行修改。如果本协议的中文版本与非中文版本之间存在冲突,应以中文版本为准。 -十一、 知识产权保护 -1. Neuron系基金会开发并拥有知识产权的应用程序。Neuron中显示的任何内容(包括本协议、公告、文章、视频、音频、图片、档案、资讯、资料、商标或标识)的知识产权归基金会或第三方权利人所有。用户仅可为持有和管理数字代币之目的使用Neuron应用程序及其中的内容。未经基金会或第三方权利人的事先书面同意,任何人不得擅自使用、修改、反向编译、复制、公开传播、改变、散布、发行或公开发表上述应用程序及内容。 -十二、 法律适用与争议解决 -1. 本协议及其修订版之效力、解释、变更、执行与争议解决均适用中华人民共和国香港特别行政区法律,如无相关法律规定,则应当适用国际商业惯例和(或)行业惯例。 -2.凡因本合同所引起的或与之相关的任何争议、纠纷、分歧或索赔,包括合同的存在、效力、解释、履行、违反或终止,或因本合同引起的或与之相关的任何非合同性争议,均应提交由香港国际仲裁中心管理的仲裁,并按照提交仲裁通知时有效的《香港国际仲裁中心机构仲裁规则》最终解决。本仲裁条款适用的法律为香港特别行政区法律。仲裁地应为香港特别行政区。仲裁员人数为三名。仲裁程序应按照中文来进行。 - -十三、 其他 -1. 您需全面了解并遵守您所在司法辖区与使用基金会服务所有相关法律、法规及规则。 -2. 您在使用基金会服务过程中,如遇到任何问题,您可以通过在Neuron提交反馈等方式联系我们。 -3. 您可以在Neuron中查看本协议。 基金会鼓励您在每次访问Neuron时都查阅基金会的服务协议。 -4. 本协议自2018年6月29日起适用。 -本协议未尽事宜,您需遵守基金会不时更新的公告及相关规则。 -Nervos基金会 - diff --git a/Neuron/Resource/tokens-eth.json b/Neuron/Resource/tokens-eth.json deleted file mode 100755 index 35ddcf39..00000000 --- a/Neuron/Resource/tokens-eth.json +++ /dev/null @@ -1,1587 +0,0 @@ -[ - { - "symbol":"TRX", - "address":"0xf230b790e05390fc8295f4d3f60332c93bed42e2", - "decimals":6, - "name":"Tron Lab Token", - "ens_address":"", - "website":"https://tronlab.com/en.html", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"service@tronlab.com", - "url":"" - }, - "social":{ - "blog":"", - "chat":"", - "facebook":"https://www.facebook.com/TronFoundation-144555002795817", - "forum":"", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"", - "slack":"https://tronfoundation.slack.com", - "telegram":"https://t.me/joinchat/GIjGvkK7dhnO8gapCPfqew", - "twitter":"https://twitter.com/tronfoundation", - "youtube":"" - } - }, - { - "symbol":"BNB", - "address":"0xb8c77482e45f1f44de1745f52c74426c631bdd52", - "decimals":18, - "name":"BNB", - "ens_address":"", - "website":"https://www.binance.com", - "logo":{ - "src":"https://etherscan.io/token/images/binance_28.png", - "width":28, - "height":28, - "ipfs_hash":"" - }, - "support":{ - "email":"support@binance.zendesk.com", - "url":"" - }, - "social":{ - "blog":"", - "chat":"", - "facebook":"https://www.facebook.com/binance2017", - "forum":"", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"https://www.reddit.com/r/binance", - "slack":"", - "telegram":"", - "twitter":"https://twitter.com/binance_2017", - "youtube":"" - } - }, - { - "symbol":"VEN", - "address":"0xD850942eF8811f2A866692A623011bDE52a462C1", - "decimals":18, - "name":"Vechain", - "ens_address":"", - "website":"https://tokensale.vechain.com/en", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"support@vechain.com", - "url":"" - }, - "social":{ - "blog":"", - "chat":"http://u.wechat.com/MH_e7eabTidsPXiG842RsHM", - "facebook":"", - "forum":"", - "github":"https://github.com/vechain-team", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"", - "slack":"https://vechainofficial.slack.com", - "telegram":"", - "twitter":"", - "youtube":"" - } - }, - { - "symbol":"OMG", - "address":"0xd26114cd6EE289AccF82350c8d8487fedB8A0C07", - "decimals":18, - "name":"OMG", - "ens_address":"", - "website":"", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"", - "url":"" - }, - "social":{ - "blog":"", - "chat":"", - "facebook":"", - "forum":"", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"", - "slack":"", - "telegram":"", - "twitter":"", - "youtube":"" - } - }, - { - "symbol":"ICX", - "address":"0xb5a5f22694352c15b00323844ad545abb2b11028", - "decimals":18, - "name":"ICON", - "ens_address":"", - "website":"https://www.icon.foundation", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"hello@icon.foundation", - "url":"" - }, - "social":{ - "blog":"https://medium.com/helloiconworld", - "chat":"", - "facebook":"", - "forum":"", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"https://www.reddit.com/r/icon", - "slack":"", - "telegram":"https://t.me/joinchat/Fqw4igkkVmYtj--ZVi-QcA", - "twitter":"https://twitter.com/helloiconworld", - "youtube":"" - } - }, - { - "symbol":"ZIL", - "address":"0x05f4a42e251f2d52b8ed15E9FEdAacFcEF1FAD27", - "decimals":12, - "name":"Zilliqa", - "ens_address":"", - "website":"https://www.zilliqa.com/", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"enquiry@zilliqa.com", - "url":"" - }, - "social":{ - "blog":"", - "chat":"", - "facebook":"", - "forum":"", - "github":"https://github.com/zilliqa", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"https://www.reddit.com/r/zilliqa/", - "slack":"", - "telegram":"https://t.me/zilliqa", - "twitter":"https://twitter.com/zilliqa", - "youtube":"https://www.youtube.com/channel/UCvinnFbf0u71cajoxKcfZIQ" - } - }, - { - "symbol":"AE", - "address":"0x5ca9a71b1d01849c0a95490cc00559717fcf0d1d", - "decimals":18, - "name":"aeternity", - "ens_address":"", - "website":"https://www.aeternity.com/", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"info@aeternity.com", - "url":"" - }, - "social":{ - "blog":"https://blog.aeternity.com/", - "chat":"", - "facebook":"https://www.facebook.com/aeternityproject/", - "forum":"", - "github":"https://github.com/aeternity", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"https://www.reddit.com/r/Aeternity/", - "slack":"", - "telegram":"https://telegram.me/aeternity", - "twitter":"https://twitter.com/aetrnty", - "youtube":"" - } - }, - { - "symbol":"BTM", - "address":"0xcb97e65f07da24d46bcdd078ebebd7c6e6e3d750", - "decimals":8, - "name":"Bytom", - "ens_address":"", - "website":"https://bytom.io", - "logo":{ - "src":"https://etherscan.io/token/images/bytom_28.png", - "width":28, - "height":28, - "ipfs_hash":"" - }, - "support":{ - "email":"contact@bytom.io", - "url":"" - }, - "social":{ - "blog":"", - "chat":"", - "facebook":"", - "forum":"", - "github":"https://github.com/bytom", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"", - "slack":"", - "telegram":"", - "twitter":"https://twitter.com/Bytom_Official", - "youtube":"" - } - }, - { - "symbol":"ZRX", - "address":"0xE41d2489571d322189246DaFA5ebDe1F4699F498", - "decimals":18, - "name":"0x Project", - "ens_address":"", - "website":"", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"", - "url":"" - }, - "social":{ - "blog":"", - "chat":"", - "facebook":"", - "forum":"", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"", - "slack":"", - "telegram":"", - "twitter":"", - "youtube":"" - } - }, - { - "symbol":"REP", - "address":"0xE94327D07Fc17907b4DB788E5aDf2ed424adDff6", - "decimals":18, - "name":"Augur", - "ens_address":"", - "website":"https://augur.net", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"", - "url":"" - }, - "social":{ - "blog":"", - "chat":"", - "facebook":"", - "forum":"", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"https://www.reddit.com/r/Augur", - "slack":"https://invite.augur.net", - "telegram":"", - "twitter":"", - "youtube":"" - } - }, - { - "symbol":"RHOC", - "address":"0x168296bb09e24a88805cb9c33356536b980d3fc5", - "decimals":8, - "name":"RHOC", - "ens_address":"", - "website":"", - "logo":{ - - }, - "support":{ - - }, - "social":{ - "blog":"", - "chat":"", - "facebook":"", - "forum":"", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"", - "slack":"", - "telegram":"", - "twitter":"", - "youtube":"" - } - }, - { - "symbol":"MKR", - "address":"0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2", - "decimals":18, - "name":"MakerDAO", - "ens_address":"", - "website":"https://makerdao.com", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"support@makerdao.com", - "url":"https://chat.makerdao.com" - }, - "social":{ - "blog":"", - "chat":"https://chat.makerdao.com", - "facebook":"", - "forum":"", - "github":"https://github.com/makerdao", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"https://reddit.com/r/makerdao", - "slack":"", - "telegram":"", - "twitter":"https://twitter.com/MakerDAO", - "youtube":"" - } - }, - { - "symbol":"GNT", - "address":"0xa74476443119A942dE498590Fe1f2454d7D4aC0d", - "decimals":18, - "name":"Golem", - "ens_address":"", - "website":"https://golem.network", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"", - "url":"" - }, - "social":{ - "blog":"", - "chat":"", - "facebook":"", - "forum":"", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"", - "slack":"https://golemproject.org:3000", - "telegram":"", - "twitter":"", - "youtube":"" - } - }, - { - "symbol":"PPT", - "address":"0xd4fa1460F537bb9085d22C7bcCB5DD450Ef28e3a", - "decimals":8, - "name":"Populous", - "ens_address":"", - "website":"https://populous.co", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"info@populous.co", - "url":"" - }, - "social":{ - "blog":"https://medium.com/@BitPopulous", - "chat":"", - "facebook":"", - "forum":"", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"", - "slack":"", - "telegram":"", - "twitter":"", - "youtube":"" - } - }, - { - "symbol":"WTC", - "address":"0xb7cb1c96db6b22b0d3d9536e0108d062bd488f74", - "decimals":18, - "name":"Walton", - "ens_address":"", - "website":"", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"", - "url":"" - }, - "social":{ - "blog":"", - "chat":"", - "facebook":"", - "forum":"", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"", - "slack":"", - "telegram":"", - "twitter":"", - "youtube":"" - } - }, - { - "symbol":"SNT", - "address":"0x744d70FDBE2Ba4CF95131626614a1763DF805B9E", - "decimals":18, - "name":"Status Network Token", - "ens_address":"", - "website":"https://status.im", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"", - "url":"" - }, - "social":{ - "blog":"", - "chat":"", - "facebook":"", - "forum":"", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"", - "slack":"", - "telegram":"", - "twitter":"", - "youtube":"" - } - }, - { - "symbol":"BAT", - "address":"0x0D8775F648430679A709E98d2b0Cb6250d2887EF", - "decimals":18, - "name":"BAT", - "ens_address":"", - "website":"", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"", - "url":"" - }, - "social":{ - "blog":"", - "chat":"", - "facebook":"", - "forum":"", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"", - "slack":"", - "telegram":"", - "twitter":"", - "youtube":"" - } - }, - { - "symbol":"NAS", - "address":"0x5d65D971895Edc438f465c17DB6992698a52318D", - "decimals":18, - "name":"Nebulas", - "ens_address":"", - "website":"", - "logo":{ - - }, - "support":{ - - }, - "social":{ - "blog":"", - "chat":"", - "facebook":"", - "forum":"", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"", - "slack":"", - "telegram":"", - "twitter":"", - "youtube":"" - } - }, - { - "symbol":"AION", - "address":"0x4CEdA7906a5Ed2179785Cd3A40A69ee8bc99C466", - "decimals":8, - "name":"Aion", - "ens_address":"", - "website":"https://aion.network/", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"", - "url":"" - }, - "social":{ - "blog":"https://blog.aion.network/", - "chat":"", - "facebook":"https://www.facebook.com/AionBlockchain/", - "forum":"https://forum.aion.network/", - "github":"https://github.com/aionnetwork", - "gitter":"", - "instagram":"", - "linkedin":"https://linkedin.com/company/aion-network", - "reddit":"", - "slack":"", - "telegram":"https://t.me/aion_blockchain", - "twitter":"https://twitter.com/Aion_Network", - "youtube":"https://youtube.com/channel/UCu4u9tYEgUyNL9KMgrCZvXQ" - } - }, - { - "symbol":"DGD", - "address":"0xE0B7927c4aF23765Cb51314A0E0521A9645F0E2A", - "decimals":9, - "name":"Digix DAO", - "ens_address":"", - "website":"https://www.dgx.io", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"", - "url":"" - }, - "social":{ - "blog":"", - "chat":"", - "facebook":"", - "forum":"", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"https://www.reddit.com/r/digix", - "slack":"", - "telegram":"", - "twitter":"", - "youtube":"" - } - }, - { - "symbol":"IOST", - "address":"0xFA1a856Cfa3409CFa145Fa4e20Eb270dF3EB21ab", - "decimals":18, - "name":"IOSToken", - "ens_address":"", - "website":"https://iost.io/", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"", - "url":"" - }, - "social":{ - "blog":"https://medium.com/@iostoken", - "chat":"", - "facebook":"", - "forum":"", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"", - "slack":"", - "telegram":"https://t.me/officialios", - "twitter":"https://twitter.com/iostoken", - "youtube":"" - } - }, - { - "symbol":"HT", - "address":"0x6f259637dcd74c767781e37bc6133cd6a68aa161", - "decimals":18, - "name":"HuobiToken", - "ens_address":"", - "website":"", - "logo":{ - - }, - "support":{ - - }, - "social":{ - "blog":"", - "chat":"", - "facebook":"", - "forum":"", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"", - "slack":"", - "telegram":"", - "twitter":"", - "youtube":"" - } - }, - { - "symbol":"LRC", - "address":"0xEF68e7C694F40c8202821eDF525dE3782458639f", - "decimals":18, - "name":"LRC", - "ens_address":"", - "website":"https://loopring.org", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"foundation@loopring.org", - "url":"" - }, - "social":{ - "blog":"", - "chat":"", - "facebook":"", - "forum":"", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"", - "slack":"", - "telegram":"", - "twitter":"https://twitter.com/loopringorg", - "youtube":"" - } - }, - { - "symbol":"BNT", - "address":"0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C", - "decimals":18, - "name":"Bancor", - "ens_address":"", - "website":"", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"", - "url":"" - }, - "social":{ - "blog":"", - "chat":"", - "facebook":"", - "forum":"", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"", - "slack":"", - "telegram":"", - "twitter":"", - "youtube":"" - } - }, - { - "symbol":"ELF", - "address":"0xbf2179859fc6d5bee9bf9158632dc51678a4100e", - "decimals":18, - "name":"ELF Token", - "ens_address":"", - "website":"https://aelf.io/", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"", - "url":"" - }, - "social":{ - "blog":"", - "chat":"", - "facebook":"https://www.facebook.com/aelfio/", - "forum":"", - "github":"https://github.com/aelfProject", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"https://www.reddit.com/r/aelfofficial/", - "slack":"https://slack.aelf.io/", - "telegram":"https://t.me/aelfblockchain", - "twitter":"https://twitter.com/aelfblockchain", - "youtube":"" - } - }, - { - "symbol":"CMT", - "address":"0xf85fEea2FdD81d51177F6b8F35F0e6734Ce45F5F", - "decimals":18, - "name":"CyberMiles Token", - "ens_address":"", - "website":"https://cm.5miles.com", - "logo":{ - "src":"http://res.5milesapp.com/image/upload/v1512116368/ico/cmt28.png", - "width":28, - "height":28, - "ipfs_hash":"" - }, - "support":{ - "email":"contact@5miles.com", - "url":"" - }, - "social":{ - "blog":"http://www.cybermiles.io", - "chat":"", - "facebook":"https://www.facebook.com/cybermiles", - "forum":"", - "github":"https://github.com/CyberMiles", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"https://www.reddit.com/user/CyberMiles", - "slack":"https://slack.5miles.com", - "telegram":"https://t.me/cybermilestoken", - "twitter":"https://twitter.com/cybermiles", - "youtube":"" - } - }, - { - "symbol":"Dentacoin ", - "address":"0x08d32b0da63e2C3bcF8019c9c5d849d7a9d791e6", - "decimals":0, - "name":"Dentacoin", - "ens_address":"", - "website":"", - "logo":{ - - }, - "support":{ - - }, - "social":{ - "blog":"", - "chat":"", - "facebook":"", - "forum":"", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"", - "slack":"", - "telegram":"", - "twitter":"", - "youtube":"" - } - }, - { - "symbol":"KNC", - "address":"0xdd974D5C2e2928deA5F71b9825b8b646686BD200", - "decimals":18, - "name":"Kyber Network", - "ens_address":"", - "website":"https://kyber.network", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"hello@kyber.network", - "url":"" - }, - "social":{ - "blog":"", - "chat":"", - "facebook":"", - "forum":"", - "github":"https://github.com/KyberNetwork", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"", - "slack":"https://kybernetwork.slack.com", - "telegram":"", - "twitter":"https://twitter.com/KyberNetwork", - "youtube":"" - } - }, - { - "symbol":"VERI", - "address":"0x8f3470A7388c05eE4e7AF3d01D8C722b0FF52374", - "decimals":18, - "name":"Veritas", - "ens_address":"", - "website":"http://veritas.veritaseum.com/index.php", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"reggie@veritaseum.com%20", - "url":"" - }, - "social":{ - "blog":"", - "chat":"", - "facebook":"", - "forum":"", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"", - "slack":"", - "telegram":"", - "twitter":"", - "youtube":"" - } - }, - { - "symbol":"FSN", - "address":"0xd0352a019e9ab9d757776f532377aaebd36fd541", - "decimals":18, - "name":"Fusion", - "ens_address":"", - "website":"", - "logo":{ - - }, - "support":{ - - }, - "social":{ - "blog":"", - "chat":"", - "facebook":"", - "forum":"", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"", - "slack":"", - "telegram":"", - "twitter":"", - "youtube":"" - } - }, - { - "symbol":"BIX ", - "address":"0xb3104b4b9da82025e8b9f8fb28b3553ce2f67069", - "decimals":18, - "name":"BIX Token", - "ens_address":"", - "website":"", - "logo":{ - - }, - "support":{ - - }, - "social":{ - "blog":"", - "chat":"", - "facebook":"", - "forum":"", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"", - "slack":"", - "telegram":"", - "twitter":"", - "youtube":"" - } - }, - { - "symbol":"ETHOS", - "address":"0x5af2be193a6abca9c8817001f45744777db30756", - "decimals":8, - "name":"Ethos", - "ens_address":"", - "website":"", - "logo":{ - - }, - "support":{ - - }, - "social":{ - "blog":"", - "chat":"", - "facebook":"", - "forum":"", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"", - "slack":"", - "telegram":"", - "twitter":"", - "youtube":"" - } - }, - { - "symbol":"FUN", - "address":"0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b", - "decimals":8, - "name":"Funfair", - "ens_address":"", - "website":"https://funfair.io", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"", - "url":"" - }, - "social":{ - "blog":"", - "chat":"", - "facebook":"", - "forum":"", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"https://www.reddit.com/r/FunfairTech/comments/6nadvm/funfair_token_contract_update", - "slack":"https://funfair-slackin.herokuapp.com", - "telegram":"", - "twitter":"https://twitter.com/FunFairTech/status/885910956701876224", - "youtube":"" - } - }, - { - "symbol":"QASH", - "address":"0x618e75ac90b12c6049ba3b27f5d5f8651b0037f6", - "decimals":6, - "name":"QASH", - "ens_address":"", - "website":"https://liquid.plus", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"", - "url":"https://liquid-qash.zendesk.com" - }, - "social":{ - "blog":"https://steemit.com/@quoineliquid", - "chat":"", - "facebook":"https://www.facebook.com/QUOINE.SG", - "forum":"https://bitcointalk.org/index.php?topic=2256844", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"https://www.reddit.com/r/QASH", - "slack":"", - "telegram":"https://t.me/QUOINE", - "twitter":"https://twitter.com/quoine_SG", - "youtube":"https://www.youtube.com/channel/UCOR2GJnFoOgTazC5v6mBTSA" - } - }, - { - "symbol":"LOOM", - "address":"0xa4e8c3ec456107ea67d3075bf9e3df3a75823db0", - "decimals":18, - "name":"LOOM", - "ens_address":"", - "website":"", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"", - "url":"" - }, - "social":{ - "blog":"", - "chat":"", - "facebook":"", - "forum":"", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"", - "slack":"", - "telegram":"", - "twitter":"", - "youtube":"" - } - }, - { - "symbol":"KIN", - "address":"0x818Fc6C2Ec5986bc6E2CBf00939d90556aB12ce5", - "decimals":18, - "name":"Kin Foundation", - "ens_address":"", - "website":"https://kin.kik.com", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"kin@kik.com", - "url":"" - }, - "social":{ - "blog":"https://medium.com/kinfoundation", - "chat":"", - "facebook":"", - "forum":"", - "github":"https://github.com/kikinteractive/kin-token", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"https://www.reddit.com/r/KinFoundation", - "slack":"https://kinfoundation.slack.com", - "telegram":"", - "twitter":"https://twitter.com/@kin_foundation", - "youtube":"" - } - }, - { - "symbol":"NULS", - "address":"0xb91318f35bdb262e9423bc7c7c2a3a93dd93c92c", - "decimals":18, - "name":"NULS", - "ens_address":"", - "website":"https://nuls.io", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"hi@nuls.io", - "url":"" - }, - "social":{ - "blog":"", - "chat":"", - "facebook":"https://www.facebook.com/nulscommunity", - "forum":"", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"https://www.reddit.com/r/nulsservice", - "slack":"", - "telegram":"https://t.me/Nulsio", - "twitter":"https://twitter.com/nulsservice", - "youtube":"" - } - }, - { - "symbol":"CTXC", - "address":"0xea11755ae41d889ceec39a63e6ff75a02bc1c00d", - "decimals":18, - "name":"Cortex Coin", - "ens_address":"", - "website":"", - "logo":{ - - }, - "support":{ - - }, - "social":{ - "blog":"", - "chat":"", - "facebook":"", - "forum":"", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"", - "slack":"", - "telegram":"", - "twitter":"", - "youtube":"" - } - }, - { - "symbol":"POLY", - "address":"0x9992eC3cF6A55b00978cdDF2b27BC6882d88D1eC", - "decimals":18, - "name":"Polymath Network", - "ens_address":"", - "website":"https://polymath.network", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"support@polymath.zendesk.com", - "url":"" - }, - "social":{ - "blog":"https://blog.polymath.network", - "chat":"", - "facebook":"", - "forum":"", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"", - "slack":"", - "telegram":"http://t.me/polymathnetwork", - "twitter":"https://twitter.com/polymathnetwork", - "youtube":"" - } - }, - { - "symbol":"SUB", - "address":"0x12480E24eb5bec1a9D4369CaB6a80caD3c0A377A", - "decimals":2, - "name":"Substratum", - "ens_address":"", - "website":"https://substratum.net", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"", - "url":"" - }, - "social":{ - "blog":"", - "chat":"", - "facebook":"", - "forum":"", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"https://www.reddit.com/r/SubstratumNetwork", - "slack":"http://x.co/SubSlack", - "telegram":"", - "twitter":"https://twitter.com/SubstratumNet", - "youtube":"" - } - }, - { - "symbol":"MANA", - "address":"0x0F5D2fB29fb7d3CFeE444a200298f468908cC942", - "decimals":18, - "name":"Decentraland MANA", - "ens_address":"", - "website":"https://decentraland.org", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"", - "url":"" - }, - "social":{ - "blog":"https://blog.decentraland.org", - "chat":"", - "facebook":"", - "forum":"", - "github":"https://github.com/decentraland", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"", - "slack":"https://slack.decentraland.org", - "telegram":"", - "twitter":"https://twitter.com/decentraland", - "youtube":"" - } - }, - { - "symbol":"ENG", - "address":"0xf0ee6b27b759c9893ce4f094b49ad28fd15a23e4", - "decimals":8, - "name":"Enigma", - "ens_address":"", - "website":"https://enigma.co/", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"info@enigma.co", - "url":"" - }, - "social":{ - "blog":"https://blog.enigma.co/", - "chat":"", - "facebook":"https://www.facebook.com/enigmacatalyst/", - "forum":"", - "github":"https://github.com/enigmampc", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"https://www.reddit.com/r/enigmacatalyst", - "slack":"https://slack.enigma.co/", - "telegram":"https://t.me/enigmacatalyst", - "twitter":"https://twitter.com/enigmampc", - "youtube":"" - } - }, - { - "symbol":"DRGN", - "address":"0x419c4db4b9e25d6db2ad9691ccb832c8d9fda05e", - "decimals":18, - "name":"Dragon", - "ens_address":"dragonchain.eth", - "website":"https://dragonchain.com", - "logo":{ - "src":"https://dragonchain.com/assets/images/dragon.png", - "width":813, - "height":879, - "ipfs_hash":"" - }, - "support":{ - "email":"support@dragonchain.com", - "url":"" - }, - "social":{ - "blog":"https://dragonchain.com/blog", - "chat":"https://t.me/dragontalk", - "facebook":"", - "forum":"", - "github":"https://github.com/dragonchain/dragonchain", - "gitter":"", - "instagram":"", - "linkedin":"https://www.linkedin.com/company/18216867", - "reddit":"https://www.reddit.com/r/dragonchain", - "slack":"", - "telegram":"https://t.me/dragontalk", - "twitter":"https://twitter.com/dragonchaingang", - "youtube":"https://www.youtube.com/channel/UC2_StJYNWFrQz2wiL8n6hoA/videos" - } - }, - { - "symbol":"THETA", - "address":"0x3883f5e181fccaf8410fa61e12b59bad963fb645", - "decimals":18, - "name":"Theta Token", - "ens_address":"", - "website":"https://www.thetatoken.org/", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"support@thetatoken.org", - "url":"" - }, - "social":{ - "blog":"", - "chat":"", - "facebook":"facebook.com/ThetaToken/", - "forum":"", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"reddit.com/r/thetatoken/", - "slack":"", - "telegram":"https://t.me/thetatoken", - "twitter":"twitter.com/thetatoken", - "youtube":"" - } - }, - { - "symbol":"POWR", - "address":"0x595832f8fc6bf59c85c527fec3740a1b7a361269", - "decimals":6, - "name":"PowerLedger", - "ens_address":"", - "website":"https://powerledger.io", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"mc@powerledger.io", - "url":"" - }, - "social":{ - "blog":"", - "chat":"", - "facebook":"", - "forum":"", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"", - "slack":"", - "telegram":"", - "twitter":"", - "youtube":"" - } - }, - { - "symbol":"STORM", - "address":"0xD0a4b8946Cb52f0661273bfbC6fD0E0C75Fc6433", - "decimals":18, - "name":"Storm Token", - "ens_address":"", - "website":"https://www.stormtoken.com", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"info@stormtoken.com", - "url":"" - }, - "social":{ - "blog":"", - "chat":"", - "facebook":"https://www.facebook.com/stormtoken", - "forum":"", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"", - "slack":"", - "telegram":"https://t.me/joinchat/GHTZGQwsy9mZk0KFEEjGtg", - "twitter":"https://twitter.com/storm_token", - "youtube":"" - } - }, - { - "symbol":"GTO", - "address":"0xc5bbae50781be1669306b9e001eff57a2957b09d", - "decimals":5, - "name":"Gifto", - "ens_address":"", - "website":"https://gifto.io/", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"", - "url":"" - }, - "social":{ - "blog":"https://medium.com/@GIFTO", - "chat":"", - "facebook":"https://www.facebook.com/gifto.io/", - "forum":"", - "github":"https://github.com/GIFTO-io", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"https://www.reddit.com/user/GIFTO-io/", - "slack":"", - "telegram":"https://t.me/GIFTOOfficial", - "twitter":"https://twitter.com/GIFTO_io", - "youtube":"" - } - }, - { - "symbol":"MTC", - "address":"0x905E337c6c8645263D3521205Aa37bf4d034e745", - "decimals":18, - "name":"Medical Token Currency", - "ens_address":"", - "website":"https://ico.docademic.com/", - "logo":{ - "src":"https://cdn.docademic.com/images/ico/mtc200.png", - "width":"200", - "height":"200", - "ipfs_hash":"" - }, - "support":{ - "email":"support@docademic.com", - "url":"" - }, - "social":{ - "blog":"https://news.docademic.com", - "chat":"", - "facebook":"https://www.facebook.com/docademic", - "forum":"", - "github":"https://github.com/Docademic", - "gitter":"", - "instagram":"https://www.instagram.com/docademic/", - "linkedin":"https://www.linkedin.com/company/doctordice/", - "reddit":"https://www.reddit.com/user/Docademic/", - "slack":"", - "telegram":"https://t.me/docademicofficial", - "twitter":"https://twitter.com/docademic", - "youtube":"https://www.youtube.com/channel/UCnF48IoeGNu6P78ABB2XhSw/videos?view_as=subscriber" - } - }, - { - "symbol":"MCO", - "address":"0xB63B606Ac810a52cCa15e44bB630fd42D8d1d83d", - "decimals":8, - "name":"MCO", - "ens_address":"", - "website":"", - "logo":{ - "src":"", - "width":"", - "height":"", - "ipfs_hash":"" - }, - "support":{ - "email":"", - "url":"" - }, - "social":{ - "blog":"", - "chat":"", - "facebook":"", - "forum":"", - "github":"", - "gitter":"", - "instagram":"", - "linkedin":"", - "reddit":"", - "slack":"", - "telegram":"", - "twitter":"", - "youtube":"" - } - } -] \ No newline at end of file diff --git a/Neuron/Resource/tokens-list.json b/Neuron/Resource/tokens-list.json deleted file mode 100755 index 795c10fc..00000000 --- a/Neuron/Resource/tokens-list.json +++ /dev/null @@ -1,11469 +0,0 @@ -{ - "data": [ - { - "id": 1, - "name": "Bitcoin", - "symbol": "BTC", - "website_slug": "bitcoin" - }, - { - "id": 2, - "name": "Litecoin", - "symbol": "LTC", - "website_slug": "litecoin" - }, - { - "id": 3, - "name": "Namecoin", - "symbol": "NMC", - "website_slug": "namecoin" - }, - { - "id": 4, - "name": "Terracoin", - "symbol": "TRC", - "website_slug": "terracoin" - }, - { - "id": 5, - "name": "Peercoin", - "symbol": "PPC", - "website_slug": "peercoin" - }, - { - "id": 6, - "name": "Novacoin", - "symbol": "NVC", - "website_slug": "novacoin" - }, - { - "id": 8, - "name": "Feathercoin", - "symbol": "FTC", - "website_slug": "feathercoin" - }, - { - "id": 9, - "name": "Mincoin", - "symbol": "MNC", - "website_slug": "mincoin" - }, - { - "id": 10, - "name": "Freicoin", - "symbol": "FRC", - "website_slug": "freicoin" - }, - { - "id": 13, - "name": "Ixcoin", - "symbol": "IXC", - "website_slug": "ixcoin" - }, - { - "id": 14, - "name": "BitBar", - "symbol": "BTB", - "website_slug": "bitbar" - }, - { - "id": 16, - "name": "WorldCoin", - "symbol": "WDC", - "website_slug": "worldcoin" - }, - { - "id": 18, - "name": "Digitalcoin", - "symbol": "DGC", - "website_slug": "digitalcoin" - }, - { - "id": 25, - "name": "GoldCoin", - "symbol": "GLD", - "website_slug": "goldcoin" - }, - { - "id": 31, - "name": "Argentum", - "symbol": "ARG", - "website_slug": "argentum" - }, - { - "id": 32, - "name": "Fastcoin", - "symbol": "FST", - "website_slug": "fastcoin" - }, - { - "id": 35, - "name": "Phoenixcoin", - "symbol": "PXC", - "website_slug": "phoenixcoin" - }, - { - "id": 37, - "name": "Megacoin", - "symbol": "MEC", - "website_slug": "megacoin" - }, - { - "id": 41, - "name": "Infinitecoin", - "symbol": "IFC", - "website_slug": "infinitecoin" - }, - { - "id": 42, - "name": "Primecoin", - "symbol": "XPM", - "website_slug": "primecoin" - }, - { - "id": 43, - "name": "Anoncoin", - "symbol": "ANC", - "website_slug": "anoncoin" - }, - { - "id": 45, - "name": "CasinoCoin", - "symbol": "CSC", - "website_slug": "casinocoin" - }, - { - "id": 49, - "name": "Bullion", - "symbol": "CBX", - "website_slug": "bullion" - }, - { - "id": 50, - "name": "Emerald Crypto", - "symbol": "EMD", - "website_slug": "emerald" - }, - { - "id": 52, - "name": "XRP", - "symbol": "XRP", - "website_slug": "ripple" - }, - { - "id": 53, - "name": "Quark", - "symbol": "QRK", - "website_slug": "quark" - }, - { - "id": 56, - "name": "Zetacoin", - "symbol": "ZET", - "website_slug": "zetacoin" - }, - { - "id": 57, - "name": "SecureCoin", - "symbol": "SRC", - "website_slug": "securecoin" - }, - { - "id": 58, - "name": "Sexcoin", - "symbol": "SXC", - "website_slug": "sexcoin" - }, - { - "id": 61, - "name": "TagCoin", - "symbol": "TAG", - "website_slug": "tagcoin" - }, - { - "id": 63, - "name": "I0Coin", - "symbol": "I0C", - "website_slug": "i0coin" - }, - { - "id": 64, - "name": "FLO", - "symbol": "FLO", - "website_slug": "flo" - }, - { - "id": 66, - "name": "Nxt", - "symbol": "NXT", - "website_slug": "nxt" - }, - { - "id": 67, - "name": "Unobtanium", - "symbol": "UNO", - "website_slug": "unobtanium" - }, - { - "id": 68, - "name": "Joulecoin", - "symbol": "XJO", - "website_slug": "joulecoin" - }, - { - "id": 69, - "name": "Datacoin", - "symbol": "DTC", - "website_slug": "datacoin" - }, - { - "id": 70, - "name": "BetaCoin", - "symbol": "BET", - "website_slug": "betacoin" - }, - { - "id": 71, - "name": "GrandCoin", - "symbol": "GDC", - "website_slug": "grandcoin" - }, - { - "id": 72, - "name": "Deutsche eMark", - "symbol": "DEM", - "website_slug": "deutsche-emark" - }, - { - "id": 74, - "name": "Dogecoin", - "symbol": "DOGE", - "website_slug": "dogecoin" - }, - { - "id": 75, - "name": "NetCoin", - "symbol": "NET", - "website_slug": "netcoin" - }, - { - "id": 76, - "name": "Philosopher Stones", - "symbol": "PHS", - "website_slug": "philosopher-stones" - }, - { - "id": 77, - "name": "Diamond", - "symbol": "DMD", - "website_slug": "diamond" - }, - { - "id": 78, - "name": "HoboNickels", - "symbol": "HBN", - "website_slug": "hobonickels" - }, - { - "id": 79, - "name": "Tigercoin", - "symbol": "TGC", - "website_slug": "tigercoin" - }, - { - "id": 80, - "name": "Orbitcoin", - "symbol": "ORB", - "website_slug": "orbitcoin" - }, - { - "id": 83, - "name": "Omni", - "symbol": "OMNI", - "website_slug": "omni" - }, - { - "id": 84, - "name": "Catcoin", - "symbol": "CAT", - "website_slug": "catcoin" - }, - { - "id": 87, - "name": "FedoraCoin", - "symbol": "TIPS", - "website_slug": "fedoracoin" - }, - { - "id": 88, - "name": "RonPaulCoin", - "symbol": "RPC", - "website_slug": "ronpaulcoin" - }, - { - "id": 89, - "name": "Mooncoin", - "symbol": "MOON", - "website_slug": "mooncoin" - }, - { - "id": 90, - "name": "Dimecoin", - "symbol": "DIME", - "website_slug": "dimecoin" - }, - { - "id": 93, - "name": "42-coin", - "symbol": "42", - "website_slug": "42-coin" - }, - { - "id": 99, - "name": "Vertcoin", - "symbol": "VTC", - "website_slug": "vertcoin" - }, - { - "id": 101, - "name": "KlondikeCoin", - "symbol": "KDC", - "website_slug": "klondikecoin" - }, - { - "id": 103, - "name": "RedCoin", - "symbol": "RED", - "website_slug": "redcoin" - }, - { - "id": 109, - "name": "DigiByte", - "symbol": "DGB", - "website_slug": "digibyte" - }, - { - "id": 113, - "name": "SmartCoin", - "symbol": "SMC", - "website_slug": "smartcoin" - }, - { - "id": 114, - "name": "TeslaCoin", - "symbol": "TES", - "website_slug": "teslacoin" - }, - { - "id": 117, - "name": "NobleCoin", - "symbol": "NOBL", - "website_slug": "noblecoin" - }, - { - "id": 118, - "name": "ReddCoin", - "symbol": "RDD", - "website_slug": "reddcoin" - }, - { - "id": 120, - "name": "Nyancoin", - "symbol": "NYAN", - "website_slug": "nyancoin" - }, - { - "id": 121, - "name": "UltraCoin", - "symbol": "UTC", - "website_slug": "ultracoin" - }, - { - "id": 122, - "name": "PotCoin", - "symbol": "POT", - "website_slug": "potcoin" - }, - { - "id": 125, - "name": "Blakecoin", - "symbol": "BLC", - "website_slug": "blakecoin" - }, - { - "id": 128, - "name": "MaxCoin", - "symbol": "MAX", - "website_slug": "maxcoin" - }, - { - "id": 129, - "name": "QubitCoin", - "symbol": "Q2C", - "website_slug": "qubitcoin" - }, - { - "id": 130, - "name": "HunterCoin", - "symbol": "HUC", - "website_slug": "huntercoin" - }, - { - "id": 131, - "name": "Dash", - "symbol": "DASH", - "website_slug": "dash" - }, - { - "id": 132, - "name": "Counterparty", - "symbol": "XCP", - "website_slug": "counterparty" - }, - { - "id": 134, - "name": "CacheCoin", - "symbol": "CACH", - "website_slug": "cachecoin" - }, - { - "id": 138, - "name": "iCoin", - "symbol": "ICN", - "website_slug": "icoin" - }, - { - "id": 141, - "name": "Mintcoin", - "symbol": "MINT", - "website_slug": "mintcoin" - }, - { - "id": 142, - "name": "Aricoin", - "symbol": "ARI", - "website_slug": "aricoin" - }, - { - "id": 145, - "name": "DopeCoin", - "symbol": "DOPE", - "website_slug": "dopecoin" - }, - { - "id": 148, - "name": "Auroracoin", - "symbol": "AUR", - "website_slug": "auroracoin" - }, - { - "id": 150, - "name": "Animecoin", - "symbol": "ANI", - "website_slug": "animecoin" - }, - { - "id": 151, - "name": "Pesetacoin", - "symbol": "PTC", - "website_slug": "pesetacoin" - }, - { - "id": 154, - "name": "Marscoin", - "symbol": "MARS", - "website_slug": "marscoin" - }, - { - "id": 159, - "name": "Cashcoin", - "symbol": "CASH", - "website_slug": "cashcoin" - }, - { - "id": 161, - "name": "Pandacoin", - "symbol": "PND", - "website_slug": "pandacoin-pnd" - }, - { - "id": 164, - "name": "MAZA", - "symbol": "MAZA", - "website_slug": "mazacoin" - }, - { - "id": 168, - "name": "Uniform Fiscal Object", - "symbol": "UFO", - "website_slug": "uniform-fiscal-object" - }, - { - "id": 170, - "name": "BlackCoin", - "symbol": "BLK", - "website_slug": "blackcoin" - }, - { - "id": 174, - "name": "LiteBar", - "symbol": "LTB", - "website_slug": "litebar" - }, - { - "id": 175, - "name": "Photon", - "symbol": "PHO", - "website_slug": "photon" - }, - { - "id": 181, - "name": "Zeitcoin", - "symbol": "ZEIT", - "website_slug": "zeitcoin" - }, - { - "id": 182, - "name": "Myriad", - "symbol": "XMY", - "website_slug": "myriad" - }, - { - "id": 184, - "name": "DNotes", - "symbol": "NOTE", - "website_slug": "dnotes" - }, - { - "id": 199, - "name": "Skeincoin", - "symbol": "SKC", - "website_slug": "skeincoin" - }, - { - "id": 201, - "name": "Einsteinium", - "symbol": "EMC2", - "website_slug": "einsteinium" - }, - { - "id": 205, - "name": "Bitcoin Scrypt", - "symbol": "BTCS", - "website_slug": "bitcoin-scrypt" - }, - { - "id": 206, - "name": "Coin(O)", - "symbol": "CNO", - "website_slug": "coin" - }, - { - "id": 212, - "name": "ECC", - "symbol": "ECC", - "website_slug": "eccoin" - }, - { - "id": 213, - "name": "MonaCoin", - "symbol": "MONA", - "website_slug": "monacoin" - }, - { - "id": 215, - "name": "Rubycoin", - "symbol": "RBY", - "website_slug": "rubycoin" - }, - { - "id": 217, - "name": "Bela", - "symbol": "BELA", - "website_slug": "belacoin" - }, - { - "id": 218, - "name": "FlutterCoin", - "symbol": "FLT", - "website_slug": "fluttercoin" - }, - { - "id": 221, - "name": "OctoCoin", - "symbol": "888", - "website_slug": "octocoin" - }, - { - "id": 224, - "name": "FairCoin", - "symbol": "FAIR", - "website_slug": "faircoin" - }, - { - "id": 233, - "name": "SolarCoin", - "symbol": "SLR", - "website_slug": "solarcoin" - }, - { - "id": 234, - "name": "e-Gulden", - "symbol": "EFL", - "website_slug": "e-gulden" - }, - { - "id": 254, - "name": "Gulden", - "symbol": "NLG", - "website_slug": "gulden" - }, - { - "id": 257, - "name": "Polcoin", - "symbol": "PLC", - "website_slug": "polcoin" - }, - { - "id": 258, - "name": "Groestlcoin", - "symbol": "GRS", - "website_slug": "groestlcoin" - }, - { - "id": 260, - "name": "PetroDollar", - "symbol": "XPD", - "website_slug": "petrodollar" - }, - { - "id": 263, - "name": "PLNcoin", - "symbol": "PLNC", - "website_slug": "plncoin" - }, - { - "id": 268, - "name": "WhiteCoin", - "symbol": "XWC", - "website_slug": "whitecoin" - }, - { - "id": 269, - "name": "AsiaCoin", - "symbol": "AC", - "website_slug": "asiacoin" - }, - { - "id": 275, - "name": "PopularCoin", - "symbol": "POP", - "website_slug": "popularcoin" - }, - { - "id": 276, - "name": "Bitstar", - "symbol": "BITS", - "website_slug": "bitstar" - }, - { - "id": 278, - "name": "Quebecoin", - "symbol": "QBC", - "website_slug": "quebecoin" - }, - { - "id": 279, - "name": "CannaCoin", - "symbol": "CCN", - "website_slug": "cannacoin" - }, - { - "id": 287, - "name": "Slothcoin", - "symbol": "SLOTH", - "website_slug": "slothcoin" - }, - { - "id": 290, - "name": "BlueCoin", - "symbol": "BLU", - "website_slug": "bluecoin" - }, - { - "id": 291, - "name": "MaidSafeCoin", - "symbol": "MAID", - "website_slug": "maidsafecoin" - }, - { - "id": 293, - "name": "Bitcoin Plus", - "symbol": "XBC", - "website_slug": "bitcoin-plus" - }, - { - "id": 295, - "name": "BTCtalkcoin", - "symbol": "TALK", - "website_slug": "btctalkcoin" - }, - { - "id": 298, - "name": "NewYorkCoin", - "symbol": "NYC", - "website_slug": "newyorkcoin" - }, - { - "id": 304, - "name": "Canada eCoin", - "symbol": "CDN", - "website_slug": "canada-ecoin" - }, - { - "id": 312, - "name": "Guncoin", - "symbol": "GUN", - "website_slug": "guncoin" - }, - { - "id": 313, - "name": "PinkCoin", - "symbol": "PINK", - "website_slug": "pinkcoin" - }, - { - "id": 316, - "name": "Dreamcoin", - "symbol": "DRM", - "website_slug": "dreamcoin" - }, - { - "id": 317, - "name": "CoffeeCoin", - "symbol": "CFC", - "website_slug": "coffeecoin" - }, - { - "id": 322, - "name": "Energycoin", - "symbol": "ENRG", - "website_slug": "energycoin" - }, - { - "id": 323, - "name": "VeriCoin", - "symbol": "VRC", - "website_slug": "vericoin" - }, - { - "id": 325, - "name": "TEKcoin", - "symbol": "TEK", - "website_slug": "tekcoin" - }, - { - "id": 328, - "name": "Monero", - "symbol": "XMR", - "website_slug": "monero" - }, - { - "id": 331, - "name": "Litecoin Plus", - "symbol": "LCP", - "website_slug": "litecoin-plus" - }, - { - "id": 333, - "name": "Curecoin", - "symbol": "CURE", - "website_slug": "curecoin" - }, - { - "id": 334, - "name": "UnbreakableCoin", - "symbol": "UNB", - "website_slug": "unbreakablecoin" - }, - { - "id": 337, - "name": "CryptCoin", - "symbol": "CRYPT", - "website_slug": "cryptcoin" - }, - { - "id": 341, - "name": "SuperCoin", - "symbol": "SUPER", - "website_slug": "supercoin" - }, - { - "id": 350, - "name": "BoostCoin", - "symbol": "BOST", - "website_slug": "boostcoin" - }, - { - "id": 353, - "name": "Hyper", - "symbol": "HYPER", - "website_slug": "hyper" - }, - { - "id": 356, - "name": "BitQuark", - "symbol": "BTQ", - "website_slug": "bitquark" - }, - { - "id": 360, - "name": "Motocoin", - "symbol": "MOTO", - "website_slug": "motocoin" - }, - { - "id": 362, - "name": "CloakCoin", - "symbol": "CLOAK", - "website_slug": "cloakcoin" - }, - { - "id": 366, - "name": "BitSend", - "symbol": "BSD", - "website_slug": "bitsend" - }, - { - "id": 367, - "name": "Coin2.1", - "symbol": "C2", - "website_slug": "coin2-1" - }, - { - "id": 370, - "name": "Fantomcoin", - "symbol": "FCN", - "website_slug": "fantomcoin" - }, - { - "id": 372, - "name": "Bytecoin", - "symbol": "BCN", - "website_slug": "bytecoin-bcn" - }, - { - "id": 374, - "name": "ArtByte", - "symbol": "ABY", - "website_slug": "artbyte" - }, - { - "id": 377, - "name": "NavCoin", - "symbol": "NAV", - "website_slug": "nav-coin" - }, - { - "id": 382, - "name": "Granite", - "symbol": "GRN", - "website_slug": "granitecoin" - }, - { - "id": 385, - "name": "Donationcoin", - "symbol": "DON", - "website_slug": "donationcoin" - }, - { - "id": 386, - "name": "Piggycoin", - "symbol": "PIGGY", - "website_slug": "piggycoin" - }, - { - "id": 389, - "name": "Startcoin", - "symbol": "START", - "website_slug": "startcoin" - }, - { - "id": 400, - "name": "Kore", - "symbol": "KORE", - "website_slug": "korecoin" - }, - { - "id": 405, - "name": "DigitalNote", - "symbol": "XDN", - "website_slug": "digitalnote" - }, - { - "id": 406, - "name": "Boolberry", - "symbol": "BBR", - "website_slug": "boolberry" - }, - { - "id": 411, - "name": "SHACoin", - "symbol": "SHA", - "website_slug": "shacoin" - }, - { - "id": 415, - "name": "BlazeCoin", - "symbol": "BLZ", - "website_slug": "blazecoin" - }, - { - "id": 416, - "name": "HempCoin", - "symbol": "THC", - "website_slug": "hempcoin" - }, - { - "id": 426, - "name": "BritCoin", - "symbol": "BRIT", - "website_slug": "britcoin" - }, - { - "id": 448, - "name": "Stealth", - "symbol": "XST", - "website_slug": "stealth" - }, - { - "id": 450, - "name": "TrustPlus", - "symbol": "TRUST", - "website_slug": "trustplus" - }, - { - "id": 460, - "name": "Clams", - "symbol": "CLAM", - "website_slug": "clams" - }, - { - "id": 461, - "name": "Quatloo", - "symbol": "QTL", - "website_slug": "quatloo" - }, - { - "id": 463, - "name": "BitShares", - "symbol": "BTS", - "website_slug": "bitshares" - }, - { - "id": 467, - "name": "BitcoinDark", - "symbol": "BTCD", - "website_slug": "bitcoindark" - }, - { - "id": 468, - "name": "Truckcoin", - "symbol": "TRK", - "website_slug": "truckcoin" - }, - { - "id": 470, - "name": "Viacoin", - "symbol": "VIA", - "website_slug": "viacoin" - }, - { - "id": 477, - "name": "Triangles", - "symbol": "TRI", - "website_slug": "triangles" - }, - { - "id": 495, - "name": "I/O Coin", - "symbol": "IOC", - "website_slug": "iocoin" - }, - { - "id": 501, - "name": "Cryptonite", - "symbol": "XCN", - "website_slug": "cryptonite" - }, - { - "id": 502, - "name": "Carboncoin", - "symbol": "CARBON", - "website_slug": "carboncoin" - }, - { - "id": 506, - "name": "CannabisCoin", - "symbol": "CANN", - "website_slug": "cannabiscoin" - }, - { - "id": 512, - "name": "Stellar", - "symbol": "XLM", - "website_slug": "stellar" - }, - { - "id": 513, - "name": "Titcoin", - "symbol": "TIT", - "website_slug": "titcoin" - }, - { - "id": 520, - "name": "Virtacoin", - "symbol": "VTA", - "website_slug": "virtacoin" - }, - { - "id": 525, - "name": "HyperStake", - "symbol": "HYP", - "website_slug": "hyperstake" - }, - { - "id": 536, - "name": "Joincoin", - "symbol": "J", - "website_slug": "joincoin" - }, - { - "id": 541, - "name": "Syscoin", - "symbol": "SYS", - "website_slug": "syscoin" - }, - { - "id": 543, - "name": "Bitmark", - "symbol": "BTM", - "website_slug": "bitmark" - }, - { - "id": 545, - "name": "Halcyon", - "symbol": "HAL", - "website_slug": "halcyon" - }, - { - "id": 549, - "name": "Storjcoin X", - "symbol": "SJCX", - "website_slug": "storjcoin-x" - }, - { - "id": 551, - "name": "NeosCoin", - "symbol": "NEOS", - "website_slug": "neoscoin" - }, - { - "id": 558, - "name": "Emercoin", - "symbol": "EMC", - "website_slug": "emercoin" - }, - { - "id": 572, - "name": "RabbitCoin", - "symbol": "RBBT", - "website_slug": "rabbitcoin" - }, - { - "id": 573, - "name": "Burst", - "symbol": "BURST", - "website_slug": "burst" - }, - { - "id": 576, - "name": "GameCredits", - "symbol": "GAME", - "website_slug": "gamecredits" - }, - { - "id": 584, - "name": "WeAreSatoshi", - "symbol": "WSX", - "website_slug": "wearesatoshi" - }, - { - "id": 588, - "name": "Ubiq", - "symbol": "UBQ", - "website_slug": "ubiq" - }, - { - "id": 594, - "name": "BunnyCoin", - "symbol": "BUN", - "website_slug": "bunnycoin" - }, - { - "id": 597, - "name": "Opal", - "symbol": "OPAL", - "website_slug": "opal" - }, - { - "id": 601, - "name": "Acoin", - "symbol": "ACOIN", - "website_slug": "acoin" - }, - { - "id": 606, - "name": "FoldingCoin", - "symbol": "FLDC", - "website_slug": "foldingcoin" - }, - { - "id": 623, - "name": "bitUSD", - "symbol": "BITUSD", - "website_slug": "bitusd" - }, - { - "id": 624, - "name": "bitCNY", - "symbol": "BITCNY", - "website_slug": "bitcny" - }, - { - "id": 625, - "name": "bitBTC", - "symbol": "BITBTC", - "website_slug": "bitbtc" - }, - { - "id": 626, - "name": "NuBits", - "symbol": "USNBT", - "website_slug": "nubits" - }, - { - "id": 627, - "name": "Sterlingcoin", - "symbol": "SLG", - "website_slug": "sterlingcoin" - }, - { - "id": 629, - "name": "Magi", - "symbol": "XMG", - "website_slug": "magi" - }, - { - "id": 633, - "name": "ExclusiveCoin", - "symbol": "EXCL", - "website_slug": "exclusivecoin" - }, - { - "id": 638, - "name": "Trollcoin", - "symbol": "TROLL", - "website_slug": "trollcoin" - }, - { - "id": 643, - "name": "SuperNET", - "symbol": "UNITY", - "website_slug": "supernet-unity" - }, - { - "id": 644, - "name": "GlobalBoost-Y", - "symbol": "BSTY", - "website_slug": "globalboost-y" - }, - { - "id": 654, - "name": "DigitalPrice", - "symbol": "DP", - "website_slug": "digitalprice" - }, - { - "id": 656, - "name": "Prime-XI", - "symbol": "PXI", - "website_slug": "prime-xi" - }, - { - "id": 659, - "name": "Bitswift", - "symbol": "BITS", - "website_slug": "bitswift" - }, - { - "id": 660, - "name": "Dashcoin", - "symbol": "DSH", - "website_slug": "dashcoin" - }, - { - "id": 666, - "name": "AurumCoin", - "symbol": "AU", - "website_slug": "aurumcoin" - }, - { - "id": 680, - "name": "Sativacoin", - "symbol": "STV", - "website_slug": "sativacoin" - }, - { - "id": 693, - "name": "Verge", - "symbol": "XVG", - "website_slug": "verge" - }, - { - "id": 699, - "name": "NuShares", - "symbol": "NSR", - "website_slug": "nushares" - }, - { - "id": 702, - "name": "SpreadCoin", - "symbol": "SPR", - "website_slug": "spreadcoin" - }, - { - "id": 703, - "name": "Rimbit", - "symbol": "RBT", - "website_slug": "rimbit" - }, - { - "id": 706, - "name": "MonetaryUnit", - "symbol": "MUE", - "website_slug": "monetaryunit" - }, - { - "id": 707, - "name": "Blocknet", - "symbol": "BLOCK", - "website_slug": "blocknet" - }, - { - "id": 708, - "name": "Gapcoin", - "symbol": "GAP", - "website_slug": "gapcoin" - }, - { - "id": 719, - "name": "TittieCoin", - "symbol": "TTC", - "website_slug": "tittiecoin" - }, - { - "id": 720, - "name": "Crown", - "symbol": "CRW", - "website_slug": "crown" - }, - { - "id": 723, - "name": "BitBay", - "symbol": "BAY", - "website_slug": "bitbay" - }, - { - "id": 730, - "name": "GCN Coin", - "symbol": "GCN", - "website_slug": "gcn-coin" - }, - { - "id": 733, - "name": "Quotient", - "symbol": "XQN", - "website_slug": "quotient" - }, - { - "id": 734, - "name": "Bytecent", - "symbol": "BYC", - "website_slug": "bytecent" - }, - { - "id": 747, - "name": "Bitcoin Fast", - "symbol": "BCF", - "website_slug": "bitcoinfast" - }, - { - "id": 760, - "name": "OKCash", - "symbol": "OK", - "website_slug": "okcash" - }, - { - "id": 764, - "name": "PayCoin", - "symbol": "XPY", - "website_slug": "paycoin2" - }, - { - "id": 778, - "name": "bitGold", - "symbol": "BITGOLD", - "website_slug": "bitgold" - }, - { - "id": 781, - "name": "Unitus", - "symbol": "UIS", - "website_slug": "unitus" - }, - { - "id": 785, - "name": "GoldPieces", - "symbol": "GP", - "website_slug": "goldpieces" - }, - { - "id": 788, - "name": "Circuits of Value", - "symbol": "COVAL", - "website_slug": "circuits-of-value" - }, - { - "id": 789, - "name": "Nexus", - "symbol": "NXS", - "website_slug": "nexus" - }, - { - "id": 795, - "name": "SoonCoin", - "symbol": "SOON", - "website_slug": "sooncoin" - }, - { - "id": 797, - "name": "IncaKoin", - "symbol": "NKA", - "website_slug": "incakoin" - }, - { - "id": 799, - "name": "SmileyCoin", - "symbol": "SMLY", - "website_slug": "smileycoin" - }, - { - "id": 812, - "name": "Machinecoin", - "symbol": "MAC", - "website_slug": "machinecoin" - }, - { - "id": 813, - "name": "bitSilver", - "symbol": "BITSILVER", - "website_slug": "bitsilver" - }, - { - "id": 814, - "name": "Dotcoin", - "symbol": "DOT", - "website_slug": "dotcoin" - }, - { - "id": 815, - "name": "Kobocoin", - "symbol": "KOBO", - "website_slug": "kobocoin" - }, - { - "id": 819, - "name": "Bean Cash", - "symbol": "BITB", - "website_slug": "bean-cash" - }, - { - "id": 823, - "name": "GeoCoin", - "symbol": "GEO", - "website_slug": "geocoin" - }, - { - "id": 825, - "name": "Tether", - "symbol": "USDT", - "website_slug": "tether" - }, - { - "id": 831, - "name": "Wild Beast Block", - "symbol": "WBB", - "website_slug": "wild-beast-block" - }, - { - "id": 833, - "name": "GridCoin", - "symbol": "GRC", - "website_slug": "gridcoin" - }, - { - "id": 837, - "name": "X-Coin", - "symbol": "XCO", - "website_slug": "x-coin" - }, - { - "id": 841, - "name": "Sharkcoin", - "symbol": "SAK", - "website_slug": "sharkcoin" - }, - { - "id": 853, - "name": "LiteDoge", - "symbol": "LDOGE", - "website_slug": "litedoge" - }, - { - "id": 857, - "name": "SongCoin", - "symbol": "SONG", - "website_slug": "songcoin" - }, - { - "id": 859, - "name": "Woodcoin", - "symbol": "LOG", - "website_slug": "woodcoin" - }, - { - "id": 869, - "name": "Crave", - "symbol": "CRAVE", - "website_slug": "crave" - }, - { - "id": 870, - "name": "Pura", - "symbol": "PURA", - "website_slug": "pura" - }, - { - "id": 873, - "name": "NEM", - "symbol": "XEM", - "website_slug": "nem" - }, - { - "id": 890, - "name": "8Bit", - "symbol": "8BIT", - "website_slug": "8bit" - }, - { - "id": 892, - "name": "LeaCoin", - "symbol": "LEA", - "website_slug": "leacoin" - }, - { - "id": 894, - "name": "Neutron", - "symbol": "NTRN", - "website_slug": "neutron" - }, - { - "id": 895, - "name": "Xaurum", - "symbol": "XAUR", - "website_slug": "xaurum" - }, - { - "id": 898, - "name": "Californium", - "symbol": "CF", - "website_slug": "californium" - }, - { - "id": 911, - "name": "Advanced Internet Blocks", - "symbol": "AIB", - "website_slug": "advanced-internet-blocks" - }, - { - "id": 914, - "name": "Sphere", - "symbol": "SPHR", - "website_slug": "sphere" - }, - { - "id": 916, - "name": "MedicCoin", - "symbol": "MEDIC", - "website_slug": "mediccoin" - }, - { - "id": 918, - "name": "Bubble", - "symbol": "BUB", - "website_slug": "bubble" - }, - { - "id": 920, - "name": "SounDAC", - "symbol": "XSD", - "website_slug": "bitshares-music" - }, - { - "id": 921, - "name": "Universal Currency", - "symbol": "UNIT", - "website_slug": "universal-currency" - }, - { - "id": 933, - "name": "Crypto", - "symbol": "CTO", - "website_slug": "crypto" - }, - { - "id": 934, - "name": "ParkByte", - "symbol": "PKB", - "website_slug": "parkbyte" - }, - { - "id": 938, - "name": "ARbit", - "symbol": "ARB", - "website_slug": "arbit" - }, - { - "id": 939, - "name": "Gambit", - "symbol": "GAM", - "website_slug": "gambit" - }, - { - "id": 945, - "name": "Bata", - "symbol": "BTA", - "website_slug": "bata" - }, - { - "id": 948, - "name": "AudioCoin", - "symbol": "ADC", - "website_slug": "audiocoin" - }, - { - "id": 951, - "name": "Synergy", - "symbol": "SNRG", - "website_slug": "synergy" - }, - { - "id": 954, - "name": "bitEUR", - "symbol": "BITEUR", - "website_slug": "biteur" - }, - { - "id": 959, - "name": "UniCoin", - "symbol": "UNIC", - "website_slug": "unicoin" - }, - { - "id": 960, - "name": "FujiCoin", - "symbol": "FJC", - "website_slug": "fujicoin" - }, - { - "id": 964, - "name": "EuropeCoin", - "symbol": "ERC", - "website_slug": "europecoin" - }, - { - "id": 965, - "name": "The Cypherfunks", - "symbol": "FUNK", - "website_slug": "the-cypherfunks" - }, - { - "id": 977, - "name": "Hexx", - "symbol": "HXX", - "website_slug": "hexx" - }, - { - "id": 978, - "name": "Ratecoin", - "symbol": "XRA", - "website_slug": "ratecoin" - }, - { - "id": 986, - "name": "CrevaCoin", - "symbol": "CREVA", - "website_slug": "crevacoin" - }, - { - "id": 988, - "name": "IrishCoin", - "symbol": "IRL", - "website_slug": "irishcoin" - }, - { - "id": 990, - "name": "Bitzeny", - "symbol": "ZNY", - "website_slug": "bitzeny" - }, - { - "id": 993, - "name": "BowsCoin", - "symbol": "BSC", - "website_slug": "bowscoin" - }, - { - "id": 994, - "name": "AnarchistsPrime", - "symbol": "ACP", - "website_slug": "anarchistsprime" - }, - { - "id": 998, - "name": "CompuCoin", - "symbol": "CPN", - "website_slug": "compucoin" - }, - { - "id": 999, - "name": "ChainCoin", - "symbol": "CHC", - "website_slug": "chaincoin" - }, - { - "id": 1002, - "name": "Sprouts", - "symbol": "SPRTS", - "website_slug": "sprouts" - }, - { - "id": 1004, - "name": "Helleniccoin", - "symbol": "HNC", - "website_slug": "helleniccoin" - }, - { - "id": 1008, - "name": "Capricoin", - "symbol": "CPC", - "website_slug": "capricoin" - }, - { - "id": 1010, - "name": "Flaxscript", - "symbol": "FLAX", - "website_slug": "flaxscript" - }, - { - "id": 1019, - "name": "Manna", - "symbol": "MANNA", - "website_slug": "manna" - }, - { - "id": 1020, - "name": "Axiom", - "symbol": "AXIOM", - "website_slug": "axiom" - }, - { - "id": 1022, - "name": "LEOcoin", - "symbol": "LEO", - "website_slug": "leocoin" - }, - { - "id": 1026, - "name": "Aeon", - "symbol": "AEON", - "website_slug": "aeon" - }, - { - "id": 1027, - "name": "Ethereum", - "symbol": "ETH", - "website_slug": "ethereum" - }, - { - "id": 1028, - "name": "SJWCoin", - "symbol": "SJW", - "website_slug": "sjwcoin" - }, - { - "id": 1032, - "name": "TransferCoin", - "symbol": "TX", - "website_slug": "transfercoin" - }, - { - "id": 1033, - "name": "GuccioneCoin", - "symbol": "GCC", - "website_slug": "guccionecoin" - }, - { - "id": 1035, - "name": "AmsterdamCoin", - "symbol": "AMS", - "website_slug": "amsterdamcoin" - }, - { - "id": 1038, - "name": "Eurocoin", - "symbol": "EUC", - "website_slug": "eurocoin" - }, - { - "id": 1042, - "name": "Siacoin", - "symbol": "SC", - "website_slug": "siacoin" - }, - { - "id": 1044, - "name": "Global Currency Reserve", - "symbol": "GCR", - "website_slug": "global-currency-reserve" - }, - { - "id": 1050, - "name": "Shift", - "symbol": "SHIFT", - "website_slug": "shift" - }, - { - "id": 1052, - "name": "VectorAI", - "symbol": "VEC2", - "website_slug": "vector" - }, - { - "id": 1053, - "name": "Bolivarcoin", - "symbol": "BOLI", - "website_slug": "bolivarcoin" - }, - { - "id": 1058, - "name": "SpaceCoin", - "symbol": "SPACE", - "website_slug": "spacecoin" - }, - { - "id": 1063, - "name": "Bitcrystals", - "symbol": "BCY", - "website_slug": "bitcrystals" - }, - { - "id": 1066, - "name": "Pakcoin", - "symbol": "PAK", - "website_slug": "pakcoin" - }, - { - "id": 1069, - "name": "Influxcoin", - "symbol": "INFX", - "website_slug": "influxcoin" - }, - { - "id": 1070, - "name": "Expanse", - "symbol": "EXP", - "website_slug": "expanse" - }, - { - "id": 1082, - "name": "SIBCoin", - "symbol": "SIB", - "website_slug": "sibcoin" - }, - { - "id": 1085, - "name": "Swing", - "symbol": "SWING", - "website_slug": "swing" - }, - { - "id": 1087, - "name": "Factom", - "symbol": "FCT", - "website_slug": "factom" - }, - { - "id": 1089, - "name": "ParallelCoin", - "symbol": "DUO", - "website_slug": "parallelcoin" - }, - { - "id": 1090, - "name": "Save and Gain", - "symbol": "SANDG", - "website_slug": "save-and-gain" - }, - { - "id": 1093, - "name": "Prototanium", - "symbol": "PR", - "website_slug": "prototanium" - }, - { - "id": 1104, - "name": "Augur", - "symbol": "REP", - "website_slug": "augur" - }, - { - "id": 1106, - "name": "StrongHands", - "symbol": "SHND", - "website_slug": "stronghands" - }, - { - "id": 1107, - "name": "PACcoin", - "symbol": "$PAC", - "website_slug": "paccoin" - }, - { - "id": 1109, - "name": "Elite", - "symbol": "1337", - "website_slug": "1337coin" - }, - { - "id": 1110, - "name": "Money", - "symbol": "$$$", - "website_slug": "money" - }, - { - "id": 1111, - "name": "SOILcoin", - "symbol": "SOIL", - "website_slug": "soilcoin" - }, - { - "id": 1113, - "name": "SecretCoin", - "symbol": "SCRT", - "website_slug": "secretcoin" - }, - { - "id": 1120, - "name": "DraftCoin", - "symbol": "DFT", - "website_slug": "draftcoin" - }, - { - "id": 1123, - "name": "OBITS", - "symbol": "OBITS", - "website_slug": "obits" - }, - { - "id": 1125, - "name": "Synereo", - "symbol": "AMP", - "website_slug": "synereo" - }, - { - "id": 1135, - "name": "ClubCoin", - "symbol": "CLUB", - "website_slug": "clubcoin" - }, - { - "id": 1136, - "name": "Adzcoin", - "symbol": "ADZ", - "website_slug": "adzcoin" - }, - { - "id": 1141, - "name": "Moin", - "symbol": "MOIN", - "website_slug": "moin" - }, - { - "id": 1146, - "name": "AvatarCoin", - "symbol": "AV", - "website_slug": "avatarcoin" - }, - { - "id": 1147, - "name": "RussiaCoin", - "symbol": "RC", - "website_slug": "russiacoin" - }, - { - "id": 1148, - "name": "EverGreenCoin", - "symbol": "EGC", - "website_slug": "evergreencoin" - }, - { - "id": 1153, - "name": "Creditbit", - "symbol": "CRB", - "website_slug": "creditbit" - }, - { - "id": 1154, - "name": "Radium", - "symbol": "RADS", - "website_slug": "radium" - }, - { - "id": 1155, - "name": "Litecred", - "symbol": "LTCR", - "website_slug": "litecred" - }, - { - "id": 1156, - "name": "Yocoin", - "symbol": "YOC", - "website_slug": "yocoin" - }, - { - "id": 1159, - "name": "SaluS", - "symbol": "SLS", - "website_slug": "salus" - }, - { - "id": 1164, - "name": "Francs", - "symbol": "FRN", - "website_slug": "francs" - }, - { - "id": 1165, - "name": "Evil Coin", - "symbol": "EVIL", - "website_slug": "evil-coin" - }, - { - "id": 1168, - "name": "Decred", - "symbol": "DCR", - "website_slug": "decred" - }, - { - "id": 1169, - "name": "PIVX", - "symbol": "PIVX", - "website_slug": "pivx" - }, - { - "id": 1172, - "name": "Safe Exchange Coin", - "symbol": "SAFEX", - "website_slug": "safe-exchange-coin" - }, - { - "id": 1175, - "name": "Rubies", - "symbol": "RBIES", - "website_slug": "rubies" - }, - { - "id": 1176, - "name": "Asiadigicoin", - "symbol": "ADCN", - "website_slug": "asiadigicoin" - }, - { - "id": 1185, - "name": "TrumpCoin", - "symbol": "TRUMP", - "website_slug": "trumpcoin" - }, - { - "id": 1191, - "name": "Memetic / PepeCoin", - "symbol": "MEME", - "website_slug": "memetic" - }, - { - "id": 1193, - "name": "C-Bit", - "symbol": "XCT", - "website_slug": "c-bit" - }, - { - "id": 1194, - "name": "Independent Money System", - "symbol": "IMS", - "website_slug": "independent-money-system" - }, - { - "id": 1195, - "name": "HOdlcoin", - "symbol": "HODL", - "website_slug": "hodlcoin" - }, - { - "id": 1198, - "name": "BigUp", - "symbol": "BIGUP", - "website_slug": "bigup" - }, - { - "id": 1200, - "name": "NevaCoin", - "symbol": "NEVA", - "website_slug": "nevacoin" - }, - { - "id": 1206, - "name": "BumbaCoin", - "symbol": "BUMBA", - "website_slug": "bumbacoin" - }, - { - "id": 1208, - "name": "RevolutionVR", - "symbol": "RVR", - "website_slug": "revolutionvr" - }, - { - "id": 1209, - "name": "PosEx", - "symbol": "PEX", - "website_slug": "posex" - }, - { - "id": 1210, - "name": "Cabbage", - "symbol": "CAB", - "website_slug": "cabbage" - }, - { - "id": 1212, - "name": "MojoCoin", - "symbol": "MOJO", - "website_slug": "mojocoin" - }, - { - "id": 1213, - "name": "GoldMaxCoin", - "symbol": "GMX", - "website_slug": "goldmaxcoin" - }, - { - "id": 1214, - "name": "Lisk", - "symbol": "LSK", - "website_slug": "lisk" - }, - { - "id": 1216, - "name": "EDRCoin", - "symbol": "EDRC", - "website_slug": "edrcoin" - }, - { - "id": 1218, - "name": "PostCoin", - "symbol": "POST", - "website_slug": "postcoin" - }, - { - "id": 1223, - "name": "BERNcash", - "symbol": "BERN", - "website_slug": "berncash" - }, - { - "id": 1226, - "name": "Qwark", - "symbol": "QWARK", - "website_slug": "qwark" - }, - { - "id": 1229, - "name": "DigixDAO", - "symbol": "DGD", - "website_slug": "digixdao" - }, - { - "id": 1230, - "name": "Steem", - "symbol": "STEEM", - "website_slug": "steem" - }, - { - "id": 1234, - "name": "Fantasy Cash", - "symbol": "FANS", - "website_slug": "fantasy-cash" - }, - { - "id": 1238, - "name": "Espers", - "symbol": "ESP", - "website_slug": "espers" - }, - { - "id": 1241, - "name": "FuzzBalls", - "symbol": "FUZZ", - "website_slug": "fuzzballs" - }, - { - "id": 1244, - "name": "HiCoin", - "symbol": "XHI", - "website_slug": "hicoin" - }, - { - "id": 1247, - "name": "AquariusCoin", - "symbol": "ARCO", - "website_slug": "aquariuscoin" - }, - { - "id": 1248, - "name": "Bitcoin 21", - "symbol": "XBTC21", - "website_slug": "bitcoin-21" - }, - { - "id": 1249, - "name": "Elcoin", - "symbol": "EL", - "website_slug": "elcoin-el" - }, - { - "id": 1250, - "name": "Zurcoin", - "symbol": "ZUR", - "website_slug": "zurcoin" - }, - { - "id": 1251, - "name": "SixEleven", - "symbol": "611", - "website_slug": "sixeleven" - }, - { - "id": 1252, - "name": "2GIVE", - "symbol": "2GIVE", - "website_slug": "2give" - }, - { - "id": 1254, - "name": "PlatinumBAR", - "symbol": "XPTX", - "website_slug": "platinumbar" - }, - { - "id": 1256, - "name": "Alphabit", - "symbol": "ABC", - "website_slug": "alphabitcoinfund" - }, - { - "id": 1257, - "name": "LanaCoin", - "symbol": "LANA", - "website_slug": "lanacoin" - }, - { - "id": 1259, - "name": "PonziCoin", - "symbol": "PONZI", - "website_slug": "ponzicoin" - }, - { - "id": 1264, - "name": "TeslaCoilCoin", - "symbol": "TESLA", - "website_slug": "teslacoilcoin" - }, - { - "id": 1266, - "name": "MarteXcoin", - "symbol": "MXT", - "website_slug": "martexcoin" - }, - { - "id": 1268, - "name": "Nullex", - "symbol": "NLX", - "website_slug": "nullex" - }, - { - "id": 1269, - "name": "RichCoin", - "symbol": "RICHX", - "website_slug": "richcoin" - }, - { - "id": 1273, - "name": "Citadel", - "symbol": "CTL", - "website_slug": "citadel" - }, - { - "id": 1274, - "name": "Waves", - "symbol": "WAVES", - "website_slug": "waves" - }, - { - "id": 1276, - "name": "ICO OpenLedger", - "symbol": "ICOO", - "website_slug": "ico-openledger" - }, - { - "id": 1279, - "name": "Powercoin", - "symbol": "PWR", - "website_slug": "powercoin" - }, - { - "id": 1281, - "name": "ION", - "symbol": "ION", - "website_slug": "ion" - }, - { - "id": 1282, - "name": "High Voltage", - "symbol": "HVCO", - "website_slug": "high-voltage" - }, - { - "id": 1284, - "name": "RevolverCoin", - "symbol": "XRE", - "website_slug": "revolvercoin" - }, - { - "id": 1285, - "name": "GoldBlocks", - "symbol": "GB", - "website_slug": "goldblocks" - }, - { - "id": 1286, - "name": "Breakout", - "symbol": "BRK", - "website_slug": "breakout" - }, - { - "id": 1288, - "name": "Debitcoin", - "symbol": "DBTC", - "website_slug": "debitcoin" - }, - { - "id": 1291, - "name": "Comet", - "symbol": "CMT", - "website_slug": "comet" - }, - { - "id": 1294, - "name": "Rise", - "symbol": "RISE", - "website_slug": "rise" - }, - { - "id": 1297, - "name": "ChessCoin", - "symbol": "CHESS", - "website_slug": "chesscoin" - }, - { - "id": 1298, - "name": "LBRY Credits", - "symbol": "LBC", - "website_slug": "library-credit" - }, - { - "id": 1299, - "name": "PutinCoin", - "symbol": "PUT", - "website_slug": "putincoin" - }, - { - "id": 1303, - "name": "Breakout Stake", - "symbol": "BRX", - "website_slug": "breakout-stake" - }, - { - "id": 1304, - "name": "Syndicate", - "symbol": "SYNX", - "website_slug": "syndicate" - }, - { - "id": 1306, - "name": "Cryptojacks", - "symbol": "CJ", - "website_slug": "cryptojacks" - }, - { - "id": 1308, - "name": "HEAT", - "symbol": "HEAT", - "website_slug": "heat-ledger" - }, - { - "id": 1312, - "name": "Steem Dollars", - "symbol": "SBD", - "website_slug": "steem-dollars" - }, - { - "id": 1320, - "name": "Ardor", - "symbol": "ARDR", - "website_slug": "ardor" - }, - { - "id": 1321, - "name": "Ethereum Classic", - "symbol": "ETC", - "website_slug": "ethereum-classic" - }, - { - "id": 1322, - "name": "808Coin", - "symbol": "808", - "website_slug": "808coin" - }, - { - "id": 1323, - "name": "First Bitcoin", - "symbol": "BIT", - "website_slug": "first-bitcoin" - }, - { - "id": 1334, - "name": "Elementrem", - "symbol": "ELE", - "website_slug": "elementrem" - }, - { - "id": 1340, - "name": "Karbo", - "symbol": "KRB", - "website_slug": "karbo" - }, - { - "id": 1341, - "name": "VapersCoin", - "symbol": "VPRC", - "website_slug": "vaperscoin" - }, - { - "id": 1343, - "name": "Stratis", - "symbol": "STRAT", - "website_slug": "stratis" - }, - { - "id": 1348, - "name": "President Trump", - "symbol": "PRES", - "website_slug": "president-trump" - }, - { - "id": 1351, - "name": "Aces", - "symbol": "ACES", - "website_slug": "aces" - }, - { - "id": 1352, - "name": "President Johnson", - "symbol": "GARY", - "website_slug": "president-johnson" - }, - { - "id": 1353, - "name": "TajCoin", - "symbol": "TAJ", - "website_slug": "tajcoin" - }, - { - "id": 1358, - "name": "E-Dinar Coin", - "symbol": "EDR", - "website_slug": "e-dinar-coin" - }, - { - "id": 1361, - "name": "Artex Coin", - "symbol": "ATX", - "website_slug": "artex-coin" - }, - { - "id": 1367, - "name": "Experience Points", - "symbol": "XP", - "website_slug": "experience-points" - }, - { - "id": 1368, - "name": "Veltor", - "symbol": "VLT", - "website_slug": "veltor" - }, - { - "id": 1371, - "name": "B3Coin", - "symbol": "KB3", - "website_slug": "b3coin" - }, - { - "id": 1375, - "name": "Golfcoin", - "symbol": "GOLF", - "website_slug": "golfcoin" - }, - { - "id": 1376, - "name": "NEO", - "symbol": "NEO", - "website_slug": "neo" - }, - { - "id": 1380, - "name": "LoMoCoin", - "symbol": "LMC", - "website_slug": "lomocoin" - }, - { - "id": 1381, - "name": "Bitcloud", - "symbol": "BTDX", - "website_slug": "bitcloud" - }, - { - "id": 1382, - "name": "NoLimitCoin", - "symbol": "NLC2", - "website_slug": "nolimitcoin" - }, - { - "id": 1387, - "name": "VeriumReserve", - "symbol": "VRM", - "website_slug": "veriumreserve" - }, - { - "id": 1389, - "name": "Zayedcoin", - "symbol": "ZYD", - "website_slug": "zayedcoin" - }, - { - "id": 1390, - "name": "Jin Coin", - "symbol": "JIN", - "website_slug": "jin-coin" - }, - { - "id": 1391, - "name": "Tao", - "symbol": "XTO", - "website_slug": "tao" - }, - { - "id": 1392, - "name": "Pluton", - "symbol": "PLU", - "website_slug": "pluton" - }, - { - "id": 1393, - "name": "Tellurion", - "symbol": "TELL", - "website_slug": "tellurion" - }, - { - "id": 1395, - "name": "Dollarcoin", - "symbol": "DLC", - "website_slug": "dollarcoin" - }, - { - "id": 1396, - "name": "MustangCoin", - "symbol": "MST", - "website_slug": "mustangcoin" - }, - { - "id": 1398, - "name": "PROUD Money", - "symbol": "PROUD", - "website_slug": "proud-money" - }, - { - "id": 1399, - "name": "Sequence", - "symbol": "SEQ", - "website_slug": "sequence" - }, - { - "id": 1400, - "name": "Omicron", - "symbol": "OMC", - "website_slug": "omicron" - }, - { - "id": 1403, - "name": "FirstBlood", - "symbol": "1ST", - "website_slug": "firstblood" - }, - { - "id": 1405, - "name": "Pepe Cash", - "symbol": "PEPECASH", - "website_slug": "pepe-cash" - }, - { - "id": 1408, - "name": "Iconomi", - "symbol": "ICN", - "website_slug": "iconomi" - }, - { - "id": 1409, - "name": "SingularDTV", - "symbol": "SNGLS", - "website_slug": "singulardtv" - }, - { - "id": 1414, - "name": "ZCoin", - "symbol": "XZC", - "website_slug": "zcoin" - }, - { - "id": 1418, - "name": "Rcoin", - "symbol": "RCN", - "website_slug": "rcoin" - }, - { - "id": 1420, - "name": "Atomic Coin", - "symbol": "ATOM", - "website_slug": "atomic-coin" - }, - { - "id": 1421, - "name": "JobsCoin", - "symbol": "JOBS", - "website_slug": "jobscoin" - }, - { - "id": 1423, - "name": "Triggers", - "symbol": "TRIG", - "website_slug": "triggers" - }, - { - "id": 1425, - "name": "Sakuracoin", - "symbol": "SKR", - "website_slug": "sakuracoin" - }, - { - "id": 1429, - "name": "Levocoin", - "symbol": "LEVO", - "website_slug": "levocoin" - }, - { - "id": 1434, - "name": "Advanced Technology Coin", - "symbol": "ARC", - "website_slug": "arcticcoin" - }, - { - "id": 1435, - "name": "Cubits", - "symbol": "QBT", - "website_slug": "cubits" - }, - { - "id": 1436, - "name": "DynamicCoin", - "symbol": "DMC", - "website_slug": "dynamiccoin" - }, - { - "id": 1437, - "name": "Zcash", - "symbol": "ZEC", - "website_slug": "zcash" - }, - { - "id": 1439, - "name": "AllSafe", - "symbol": "ASAFE2", - "website_slug": "allsafe" - }, - { - "id": 1442, - "name": "BipCoin", - "symbol": "BIP", - "website_slug": "bipcoin" - }, - { - "id": 1447, - "name": "ZClassic", - "symbol": "ZCL", - "website_slug": "zclassic" - }, - { - "id": 1448, - "name": "Zoin", - "symbol": "ZOI", - "website_slug": "zoin" - }, - { - "id": 1449, - "name": "WA Space", - "symbol": "WA", - "website_slug": "wa-space" - }, - { - "id": 1454, - "name": "Lykke", - "symbol": "LKK", - "website_slug": "lykke" - }, - { - "id": 1455, - "name": "Golem", - "symbol": "GNT", - "website_slug": "golem-network-tokens" - }, - { - "id": 1456, - "name": "ZetaMicron", - "symbol": "ZMC", - "website_slug": "zetamicron" - }, - { - "id": 1457, - "name": "Bitcurrency", - "symbol": "BTCR", - "website_slug": "bitcurrency" - }, - { - "id": 1459, - "name": "Regacoin", - "symbol": "REGA", - "website_slug": "regacoin" - }, - { - "id": 1464, - "name": "Internet of People", - "symbol": "IOP", - "website_slug": "internet-of-people" - }, - { - "id": 1465, - "name": "Veros", - "symbol": "VRS", - "website_slug": "veros" - }, - { - "id": 1466, - "name": "Hush", - "symbol": "HUSH", - "website_slug": "hush" - }, - { - "id": 1468, - "name": "Kurrent", - "symbol": "KURT", - "website_slug": "kurrent" - }, - { - "id": 1473, - "name": "Pascal Coin", - "symbol": "PASC", - "website_slug": "pascal-coin" - }, - { - "id": 1474, - "name": "Eternity", - "symbol": "ENT", - "website_slug": "eternity" - }, - { - "id": 1475, - "name": "Incent", - "symbol": "INCNT", - "website_slug": "incent" - }, - { - "id": 1478, - "name": "DECENT", - "symbol": "DCT", - "website_slug": "decent" - }, - { - "id": 1480, - "name": "Golos", - "symbol": "GOLOS", - "website_slug": "golos" - }, - { - "id": 1481, - "name": "Nexium", - "symbol": "NXC", - "website_slug": "nexium" - }, - { - "id": 1483, - "name": "vSlice", - "symbol": "VSL", - "website_slug": "vslice" - }, - { - "id": 1485, - "name": "Dollar Online", - "symbol": "DOLLAR", - "website_slug": "dollar-online" - }, - { - "id": 1486, - "name": "Vault Coin", - "symbol": "VLTC", - "website_slug": "vault-coin" - }, - { - "id": 1487, - "name": "Pabyosi Coin (Special)", - "symbol": "PCS", - "website_slug": "pabyosi-coin-special" - }, - { - "id": 1489, - "name": "T-coin", - "symbol": "TCOIN", - "website_slug": "t-coin" - }, - { - "id": 1492, - "name": "Byteball Bytes", - "symbol": "GBYTE", - "website_slug": "byteball" - }, - { - "id": 1495, - "name": "PoSW Coin", - "symbol": "POSW", - "website_slug": "posw-coin" - }, - { - "id": 1496, - "name": "Luna Coin", - "symbol": "LUNA", - "website_slug": "luna-coin" - }, - { - "id": 1497, - "name": "Fargocoin", - "symbol": "FRGC", - "website_slug": "fargocoin" - }, - { - "id": 1500, - "name": "Wings", - "symbol": "WINGS", - "website_slug": "wings" - }, - { - "id": 1501, - "name": "Dix Asset", - "symbol": "DIX", - "website_slug": "dix-asset" - }, - { - "id": 1503, - "name": "Darcrus", - "symbol": "DAR", - "website_slug": "darcrus" - }, - { - "id": 1504, - "name": "InflationCoin", - "symbol": "IFLT", - "website_slug": "inflationcoin" - }, - { - "id": 1505, - "name": "Spectrecoin", - "symbol": "XSPEC", - "website_slug": "spectrecoin" - }, - { - "id": 1506, - "name": "Safe Trade Coin", - "symbol": "XSTC", - "website_slug": "safe-trade-coin" - }, - { - "id": 1509, - "name": "BenjiRolls", - "symbol": "BENJI", - "website_slug": "benjirolls" - }, - { - "id": 1510, - "name": "CryptoCarbon", - "symbol": "CCRB", - "website_slug": "cryptocarbon" - }, - { - "id": 1511, - "name": "PureVidz", - "symbol": "VIDZ", - "website_slug": "purevidz" - }, - { - "id": 1513, - "name": "BitConnect", - "symbol": "BCC", - "website_slug": "bitconnect" - }, - { - "id": 1514, - "name": "ICOBID", - "symbol": "ICOB", - "website_slug": "icobid" - }, - { - "id": 1515, - "name": "iBank", - "symbol": "IBANK", - "website_slug": "ibank" - }, - { - "id": 1518, - "name": "Maker", - "symbol": "MKR", - "website_slug": "maker" - }, - { - "id": 1520, - "name": "Digital Rupees", - "symbol": "DRS", - "website_slug": "digital-rupees" - }, - { - "id": 1521, - "name": "Komodo", - "symbol": "KMD", - "website_slug": "komodo" - }, - { - "id": 1522, - "name": "FirstCoin", - "symbol": "FRST", - "website_slug": "firstcoin" - }, - { - "id": 1523, - "name": "Magnum", - "symbol": "MGM", - "website_slug": "magnum" - }, - { - "id": 1524, - "name": "Tattoocoin (Standard Edition)", - "symbol": "TSE", - "website_slug": "tattoocoin" - }, - { - "id": 1525, - "name": "Solarflarecoin", - "symbol": "SFC", - "website_slug": "solarflarecoin" - }, - { - "id": 1527, - "name": "Waves Community Token", - "symbol": "WCT", - "website_slug": "waves-community-token" - }, - { - "id": 1528, - "name": "Iconic", - "symbol": "ICON", - "website_slug": "iconic" - }, - { - "id": 1529, - "name": "KushCoin", - "symbol": "KUSH", - "website_slug": "kushcoin" - }, - { - "id": 1531, - "name": "Global Cryptocurrency", - "symbol": "GCC", - "website_slug": "global-cryptocurrency" - }, - { - "id": 1534, - "name": "BOAT", - "symbol": "BOAT", - "website_slug": "doubloon" - }, - { - "id": 1535, - "name": "Eryllium", - "symbol": "ERY", - "website_slug": "eryllium" - }, - { - "id": 1539, - "name": "Elysium", - "symbol": "ELS", - "website_slug": "elysium" - }, - { - "id": 1542, - "name": "Golos Gold", - "symbol": "GBG", - "website_slug": "golos-gold" - }, - { - "id": 1546, - "name": "Centurion", - "symbol": "CNT", - "website_slug": "centurion" - }, - { - "id": 1548, - "name": "Marijuanacoin", - "symbol": "MAR", - "website_slug": "marijuanacoin" - }, - { - "id": 1550, - "name": "Master Swiscoin", - "symbol": "MSCN", - "website_slug": "master-swiscoin" - }, - { - "id": 1552, - "name": "Melon", - "symbol": "MLN", - "website_slug": "melon" - }, - { - "id": 1554, - "name": "Allion", - "symbol": "ALL", - "website_slug": "allion" - }, - { - "id": 1555, - "name": "PRCoin", - "symbol": "PRC", - "website_slug": "prcoin" - }, - { - "id": 1556, - "name": "Chronobank", - "symbol": "TIME", - "website_slug": "chronobank" - }, - { - "id": 1558, - "name": "Argus", - "symbol": "ARGUS", - "website_slug": "argus" - }, - { - "id": 1559, - "name": "Renos", - "symbol": "RNS", - "website_slug": "renos" - }, - { - "id": 1562, - "name": "Swarm City", - "symbol": "SWT", - "website_slug": "swarm-city" - }, - { - "id": 1563, - "name": "PIECoin", - "symbol": "PIE", - "website_slug": "piecoin" - }, - { - "id": 1565, - "name": "MarxCoin", - "symbol": "MARX", - "website_slug": "marxcoin" - }, - { - "id": 1566, - "name": "Visio", - "symbol": "VISIO", - "website_slug": "visio" - }, - { - "id": 1567, - "name": "Nano", - "symbol": "NANO", - "website_slug": "nano" - }, - { - "id": 1568, - "name": "LevoPlus", - "symbol": "LVPS", - "website_slug": "levoplus" - }, - { - "id": 1570, - "name": "GeertCoin", - "symbol": "GEERT", - "website_slug": "geertcoin" - }, - { - "id": 1575, - "name": "Pascal Lite", - "symbol": "PASL", - "website_slug": "pascal-lite" - }, - { - "id": 1576, - "name": "MiloCoin", - "symbol": "MILO", - "website_slug": "milocoin" - }, - { - "id": 1577, - "name": "Musicoin", - "symbol": "MUSIC", - "website_slug": "musicoin" - }, - { - "id": 1578, - "name": "Zero", - "symbol": "ZER", - "website_slug": "zero" - }, - { - "id": 1581, - "name": "Honey", - "symbol": "HONEY", - "website_slug": "honey" - }, - { - "id": 1582, - "name": "Netko", - "symbol": "NETKO", - "website_slug": "netko" - }, - { - "id": 1586, - "name": "Ark", - "symbol": "ARK", - "website_slug": "ark" - }, - { - "id": 1587, - "name": "Dynamic", - "symbol": "DYN", - "website_slug": "dynamic" - }, - { - "id": 1588, - "name": "Tokes", - "symbol": "TKS", - "website_slug": "tokes" - }, - { - "id": 1590, - "name": "Mercury", - "symbol": "MER", - "website_slug": "mercury" - }, - { - "id": 1592, - "name": "TaaS", - "symbol": "TAAS", - "website_slug": "taas" - }, - { - "id": 1595, - "name": "Soarcoin", - "symbol": "SOAR", - "website_slug": "soarcoin" - }, - { - "id": 1596, - "name": "Edgeless", - "symbol": "EDG", - "website_slug": "edgeless" - }, - { - "id": 1597, - "name": "Bankcoin", - "symbol": "B@", - "website_slug": "bankcoin" - }, - { - "id": 1598, - "name": "ZSEcoin", - "symbol": "ZSE", - "website_slug": "zsecoin" - }, - { - "id": 1602, - "name": "HealthyWormCoin", - "symbol": "WORM", - "website_slug": "healthywormcoin" - }, - { - "id": 1603, - "name": "Databits", - "symbol": "DTB", - "website_slug": "databits" - }, - { - "id": 1605, - "name": "Universe", - "symbol": "UNI", - "website_slug": "universe" - }, - { - "id": 1606, - "name": "Solaris", - "symbol": "XLR", - "website_slug": "solaris" - }, - { - "id": 1607, - "name": "Impact", - "symbol": "IMX", - "website_slug": "impact" - }, - { - "id": 1609, - "name": "Asch", - "symbol": "XAS", - "website_slug": "asch" - }, - { - "id": 1611, - "name": "DubaiCoin", - "symbol": "DBIX", - "website_slug": "dubaicoin-dbix" - }, - { - "id": 1614, - "name": "Darsek", - "symbol": "KED", - "website_slug": "darsek" - }, - { - "id": 1616, - "name": "Matchpool", - "symbol": "GUP", - "website_slug": "guppy" - }, - { - "id": 1617, - "name": "Ultimate Secure Cash", - "symbol": "USC", - "website_slug": "ultimate-secure-cash" - }, - { - "id": 1618, - "name": "E-coin", - "symbol": "ECN", - "website_slug": "e-coin" - }, - { - "id": 1619, - "name": "Skycoin", - "symbol": "SKY", - "website_slug": "skycoin" - }, - { - "id": 1623, - "name": "BlazerCoin", - "symbol": "BLAZR", - "website_slug": "blazercoin" - }, - { - "id": 1624, - "name": "Atmos", - "symbol": "ATMOS", - "website_slug": "atmos" - }, - { - "id": 1626, - "name": "InPay", - "symbol": "INPAY", - "website_slug": "inpay" - }, - { - "id": 1628, - "name": "Happycoin", - "symbol": "HPC", - "website_slug": "happycoin" - }, - { - "id": 1629, - "name": "Zennies", - "symbol": "ZENI", - "website_slug": "zennies" - }, - { - "id": 1630, - "name": "Coinonat", - "symbol": "CXT", - "website_slug": "coinonat" - }, - { - "id": 1631, - "name": "Internet of Things", - "symbol": "XOT", - "website_slug": "internet-of-things" - }, - { - "id": 1632, - "name": "Concoin", - "symbol": "CONX", - "website_slug": "concoin" - }, - { - "id": 1636, - "name": "XTRABYTES", - "symbol": "XBY", - "website_slug": "xtrabytes" - }, - { - "id": 1637, - "name": "iExec RLC", - "symbol": "RLC", - "website_slug": "rlc" - }, - { - "id": 1638, - "name": "WeTrust", - "symbol": "TRST", - "website_slug": "trust" - }, - { - "id": 1640, - "name": "DeusCoin", - "symbol": "DEUS", - "website_slug": "deuscoin" - }, - { - "id": 1642, - "name": "Altcoin", - "symbol": "ALT", - "website_slug": "altcoin-alt" - }, - { - "id": 1643, - "name": "WavesGo", - "symbol": "WGO", - "website_slug": "wavesgo" - }, - { - "id": 1644, - "name": "MACRON", - "symbol": "MCRN", - "website_slug": "macron" - }, - { - "id": 1647, - "name": "Tattoocoin (Limited Edition)", - "symbol": "TLE", - "website_slug": "tattoocoin-limited" - }, - { - "id": 1650, - "name": "ProCurrency", - "symbol": "PROC", - "website_slug": "procurrency" - }, - { - "id": 1651, - "name": "SpeedCash", - "symbol": "SCS", - "website_slug": "speedcash" - }, - { - "id": 1654, - "name": "Bitcore", - "symbol": "BTX", - "website_slug": "bitcore" - }, - { - "id": 1657, - "name": "Bitvolt", - "symbol": "VOLT", - "website_slug": "bitvolt" - }, - { - "id": 1658, - "name": "Lunyr", - "symbol": "LUN", - "website_slug": "lunyr" - }, - { - "id": 1659, - "name": "Gnosis", - "symbol": "GNO", - "website_slug": "gnosis-gno" - }, - { - "id": 1660, - "name": "TokenCard", - "symbol": "TKN", - "website_slug": "tokencard" - }, - { - "id": 1662, - "name": "Condensate", - "symbol": "RAIN", - "website_slug": "condensate" - }, - { - "id": 1665, - "name": "Gold Pressed Latinum", - "symbol": "GPL", - "website_slug": "gold-pressed-latinum" - }, - { - "id": 1669, - "name": "Humaniq", - "symbol": "HMQ", - "website_slug": "humaniq" - }, - { - "id": 1671, - "name": "iTicoin", - "symbol": "ITI", - "website_slug": "iticoin" - }, - { - "id": 1673, - "name": "Minereum", - "symbol": "MNE", - "website_slug": "minereum" - }, - { - "id": 1674, - "name": "Cannation", - "symbol": "CNNC", - "website_slug": "cannation" - }, - { - "id": 1676, - "name": "Creativecoin", - "symbol": "CREA", - "website_slug": "creativecoin" - }, - { - "id": 1677, - "name": "Etheroll", - "symbol": "DICE", - "website_slug": "etheroll" - }, - { - "id": 1678, - "name": "InsaneCoin", - "symbol": "INSN", - "website_slug": "insanecoin-insn" - }, - { - "id": 1679, - "name": "Halloween Coin", - "symbol": "HALLO", - "website_slug": "halloween-coin" - }, - { - "id": 1680, - "name": "Aragon", - "symbol": "ANT", - "website_slug": "aragon" - }, - { - "id": 1681, - "name": "PRIZM", - "symbol": "PZM", - "website_slug": "prizm" - }, - { - "id": 1683, - "name": "RouletteToken", - "symbol": "RLT", - "website_slug": "roulettetoken" - }, - { - "id": 1684, - "name": "Qtum", - "symbol": "QTUM", - "website_slug": "qtum" - }, - { - "id": 1685, - "name": "EcoCoin", - "symbol": "ECO", - "website_slug": "ecocoin" - }, - { - "id": 1686, - "name": "EquiTrader", - "symbol": "EQT", - "website_slug": "equitrader" - }, - { - "id": 1687, - "name": "Digital Money Bits", - "symbol": "DMB", - "website_slug": "digital-money-bits" - }, - { - "id": 1688, - "name": "APX", - "symbol": "APX", - "website_slug": "apx" - }, - { - "id": 1690, - "name": "MCAP", - "symbol": "MCAP", - "website_slug": "mcap" - }, - { - "id": 1691, - "name": "Project-X", - "symbol": "NANOX", - "website_slug": "project-x" - }, - { - "id": 1693, - "name": "Theresa May Coin", - "symbol": "MAY", - "website_slug": "theresa-may-coin" - }, - { - "id": 1694, - "name": "Sumokoin", - "symbol": "SUMO", - "website_slug": "sumokoin" - }, - { - "id": 1695, - "name": "ZenGold", - "symbol": "ZENGOLD", - "website_slug": "zengold" - }, - { - "id": 1697, - "name": "Basic Attention Token", - "symbol": "BAT", - "website_slug": "basic-attention-token" - }, - { - "id": 1698, - "name": "Horizen", - "symbol": "ZEN", - "website_slug": "zencash" - }, - { - "id": 1699, - "name": "Ethbits", - "symbol": "ETBS", - "website_slug": "ethbits" - }, - { - "id": 1700, - "name": "Aeternity", - "symbol": "AE", - "website_slug": "aeternity" - }, - { - "id": 1702, - "name": "Version", - "symbol": "V", - "website_slug": "version" - }, - { - "id": 1703, - "name": "Metaverse ETP", - "symbol": "ETP", - "website_slug": "metaverse" - }, - { - "id": 1704, - "name": "eBoost", - "symbol": "EBST", - "website_slug": "eboostcoin" - }, - { - "id": 1706, - "name": "Aidos Kuneen", - "symbol": "ADK", - "website_slug": "aidos-kuneen" - }, - { - "id": 1707, - "name": "STEX", - "symbol": "STEX", - "website_slug": "stex" - }, - { - "id": 1708, - "name": "Patientory", - "symbol": "PTOY", - "website_slug": "patientory" - }, - { - "id": 1709, - "name": "Quantum", - "symbol": "QAU", - "website_slug": "quantum" - }, - { - "id": 1710, - "name": "Veritaseum", - "symbol": "VERI", - "website_slug": "veritaseum" - }, - { - "id": 1711, - "name": "Electra", - "symbol": "ECA", - "website_slug": "electra" - }, - { - "id": 1712, - "name": "Quantum Resistant Ledger", - "symbol": "QRL", - "website_slug": "quantum-resistant-ledger" - }, - { - "id": 1714, - "name": "EncryptoTel [WAVES]", - "symbol": "ETT", - "website_slug": "encryptotel" - }, - { - "id": 1715, - "name": "MobileGo", - "symbol": "MGO", - "website_slug": "mobilego" - }, - { - "id": 1716, - "name": "Ammo Reloaded", - "symbol": "AMMO", - "website_slug": "ammo-reloaded" - }, - { - "id": 1717, - "name": "Neuro", - "symbol": "NRO", - "website_slug": "neuro" - }, - { - "id": 1719, - "name": "Peerplays", - "symbol": "PPY", - "website_slug": "peerplays-ppy" - }, - { - "id": 1720, - "name": "IOTA", - "symbol": "MIOTA", - "website_slug": "iota" - }, - { - "id": 1721, - "name": "Mysterium", - "symbol": "MYST", - "website_slug": "mysterium" - }, - { - "id": 1722, - "name": "More Coin", - "symbol": "MORE", - "website_slug": "more-coin" - }, - { - "id": 1723, - "name": "SONM", - "symbol": "SNM", - "website_slug": "sonm" - }, - { - "id": 1724, - "name": "Linx", - "symbol": "LINX", - "website_slug": "linx" - }, - { - "id": 1726, - "name": "ZrCoin", - "symbol": "ZRC", - "website_slug": "zrcoin" - }, - { - "id": 1727, - "name": "Bancor", - "symbol": "BNT", - "website_slug": "bancor" - }, - { - "id": 1728, - "name": "Cheapcoin", - "symbol": "CHEAP", - "website_slug": "cheapcoin" - }, - { - "id": 1729, - "name": "Cofound.it", - "symbol": "CFI", - "website_slug": "cofound-it" - }, - { - "id": 1731, - "name": "GlobalToken", - "symbol": "GLT", - "website_slug": "globaltoken" - }, - { - "id": 1732, - "name": "Numeraire", - "symbol": "NMR", - "website_slug": "numeraire" - }, - { - "id": 1733, - "name": "Octanox", - "symbol": "OTX", - "website_slug": "octanox" - }, - { - "id": 1736, - "name": "Unify", - "symbol": "UNIFY", - "website_slug": "unify" - }, - { - "id": 1737, - "name": "Elastic", - "symbol": "XEL", - "website_slug": "elastic" - }, - { - "id": 1738, - "name": "Coupecoin", - "symbol": "COUPE", - "website_slug": "coupecoin" - }, - { - "id": 1739, - "name": "Miners' Reward Token", - "symbol": "MRT", - "website_slug": "miners-reward-token" - }, - { - "id": 1741, - "name": "Bitok", - "symbol": "BITOK", - "website_slug": "bitok" - }, - { - "id": 1742, - "name": "Huncoin", - "symbol": "HNC", - "website_slug": "huncoin" - }, - { - "id": 1743, - "name": "KingN Coin", - "symbol": "KNC", - "website_slug": "kingn-coin" - }, - { - "id": 1745, - "name": "Dinastycoin", - "symbol": "DCY", - "website_slug": "dinastycoin" - }, - { - "id": 1746, - "name": "Leviar", - "symbol": "XLC", - "website_slug": "leviar" - }, - { - "id": 1747, - "name": "Onix", - "symbol": "ONX", - "website_slug": "onix" - }, - { - "id": 1748, - "name": "Bitcoin Planet", - "symbol": "BTPL", - "website_slug": "bitcoin-planet" - }, - { - "id": 1750, - "name": "GXChain", - "symbol": "GXS", - "website_slug": "gxchain" - }, - { - "id": 1751, - "name": "ATC Coin", - "symbol": "ATCC", - "website_slug": "atc-coin" - }, - { - "id": 1752, - "name": "Goodomy", - "symbol": "GOOD", - "website_slug": "goodomy" - }, - { - "id": 1753, - "name": "Antimatter", - "symbol": "ANTX", - "website_slug": "antimatter" - }, - { - "id": 1754, - "name": "Bitradio", - "symbol": "BRO", - "website_slug": "bitradio" - }, - { - "id": 1755, - "name": "Flash", - "symbol": "FLASH", - "website_slug": "flash" - }, - { - "id": 1757, - "name": "FunFair", - "symbol": "FUN", - "website_slug": "funfair" - }, - { - "id": 1758, - "name": "TenX", - "symbol": "PAY", - "website_slug": "tenx" - }, - { - "id": 1759, - "name": "Status", - "symbol": "SNT", - "website_slug": "status" - }, - { - "id": 1760, - "name": "ChanCoin", - "symbol": "CHAN", - "website_slug": "chancoin" - }, - { - "id": 1762, - "name": "Ergo", - "symbol": "EFYT", - "website_slug": "ergo" - }, - { - "id": 1763, - "name": "BriaCoin", - "symbol": "BRIA", - "website_slug": "briacoin" - }, - { - "id": 1765, - "name": "EOS", - "symbol": "EOS", - "website_slug": "eos" - }, - { - "id": 1767, - "name": "TurboCoin", - "symbol": "TURBO", - "website_slug": "turbocoin" - }, - { - "id": 1768, - "name": "AdEx", - "symbol": "ADX", - "website_slug": "adx-net" - }, - { - "id": 1769, - "name": "Denarius", - "symbol": "DNR", - "website_slug": "denarius-dnr" - }, - { - "id": 1771, - "name": "DAO.Casino", - "symbol": "BET", - "website_slug": "dao-casino" - }, - { - "id": 1772, - "name": "Storj", - "symbol": "STORJ", - "website_slug": "storj" - }, - { - "id": 1773, - "name": "BnrtxCoin", - "symbol": "BNX", - "website_slug": "bnrtxcoin" - }, - { - "id": 1774, - "name": "SocialCoin", - "symbol": "SOCC", - "website_slug": "socialcoin-socc" - }, - { - "id": 1775, - "name": "adToken", - "symbol": "ADT", - "website_slug": "adtoken" - }, - { - "id": 1776, - "name": "MCO", - "symbol": "MCO", - "website_slug": "mco" - }, - { - "id": 1777, - "name": "CryptoPing", - "symbol": "PING", - "website_slug": "cryptoping" - }, - { - "id": 1778, - "name": "Useless Ethereum Token", - "symbol": "UET", - "website_slug": "useless-ethereum-token" - }, - { - "id": 1779, - "name": "Wagerr", - "symbol": "WGR", - "website_slug": "wagerr" - }, - { - "id": 1781, - "name": "Slevin", - "symbol": "SLEVIN", - "website_slug": "slevin" - }, - { - "id": 1782, - "name": "Ecobit", - "symbol": "ECOB", - "website_slug": "ecobit" - }, - { - "id": 1783, - "name": "UniversalRoyalCoin", - "symbol": "UNRC", - "website_slug": "universalroyalcoin" - }, - { - "id": 1784, - "name": "Polybius", - "symbol": "PLBT", - "website_slug": "polybius" - }, - { - "id": 1785, - "name": "Gas", - "symbol": "GAS", - "website_slug": "gas" - }, - { - "id": 1786, - "name": "SunContract", - "symbol": "SNC", - "website_slug": "suncontract" - }, - { - "id": 1787, - "name": "Jetcoin", - "symbol": "JET", - "website_slug": "jetcoin" - }, - { - "id": 1788, - "name": "Metal", - "symbol": "MTL", - "website_slug": "metal" - }, - { - "id": 1789, - "name": "Populous", - "symbol": "PPT", - "website_slug": "populous" - }, - { - "id": 1790, - "name": "WomenCoin", - "symbol": "WOMEN", - "website_slug": "women" - }, - { - "id": 1792, - "name": "Virta Unique Coin", - "symbol": "VUC", - "website_slug": "virta-unique-coin" - }, - { - "id": 1793, - "name": "Bitdeal", - "symbol": "BDL", - "website_slug": "bitdeal" - }, - { - "id": 1795, - "name": "Sphre AIR ", - "symbol": "XID", - "website_slug": "sphre-air" - }, - { - "id": 1797, - "name": "DaxxCoin", - "symbol": "DAXX", - "website_slug": "daxxcoin" - }, - { - "id": 1799, - "name": "Rupee", - "symbol": "RUP", - "website_slug": "rupee" - }, - { - "id": 1801, - "name": "Global Tour Coin", - "symbol": "GTC", - "website_slug": "global-tour-coin" - }, - { - "id": 1803, - "name": "PeepCoin", - "symbol": "PCN", - "website_slug": "peepcoin" - }, - { - "id": 1805, - "name": "Sovereign Hero", - "symbol": "HERO", - "website_slug": "sovereign-hero" - }, - { - "id": 1807, - "name": "Santiment Network Token", - "symbol": "SAN", - "website_slug": "santiment" - }, - { - "id": 1808, - "name": "OmiseGO", - "symbol": "OMG", - "website_slug": "omisego" - }, - { - "id": 1809, - "name": "TerraNova", - "symbol": "TER", - "website_slug": "terranova" - }, - { - "id": 1810, - "name": "CVCoin", - "symbol": "CVN", - "website_slug": "cvcoin" - }, - { - "id": 1811, - "name": "Nimiq Exchange Token", - "symbol": "NET", - "website_slug": "nimiq-exchange-token" - }, - { - "id": 1812, - "name": "Rialto", - "symbol": "XRL", - "website_slug": "rialto" - }, - { - "id": 1814, - "name": "Linda", - "symbol": "LINDA", - "website_slug": "linda" - }, - { - "id": 1815, - "name": "Embers", - "symbol": "MBRS", - "website_slug": "embers" - }, - { - "id": 1816, - "name": "Civic", - "symbol": "CVC", - "website_slug": "civic" - }, - { - "id": 1817, - "name": "Ethos", - "symbol": "ETHOS", - "website_slug": "ethos" - }, - { - "id": 1818, - "name": "Bit20", - "symbol": "BTWTY", - "website_slug": "bit20" - }, - { - "id": 1819, - "name": "Starta", - "symbol": "STA", - "website_slug": "starta" - }, - { - "id": 1824, - "name": "BitCoal", - "symbol": "COAL", - "website_slug": "bitcoal" - }, - { - "id": 1825, - "name": "LiteBitcoin", - "symbol": "LBTC", - "website_slug": "litebitcoin" - }, - { - "id": 1826, - "name": "Particl", - "symbol": "PART", - "website_slug": "particl" - }, - { - "id": 1828, - "name": "SmartCash", - "symbol": "SMART", - "website_slug": "smartcash" - }, - { - "id": 1830, - "name": "SkinCoin", - "symbol": "SKIN", - "website_slug": "skincoin" - }, - { - "id": 1831, - "name": "Bitcoin Cash", - "symbol": "BCH", - "website_slug": "bitcoin-cash" - }, - { - "id": 1832, - "name": "HarmonyCoin", - "symbol": "HMC", - "website_slug": "harmonycoin-hmc" - }, - { - "id": 1833, - "name": "ToaCoin", - "symbol": "TOA", - "website_slug": "toacoin" - }, - { - "id": 1834, - "name": "Pillar", - "symbol": "PLR", - "website_slug": "pillar" - }, - { - "id": 1835, - "name": "Royalties", - "symbol": "XRY", - "website_slug": "royalties" - }, - { - "id": 1836, - "name": "Signatum", - "symbol": "SIGT", - "website_slug": "signatum" - }, - { - "id": 1837, - "name": "Coimatic 2.0", - "symbol": "CTIC2", - "website_slug": "coimatic-2" - }, - { - "id": 1838, - "name": "OracleChain", - "symbol": "OCT", - "website_slug": "oraclechain" - }, - { - "id": 1839, - "name": "Binance Coin", - "symbol": "BNB", - "website_slug": "binance-coin" - }, - { - "id": 1840, - "name": "300 Token", - "symbol": "300", - "website_slug": "300-token" - }, - { - "id": 1841, - "name": "Primalbase Token", - "symbol": "PBT", - "website_slug": "primalbase" - }, - { - "id": 1842, - "name": "CampusCoin", - "symbol": "CMPCO", - "website_slug": "campuscoin" - }, - { - "id": 1843, - "name": "EmberCoin", - "symbol": "EMB", - "website_slug": "embercoin" - }, - { - "id": 1845, - "name": "IXT", - "symbol": "IXT", - "website_slug": "ixledger" - }, - { - "id": 1846, - "name": "GeyserCoin", - "symbol": "GSR", - "website_slug": "geysercoin" - }, - { - "id": 1847, - "name": "Mothership", - "symbol": "MSP", - "website_slug": "mothership" - }, - { - "id": 1848, - "name": "Aseancoin", - "symbol": "ASN", - "website_slug": "aseancoin" - }, - { - "id": 1849, - "name": "Birds", - "symbol": "BIRDS", - "website_slug": "birds" - }, - { - "id": 1850, - "name": "Cream", - "symbol": "CRM", - "website_slug": "cream" - }, - { - "id": 1851, - "name": "ERA", - "symbol": "ERA", - "website_slug": "blakestar" - }, - { - "id": 1852, - "name": "KekCoin", - "symbol": "KEK", - "website_slug": "kekcoin" - }, - { - "id": 1853, - "name": "OAX", - "symbol": "OAX", - "website_slug": "oax" - }, - { - "id": 1856, - "name": "district0x", - "symbol": "DNT", - "website_slug": "district0x" - }, - { - "id": 1857, - "name": "FundYourselfNow", - "symbol": "FYN", - "website_slug": "fundyourselfnow" - }, - { - "id": 1861, - "name": "Stox", - "symbol": "STX", - "website_slug": "stox" - }, - { - "id": 1863, - "name": "Minex", - "symbol": "MINEX", - "website_slug": "minex" - }, - { - "id": 1864, - "name": "Blox", - "symbol": "CDT", - "website_slug": "blox" - }, - { - "id": 1865, - "name": "Wink", - "symbol": "WINK", - "website_slug": "wink" - }, - { - "id": 1866, - "name": "Bytom", - "symbol": "BTM", - "website_slug": "bytom" - }, - { - "id": 1869, - "name": "Mao Zedong", - "symbol": "MAO", - "website_slug": "mao-zedong" - }, - { - "id": 1871, - "name": "First Bitcoin Capital", - "symbol": "BITCF", - "website_slug": "first-bitcoin-capital" - }, - { - "id": 1872, - "name": "NEVERDIE", - "symbol": "NDC", - "website_slug": "neverdie" - }, - { - "id": 1873, - "name": "Blocktix", - "symbol": "TIX", - "website_slug": "blocktix" - }, - { - "id": 1876, - "name": "Dentacoin", - "symbol": "DCN", - "website_slug": "dentacoin" - }, - { - "id": 1877, - "name": "Rupaya", - "symbol": "RUPX", - "website_slug": "rupaya" - }, - { - "id": 1878, - "name": "Shadow Token", - "symbol": "SHDW", - "website_slug": "shadow-token" - }, - { - "id": 1881, - "name": "DeepOnion", - "symbol": "ONION", - "website_slug": "deeponion" - }, - { - "id": 1882, - "name": "BlockCAT", - "symbol": "CAT", - "website_slug": "blockcat" - }, - { - "id": 1883, - "name": "AdShares", - "symbol": "ADST", - "website_slug": "adshares" - }, - { - "id": 1884, - "name": "DigitalDevelopersFund", - "symbol": "DDF", - "website_slug": "digital-developers-fund" - }, - { - "id": 1885, - "name": "BitAsean", - "symbol": "BAS", - "website_slug": "bitasean" - }, - { - "id": 1886, - "name": "Dent", - "symbol": "DENT", - "website_slug": "dent" - }, - { - "id": 1887, - "name": "Monster Byte", - "symbol": "MBI", - "website_slug": "monster-byte" - }, - { - "id": 1888, - "name": "InvestFeed", - "symbol": "IFT", - "website_slug": "investfeed" - }, - { - "id": 1889, - "name": "CoinonatX", - "symbol": "XCXT", - "website_slug": "coinonatx" - }, - { - "id": 1890, - "name": "Etheriya", - "symbol": "RIYA", - "website_slug": "etheriya" - }, - { - "id": 1894, - "name": "The ChampCoin", - "symbol": "TCC", - "website_slug": "the-champcoin" - }, - { - "id": 1896, - "name": "0x", - "symbol": "ZRX", - "website_slug": "0x" - }, - { - "id": 1897, - "name": "Bolenum", - "symbol": "BLN", - "website_slug": "bolenum" - }, - { - "id": 1898, - "name": "Smoke", - "symbol": "SMOKE", - "website_slug": "smoke" - }, - { - "id": 1899, - "name": "YOYOW", - "symbol": "YOYOW", - "website_slug": "yoyow" - }, - { - "id": 1900, - "name": "Growers International", - "symbol": "GRWI", - "website_slug": "growers-international" - }, - { - "id": 1902, - "name": "MyBit", - "symbol": "MYB", - "website_slug": "mybit" - }, - { - "id": 1903, - "name": "Hshare", - "symbol": "HSR", - "website_slug": "hshare" - }, - { - "id": 1905, - "name": "TrueFlip", - "symbol": "TFL", - "website_slug": "trueflip" - }, - { - "id": 1908, - "name": "Nebulas", - "symbol": "NAS", - "website_slug": "nebulas-token" - }, - { - "id": 1910, - "name": "ATMCoin", - "symbol": "ATMC", - "website_slug": "atmcoin" - }, - { - "id": 1912, - "name": "Dalecoin", - "symbol": "DALC", - "website_slug": "dalecoin" - }, - { - "id": 1913, - "name": "Protean", - "symbol": "PRN", - "website_slug": "protean" - }, - { - "id": 1915, - "name": "AdCoin", - "symbol": "ACC", - "website_slug": "adcoin" - }, - { - "id": 1916, - "name": "BiblePay", - "symbol": "BBP", - "website_slug": "biblepay" - }, - { - "id": 1917, - "name": "bitqy", - "symbol": "BQ", - "website_slug": "bitqy" - }, - { - "id": 1918, - "name": "Achain", - "symbol": "ACT", - "website_slug": "achain" - }, - { - "id": 1920, - "name": "NamoCoin", - "symbol": "NAMO", - "website_slug": "namocoin" - }, - { - "id": 1921, - "name": "SIGMAcoin", - "symbol": "SIGMA", - "website_slug": "sigmacoin" - }, - { - "id": 1922, - "name": "Monoeci", - "symbol": "XMCC", - "website_slug": "monacocoin" - }, - { - "id": 1923, - "name": "Tierion", - "symbol": "TNT", - "website_slug": "tierion" - }, - { - "id": 1925, - "name": "Waltonchain", - "symbol": "WTC", - "website_slug": "waltonchain" - }, - { - "id": 1926, - "name": "BROTHER", - "symbol": "BRAT", - "website_slug": "brat" - }, - { - "id": 1930, - "name": "Primas", - "symbol": "PST", - "website_slug": "primas" - }, - { - "id": 1931, - "name": "Opus", - "symbol": "OPT", - "website_slug": "opus" - }, - { - "id": 1933, - "name": "Suretly", - "symbol": "SUR", - "website_slug": "suretly" - }, - { - "id": 1934, - "name": "Loopring", - "symbol": "LRC", - "website_slug": "loopring" - }, - { - "id": 1935, - "name": "LiteCoin Ultra", - "symbol": "LTCU", - "website_slug": "litecoin-ultra" - }, - { - "id": 1937, - "name": "Po.et", - "symbol": "POE", - "website_slug": "poet" - }, - { - "id": 1938, - "name": "Fujinto", - "symbol": "NTO", - "website_slug": "fujinto" - }, - { - "id": 1942, - "name": "StarCredits", - "symbol": "STRC", - "website_slug": "starcredits" - }, - { - "id": 1943, - "name": "Kronecoin", - "symbol": "KRONE", - "website_slug": "kronecoin" - }, - { - "id": 1944, - "name": "Moving Cloud Coin", - "symbol": "MCC", - "website_slug": "moving-cloud-coin" - }, - { - "id": 1945, - "name": "Cyder", - "symbol": "CYDER", - "website_slug": "cyder" - }, - { - "id": 1946, - "name": "Masternodecoin", - "symbol": "MTNC", - "website_slug": "masternodecoin" - }, - { - "id": 1947, - "name": "Monetha", - "symbol": "MTH", - "website_slug": "monetha" - }, - { - "id": 1948, - "name": "Aventus", - "symbol": "AVT", - "website_slug": "aventus" - }, - { - "id": 1949, - "name": "Agrello", - "symbol": "DLT", - "website_slug": "agrello-delta" - }, - { - "id": 1950, - "name": "Hive Project", - "symbol": "HVN", - "website_slug": "hive-project" - }, - { - "id": 1951, - "name": "Vsync", - "symbol": "VSX", - "website_slug": "vsync-vsx" - }, - { - "id": 1952, - "name": "Magnetcoin", - "symbol": "MAGN", - "website_slug": "magnetcoin" - }, - { - "id": 1954, - "name": "Moeda Loyalty Points", - "symbol": "MDA", - "website_slug": "moeda-loyalty-points" - }, - { - "id": 1955, - "name": "Neblio", - "symbol": "NEBL", - "website_slug": "neblio" - }, - { - "id": 1956, - "name": "VIVO", - "symbol": "VIVO", - "website_slug": "vivo" - }, - { - "id": 1958, - "name": "TRON", - "symbol": "TRX", - "website_slug": "tron" - }, - { - "id": 1959, - "name": "Oceanlab", - "symbol": "OCL", - "website_slug": "oceanlab" - }, - { - "id": 1961, - "name": "imbrex", - "symbol": "REX", - "website_slug": "imbrex" - }, - { - "id": 1962, - "name": "BuzzCoin", - "symbol": "BUZZ", - "website_slug": "buzzcoin" - }, - { - "id": 1963, - "name": "Credo", - "symbol": "CREDO", - "website_slug": "credo" - }, - { - "id": 1964, - "name": "DROXNE", - "symbol": "DRXNE", - "website_slug": "droxne" - }, - { - "id": 1965, - "name": "Bowhead", - "symbol": "AHT", - "website_slug": "bowhead" - }, - { - "id": 1966, - "name": "Decentraland", - "symbol": "MANA", - "website_slug": "decentraland" - }, - { - "id": 1967, - "name": "Indorse Token", - "symbol": "IND", - "website_slug": "indorse-token" - }, - { - "id": 1968, - "name": "XPA", - "symbol": "XPA", - "website_slug": "xpa" - }, - { - "id": 1969, - "name": "Sociall", - "symbol": "SCL", - "website_slug": "sociall" - }, - { - "id": 1970, - "name": "ATBCoin", - "symbol": "ATB", - "website_slug": "atbcoin" - }, - { - "id": 1971, - "name": "iQuant", - "symbol": "IQT", - "website_slug": "iquant" - }, - { - "id": 1973, - "name": "Ethereum Dark", - "symbol": "ETHD", - "website_slug": "ethereum-dark" - }, - { - "id": 1974, - "name": "Propy", - "symbol": "PRO", - "website_slug": "propy" - }, - { - "id": 1975, - "name": "Chainlink", - "symbol": "LINK", - "website_slug": "chainlink" - }, - { - "id": 1976, - "name": "Blackmoon", - "symbol": "BMC", - "website_slug": "blackmoon" - }, - { - "id": 1979, - "name": "Wi Coin", - "symbol": "WIC", - "website_slug": "wi-coin" - }, - { - "id": 1980, - "name": "Elixir", - "symbol": "ELIX", - "website_slug": "elixir" - }, - { - "id": 1981, - "name": "Billionaire Token", - "symbol": "XBL", - "website_slug": "billionaire-token" - }, - { - "id": 1982, - "name": "Kyber Network", - "symbol": "KNC", - "website_slug": "kyber-network" - }, - { - "id": 1983, - "name": "VIBE", - "symbol": "VIBE", - "website_slug": "vibe" - }, - { - "id": 1984, - "name": "Substratum", - "symbol": "SUB", - "website_slug": "substratum" - }, - { - "id": 1985, - "name": "Chronologic", - "symbol": "DAY", - "website_slug": "chronologic" - }, - { - "id": 1986, - "name": "CHIPS", - "symbol": "CHIPS", - "website_slug": "chips" - }, - { - "id": 1987, - "name": "CryptoInsight", - "symbol": "TKR", - "website_slug": "trackr" - }, - { - "id": 1988, - "name": "Lampix", - "symbol": "PIX", - "website_slug": "lampix" - }, - { - "id": 1989, - "name": "COSS", - "symbol": "COSS", - "website_slug": "coss" - }, - { - "id": 1990, - "name": "BitDice", - "symbol": "CSNO", - "website_slug": "bitdice" - }, - { - "id": 1991, - "name": "Rivetz", - "symbol": "RVT", - "website_slug": "rivetz" - }, - { - "id": 1993, - "name": "Kin", - "symbol": "KIN", - "website_slug": "kin" - }, - { - "id": 1994, - "name": "Interzone", - "symbol": "ITZ", - "website_slug": "interzone" - }, - { - "id": 1995, - "name": "Target Coin", - "symbol": "TGT", - "website_slug": "target-coin" - }, - { - "id": 1996, - "name": "SALT", - "symbol": "SALT", - "website_slug": "salt" - }, - { - "id": 1998, - "name": "Ormeus Coin", - "symbol": "ORME", - "website_slug": "ormeus-coin" - }, - { - "id": 1999, - "name": "Kolion", - "symbol": "KLN", - "website_slug": "kolion" - }, - { - "id": 2000, - "name": "Musiconomi", - "symbol": "MCI", - "website_slug": "musiconomi" - }, - { - "id": 2001, - "name": "ColossusXT", - "symbol": "COLX", - "website_slug": "colossusxt" - }, - { - "id": 2002, - "name": "TrezarCoin", - "symbol": "TZC", - "website_slug": "trezarcoin" - }, - { - "id": 2004, - "name": "HODL Bucks", - "symbol": "HDLB", - "website_slug": "hodl-bucks" - }, - { - "id": 2005, - "name": "Obsidian", - "symbol": "ODN", - "website_slug": "obsidian" - }, - { - "id": 2006, - "name": "Cobinhood", - "symbol": "COB", - "website_slug": "cobinhood" - }, - { - "id": 2007, - "name": "Regalcoin", - "symbol": "REC", - "website_slug": "regalcoin" - }, - { - "id": 2008, - "name": "MSD", - "symbol": "MSD", - "website_slug": "msd" - }, - { - "id": 2009, - "name": "Bismuth", - "symbol": "BIS", - "website_slug": "bismuth" - }, - { - "id": 2010, - "name": "Cardano", - "symbol": "ADA", - "website_slug": "cardano" - }, - { - "id": 2011, - "name": "Tezos", - "symbol": "XTZ", - "website_slug": "tezos" - }, - { - "id": 2012, - "name": "Voise", - "symbol": "VOISE", - "website_slug": "voisecom" - }, - { - "id": 2013, - "name": "Infinity Economics", - "symbol": "XIN", - "website_slug": "infinity-economics" - }, - { - "id": 2015, - "name": "ATMChain", - "symbol": "ATM", - "website_slug": "attention-token-of-media" - }, - { - "id": 2017, - "name": "KickCoin", - "symbol": "KICK", - "website_slug": "kickico" - }, - { - "id": 2018, - "name": "EncryptoTel [ETH]", - "symbol": "ETT", - "website_slug": "encryptotel-eth" - }, - { - "id": 2019, - "name": "Viberate", - "symbol": "VIB", - "website_slug": "viberate" - }, - { - "id": 2021, - "name": "RChain", - "symbol": "RHOC", - "website_slug": "rchain" - }, - { - "id": 2022, - "name": "Internxt", - "symbol": "INXT", - "website_slug": "internxt" - }, - { - "id": 2024, - "name": "WhaleCoin", - "symbol": "WHL", - "website_slug": "whalecoin" - }, - { - "id": 2025, - "name": "FLiK", - "symbol": "FLIK", - "website_slug": "flik" - }, - { - "id": 2026, - "name": "EthBet", - "symbol": "EBET", - "website_slug": "ethbet" - }, - { - "id": 2027, - "name": "Cryptonex", - "symbol": "CNX", - "website_slug": "cryptonex" - }, - { - "id": 2029, - "name": "Wild Crypto", - "symbol": "WILD", - "website_slug": "wild-crypto" - }, - { - "id": 2030, - "name": "REAL", - "symbol": "REAL", - "website_slug": "real" - }, - { - "id": 2031, - "name": "Hubii Network", - "symbol": "HBT", - "website_slug": "hubii-network" - }, - { - "id": 2032, - "name": "Crystal Clear ", - "symbol": "CCT", - "website_slug": "crystal-clear" - }, - { - "id": 2033, - "name": "BridgeCoin", - "symbol": "BCO", - "website_slug": "bridgecoin" - }, - { - "id": 2034, - "name": "Everex", - "symbol": "EVX", - "website_slug": "everex" - }, - { - "id": 2036, - "name": "PayPie", - "symbol": "PPP", - "website_slug": "paypie" - }, - { - "id": 2037, - "name": "AirToken", - "symbol": "AIR", - "website_slug": "airtoken" - }, - { - "id": 2038, - "name": "PoSToken", - "symbol": "POS", - "website_slug": "postoken" - }, - { - "id": 2039, - "name": "Senderon", - "symbol": "SDRN", - "website_slug": "senderon" - }, - { - "id": 2040, - "name": "ALIS", - "symbol": "ALIS", - "website_slug": "alis" - }, - { - "id": 2041, - "name": "BitcoinZ", - "symbol": "BTCZ", - "website_slug": "bitcoinz" - }, - { - "id": 2042, - "name": "HelloGold", - "symbol": "HGT", - "website_slug": "hellogold" - }, - { - "id": 2043, - "name": "Cindicator", - "symbol": "CND", - "website_slug": "cindicator" - }, - { - "id": 2044, - "name": "Enigma", - "symbol": "ENG", - "website_slug": "enigma-project" - }, - { - "id": 2045, - "name": "Coimatic 3.0", - "symbol": "CTIC3", - "website_slug": "coimatic-3" - }, - { - "id": 2046, - "name": "Bastonet", - "symbol": "BSN", - "website_slug": "bastonet" - }, - { - "id": 2047, - "name": "Zeusshield", - "symbol": "ZSC", - "website_slug": "zeusshield" - }, - { - "id": 2048, - "name": "Ethereum Cash", - "symbol": "ECASH", - "website_slug": "ethereumcash" - }, - { - "id": 2049, - "name": "CORION", - "symbol": "COR", - "website_slug": "corion" - }, - { - "id": 2050, - "name": "Swisscoin", - "symbol": "SIC", - "website_slug": "swisscoin" - }, - { - "id": 2051, - "name": "Authorship", - "symbol": "ATS", - "website_slug": "authorship" - }, - { - "id": 2053, - "name": "Royal Kingdom Coin", - "symbol": "RKC", - "website_slug": "royal-kingdom-coin" - }, - { - "id": 2054, - "name": "Akuya Coin", - "symbol": "AKY", - "website_slug": "akuya-coin" - }, - { - "id": 2055, - "name": "ExchangeN", - "symbol": "EXN", - "website_slug": "exchangen" - }, - { - "id": 2056, - "name": "PiplCoin", - "symbol": "PIPL", - "website_slug": "piplcoin" - }, - { - "id": 2057, - "name": "Eidoo", - "symbol": "EDO", - "website_slug": "eidoo" - }, - { - "id": 2058, - "name": "AirSwap", - "symbol": "AST", - "website_slug": "airswap" - }, - { - "id": 2059, - "name": "BitSoar", - "symbol": "BSR", - "website_slug": "bitsoar" - }, - { - "id": 2060, - "name": "Change", - "symbol": "CAG", - "website_slug": "change" - }, - { - "id": 2061, - "name": "BlockMason Credit Protocol", - "symbol": "BCPT", - "website_slug": "blockmason" - }, - { - "id": 2062, - "name": "Aion", - "symbol": "AION", - "website_slug": "aion" - }, - { - "id": 2063, - "name": "Tracto", - "symbol": "TRCT", - "website_slug": "tracto" - }, - { - "id": 2064, - "name": "Maecenas", - "symbol": "ART", - "website_slug": "maecenas" - }, - { - "id": 2065, - "name": "XGOX", - "symbol": "XGOX", - "website_slug": "xgox" - }, - { - "id": 2066, - "name": "Everus", - "symbol": "EVR", - "website_slug": "everus" - }, - { - "id": 2067, - "name": "Dutch Coin", - "symbol": "DUTCH", - "website_slug": "dutch-coin" - }, - { - "id": 2069, - "name": "Open Trading Network", - "symbol": "OTN", - "website_slug": "open-trading-network" - }, - { - "id": 2070, - "name": "DomRaider", - "symbol": "DRT", - "website_slug": "domraider" - }, - { - "id": 2071, - "name": "Request Network", - "symbol": "REQ", - "website_slug": "request-network" - }, - { - "id": 2072, - "name": "SegWit2x", - "symbol": "B2X", - "website_slug": "segwit2x" - }, - { - "id": 2074, - "name": "Ethereum Gold", - "symbol": "ETG", - "website_slug": "ethereum-gold" - }, - { - "id": 2076, - "name": "Blue Protocol", - "symbol": "BLUE", - "website_slug": "ethereum-blue" - }, - { - "id": 2077, - "name": "Runners", - "symbol": "RUNNERS", - "website_slug": "runners" - }, - { - "id": 2078, - "name": "LIFE", - "symbol": "LIFE", - "website_slug": "life" - }, - { - "id": 2079, - "name": "Hedge", - "symbol": "HDG", - "website_slug": "hedge" - }, - { - "id": 2080, - "name": "Modum", - "symbol": "MOD", - "website_slug": "modum" - }, - { - "id": 2081, - "name": "Ambrosus", - "symbol": "AMB", - "website_slug": "amber" - }, - { - "id": 2082, - "name": "ICOS", - "symbol": "ICOS", - "website_slug": "icos" - }, - { - "id": 2083, - "name": "Bitcoin Gold", - "symbol": "BTG", - "website_slug": "bitcoin-gold" - }, - { - "id": 2087, - "name": "KuCoin Shares", - "symbol": "KCS", - "website_slug": "kucoin-shares" - }, - { - "id": 2088, - "name": "EXRNchain", - "symbol": "EXRN", - "website_slug": "exrnchain" - }, - { - "id": 2089, - "name": "ClearPoll", - "symbol": "POLL", - "website_slug": "clearpoll" - }, - { - "id": 2090, - "name": "LATOKEN", - "symbol": "LA", - "website_slug": "latoken" - }, - { - "id": 2091, - "name": "Exchange Union", - "symbol": "XUC", - "website_slug": "exchange-union" - }, - { - "id": 2092, - "name": "Nuls", - "symbol": "NULS", - "website_slug": "nuls" - }, - { - "id": 2093, - "name": "Bitcoin Red", - "symbol": "BTCRED", - "website_slug": "bitcoin-red" - }, - { - "id": 2094, - "name": "Paragon", - "symbol": "PRG", - "website_slug": "paragon" - }, - { - "id": 2095, - "name": "BOScoin", - "symbol": "BOS", - "website_slug": "boscoin" - }, - { - "id": 2096, - "name": "Ripio Credit Network", - "symbol": "RCN", - "website_slug": "ripio-credit-network" - }, - { - "id": 2098, - "name": "Mercury Protocol", - "symbol": "GMT", - "website_slug": "mercury-protocol" - }, - { - "id": 2099, - "name": "ICON", - "symbol": "ICX", - "website_slug": "icon" - }, - { - "id": 2100, - "name": "JavaScript Token", - "symbol": "JS", - "website_slug": "javascript-token" - }, - { - "id": 2101, - "name": "Ethereum Lite", - "symbol": "ELITE", - "website_slug": "ethereum-lite" - }, - { - "id": 2103, - "name": "Intelligent Trading Foundation", - "symbol": "ITT", - "website_slug": "intelligent-trading-foundation" - }, - { - "id": 2104, - "name": "iEthereum", - "symbol": "IETH", - "website_slug": "iethereum" - }, - { - "id": 2105, - "name": "Pirl", - "symbol": "PIRL", - "website_slug": "pirl" - }, - { - "id": 2106, - "name": "Xenon", - "symbol": "XNN", - "website_slug": "xenon" - }, - { - "id": 2107, - "name": "LUXCoin", - "symbol": "LUX", - "website_slug": "luxcoin" - }, - { - "id": 2109, - "name": "Network Token", - "symbol": "NTWK", - "website_slug": "network-token" - }, - { - "id": 2110, - "name": "Dovu", - "symbol": "DOV", - "website_slug": "dovu" - }, - { - "id": 2112, - "name": "Red Pulse Phoenix", - "symbol": "PHX", - "website_slug": "red-pulse" - }, - { - "id": 2114, - "name": "BT2 [CST]", - "symbol": "BT2", - "website_slug": "bt2-cst" - }, - { - "id": 2115, - "name": "PlayerCoin", - "symbol": "PLACO", - "website_slug": "playercoin" - }, - { - "id": 2117, - "name": "Roofs", - "symbol": "ROOFS", - "website_slug": "roofs" - }, - { - "id": 2118, - "name": "FAPcoin", - "symbol": "FAP", - "website_slug": "fapcoin" - }, - { - "id": 2119, - "name": "BTCMoon", - "symbol": "BTCM", - "website_slug": "btcmoon" - }, - { - "id": 2120, - "name": "Etherparty", - "symbol": "FUEL", - "website_slug": "etherparty" - }, - { - "id": 2122, - "name": "Ellaism", - "symbol": "ELLA", - "website_slug": "ellaism" - }, - { - "id": 2123, - "name": "Vulcano [OLD]", - "symbol": "VULC", - "website_slug": "vulcano-old" - }, - { - "id": 2124, - "name": "Qvolta", - "symbol": "QVT", - "website_slug": "qvolta" - }, - { - "id": 2125, - "name": "Russian Miner Coin", - "symbol": "RMC", - "website_slug": "russian-mining-coin" - }, - { - "id": 2126, - "name": "FlypMe", - "symbol": "FYP", - "website_slug": "flypme" - }, - { - "id": 2127, - "name": "eBitcoin", - "symbol": "EBTC", - "website_slug": "ebtcnew" - }, - { - "id": 2129, - "name": "Bitbase", - "symbol": "BTBc", - "website_slug": "bitbase" - }, - { - "id": 2130, - "name": "Enjin Coin", - "symbol": "ENJ", - "website_slug": "enjin-coin" - }, - { - "id": 2132, - "name": "Power Ledger", - "symbol": "POWR", - "website_slug": "power-ledger" - }, - { - "id": 2134, - "name": "Grid+", - "symbol": "GRID", - "website_slug": "grid" - }, - { - "id": 2135, - "name": "Revain", - "symbol": "R", - "website_slug": "revain" - }, - { - "id": 2136, - "name": "ATLANT", - "symbol": "ATL", - "website_slug": "atlant" - }, - { - "id": 2137, - "name": "Electroneum", - "symbol": "ETN", - "website_slug": "electroneum" - }, - { - "id": 2138, - "name": "High Gain", - "symbol": "HIGH", - "website_slug": "high-gain" - }, - { - "id": 2139, - "name": "MinexCoin", - "symbol": "MNX", - "website_slug": "minexcoin" - }, - { - "id": 2140, - "name": "SONO", - "symbol": "SONO", - "website_slug": "altcommunity-coin" - }, - { - "id": 2142, - "name": "FORCE", - "symbol": "FOR", - "website_slug": "force" - }, - { - "id": 2143, - "name": "Streamr DATAcoin", - "symbol": "DATA", - "website_slug": "streamr-datacoin" - }, - { - "id": 2144, - "name": "SHIELD", - "symbol": "XSH", - "website_slug": "shield-xsh" - }, - { - "id": 2147, - "name": "ELTCOIN", - "symbol": "ELTCOIN", - "website_slug": "eltcoin" - }, - { - "id": 2148, - "name": "Desire", - "symbol": "DSR", - "website_slug": "desire" - }, - { - "id": 2149, - "name": "Unikoin Gold", - "symbol": "UKG", - "website_slug": "unikoin-gold" - }, - { - "id": 2150, - "name": "Credence Coin", - "symbol": "CRDNC", - "website_slug": "credence-coin" - }, - { - "id": 2151, - "name": "Autonio", - "symbol": "NIO", - "website_slug": "autonio" - }, - { - "id": 2152, - "name": "CarTaxi Token", - "symbol": "CTX", - "website_slug": "cartaxi-token" - }, - { - "id": 2153, - "name": "Aeron", - "symbol": "ARN", - "website_slug": "aeron" - }, - { - "id": 2157, - "name": "StarCash Network", - "symbol": "STARS", - "website_slug": "starcash-network" - }, - { - "id": 2158, - "name": "Phore", - "symbol": "PHR", - "website_slug": "phore" - }, - { - "id": 2160, - "name": "Innova", - "symbol": "INN", - "website_slug": "innova" - }, - { - "id": 2161, - "name": "Raiden Network Token", - "symbol": "RDN", - "website_slug": "raiden-network-token" - }, - { - "id": 2162, - "name": "Delphy", - "symbol": "DPY", - "website_slug": "delphy" - }, - { - "id": 2163, - "name": "Zephyr", - "symbol": "ZEPH", - "website_slug": "zephyr" - }, - { - "id": 2165, - "name": "ERC20", - "symbol": "ERC20", - "website_slug": "erc20" - }, - { - "id": 2166, - "name": "Ties.DB", - "symbol": "TIE", - "website_slug": "tiesdb" - }, - { - "id": 2167, - "name": "Blockpool", - "symbol": "BPL", - "website_slug": "blockpool" - }, - { - "id": 2168, - "name": "Grimcoin", - "symbol": "GRIM", - "website_slug": "grimcoin" - }, - { - "id": 2170, - "name": "Oxycoin", - "symbol": "OXY", - "website_slug": "oxycoin" - }, - { - "id": 2172, - "name": "Emphy", - "symbol": "EPY", - "website_slug": "emphy" - }, - { - "id": 2173, - "name": "Stellar Holdings", - "symbol": "HOLD", - "website_slug": "interstellar-holdings" - }, - { - "id": 2174, - "name": "NEO GOLD", - "symbol": "NEOG", - "website_slug": "neo-gold" - }, - { - "id": 2175, - "name": "DecentBet", - "symbol": "DBET", - "website_slug": "decent-bet" - }, - { - "id": 2176, - "name": "Decision Token", - "symbol": "HST", - "website_slug": "decision-token" - }, - { - "id": 2177, - "name": "Sharechain", - "symbol": "SSS", - "website_slug": "sharechain" - }, - { - "id": 2178, - "name": "Upfiring", - "symbol": "UFR", - "website_slug": "upfiring" - }, - { - "id": 2180, - "name": "bitJob", - "symbol": "STU", - "website_slug": "student-coin" - }, - { - "id": 2181, - "name": "Genesis Vision", - "symbol": "GVT", - "website_slug": "genesis-vision" - }, - { - "id": 2182, - "name": "EagleCoin", - "symbol": "EAGLE", - "website_slug": "eaglecoin" - }, - { - "id": 2183, - "name": "EA Coin", - "symbol": "EAG", - "website_slug": "ea-coin" - }, - { - "id": 2184, - "name": "Privatix", - "symbol": "PRIX", - "website_slug": "privatix" - }, - { - "id": 2185, - "name": "Lethean", - "symbol": "LTHN", - "website_slug": "lethean" - }, - { - "id": 2187, - "name": "EBCH", - "symbol": "EBCH", - "website_slug": "ebitcoin-cash" - }, - { - "id": 2190, - "name": "Astro", - "symbol": "ASTRO", - "website_slug": "astro" - }, - { - "id": 2191, - "name": "Paypex", - "symbol": "PAYX", - "website_slug": "paypex" - }, - { - "id": 2192, - "name": "GOLD Reward Token", - "symbol": "GRX", - "website_slug": "gold-reward-token" - }, - { - "id": 2194, - "name": "BitSerial", - "symbol": "BTE", - "website_slug": "bitserial" - }, - { - "id": 2196, - "name": "Sugar Exchange", - "symbol": "SGR", - "website_slug": "sugar-exchange" - }, - { - "id": 2198, - "name": "Viuly", - "symbol": "VIU", - "website_slug": "viuly" - }, - { - "id": 2199, - "name": "ALQO", - "symbol": "XLQ", - "website_slug": "alqo" - }, - { - "id": 2200, - "name": "GoByte", - "symbol": "GBX", - "website_slug": "gobyte" - }, - { - "id": 2201, - "name": "WINCOIN", - "symbol": "WC", - "website_slug": "win-coin" - }, - { - "id": 2202, - "name": "Oyster", - "symbol": "PRL", - "website_slug": "oyster" - }, - { - "id": 2204, - "name": "B2BX", - "symbol": "B2B", - "website_slug": "b2bx" - }, - { - "id": 2205, - "name": "Phantomx", - "symbol": "PNX", - "website_slug": "phantomx" - }, - { - "id": 2207, - "name": "DigiPulse", - "symbol": "DGPT", - "website_slug": "digipulse" - }, - { - "id": 2208, - "name": "EncrypGen", - "symbol": "DNA", - "website_slug": "encrypgen" - }, - { - "id": 2209, - "name": "Ink", - "symbol": "INK", - "website_slug": "ink" - }, - { - "id": 2211, - "name": "Bodhi", - "symbol": "BOT", - "website_slug": "bodhi" - }, - { - "id": 2212, - "name": "Quantstamp", - "symbol": "QSP", - "website_slug": "quantstamp" - }, - { - "id": 2213, - "name": "QASH", - "symbol": "QASH", - "website_slug": "qash" - }, - { - "id": 2214, - "name": "ZoZoCoin", - "symbol": "ZZC", - "website_slug": "zozocoin" - }, - { - "id": 2215, - "name": "Energo", - "symbol": "TSL", - "website_slug": "energo" - }, - { - "id": 2217, - "name": "Publica", - "symbol": "PBL", - "website_slug": "publica" - }, - { - "id": 2218, - "name": "Magnet", - "symbol": "MAG", - "website_slug": "magnet" - }, - { - "id": 2219, - "name": "SpankChain", - "symbol": "SPANK", - "website_slug": "spankchain" - }, - { - "id": 2221, - "name": "VoteCoin", - "symbol": "VOT", - "website_slug": "votecoin" - }, - { - "id": 2222, - "name": "Bitcoin Diamond", - "symbol": "BCD", - "website_slug": "bitcoin-diamond" - }, - { - "id": 2223, - "name": "BLOCKv", - "symbol": "VEE", - "website_slug": "blockv" - }, - { - "id": 2224, - "name": "POLY AI", - "symbol": "AI", - "website_slug": "poly-ai" - }, - { - "id": 2225, - "name": "Accelerator Network", - "symbol": "ACC", - "website_slug": "accelerator-network" - }, - { - "id": 2228, - "name": "PlexCoin", - "symbol": "PLX", - "website_slug": "plexcoin" - }, - { - "id": 2229, - "name": "Divi", - "symbol": "DIVX", - "website_slug": "divi" - }, - { - "id": 2230, - "name": "Monkey Project", - "symbol": "MONK", - "website_slug": "monkey-project" - }, - { - "id": 2231, - "name": "Flixxo", - "symbol": "FLIXX", - "website_slug": "flixxo" - }, - { - "id": 2232, - "name": "GlassCoin", - "symbol": "GLS", - "website_slug": "glasscoin" - }, - { - "id": 2235, - "name": "Time New Bank", - "symbol": "TNB", - "website_slug": "time-new-bank" - }, - { - "id": 2236, - "name": "MyWish", - "symbol": "WISH", - "website_slug": "mywish" - }, - { - "id": 2237, - "name": "EventChain", - "symbol": "EVC", - "website_slug": "eventchain" - }, - { - "id": 2239, - "name": "ETHLend", - "symbol": "LEND", - "website_slug": "ethlend" - }, - { - "id": 2240, - "name": "SoMee.Social", - "symbol": "ONG", - "website_slug": "ongsocial" - }, - { - "id": 2241, - "name": "Ccore", - "symbol": "CCO", - "website_slug": "ccore" - }, - { - "id": 2242, - "name": "Qbao", - "symbol": "QBT", - "website_slug": "qbao" - }, - { - "id": 2243, - "name": "Dragonchain", - "symbol": "DRGN", - "website_slug": "dragonchain" - }, - { - "id": 2244, - "name": "Payfair", - "symbol": "PFR", - "website_slug": "payfair" - }, - { - "id": 2245, - "name": "Presearch", - "symbol": "PRE", - "website_slug": "presearch" - }, - { - "id": 2246, - "name": "CyberMiles", - "symbol": "CMT", - "website_slug": "cybermiles" - }, - { - "id": 2247, - "name": "BlockCDN", - "symbol": "BCDN", - "website_slug": "blockcdn" - }, - { - "id": 2248, - "name": "Cappasity", - "symbol": "CAPP", - "website_slug": "cappasity" - }, - { - "id": 2249, - "name": "Eroscoin", - "symbol": "ERO", - "website_slug": "eroscoin" - }, - { - "id": 2250, - "name": "MagicCoin", - "symbol": "MAGE", - "website_slug": "magiccoin" - }, - { - "id": 2251, - "name": "IoT Chain", - "symbol": "ITC", - "website_slug": "iot-chain" - }, - { - "id": 2253, - "name": "Jiyo", - "symbol": "JIYO", - "website_slug": "jiyo" - }, - { - "id": 2255, - "name": "Social Send", - "symbol": "SEND", - "website_slug": "social-send" - }, - { - "id": 2256, - "name": "Bonpay", - "symbol": "BON", - "website_slug": "bonpay" - }, - { - "id": 2257, - "name": "Nekonium", - "symbol": "NUKO", - "website_slug": "nekonium" - }, - { - "id": 2258, - "name": "Snovio", - "symbol": "SNOV", - "website_slug": "snovio" - }, - { - "id": 2260, - "name": "Bulwark", - "symbol": "BWK", - "website_slug": "bulwark" - }, - { - "id": 2261, - "name": "SagaCoin", - "symbol": "SAGA", - "website_slug": "sagacoin" - }, - { - "id": 2262, - "name": "COMSA [ETH]", - "symbol": "CMS", - "website_slug": "comsa-eth" - }, - { - "id": 2263, - "name": "Kubera Coin", - "symbol": "KBR", - "website_slug": "kubera-coin" - }, - { - "id": 2264, - "name": "Tokugawa", - "symbol": "TOK", - "website_slug": "tokugawa" - }, - { - "id": 2265, - "name": "Pioneer Coin", - "symbol": "PCOIN", - "website_slug": "pioneer-coin" - }, - { - "id": 2266, - "name": "COMSA [XEM]", - "symbol": "CMS", - "website_slug": "comsa-xem" - }, - { - "id": 2267, - "name": "WaBi", - "symbol": "WABI", - "website_slug": "wabi" - }, - { - "id": 2268, - "name": "CrowdCoin", - "symbol": "CRC", - "website_slug": "crowdcoin" - }, - { - "id": 2269, - "name": "WandX", - "symbol": "WAND", - "website_slug": "wandx" - }, - { - "id": 2270, - "name": "SportyCo", - "symbol": "SPF", - "website_slug": "sportyco" - }, - { - "id": 2271, - "name": "Verify", - "symbol": "CRED", - "website_slug": "verify" - }, - { - "id": 2272, - "name": "Soma", - "symbol": "SCT", - "website_slug": "soma" - }, - { - "id": 2273, - "name": "Uquid Coin", - "symbol": "UQC", - "website_slug": "uquid-coin" - }, - { - "id": 2274, - "name": "MediShares", - "symbol": "MDS", - "website_slug": "medishares" - }, - { - "id": 2275, - "name": "ProChain", - "symbol": "PRA", - "website_slug": "prochain" - }, - { - "id": 2276, - "name": "Ignis", - "symbol": "IGNIS", - "website_slug": "ignis" - }, - { - "id": 2277, - "name": "SmartMesh", - "symbol": "SMT", - "website_slug": "smartmesh" - }, - { - "id": 2278, - "name": "HollyWoodCoin", - "symbol": "HWC", - "website_slug": "hollywoodcoin" - }, - { - "id": 2279, - "name": "Playkey", - "symbol": "PKT", - "website_slug": "playkey" - }, - { - "id": 2280, - "name": "Filecoin [Futures]", - "symbol": "FIL", - "website_slug": "filecoin" - }, - { - "id": 2281, - "name": "BitcoinX", - "symbol": "BCX", - "website_slug": "bitcoinx" - }, - { - "id": 2282, - "name": "Super Bitcoin", - "symbol": "SBTC", - "website_slug": "super-bitcoin" - }, - { - "id": 2283, - "name": "Datum", - "symbol": "DAT", - "website_slug": "datum" - }, - { - "id": 2284, - "name": "Trident Group", - "symbol": "TRDT", - "website_slug": "trident" - }, - { - "id": 2286, - "name": "MicroMoney", - "symbol": "AMM", - "website_slug": "micromoney" - }, - { - "id": 2287, - "name": "LockTrip", - "symbol": "LOC", - "website_slug": "lockchain" - }, - { - "id": 2288, - "name": "Worldcore", - "symbol": "WRC", - "website_slug": "worldcore" - }, - { - "id": 2289, - "name": "Gifto", - "symbol": "GTO", - "website_slug": "gifto" - }, - { - "id": 2290, - "name": "YENTEN", - "symbol": "YTN", - "website_slug": "yenten" - }, - { - "id": 2291, - "name": "Genaro Network", - "symbol": "GNX", - "website_slug": "genaro-network" - }, - { - "id": 2293, - "name": "United Bitcoin", - "symbol": "UBTC", - "website_slug": "united-bitcoin" - }, - { - "id": 2295, - "name": "Starbase", - "symbol": "STAR", - "website_slug": "starbase" - }, - { - "id": 2296, - "name": "OST", - "symbol": "OST", - "website_slug": "ost" - }, - { - "id": 2297, - "name": "Storm", - "symbol": "STORM", - "website_slug": "storm" - }, - { - "id": 2298, - "name": "Dynamic Trading Rights", - "symbol": "DTR", - "website_slug": "dynamic-trading-rights" - }, - { - "id": 2299, - "name": "aelf", - "symbol": "ELF", - "website_slug": "aelf" - }, - { - "id": 2300, - "name": "WAX", - "symbol": "WAX", - "website_slug": "wax" - }, - { - "id": 2303, - "name": "MediBloc [QRC20]", - "symbol": "MED", - "website_slug": "medibloc" - }, - { - "id": 2304, - "name": "DEW", - "symbol": "DEW", - "website_slug": "dew" - }, - { - "id": 2305, - "name": "NAGA", - "symbol": "NGC", - "website_slug": "naga" - }, - { - "id": 2306, - "name": "Bread", - "symbol": "BRD", - "website_slug": "bread" - }, - { - "id": 2307, - "name": "Bibox Token", - "symbol": "BIX", - "website_slug": "bibox-token" - }, - { - "id": 2308, - "name": "Dai", - "symbol": "DAI", - "website_slug": "dai" - }, - { - "id": 2309, - "name": "SophiaTX", - "symbol": "SPHTX", - "website_slug": "sophiatx" - }, - { - "id": 2310, - "name": "Bounty0x", - "symbol": "BNTY", - "website_slug": "bounty0x" - }, - { - "id": 2311, - "name": "ACE (TokenStars)", - "symbol": "ACE", - "website_slug": "ace" - }, - { - "id": 2312, - "name": "DIMCOIN", - "symbol": "DIM", - "website_slug": "dimcoin" - }, - { - "id": 2313, - "name": "SIRIN LABS Token", - "symbol": "SRN", - "website_slug": "sirin-labs-token" - }, - { - "id": 2314, - "name": "Cryptopay", - "symbol": "CPAY", - "website_slug": "cryptopay" - }, - { - "id": 2315, - "name": "HTMLCOIN", - "symbol": "HTML", - "website_slug": "html-coin" - }, - { - "id": 2316, - "name": "DeepBrain Chain", - "symbol": "DBC", - "website_slug": "deepbrain-chain" - }, - { - "id": 2317, - "name": "HomeBlockCoin", - "symbol": "HBC", - "website_slug": "homeblockcoin" - }, - { - "id": 2318, - "name": "Neumark", - "symbol": "NEU", - "website_slug": "neumark" - }, - { - "id": 2320, - "name": "UTRUST", - "symbol": "UTK", - "website_slug": "utrust" - }, - { - "id": 2321, - "name": "QLC Chain", - "symbol": "QLC", - "website_slug": "qlink" - }, - { - "id": 2323, - "name": "HEROcoin", - "symbol": "PLAY", - "website_slug": "herocoin" - }, - { - "id": 2324, - "name": "BigONE Token", - "symbol": "BIG", - "website_slug": "bigone-token" - }, - { - "id": 2325, - "name": "Matryx", - "symbol": "MTX", - "website_slug": "matryx" - }, - { - "id": 2327, - "name": "Olympus Labs", - "symbol": "MOT", - "website_slug": "olympus-labs" - }, - { - "id": 2329, - "name": "Hyper Pay", - "symbol": "HPY", - "website_slug": "hyper-pay" - }, - { - "id": 2330, - "name": "Pylon Network", - "symbol": "PYLNT", - "website_slug": "pylon-network" - }, - { - "id": 2331, - "name": "ENTCash", - "symbol": "ENT", - "website_slug": "entcash" - }, - { - "id": 2332, - "name": "STRAKS", - "symbol": "STAK", - "website_slug": "straks" - }, - { - "id": 2333, - "name": "FidentiaX", - "symbol": "FDX", - "website_slug": "fidentiax" - }, - { - "id": 2334, - "name": "BitClave", - "symbol": "CAT", - "website_slug": "bitclave" - }, - { - "id": 2335, - "name": "Lightning Bitcoin", - "symbol": "LBTC", - "website_slug": "lightning-bitcoin" - }, - { - "id": 2336, - "name": "Game.com", - "symbol": "GTC", - "website_slug": "game" - }, - { - "id": 2337, - "name": "Lamden", - "symbol": "TAU", - "website_slug": "lamden" - }, - { - "id": 2338, - "name": "Escroco", - "symbol": "ESC", - "website_slug": "escoro" - }, - { - "id": 2340, - "name": "Bloom", - "symbol": "BLT", - "website_slug": "bloomtoken" - }, - { - "id": 2341, - "name": "SwftCoin", - "symbol": "SWFTC", - "website_slug": "swftcoin" - }, - { - "id": 2342, - "name": "Covesting", - "symbol": "COV", - "website_slug": "covesting" - }, - { - "id": 2343, - "name": "CanYaCoin", - "symbol": "CAN", - "website_slug": "canyacoin" - }, - { - "id": 2344, - "name": "AppCoins", - "symbol": "APPC", - "website_slug": "appcoins" - }, - { - "id": 2345, - "name": "High Performance Blockchain", - "symbol": "HPB", - "website_slug": "high-performance-blockchain" - }, - { - "id": 2346, - "name": "WaykiChain", - "symbol": "WICC", - "website_slug": "waykichain" - }, - { - "id": 2348, - "name": "Measurable Data Token", - "symbol": "MDT", - "website_slug": "measurable-data-token" - }, - { - "id": 2349, - "name": "Mixin", - "symbol": "XIN", - "website_slug": "mixin" - }, - { - "id": 2350, - "name": "GameChain System", - "symbol": "GCS", - "website_slug": "gamechain" - }, - { - "id": 2351, - "name": "Numus", - "symbol": "NMS", - "website_slug": "numus" - }, - { - "id": 2352, - "name": "Coinlancer", - "symbol": "CL", - "website_slug": "coinlancer" - }, - { - "id": 2353, - "name": "CryptopiaFeeShares", - "symbol": "CEFS", - "website_slug": "cryptopiafeeshares" - }, - { - "id": 2354, - "name": "GET Protocol", - "symbol": "GET", - "website_slug": "get-protocol" - }, - { - "id": 2355, - "name": "OP Coin", - "symbol": "OPC", - "website_slug": "op-coin" - }, - { - "id": 2356, - "name": "CFun", - "symbol": "CFUN", - "website_slug": "cfun" - }, - { - "id": 2357, - "name": "AI Doctor", - "symbol": "AIDOC", - "website_slug": "aidoc" - }, - { - "id": 2358, - "name": "Content and AD Network", - "symbol": "CAN", - "website_slug": "content-and-ad-network" - }, - { - "id": 2359, - "name": "Polis", - "symbol": "POLIS", - "website_slug": "polis" - }, - { - "id": 2360, - "name": "Hacken", - "symbol": "HKN", - "website_slug": "hacken" - }, - { - "id": 2361, - "name": "Show", - "symbol": "SHOW", - "website_slug": "show" - }, - { - "id": 2362, - "name": "Steneum Coin", - "symbol": "STN", - "website_slug": "steneum-coin" - }, - { - "id": 2363, - "name": "Zap", - "symbol": "ZAP", - "website_slug": "zap" - }, - { - "id": 2364, - "name": "TokenClub", - "symbol": "TCT", - "website_slug": "tokenclub" - }, - { - "id": 2366, - "name": "FairGame", - "symbol": "FAIR", - "website_slug": "fairgame" - }, - { - "id": 2367, - "name": "Aigang", - "symbol": "AIX", - "website_slug": "aigang" - }, - { - "id": 2368, - "name": "REBL", - "symbol": "REBL", - "website_slug": "rebl" - }, - { - "id": 2369, - "name": "INS Ecosystem", - "symbol": "INS", - "website_slug": "ins-ecosystem" - }, - { - "id": 2370, - "name": "Bitcoin God", - "symbol": "GOD", - "website_slug": "bitcoin-god" - }, - { - "id": 2371, - "name": "United Traders Token", - "symbol": "UTT", - "website_slug": "uttoken" - }, - { - "id": 2372, - "name": "Commodity Ad Network", - "symbol": "CDX", - "website_slug": "commodity-ad-network" - }, - { - "id": 2373, - "name": "Trade Token", - "symbol": "TIO", - "website_slug": "trade-token" - }, - { - "id": 2374, - "name": "BitDegree", - "symbol": "BDG", - "website_slug": "bitdegree" - }, - { - "id": 2375, - "name": "QunQun", - "symbol": "QUN", - "website_slug": "qunqun" - }, - { - "id": 2376, - "name": "TopChain", - "symbol": "TOPC", - "website_slug": "topchain" - }, - { - "id": 2377, - "name": "Leverj", - "symbol": "LEV", - "website_slug": "leverj" - }, - { - "id": 2378, - "name": "Karma", - "symbol": "KRM", - "website_slug": "karma" - }, - { - "id": 2379, - "name": "Kcash", - "symbol": "KCASH", - "website_slug": "kcash" - }, - { - "id": 2380, - "name": "ATN", - "symbol": "ATN", - "website_slug": "atn" - }, - { - "id": 2381, - "name": "Spectre.ai Dividend Token", - "symbol": "SXDT", - "website_slug": "spectre-dividend" - }, - { - "id": 2382, - "name": "Spectre.ai Utility Token", - "symbol": "SXUT", - "website_slug": "spectre-utility" - }, - { - "id": 2383, - "name": "Jingtum Tech", - "symbol": "SWTC", - "website_slug": "jingtum-tech" - }, - { - "id": 2384, - "name": "Vezt", - "symbol": "VZT", - "website_slug": "vezt" - }, - { - "id": 2385, - "name": "Cloud", - "symbol": "CLD", - "website_slug": "cloud" - }, - { - "id": 2386, - "name": "United Crypto Community", - "symbol": "UCOM", - "website_slug": "ucom" - }, - { - "id": 2387, - "name": "Bitcoin Atom", - "symbol": "BCA", - "website_slug": "bitcoin-atom" - }, - { - "id": 2389, - "name": "ugChain", - "symbol": "UGC", - "website_slug": "ugchain" - }, - { - "id": 2390, - "name": "Bankex", - "symbol": "BKX", - "website_slug": "bankex" - }, - { - "id": 2391, - "name": "EchoLink", - "symbol": "EKO", - "website_slug": "echolink" - }, - { - "id": 2392, - "name": "Bottos", - "symbol": "BTO", - "website_slug": "bottos" - }, - { - "id": 2393, - "name": "AWARE", - "symbol": "AT", - "website_slug": "aware" - }, - { - "id": 2394, - "name": "Telcoin", - "symbol": "TEL", - "website_slug": "telcoin" - }, - { - "id": 2395, - "name": "Ignition", - "symbol": "IC", - "website_slug": "ignition" - }, - { - "id": 2396, - "name": "WETH", - "symbol": "WETH", - "website_slug": "weth" - }, - { - "id": 2397, - "name": "Hackspace Capital", - "symbol": "HAC", - "website_slug": "hackspace-capital" - }, - { - "id": 2398, - "name": "Selfkey", - "symbol": "KEY", - "website_slug": "selfkey" - }, - { - "id": 2399, - "name": "Internet Node Token", - "symbol": "INT", - "website_slug": "internet-node-token" - }, - { - "id": 2400, - "name": "OneRoot Network", - "symbol": "RNT", - "website_slug": "oneroot-network" - }, - { - "id": 2402, - "name": "Sense", - "symbol": "SENSE", - "website_slug": "sense" - }, - { - "id": 2403, - "name": "MOAC", - "symbol": "MOAC", - "website_slug": "moac" - }, - { - "id": 2404, - "name": "TOKYO", - "symbol": "TOKC", - "website_slug": "tokyo" - }, - { - "id": 2405, - "name": "IOST", - "symbol": "IOST", - "website_slug": "iostoken" - }, - { - "id": 2406, - "name": "InvestDigital", - "symbol": "IDT", - "website_slug": "investdigital" - }, - { - "id": 2407, - "name": "AICHAIN", - "symbol": "AIT", - "website_slug": "aichain" - }, - { - "id": 2408, - "name": "Qube", - "symbol": "QUBE", - "website_slug": "qube" - }, - { - "id": 2409, - "name": "EtherDelta Token", - "symbol": "EDT", - "website_slug": "etherdelta-token" - }, - { - "id": 2410, - "name": "SpaceChain", - "symbol": "SPC", - "website_slug": "spacechain" - }, - { - "id": 2411, - "name": "Galactrum", - "symbol": "ORE", - "website_slug": "galactrum" - }, - { - "id": 2412, - "name": "Harvest Masternode Coin", - "symbol": "HC", - "website_slug": "harvest-masternode-coin" - }, - { - "id": 2413, - "name": "Ethorse", - "symbol": "HORSE", - "website_slug": "ethorse" - }, - { - "id": 2414, - "name": "RealChain", - "symbol": "RCT", - "website_slug": "realchain" - }, - { - "id": 2415, - "name": "ArbitrageCT", - "symbol": "ARCT", - "website_slug": "arbitragect" - }, - { - "id": 2416, - "name": "Theta Token", - "symbol": "THETA", - "website_slug": "theta-token" - }, - { - "id": 2418, - "name": "Maverick Chain", - "symbol": "MVC", - "website_slug": "maverick-chain" - }, - { - "id": 2419, - "name": "Profile Utility Token", - "symbol": "PUT", - "website_slug": "profile-utility-token" - }, - { - "id": 2420, - "name": "Nitro", - "symbol": "NOX", - "website_slug": "nitro" - }, - { - "id": 2421, - "name": "VouchForMe", - "symbol": "IPL", - "website_slug": "insurepal" - }, - { - "id": 2422, - "name": "IDEX Membership", - "symbol": "IDXM", - "website_slug": "idex-membership" - }, - { - "id": 2423, - "name": "Aurora DAO", - "symbol": "AURA", - "website_slug": "aurora-dao" - }, - { - "id": 2424, - "name": "SingularityNET", - "symbol": "AGI", - "website_slug": "singularitynet" - }, - { - "id": 2425, - "name": "Gatcoin", - "symbol": "GAT", - "website_slug": "gatcoin" - }, - { - "id": 2426, - "name": "ShareX", - "symbol": "SEXC", - "website_slug": "sharex" - }, - { - "id": 2427, - "name": "ChatCoin", - "symbol": "CHAT", - "website_slug": "chatcoin" - }, - { - "id": 2428, - "name": "Scry.info", - "symbol": "DDD", - "website_slug": "scryinfo" - }, - { - "id": 2429, - "name": "Mobius", - "symbol": "MOBI", - "website_slug": "mobius" - }, - { - "id": 2430, - "name": "Hydro Protocol", - "symbol": "HOT", - "website_slug": "hydro-protocol" - }, - { - "id": 2432, - "name": "StarChain", - "symbol": "STC", - "website_slug": "starchain" - }, - { - "id": 2433, - "name": "IPChain", - "symbol": "IPC", - "website_slug": "ipchain" - }, - { - "id": 2434, - "name": "Maggie", - "symbol": "MAG", - "website_slug": "maggie" - }, - { - "id": 2435, - "name": "LightChain", - "symbol": "LIGHT", - "website_slug": "lightchain" - }, - { - "id": 2436, - "name": "RefToken", - "symbol": "REF", - "website_slug": "reftoken" - }, - { - "id": 2437, - "name": "YEE", - "symbol": "YEE", - "website_slug": "yee" - }, - { - "id": 2438, - "name": "Acute Angle Cloud", - "symbol": "AAC", - "website_slug": "acute-angle-cloud" - }, - { - "id": 2439, - "name": "SelfSell", - "symbol": "SSC", - "website_slug": "selfsell" - }, - { - "id": 2440, - "name": "Read", - "symbol": "READ", - "website_slug": "read" - }, - { - "id": 2441, - "name": "Molecular Future", - "symbol": "MOF", - "website_slug": "molecular-future" - }, - { - "id": 2443, - "name": "Trinity Network Credit", - "symbol": "TNC", - "website_slug": "trinity-network-credit" - }, - { - "id": 2444, - "name": "CRYPTO20", - "symbol": "C20", - "website_slug": "c20" - }, - { - "id": 2445, - "name": "Block Array", - "symbol": "ARY", - "website_slug": "block-array" - }, - { - "id": 2446, - "name": "DATA", - "symbol": "DTA", - "website_slug": "data" - }, - { - "id": 2447, - "name": "Crypterium", - "symbol": "CRPT", - "website_slug": "crypterium" - }, - { - "id": 2448, - "name": "Sparks", - "symbol": "SPK", - "website_slug": "sparks" - }, - { - "id": 2450, - "name": "carVertical", - "symbol": "CV", - "website_slug": "carvertical" - }, - { - "id": 2452, - "name": "Tokenbox", - "symbol": "TBX", - "website_slug": "tokenbox" - }, - { - "id": 2453, - "name": "EDUCare", - "symbol": "EKT", - "website_slug": "educare" - }, - { - "id": 2454, - "name": "UnlimitedIP", - "symbol": "UIP", - "website_slug": "unlimitedip" - }, - { - "id": 2455, - "name": "PressOne", - "symbol": "PRS", - "website_slug": "pressone" - }, - { - "id": 2456, - "name": "OFCOIN", - "symbol": "OF", - "website_slug": "ofcoin" - }, - { - "id": 2457, - "name": "TrueChain", - "symbol": "TRUE", - "website_slug": "truechain" - }, - { - "id": 2458, - "name": "Odyssey", - "symbol": "OCN", - "website_slug": "odyssey" - }, - { - "id": 2459, - "name": "indaHash", - "symbol": "IDH", - "website_slug": "indahash" - }, - { - "id": 2460, - "name": "Qbic", - "symbol": "QBIC", - "website_slug": "qbic" - }, - { - "id": 2461, - "name": "Peerguess", - "symbol": "GUESS", - "website_slug": "guess" - }, - { - "id": 2462, - "name": "AidCoin", - "symbol": "AID", - "website_slug": "aidcoin" - }, - { - "id": 2464, - "name": "Devery", - "symbol": "EVE", - "website_slug": "devery" - }, - { - "id": 2465, - "name": "Blockport", - "symbol": "BPT", - "website_slug": "blockport" - }, - { - "id": 2466, - "name": "aXpire", - "symbol": "AXPR", - "website_slug": "axpire" - }, - { - "id": 2467, - "name": "OriginTrail", - "symbol": "TRAC", - "website_slug": "origintrail" - }, - { - "id": 2468, - "name": "LinkEye", - "symbol": "LET", - "website_slug": "linkeye" - }, - { - "id": 2469, - "name": "Zilliqa", - "symbol": "ZIL", - "website_slug": "zilliqa" - }, - { - "id": 2470, - "name": "CoinMeet", - "symbol": "MEET", - "website_slug": "coinmeet" - }, - { - "id": 2471, - "name": "Smartlands", - "symbol": "SLT", - "website_slug": "smartlands" - }, - { - "id": 2472, - "name": "Fortuna", - "symbol": "FOTA", - "website_slug": "fortuna" - }, - { - "id": 2473, - "name": "All Sports", - "symbol": "SOC", - "website_slug": "all-sports" - }, - { - "id": 2474, - "name": "Matrix AI Network", - "symbol": "MAN", - "website_slug": "matrix-ai-network" - }, - { - "id": 2475, - "name": "Garlicoin", - "symbol": "GRLC", - "website_slug": "garlicoin" - }, - { - "id": 2476, - "name": "Ruff", - "symbol": "RUFF", - "website_slug": "ruff" - }, - { - "id": 2477, - "name": "Nework", - "symbol": "NKC", - "website_slug": "nework" - }, - { - "id": 2478, - "name": "CoinFi", - "symbol": "COFI", - "website_slug": "coinfi" - }, - { - "id": 2479, - "name": "Equal", - "symbol": "EQL", - "website_slug": "equal" - }, - { - "id": 2480, - "name": "HalalChain", - "symbol": "HLC", - "website_slug": "halalchain" - }, - { - "id": 2481, - "name": "Zeepin", - "symbol": "ZPT", - "website_slug": "zeepin" - }, - { - "id": 2482, - "name": "CPChain", - "symbol": "CPC", - "website_slug": "cpchain" - }, - { - "id": 2483, - "name": "OceanChain", - "symbol": "OC", - "website_slug": "oceanchain" - }, - { - "id": 2484, - "name": "Hi Mutual Society", - "symbol": "HMC", - "website_slug": "hi-mutual-society" - }, - { - "id": 2485, - "name": "Candy", - "symbol": "CANDY", - "website_slug": "candy" - }, - { - "id": 2486, - "name": "Speed Mining Service", - "symbol": "SMS", - "website_slug": "speed-mining-service" - }, - { - "id": 2487, - "name": "Electronic PK Chain", - "symbol": "EPC", - "website_slug": "electronic-pk-chain" - }, - { - "id": 2488, - "name": "ValueChain", - "symbol": "VLC", - "website_slug": "valuechain" - }, - { - "id": 2489, - "name": "BitWhite", - "symbol": "BTW", - "website_slug": "bitwhite" - }, - { - "id": 2490, - "name": "CargoX", - "symbol": "CXO", - "website_slug": "cargox" - }, - { - "id": 2491, - "name": "Travelflex", - "symbol": "TRF", - "website_slug": "travelflex" - }, - { - "id": 2492, - "name": "Elastos", - "symbol": "ELA", - "website_slug": "elastos" - }, - { - "id": 2493, - "name": "STK", - "symbol": "STK", - "website_slug": "stk" - }, - { - "id": 2495, - "name": "Pareto Network", - "symbol": "PARETO", - "website_slug": "pareto-network" - }, - { - "id": 2496, - "name": "Polymath", - "symbol": "POLY", - "website_slug": "polymath-network" - }, - { - "id": 2497, - "name": "Medicalchain", - "symbol": "MTN", - "website_slug": "medical-chain" - }, - { - "id": 2498, - "name": "Jibrel Network", - "symbol": "JNT", - "website_slug": "jibrel-network" - }, - { - "id": 2499, - "name": "SwissBorg", - "symbol": "CHSB", - "website_slug": "swissborg" - }, - { - "id": 2500, - "name": "Zilla", - "symbol": "ZLA", - "website_slug": "zilla" - }, - { - "id": 2501, - "name": "adbank", - "symbol": "ADB", - "website_slug": "adbank" - }, - { - "id": 2502, - "name": "Huobi Token", - "symbol": "HT", - "website_slug": "huobi-token" - }, - { - "id": 2503, - "name": "DMarket", - "symbol": "DMT", - "website_slug": "dmarket" - }, - { - "id": 2504, - "name": "Iungo", - "symbol": "ING", - "website_slug": "iungo" - }, - { - "id": 2505, - "name": "Bluzelle", - "symbol": "BLZ", - "website_slug": "bluzelle" - }, - { - "id": 2506, - "name": "Swarm", - "symbol": "SWM", - "website_slug": "swarm-fund" - }, - { - "id": 2507, - "name": "THEKEY", - "symbol": "TKY", - "website_slug": "thekey" - }, - { - "id": 2508, - "name": "DCORP Utility", - "symbol": "DRPU", - "website_slug": "drp-utility" - }, - { - "id": 2509, - "name": "EtherSportz", - "symbol": "ESZ", - "website_slug": "ethersportz" - }, - { - "id": 2510, - "name": "Datawallet", - "symbol": "DXT", - "website_slug": "datawallet" - }, - { - "id": 2511, - "name": "WePower", - "symbol": "WPR", - "website_slug": "wepower" - }, - { - "id": 2512, - "name": "UNIVERSAL CASH", - "symbol": "UCASH", - "website_slug": "ucash" - }, - { - "id": 2513, - "name": "GoldMint", - "symbol": "MNTP", - "website_slug": "goldmint" - }, - { - "id": 2514, - "name": "Shekel", - "symbol": "JEW", - "website_slug": "shekel" - }, - { - "id": 2515, - "name": "ACChain", - "symbol": "ACC", - "website_slug": "acchain" - }, - { - "id": 2516, - "name": "MktCoin", - "symbol": "MLM", - "website_slug": "mktcoin" - }, - { - "id": 2517, - "name": "Animation Vision Cash", - "symbol": "AVH", - "website_slug": "animation-vision-cash" - }, - { - "id": 2518, - "name": "LOCIcoin", - "symbol": "LOCI", - "website_slug": "locicoin" - }, - { - "id": 2519, - "name": "Indicoin", - "symbol": "INDI", - "website_slug": "indicoin" - }, - { - "id": 2520, - "name": "Jesus Coin", - "symbol": "JC", - "website_slug": "jesus-coin" - }, - { - "id": 2521, - "name": "BioCoin", - "symbol": "BIO", - "website_slug": "biocoin" - }, - { - "id": 2522, - "name": "Superior Coin", - "symbol": "SUP", - "website_slug": "superior-coin" - }, - { - "id": 2523, - "name": "Tigereum", - "symbol": "TIG", - "website_slug": "tigereum" - }, - { - "id": 2524, - "name": "Universa", - "symbol": "UTNP", - "website_slug": "universa" - }, - { - "id": 2525, - "name": "Alphacat", - "symbol": "ACAT", - "website_slug": "alphacat" - }, - { - "id": 2526, - "name": "Envion", - "symbol": "EVN", - "website_slug": "envion" - }, - { - "id": 2527, - "name": "SureRemit", - "symbol": "RMT", - "website_slug": "sureremit" - }, - { - "id": 2528, - "name": "Dether", - "symbol": "DTH", - "website_slug": "dether" - }, - { - "id": 2529, - "name": "Cashaa", - "symbol": "CAS", - "website_slug": "cashaa" - }, - { - "id": 2530, - "name": "Fusion", - "symbol": "FSN", - "website_slug": "fusion" - }, - { - "id": 2531, - "name": "W3Coin", - "symbol": "W3C", - "website_slug": "w3coin" - }, - { - "id": 2532, - "name": "Etherecash", - "symbol": "ECH", - "website_slug": "etherecash" - }, - { - "id": 2533, - "name": "Restart Energy MWAT", - "symbol": "MWAT", - "website_slug": "restart-energy-mwat" - }, - { - "id": 2534, - "name": "Gladius Token", - "symbol": "GLA", - "website_slug": "gladius-token" - }, - { - "id": 2535, - "name": "DADI", - "symbol": "DADI", - "website_slug": "dadi" - }, - { - "id": 2536, - "name": "Neurotoken", - "symbol": "NTK", - "website_slug": "neurotoken" - }, - { - "id": 2537, - "name": "Gems ", - "symbol": "GEM", - "website_slug": "gems-protocol" - }, - { - "id": 2538, - "name": "Nectar", - "symbol": "NEC", - "website_slug": "nectar" - }, - { - "id": 2539, - "name": "Republic Protocol", - "symbol": "REN", - "website_slug": "republic-protocol" - }, - { - "id": 2540, - "name": "Litecoin Cash", - "symbol": "LCC", - "website_slug": "litecoin-cash" - }, - { - "id": 2541, - "name": "Storiqa", - "symbol": "STQ", - "website_slug": "storiqa" - }, - { - "id": 2542, - "name": "Tidex Token", - "symbol": "TDX", - "website_slug": "tidex-token" - }, - { - "id": 2543, - "name": "COPYTRACK", - "symbol": "CPY", - "website_slug": "copytrack" - }, - { - "id": 2544, - "name": "Nucleus Vision", - "symbol": "NCASH", - "website_slug": "nucleus-vision" - }, - { - "id": 2545, - "name": "Arcblock", - "symbol": "ABT", - "website_slug": "arcblock" - }, - { - "id": 2546, - "name": "Remme", - "symbol": "REM", - "website_slug": "remme" - }, - { - "id": 2547, - "name": "Experty", - "symbol": "EXY", - "website_slug": "experty" - }, - { - "id": 2548, - "name": "POA Network", - "symbol": "POA", - "website_slug": "poa-network" - }, - { - "id": 2549, - "name": "Ink Protocol", - "symbol": "XNK", - "website_slug": "ink-protocol" - }, - { - "id": 2550, - "name": "Rock", - "symbol": "RKT", - "website_slug": "rock" - }, - { - "id": 2551, - "name": "Bezop", - "symbol": "BEZ", - "website_slug": "bezop" - }, - { - "id": 2552, - "name": "IHT Real Estate Protocol", - "symbol": "IHT", - "website_slug": "iht-real-estate-protocol" - }, - { - "id": 2553, - "name": "Refereum", - "symbol": "RFR", - "website_slug": "refereum" - }, - { - "id": 2554, - "name": "Lympo", - "symbol": "LYM", - "website_slug": "lympo" - }, - { - "id": 2555, - "name": "Sether", - "symbol": "SETH", - "website_slug": "sether" - }, - { - "id": 2556, - "name": "Credits", - "symbol": "CS", - "website_slug": "credits" - }, - { - "id": 2557, - "name": "Bee Token", - "symbol": "BEE", - "website_slug": "bee-token" - }, - { - "id": 2558, - "name": "Insights Network", - "symbol": "INSTAR", - "website_slug": "insights-network" - }, - { - "id": 2559, - "name": "Cube", - "symbol": "AUTO", - "website_slug": "cube" - }, - { - "id": 2560, - "name": "EZToken", - "symbol": "EZT", - "website_slug": "eztoken" - }, - { - "id": 2561, - "name": "BitTube", - "symbol": "TUBE", - "website_slug": "bit-tube" - }, - { - "id": 2562, - "name": "Education Ecosystem", - "symbol": "LEDU", - "website_slug": "education-ecosystem" - }, - { - "id": 2563, - "name": "TrueUSD", - "symbol": "TUSD", - "website_slug": "trueusd" - }, - { - "id": 2564, - "name": "HOQU", - "symbol": "HQX", - "website_slug": "hoqu" - }, - { - "id": 2565, - "name": "StarterCoin", - "symbol": "STAC", - "website_slug": "startercoin" - }, - { - "id": 2566, - "name": "Ontology", - "symbol": "ONT", - "website_slug": "ontology" - }, - { - "id": 2567, - "name": "DATx", - "symbol": "DATX", - "website_slug": "datx" - }, - { - "id": 2568, - "name": "JET8", - "symbol": "J8T", - "website_slug": "jet8" - }, - { - "id": 2569, - "name": "CoinPoker", - "symbol": "CHP", - "website_slug": "coinpoker" - }, - { - "id": 2570, - "name": "TomoChain", - "symbol": "TOMO", - "website_slug": "tomochain" - }, - { - "id": 2571, - "name": "Graft", - "symbol": "GRFT", - "website_slug": "graft" - }, - { - "id": 2572, - "name": "BABB", - "symbol": "BAX", - "website_slug": "babb" - }, - { - "id": 2573, - "name": "Electrify.Asia", - "symbol": "ELEC", - "website_slug": "electrifyasia" - }, - { - "id": 2575, - "name": "Bitcoin Private", - "symbol": "BTCP", - "website_slug": "bitcoin-private" - }, - { - "id": 2576, - "name": "Tokenomy", - "symbol": "TEN", - "website_slug": "tokenomy" - }, - { - "id": 2577, - "name": "Ravencoin", - "symbol": "RVN", - "website_slug": "ravencoin" - }, - { - "id": 2578, - "name": "TE-FOOD", - "symbol": "TFD", - "website_slug": "te-food" - }, - { - "id": 2579, - "name": "ShipChain", - "symbol": "SHIP", - "website_slug": "shipchain" - }, - { - "id": 2580, - "name": "Leadcoin", - "symbol": "LDC", - "website_slug": "leadcoin" - }, - { - "id": 2581, - "name": "Sharpe Platform Token", - "symbol": "SHP", - "website_slug": "sharpe-platform-token" - }, - { - "id": 2582, - "name": "LALA World", - "symbol": "LALA", - "website_slug": "lala-world" - }, - { - "id": 2583, - "name": "Octoin Coin", - "symbol": "OCC", - "website_slug": "octoin-coin" - }, - { - "id": 2584, - "name": "Debitum", - "symbol": "DEB", - "website_slug": "debitum-network" - }, - { - "id": 2585, - "name": "Centrality", - "symbol": "CENNZ", - "website_slug": "centrality" - }, - { - "id": 2586, - "name": "Havven", - "symbol": "HAV", - "website_slug": "havven" - }, - { - "id": 2587, - "name": "Fluz Fluz", - "symbol": "FLUZ", - "website_slug": "fluz-fluz" - }, - { - "id": 2588, - "name": "Loom Network", - "symbol": "LOOM", - "website_slug": "loom-network" - }, - { - "id": 2589, - "name": "Guaranteed Ethurance Token Extra", - "symbol": "GETX", - "website_slug": "guaranteed-ethurance-token-extra" - }, - { - "id": 2590, - "name": "HireMatch", - "symbol": "HIRE", - "website_slug": "hirematch" - }, - { - "id": 2591, - "name": "Dropil", - "symbol": "DROP", - "website_slug": "dropil" - }, - { - "id": 2592, - "name": "Banca", - "symbol": "BANCA", - "website_slug": "banca" - }, - { - "id": 2593, - "name": "Dragon Coins", - "symbol": "DRG", - "website_slug": "dragon-coins" - }, - { - "id": 2594, - "name": "LatiumX", - "symbol": "LATX", - "website_slug": "latiumx" - }, - { - "id": 2595, - "name": "NANJCOIN", - "symbol": "NANJ", - "website_slug": "nanjcoin" - }, - { - "id": 2596, - "name": "CK USD", - "symbol": "CKUSD", - "website_slug": "ckusd" - }, - { - "id": 2597, - "name": "UpToken", - "symbol": "UP", - "website_slug": "uptoken" - }, - { - "id": 2598, - "name": "Banyan Network", - "symbol": "BBN", - "website_slug": "banyan-network" - }, - { - "id": 2599, - "name": "Noah Coin", - "symbol": "NOAH", - "website_slug": "noah-coin" - }, - { - "id": 2600, - "name": "LGO Exchange", - "symbol": "LGO", - "website_slug": "legolas-exchange" - }, - { - "id": 2601, - "name": "1World", - "symbol": "1WO", - "website_slug": "1world" - }, - { - "id": 2602, - "name": "NaPoleonX", - "symbol": "NPX", - "website_slug": "napoleonx" - }, - { - "id": 2603, - "name": "Pundi X", - "symbol": "NPXS", - "website_slug": "pundi-x" - }, - { - "id": 2604, - "name": "Bitcoin Green", - "symbol": "BITG", - "website_slug": "bitcoin-green" - }, - { - "id": 2605, - "name": "BnkToTheFuture", - "symbol": "BFT", - "website_slug": "bnktothefuture" - }, - { - "id": 2606, - "name": "Wanchain", - "symbol": "WAN", - "website_slug": "wanchain" - }, - { - "id": 2607, - "name": "AMLT", - "symbol": "AMLT", - "website_slug": "amlt" - }, - { - "id": 2608, - "name": "Mithril", - "symbol": "MITH", - "website_slug": "mithril" - }, - { - "id": 2609, - "name": "Lendroid Support Token", - "symbol": "LST", - "website_slug": "lendroid-support-token" - }, - { - "id": 2610, - "name": "Peculium", - "symbol": "PCL", - "website_slug": "peculium" - }, - { - "id": 2611, - "name": "Spectiv", - "symbol": "SIG", - "website_slug": "signal-token" - }, - { - "id": 2612, - "name": "BitRent", - "symbol": "RNTB", - "website_slug": "bitrent" - }, - { - "id": 2614, - "name": "BlitzPredict", - "symbol": "XBP", - "website_slug": "blitzpredict" - }, - { - "id": 2615, - "name": "Blocklancer", - "symbol": "LNC", - "website_slug": "blocklancer" - }, - { - "id": 2616, - "name": "Stipend", - "symbol": "SPD", - "website_slug": "stipend" - }, - { - "id": 2617, - "name": "IP Exchange", - "symbol": "IPSX", - "website_slug": "ip-exchange" - }, - { - "id": 2618, - "name": "StockChain", - "symbol": "SCC", - "website_slug": "stockchain" - }, - { - "id": 2619, - "name": "BitStation", - "symbol": "BSTN", - "website_slug": "bitstation" - }, - { - "id": 2620, - "name": "Switcheo", - "symbol": "SWTH", - "website_slug": "switcheo" - }, - { - "id": 2621, - "name": "Consensus", - "symbol": "SEN", - "website_slug": "consensus" - }, - { - "id": 2622, - "name": "ClearCoin", - "symbol": "XCLR", - "website_slug": "clearcoin" - }, - { - "id": 2624, - "name": "Sentinel Chain", - "symbol": "SENC", - "website_slug": "sentinel-chain" - }, - { - "id": 2625, - "name": "Vice Industry Token", - "symbol": "VIT", - "website_slug": "vice-industry-token" - }, - { - "id": 2626, - "name": "Friendz", - "symbol": "FDZ", - "website_slug": "friends" - }, - { - "id": 2627, - "name": "TokenPay", - "symbol": "TPAY", - "website_slug": "tokenpay" - }, - { - "id": 2628, - "name": "Rentberry", - "symbol": "BERRY", - "website_slug": "rentberry" - }, - { - "id": 2629, - "name": "Stellite", - "symbol": "XTL", - "website_slug": "stellite" - }, - { - "id": 2630, - "name": "PolySwarm", - "symbol": "NCT", - "website_slug": "polyswarm" - }, - { - "id": 2631, - "name": "ODEM", - "symbol": "ODE", - "website_slug": "odem" - }, - { - "id": 2632, - "name": "Monero Original", - "symbol": "XMO", - "website_slug": "monero-original" - }, - { - "id": 2633, - "name": "Stakenet", - "symbol": "XSN", - "website_slug": "stakenet" - }, - { - "id": 2634, - "name": "XinFin Network", - "symbol": "XDCE", - "website_slug": "xinfin-network" - }, - { - "id": 2635, - "name": "TokenDesk", - "symbol": "TDS", - "website_slug": "tokendesk" - }, - { - "id": 2636, - "name": "BelugaPay", - "symbol": "BBI", - "website_slug": "belugapay" - }, - { - "id": 2637, - "name": "Fidelium", - "symbol": "FID", - "website_slug": "fidelium" - }, - { - "id": 2638, - "name": "Cortex", - "symbol": "CTXC", - "website_slug": "cortex" - }, - { - "id": 2639, - "name": "Arbitracoin", - "symbol": "ATC", - "website_slug": "arbitracoin" - }, - { - "id": 2640, - "name": "WCOIN", - "symbol": "WIN", - "website_slug": "wawllet" - }, - { - "id": 2641, - "name": "Apex", - "symbol": "CPX", - "website_slug": "apex" - }, - { - "id": 2642, - "name": "CyberVein", - "symbol": "CVT", - "website_slug": "cybervein" - }, - { - "id": 2643, - "name": "Sentinel", - "symbol": "SENT", - "website_slug": "sentinel" - }, - { - "id": 2644, - "name": "eosDAC", - "symbol": "EOSDAC", - "website_slug": "eosdac" - }, - { - "id": 2645, - "name": "U Network", - "symbol": "UUU", - "website_slug": "u-network" - }, - { - "id": 2646, - "name": "AdHive", - "symbol": "ADH", - "website_slug": "adhive" - }, - { - "id": 2647, - "name": "SnipCoin", - "symbol": "SNIP", - "website_slug": "snipcoin" - }, - { - "id": 2648, - "name": "Bitsum", - "symbol": "BSM", - "website_slug": "bitsum" - }, - { - "id": 2649, - "name": "DeviantCoin", - "symbol": "DEV", - "website_slug": "deviantcoin" - }, - { - "id": 2650, - "name": "CommerceBlock", - "symbol": "CBT", - "website_slug": "commerceblock" - }, - { - "id": 2651, - "name": "GreenMed", - "symbol": "GRMD", - "website_slug": "greenmed" - }, - { - "id": 2653, - "name": "Auctus", - "symbol": "AUC", - "website_slug": "auctus" - }, - { - "id": 2654, - "name": "Budbo", - "symbol": "BUBO", - "website_slug": "budbo" - }, - { - "id": 2655, - "name": "Monero Classic", - "symbol": "XMC", - "website_slug": "monero-classic" - }, - { - "id": 2656, - "name": "Daneel", - "symbol": "DAN", - "website_slug": "daneel" - }, - { - "id": 2657, - "name": "BrahmaOS", - "symbol": "BRM", - "website_slug": "brahmaos" - }, - { - "id": 2658, - "name": "SyncFab", - "symbol": "MFG", - "website_slug": "syncfab" - }, - { - "id": 2659, - "name": "Dignity", - "symbol": "DIG", - "website_slug": "dignity" - }, - { - "id": 2660, - "name": "Aditus", - "symbol": "ADI", - "website_slug": "aditus" - }, - { - "id": 2661, - "name": "Tripio", - "symbol": "TRIO", - "website_slug": "tripio" - }, - { - "id": 2662, - "name": "Haven Protocol", - "symbol": "XHV", - "website_slug": "haven-protocol" - }, - { - "id": 2663, - "name": "StarCoin", - "symbol": "KST", - "website_slug": "starcointv" - }, - { - "id": 2664, - "name": "CryCash", - "symbol": "CRC", - "website_slug": "crycash" - }, - { - "id": 2665, - "name": "Dero", - "symbol": "DERO", - "website_slug": "dero" - }, - { - "id": 2666, - "name": "Effect.AI", - "symbol": "EFX", - "website_slug": "effect-ai" - }, - { - "id": 2667, - "name": "FintruX Network", - "symbol": "FTX", - "website_slug": "fintrux-network" - }, - { - "id": 2668, - "name": "Earth Token", - "symbol": "EARTH", - "website_slug": "earth-token" - }, - { - "id": 2669, - "name": "MARK.SPACE", - "symbol": "MRK", - "website_slug": "mark-space" - }, - { - "id": 2670, - "name": "Pixie Coin", - "symbol": "PXC", - "website_slug": "pixie-coin" - }, - { - "id": 2671, - "name": "Cropcoin", - "symbol": "CROP", - "website_slug": "cropcoin" - }, - { - "id": 2672, - "name": "SRCOIN", - "symbol": "SRCOIN", - "website_slug": "srcoin" - }, - { - "id": 2673, - "name": "Own", - "symbol": "CHX", - "website_slug": "own" - }, - { - "id": 2674, - "name": "Masari", - "symbol": "MSR", - "website_slug": "masari" - }, - { - "id": 2675, - "name": "Dock", - "symbol": "DOCK", - "website_slug": "dock" - }, - { - "id": 2676, - "name": "PHI Token", - "symbol": "PHI", - "website_slug": "phi-token" - }, - { - "id": 2677, - "name": "Linker Coin", - "symbol": "LNC", - "website_slug": "linker-coin" - }, - { - "id": 2678, - "name": "TraDove B2BCoin", - "symbol": "BBC", - "website_slug": "b2bcoin" - }, - { - "id": 2679, - "name": "Decentralized Machine Learning", - "symbol": "DML", - "website_slug": "decentralized-machine-learning" - }, - { - "id": 2680, - "name": "Helbiz", - "symbol": "HBZ", - "website_slug": "helbiz" - }, - { - "id": 2681, - "name": "Origami", - "symbol": "ORI", - "website_slug": "origami" - }, - { - "id": 2682, - "name": "Holo", - "symbol": "HOT", - "website_slug": "holo" - }, - { - "id": 2683, - "name": "TrakInvest", - "symbol": "TRAK", - "website_slug": "trakinvest" - }, - { - "id": 2684, - "name": "Aphelion", - "symbol": "APH", - "website_slug": "aphelion" - }, - { - "id": 2685, - "name": "Zebi", - "symbol": "ZCO", - "website_slug": "zebi" - }, - { - "id": 2686, - "name": "Lendingblock", - "symbol": "LND", - "website_slug": "lendingblock" - }, - { - "id": 2687, - "name": "Proxeus", - "symbol": "XES", - "website_slug": "proxeus" - }, - { - "id": 2688, - "name": "Vipstar Coin", - "symbol": "VIPS", - "website_slug": "vipstar-coin" - }, - { - "id": 2689, - "name": "Rublix", - "symbol": "RBLX", - "website_slug": "rublix" - }, - { - "id": 2690, - "name": "Biotron", - "symbol": "BTRN", - "website_slug": "biotron" - }, - { - "id": 2691, - "name": "Penta", - "symbol": "PNT", - "website_slug": "penta" - }, - { - "id": 2692, - "name": "Nebula AI", - "symbol": "NBAI", - "website_slug": "nebula-ai" - }, - { - "id": 2693, - "name": "Loopring [NEO]", - "symbol": "LRN", - "website_slug": "loopring-neo" - }, - { - "id": 2694, - "name": "Nexo", - "symbol": "NEXO", - "website_slug": "nexo" - }, - { - "id": 2695, - "name": "VeriME", - "symbol": "VME", - "website_slug": "verime" - }, - { - "id": 2696, - "name": "DAEX", - "symbol": "DAX", - "website_slug": "daex" - }, - { - "id": 2698, - "name": "Hydro", - "symbol": "HYDRO", - "website_slug": "hydrogen" - }, - { - "id": 2699, - "name": "Sharder", - "symbol": "SS", - "website_slug": "sharder" - }, - { - "id": 2701, - "name": "TrustNote", - "symbol": "TTT", - "website_slug": "trustnote" - }, - { - "id": 2702, - "name": "Bitcoin Interest", - "symbol": "BCI", - "website_slug": "bitcoin-interest" - }, - { - "id": 2703, - "name": "BetterBetting", - "symbol": "BETR", - "website_slug": "betterbetting" - }, - { - "id": 2704, - "name": "Transcodium", - "symbol": "TNS", - "website_slug": "transcodium" - }, - { - "id": 2705, - "name": "Amon", - "symbol": "AMN", - "website_slug": "amon" - }, - { - "id": 2706, - "name": "Plancoin", - "symbol": "PLAN", - "website_slug": "plancoin" - }, - { - "id": 2707, - "name": "FLIP", - "symbol": "FLP", - "website_slug": "flip" - }, - { - "id": 2708, - "name": "Crowd Machine", - "symbol": "CMCT", - "website_slug": "crowd-machine" - }, - { - "id": 2709, - "name": "Morpheus Labs", - "symbol": "MITX", - "website_slug": "morpheus-labs" - }, - { - "id": 2710, - "name": "Live Stars", - "symbol": "LIVE", - "website_slug": "live-stars" - }, - { - "id": 2711, - "name": "Docademic", - "symbol": "MTC", - "website_slug": "docademic" - }, - { - "id": 2712, - "name": "MyToken", - "symbol": "MT", - "website_slug": "mytoken" - }, - { - "id": 2713, - "name": "KEY", - "symbol": "KEY", - "website_slug": "key" - }, - { - "id": 2714, - "name": "Nexty", - "symbol": "NTY", - "website_slug": "nexty" - }, - { - "id": 2715, - "name": "ConnectJob", - "symbol": "CJT", - "website_slug": "connectjob" - }, - { - "id": 2716, - "name": "Galaxy eSolutions", - "symbol": "GES", - "website_slug": "galaxy-esolutions" - }, - { - "id": 2717, - "name": "BoutsPro", - "symbol": "BOUTS", - "website_slug": "boutspro" - }, - { - "id": 2718, - "name": "PolicyPal Network", - "symbol": "PAL", - "website_slug": "policypal-network" - }, - { - "id": 2719, - "name": "Cybereits", - "symbol": "CRE", - "website_slug": "cybereits" - }, - { - "id": 2720, - "name": "Parkgene", - "symbol": "GENE", - "website_slug": "parkgene" - }, - { - "id": 2721, - "name": "APR Coin", - "symbol": "APR", - "website_slug": "apr-coin" - }, - { - "id": 2722, - "name": "AC3", - "symbol": "AC3", - "website_slug": "ac3" - }, - { - "id": 2723, - "name": "FuzeX", - "symbol": "FXT", - "website_slug": "fuzex" - }, - { - "id": 2724, - "name": "Zippie", - "symbol": "ZIPT", - "website_slug": "zippie" - }, - { - "id": 2725, - "name": "Skrumble Network", - "symbol": "SKM", - "website_slug": "skrumble-network" - }, - { - "id": 2726, - "name": "DAOstack", - "symbol": "GEN", - "website_slug": "daostack" - }, - { - "id": 2727, - "name": "Bezant", - "symbol": "BZNT", - "website_slug": "bezant" - }, - { - "id": 2728, - "name": "Winding Tree", - "symbol": "LIF", - "website_slug": "winding-tree" - }, - { - "id": 2729, - "name": "TEAM (TokenStars)", - "symbol": "TEAM", - "website_slug": "tokenstars" - }, - { - "id": 2731, - "name": "Utrum", - "symbol": "OOT", - "website_slug": "utrum" - }, - { - "id": 2732, - "name": "Aston", - "symbol": "ATX", - "website_slug": "aston" - }, - { - "id": 2733, - "name": "Freyrchain", - "symbol": "FREC", - "website_slug": "freyrchain" - }, - { - "id": 2734, - "name": "EduCoin", - "symbol": "EDU", - "website_slug": "edu-coin" - }, - { - "id": 2735, - "name": "Content Neutrality Network", - "symbol": "CNN", - "website_slug": "content-neutrality-network" - }, - { - "id": 2736, - "name": "InsurChain", - "symbol": "INSUR", - "website_slug": "insurchain" - }, - { - "id": 2737, - "name": "Global Social Chain", - "symbol": "GSC", - "website_slug": "global-social-chain" - }, - { - "id": 2738, - "name": "Super Game Chain", - "symbol": "SGCC", - "website_slug": "super-game-chain" - }, - { - "id": 2739, - "name": "Digix Gold Token", - "symbol": "DGX", - "website_slug": "digix-gold-token" - }, - { - "id": 2740, - "name": "Influence Chain", - "symbol": "INC", - "website_slug": "influence-chain" - }, - { - "id": 2741, - "name": "Intelligent Investment Chain", - "symbol": "IIC", - "website_slug": "intelligent-investment-chain" - }, - { - "id": 2742, - "name": "Sakura Bloom", - "symbol": "SKB", - "website_slug": "sakura-bloom" - }, - { - "id": 2743, - "name": "Bank Coin", - "symbol": "BANK", - "website_slug": "bank-coin" - }, - { - "id": 2744, - "name": "NPER", - "symbol": "NPER", - "website_slug": "nper" - }, - { - "id": 2746, - "name": "DasCoin", - "symbol": "DASC", - "website_slug": "dascoin" - }, - { - "id": 2747, - "name": "BlockMesh", - "symbol": "BMH", - "website_slug": "blockmesh" - }, - { - "id": 2748, - "name": "Loki", - "symbol": "LOKI", - "website_slug": "loki" - }, - { - "id": 2749, - "name": "Signals Network", - "symbol": "SGN", - "website_slug": "signals-network" - }, - { - "id": 2750, - "name": "Oyster Shell", - "symbol": "SHL", - "website_slug": "oyster-shell" - }, - { - "id": 2751, - "name": "FundRequest", - "symbol": "FND", - "website_slug": "fundrequest" - }, - { - "id": 2752, - "name": "Datarius Credit", - "symbol": "DTRC", - "website_slug": "datarius-credit" - }, - { - "id": 2753, - "name": "Colu Local Network", - "symbol": "CLN", - "website_slug": "colu-local-network" - }, - { - "id": 2754, - "name": "HeroNode", - "symbol": "HER", - "website_slug": "heronode" - }, - { - "id": 2755, - "name": "Hero", - "symbol": "HERO", - "website_slug": "hero" - }, - { - "id": 2756, - "name": "Tokia", - "symbol": "TKA", - "website_slug": "tokia" - }, - { - "id": 2757, - "name": "Callisto Network", - "symbol": "CLO", - "website_slug": "callisto-network" - }, - { - "id": 2758, - "name": "Unibright", - "symbol": "UBT", - "website_slug": "unibright" - }, - { - "id": 2759, - "name": "Patron", - "symbol": "PAT", - "website_slug": "patron" - }, - { - "id": 2760, - "name": "Libra Credit", - "symbol": "LBA", - "website_slug": "libra-credit" - }, - { - "id": 2761, - "name": "Local World Forwarders", - "symbol": "LWF", - "website_slug": "local-world-forwarders" - }, - { - "id": 2762, - "name": "Open Platform", - "symbol": "OPEN", - "website_slug": "open-platform" - }, - { - "id": 2763, - "name": "Morpheus.Network", - "symbol": "MRPH", - "website_slug": "morpheus-network" - }, - { - "id": 2764, - "name": "Silent Notary", - "symbol": "SNTR", - "website_slug": "silent-notary" - }, - { - "id": 2765, - "name": "XYO Network", - "symbol": "XYO", - "website_slug": "xyo-network" - }, - { - "id": 2766, - "name": "Cryptaur", - "symbol": "CPT", - "website_slug": "cryptaur" - }, - { - "id": 2767, - "name": "APIS", - "symbol": "APIS", - "website_slug": "apis" - }, - { - "id": 2768, - "name": "Fabric Token", - "symbol": "FT", - "website_slug": "fabric-token" - }, - { - "id": 2769, - "name": "Rhenium", - "symbol": "XRH", - "website_slug": "rhenium" - }, - { - "id": 2770, - "name": "Cazcoin", - "symbol": "CAZ", - "website_slug": "cazcoin" - }, - { - "id": 2771, - "name": "RED", - "symbol": "RED", - "website_slug": "red" - }, - { - "id": 2772, - "name": "Digitex Futures", - "symbol": "DGTX", - "website_slug": "digitex-futures" - }, - { - "id": 2773, - "name": "GINcoin", - "symbol": "GIN", - "website_slug": "gincoin" - }, - { - "id": 2774, - "name": "Invacio", - "symbol": "INV", - "website_slug": "invacio" - }, - { - "id": 2775, - "name": "Faceter", - "symbol": "FACE", - "website_slug": "faceter" - }, - { - "id": 2776, - "name": "Travala", - "symbol": "AVA", - "website_slug": "travala" - }, - { - "id": 2777, - "name": "IoTeX", - "symbol": "IOTX", - "website_slug": "iotex" - }, - { - "id": 2778, - "name": "Eximchain", - "symbol": "EXC", - "website_slug": "eximchain" - }, - { - "id": 2779, - "name": "Level Up Coin", - "symbol": "LUC", - "website_slug": "level-up" - }, - { - "id": 2780, - "name": "NKN", - "symbol": "NKN", - "website_slug": "nkn" - }, - { - "id": 2825, - "name": "Naviaddress", - "symbol": "NAVI", - "website_slug": "naviaddress" - }, - { - "id": 2826, - "name": "Zipper", - "symbol": "ZIP", - "website_slug": "zip" - }, - { - "id": 2827, - "name": "Phantasma", - "symbol": "SOUL", - "website_slug": "phantasma" - }, - { - "id": 2828, - "name": "SPINDLE", - "symbol": "SPD", - "website_slug": "spindle" - }, - { - "id": 2829, - "name": "REPO", - "symbol": "REPO", - "website_slug": "repo" - }, - { - "id": 2830, - "name": "Seele", - "symbol": "SEELE", - "website_slug": "seele" - }, - { - "id": 2831, - "name": "EJOY", - "symbol": "EJOY", - "website_slug": "ejoy" - }, - { - "id": 2833, - "name": "Ivy", - "symbol": "IVY", - "website_slug": "ivy" - }, - { - "id": 2834, - "name": "ContractNet", - "symbol": "CNET", - "website_slug": "contractnet" - }, - { - "id": 2835, - "name": "Endor Protocol", - "symbol": "EDR", - "website_slug": "endor-protocol" - }, - { - "id": 2836, - "name": "Bigbom", - "symbol": "BBO", - "website_slug": "bigbom" - }, - { - "id": 2837, - "name": "0xBitcoin", - "symbol": "0xBTC", - "website_slug": "0xbtc" - }, - { - "id": 2838, - "name": "PCHAIN", - "symbol": "PAI", - "website_slug": "pchain" - }, - { - "id": 2840, - "name": "QuarkChain", - "symbol": "QKC", - "website_slug": "quarkchain" - }, - { - "id": 2841, - "name": "LoyalCoin", - "symbol": "LYL", - "website_slug": "loyalcoin" - }, - { - "id": 2842, - "name": "Bankera", - "symbol": "BNK", - "website_slug": "bankera" - }, - { - "id": 2843, - "name": "Ether Zero", - "symbol": "ETZ", - "website_slug": "ether-zero" - }, - { - "id": 2844, - "name": "Shivom", - "symbol": "OMX", - "website_slug": "shivom" - }, - { - "id": 2845, - "name": "MediBloc [ERC20]", - "symbol": "MEDX", - "website_slug": "medx" - }, - { - "id": 2846, - "name": "FuturoCoin", - "symbol": "FTO", - "website_slug": "futurocoin" - }, - { - "id": 2847, - "name": "The Abyss", - "symbol": "ABYSS", - "website_slug": "the-abyss" - }, - { - "id": 2848, - "name": "Paymon", - "symbol": "PMNT", - "website_slug": "paymon" - }, - { - "id": 2849, - "name": "Hurify", - "symbol": "HUR", - "website_slug": "hurify" - }, - { - "id": 2850, - "name": "TRAXIA", - "symbol": "TMT", - "website_slug": "traxia" - }, - { - "id": 2852, - "name": "Engine", - "symbol": "EGCC", - "website_slug": "engine" - }, - { - "id": 2853, - "name": "MIRQ", - "symbol": "MRQ", - "website_slug": "mirq" - }, - { - "id": 2854, - "name": "PikcioChain", - "symbol": "PKC", - "website_slug": "pikciochain" - }, - { - "id": 2855, - "name": "CashBet Coin", - "symbol": "CBC", - "website_slug": "cashbet-coin" - }, - { - "id": 2856, - "name": "CEEK VR", - "symbol": "CEEK", - "website_slug": "ceek-vr" - }, - { - "id": 2857, - "name": "SalPay", - "symbol": "SAL", - "website_slug": "salpay" - }, - { - "id": 2858, - "name": "Couchain", - "symbol": "COU", - "website_slug": "couchain" - }, - { - "id": 2859, - "name": "XMax", - "symbol": "XMX", - "website_slug": "xmax" - }, - { - "id": 2861, - "name": "GoChain", - "symbol": "GO", - "website_slug": "gochain" - }, - { - "id": 2862, - "name": "Smartshare", - "symbol": "SSP", - "website_slug": "smartshare" - }, - { - "id": 2863, - "name": "HOLD", - "symbol": "HOLD", - "website_slug": "hold" - }, - { - "id": 2865, - "name": "Trittium", - "symbol": "TRTT", - "website_slug": "trittium" - }, - { - "id": 2866, - "name": "Sentinel Protocol", - "symbol": "UPP", - "website_slug": "sentinel-protocol" - }, - { - "id": 2867, - "name": "Bittwatt", - "symbol": "BWT", - "website_slug": "bittwatt" - }, - { - "id": 2868, - "name": "Constellation", - "symbol": "DAG", - "website_slug": "constellation" - }, - { - "id": 2869, - "name": "Merculet", - "symbol": "MVP", - "website_slug": "merculet" - }, - { - "id": 2870, - "name": "FantasyGold", - "symbol": "FGC", - "website_slug": "fantasygold" - }, - { - "id": 2871, - "name": "Ubique Chain Of Things", - "symbol": "UCT", - "website_slug": "ubique-chain-of-things" - }, - { - "id": 2872, - "name": "EnergiToken", - "symbol": "ETK", - "website_slug": "energitoken" - }, - { - "id": 2873, - "name": "Metronome", - "symbol": "MET", - "website_slug": "metronome" - }, - { - "id": 2874, - "name": "Aurora", - "symbol": "AOA", - "website_slug": "aurora" - }, - { - "id": 2875, - "name": "ALAX", - "symbol": "ALX", - "website_slug": "alax" - }, - { - "id": 2876, - "name": "Ternio", - "symbol": "TERN", - "website_slug": "ternio" - }, - { - "id": 2877, - "name": "Bodhi [ETH]", - "symbol": "BOE", - "website_slug": "bodhi-eth" - }, - { - "id": 2878, - "name": "DigiFinexToken", - "symbol": "DFT", - "website_slug": "digifinextoken" - }, - { - "id": 2879, - "name": "Origin Sport", - "symbol": "ORS", - "website_slug": "origin-sport" - }, - { - "id": 2880, - "name": "Rate3", - "symbol": "RTE", - "website_slug": "rate3" - }, - { - "id": 2881, - "name": "Distributed Credit Chain", - "symbol": "DCC", - "website_slug": "distributed-credit-chain" - }, - { - "id": 2882, - "name": "0chain", - "symbol": "ZCN", - "website_slug": "0chain" - }, - { - "id": 2883, - "name": "ZINC", - "symbol": "ZINC", - "website_slug": "zinc" - }, - { - "id": 2884, - "name": "Forty Seven Bank", - "symbol": "FSBT", - "website_slug": "forty-seven-bank" - }, - { - "id": 2885, - "name": "Egretia", - "symbol": "EGT", - "website_slug": "egretia" - }, - { - "id": 2886, - "name": "TaTaTu", - "symbol": "TTU", - "website_slug": "tatatu" - }, - { - "id": 2887, - "name": "Dorado", - "symbol": "DOR", - "website_slug": "dorado" - }, - { - "id": 2888, - "name": "CarBlock", - "symbol": "CAR", - "website_slug": "carblock" - }, - { - "id": 2889, - "name": "Bob's Repair", - "symbol": "BOB", - "website_slug": "bobs-repair" - }, - { - "id": 2890, - "name": "KanadeCoin", - "symbol": "KNDC", - "website_slug": "kanadecoin" - }, - { - "id": 2891, - "name": "Cardstack", - "symbol": "CARD", - "website_slug": "cardstack" - }, - { - "id": 2892, - "name": "Wowbit", - "symbol": "WWB", - "website_slug": "wowbit" - }, - { - "id": 2893, - "name": "On.Live", - "symbol": "ONL", - "website_slug": "on-live" - }, - { - "id": 2894, - "name": "OTCBTC Token", - "symbol": "OTB", - "website_slug": "otcbtc-token" - }, - { - "id": 2895, - "name": "Coni", - "symbol": "CONI", - "website_slug": "coni" - }, - { - "id": 2896, - "name": "Mainframe", - "symbol": "MFT", - "website_slug": "mainframe" - }, - { - "id": 2897, - "name": "Clipper Coin", - "symbol": "CCCX", - "website_slug": "clipper-coin" - }, - { - "id": 2898, - "name": "GoNetwork", - "symbol": "GOT", - "website_slug": "gonetwork" - }, - { - "id": 2899, - "name": "Thrive Token", - "symbol": "THRT", - "website_slug": "thrive-token" - }, - { - "id": 2900, - "name": "Project Pai", - "symbol": "PAI", - "website_slug": "project-pai" - }, - { - "id": 2901, - "name": "FansTime", - "symbol": "FTI", - "website_slug": "fanstime" - }, - { - "id": 2902, - "name": "POPCHAIN", - "symbol": "PCH", - "website_slug": "popchain" - }, - { - "id": 2903, - "name": "SEER", - "symbol": "SEER", - "website_slug": "seer" - }, - { - "id": 2904, - "name": "FCoin Token", - "symbol": "FT", - "website_slug": "fcoin-token" - }, - { - "id": 2905, - "name": "Qurito", - "symbol": "QURO", - "website_slug": "qurito" - }, - { - "id": 2906, - "name": "Essentia", - "symbol": "ESS", - "website_slug": "essentia" - }, - { - "id": 2907, - "name": "Karatgold Coin", - "symbol": "KBC", - "website_slug": "karatgold-coin" - }, - { - "id": 2908, - "name": "HashCoin", - "symbol": "HSC", - "website_slug": "hashcoin" - }, - { - "id": 2909, - "name": "LikeCoin", - "symbol": "LIKE", - "website_slug": "likecoin" - }, - { - "id": 2910, - "name": "Crowdholding", - "symbol": "YUP", - "website_slug": "crowdholding" - }, - { - "id": 2911, - "name": "ORS Group", - "symbol": "ORS", - "website_slug": "ors-group" - }, - { - "id": 2912, - "name": "SnowGem", - "symbol": "XSG", - "website_slug": "snowgem" - }, - { - "id": 2913, - "name": "DaTa eXchange", - "symbol": "DTX", - "website_slug": "data-exchange" - }, - { - "id": 2914, - "name": "BeeKan", - "symbol": "BKBT", - "website_slug": "beekan" - }, - { - "id": 2915, - "name": "Mossland", - "symbol": "MOC", - "website_slug": "mossland" - }, - { - "id": 2916, - "name": "Nimiq", - "symbol": "NIM", - "website_slug": "nimiq" - }, - { - "id": 2917, - "name": "Saifu", - "symbol": "SFU", - "website_slug": "saifu" - }, - { - "id": 2918, - "name": "Bit-Z Token", - "symbol": "BZ", - "website_slug": "bit-z-token" - }, - { - "id": 2919, - "name": "DWS", - "symbol": "DWS", - "website_slug": "dws" - }, - { - "id": 2920, - "name": "0xcert", - "symbol": "ZXC", - "website_slug": "0xcert" - }, - { - "id": 2921, - "name": "OneLedger", - "symbol": "OLT", - "website_slug": "oneledger" - }, - { - "id": 2922, - "name": "Atonomi", - "symbol": "ATMI", - "website_slug": "atonomi" - }, - { - "id": 2923, - "name": "XMCT", - "symbol": "XMCT", - "website_slug": "xmct" - }, - { - "id": 2924, - "name": "FNKOS", - "symbol": "FNKOS", - "website_slug": "fnkos" - }, - { - "id": 2925, - "name": "RECORD", - "symbol": "RCD", - "website_slug": "record" - }, - { - "id": 2926, - "name": "PRASM", - "symbol": "PSM", - "website_slug": "prasm" - }, - { - "id": 2927, - "name": "nUSD", - "symbol": "NUSD", - "website_slug": "nusd" - }, - { - "id": 2928, - "name": "PlayCoin", - "symbol": "PLY", - "website_slug": "playcoin" - }, - { - "id": 2929, - "name": "Truegame", - "symbol": "TGAME", - "website_slug": "tgame" - }, - { - "id": 2930, - "name": "Everipedia", - "symbol": "IQ", - "website_slug": "everipedia" - }, - { - "id": 2931, - "name": "Engagement Token", - "symbol": "ENGT", - "website_slug": "engagement-token" - }, - { - "id": 2932, - "name": "No BS Crypto", - "symbol": "NOBS", - "website_slug": "no-bs-crypto" - }, - { - "id": 2933, - "name": "BitMart Token", - "symbol": "BMX", - "website_slug": "bitmart-token" - }, - { - "id": 2934, - "name": "BitKan", - "symbol": "KAN", - "website_slug": "bitkan" - }, - { - "id": 2935, - "name": "Condominium", - "symbol": "CDM", - "website_slug": "condominium" - }, - { - "id": 2936, - "name": "MTC Mesh Network", - "symbol": "MTC", - "website_slug": "mtc-mesh-network" - }, - { - "id": 2937, - "name": "VITE", - "symbol": "VITE", - "website_slug": "vite" - }, - { - "id": 2938, - "name": "Hashgard", - "symbol": "GARD", - "website_slug": "hashgard" - }, - { - "id": 2939, - "name": "SCRL", - "symbol": "SCRL", - "website_slug": "scroll" - }, - { - "id": 2940, - "name": "Sp8de", - "symbol": "SPX", - "website_slug": "sp8de" - }, - { - "id": 2941, - "name": "CoinEx Token", - "symbol": "CET", - "website_slug": "coinex-token" - }, - { - "id": 2942, - "name": "Aegeus", - "symbol": "AEG", - "website_slug": "aegeus" - }, - { - "id": 2943, - "name": "Rocket Pool", - "symbol": "RPL", - "website_slug": "rocket-pool" - }, - { - "id": 2944, - "name": "Elysian", - "symbol": "ELY", - "website_slug": "elysian" - }, - { - "id": 2945, - "name": "ContentBox", - "symbol": "BOX", - "website_slug": "contentbox" - }, - { - "id": 2946, - "name": "Proton Token", - "symbol": "PTT", - "website_slug": "proton-token" - }, - { - "id": 2947, - "name": "SoPay", - "symbol": "SOP", - "website_slug": "sopay" - }, - { - "id": 2948, - "name": "Jury.Online Token", - "symbol": "JOT", - "website_slug": "jury-online-token" - }, - { - "id": 2949, - "name": "Kryll", - "symbol": "KRL", - "website_slug": "kryll" - }, - { - "id": 2950, - "name": "LemoChain", - "symbol": "LEMO", - "website_slug": "lemochain" - }, - { - "id": 2952, - "name": "Gold Bits Coin", - "symbol": "GBC", - "website_slug": "gold-bits-coin" - }, - { - "id": 2953, - "name": "Blue Whale Token", - "symbol": "BWX", - "website_slug": "blue-whale-token" - }, - { - "id": 2954, - "name": "wys Token", - "symbol": "WYS", - "website_slug": "wys-token" - }, - { - "id": 2955, - "name": "Cosmo Coin", - "symbol": "COSM", - "website_slug": "cosmo-coin" - }, - { - "id": 2956, - "name": "Narrative", - "symbol": "NRVE", - "website_slug": "narrative" - }, - { - "id": 2957, - "name": "Olive", - "symbol": "OLE", - "website_slug": "olive" - }, - { - "id": 2958, - "name": "Turtlecoin", - "symbol": "TRTL", - "website_slug": "turtlecoin" - }, - { - "id": 2959, - "name": "WeToken", - "symbol": "WT", - "website_slug": "wetoken" - }, - { - "id": 2960, - "name": "Tourist Token", - "symbol": "TOTO", - "website_slug": "tourist-token" - }, - { - "id": 2961, - "name": "Relex", - "symbol": "RLX", - "website_slug": "relex" - }, - { - "id": 2962, - "name": "CHEX", - "symbol": "CHEX", - "website_slug": "chex" - }, - { - "id": 2963, - "name": "View", - "symbol": "VIEW", - "website_slug": "view" - }, - { - "id": 2964, - "name": "ValueCyberToken", - "symbol": "VCT", - "website_slug": "valuecybertoken" - }, - { - "id": 2965, - "name": "VikkyToken", - "symbol": "VIKKY", - "website_slug": "vikkytoken" - }, - { - "id": 2966, - "name": "Fox Trading", - "symbol": "FOXT", - "website_slug": "fox-trading" - }, - { - "id": 2967, - "name": "AB-Chain RTB", - "symbol": "RTB", - "website_slug": "ab-chain-rtb" - }, - { - "id": 2968, - "name": "Bridge Protocol", - "symbol": "TOLL", - "website_slug": "bridge-protocol" - }, - { - "id": 2969, - "name": "Globalvillage Ecosystem", - "symbol": "GVE", - "website_slug": "globalvillage-ecosystem" - }, - { - "id": 2970, - "name": "LocalCoinSwap", - "symbol": "LCS", - "website_slug": "local-coin-swap" - }, - { - "id": 2972, - "name": "ZPER", - "symbol": "ZPR", - "website_slug": "zper" - }, - { - "id": 2973, - "name": "empowr coin", - "symbol": "EMPR", - "website_slug": "empowr-coin" - }, - { - "id": 2974, - "name": "Lightpaycoin", - "symbol": "LPC", - "website_slug": "lightpaycoin" - }, - { - "id": 2975, - "name": "FundToken", - "symbol": "FUNDZ", - "website_slug": "fundtoken" - }, - { - "id": 2976, - "name": "Ryo Currency", - "symbol": "RYO", - "website_slug": "ryo-currency" - }, - { - "id": 2977, - "name": "BitRewards", - "symbol": "BIT", - "website_slug": "bitrewards" - }, - { - "id": 2978, - "name": "AceD", - "symbol": "ACED", - "website_slug": "aced" - }, - { - "id": 2979, - "name": "Linfinity", - "symbol": "LFT", - "website_slug": "linfinity" - }, - { - "id": 2980, - "name": "WABnetwork", - "symbol": "WAB", - "website_slug": "wabnetwork" - }, - { - "id": 2981, - "name": "Consentium", - "symbol": "CSM", - "website_slug": "consentium" - }, - { - "id": 2982, - "name": "Mass Vehicle Ledger", - "symbol": "MVL", - "website_slug": "mass-vehicle-ledger" - }, - { - "id": 2983, - "name": "AdultChain", - "symbol": "XXX", - "website_slug": "adultchain" - }, - { - "id": 2984, - "name": "Newton Coin Project", - "symbol": "NCP", - "website_slug": "newton-coin-project" - }, - { - "id": 2985, - "name": "ARBITRAGE", - "symbol": "ARB", - "website_slug": "arbitrage" - }, - { - "id": 2986, - "name": "DACC", - "symbol": "DACC", - "website_slug": "dacc" - }, - { - "id": 2987, - "name": "ThingsOperatingSystem", - "symbol": "TOS", - "website_slug": "thingsoperatingsystem" - }, - { - "id": 2988, - "name": "Pigeoncoin", - "symbol": "PGN", - "website_slug": "pigeoncoin" - }, - { - "id": 2989, - "name": "STASIS EURS", - "symbol": "EURS", - "website_slug": "stasis-eurs" - }, - { - "id": 2990, - "name": "Ethereum Monero", - "symbol": "EXMR", - "website_slug": "ethereum-monero" - }, - { - "id": 2991, - "name": "NIX", - "symbol": "NIX", - "website_slug": "nix" - }, - { - "id": 2992, - "name": "Apollo Currency", - "symbol": "APL", - "website_slug": "apollo-currency" - }, - { - "id": 2993, - "name": "HorusPay", - "symbol": "HORUS", - "website_slug": "horuspay" - }, - { - "id": 2994, - "name": "Bitcoin File", - "symbol": "BIFI", - "website_slug": "bitcoin-file" - }, - { - "id": 2995, - "name": "Wavebase", - "symbol": "PWV", - "website_slug": "wavebase" - }, - { - "id": 2996, - "name": "Bitcoin W Spectrum", - "symbol": "BWS", - "website_slug": "bitcoin-w-spectrum" - }, - { - "id": 2997, - "name": "DIPNET", - "symbol": "DPN", - "website_slug": "dipnet" - }, - { - "id": 2998, - "name": "Vexanium", - "symbol": "VEX", - "website_slug": "vexanium" - }, - { - "id": 2999, - "name": "Hdac", - "symbol": "HDAC", - "website_slug": "hdac" - }, - { - "id": 3000, - "name": "New Power Coin", - "symbol": "NPW", - "website_slug": "new-power-coin" - }, - { - "id": 3001, - "name": "KWHCoin", - "symbol": "KWH", - "website_slug": "kwhcoin" - }, - { - "id": 3002, - "name": "Master Contract Token", - "symbol": "MCT", - "website_slug": "master-contract-token" - }, - { - "id": 3003, - "name": "White Standard", - "symbol": "WSD", - "website_slug": "white-standard" - }, - { - "id": 3004, - "name": "Volt", - "symbol": "ACDC", - "website_slug": "volt" - }, - { - "id": 3006, - "name": "Niobio Cash", - "symbol": "NBR", - "website_slug": "niobio-cash" - }, - { - "id": 3007, - "name": "Haracoin", - "symbol": "HRC", - "website_slug": "haracoin" - }, - { - "id": 3008, - "name": "Vivid Coin", - "symbol": "VIVID", - "website_slug": "vivid-coin" - }, - { - "id": 3009, - "name": "Purex", - "symbol": "PUREX", - "website_slug": "purex" - }, - { - "id": 3010, - "name": "Coinsuper Ecosystem Network", - "symbol": "CEN", - "website_slug": "coinsuper-ecosystem-network" - }, - { - "id": 3011, - "name": "BitScreener Token", - "symbol": "BITX", - "website_slug": "bitscreener-token" - }, - { - "id": 3012, - "name": "VeThor Token", - "symbol": "VTHO", - "website_slug": "vethor-token" - }, - { - "id": 3013, - "name": "PRiVCY", - "symbol": "PRIV", - "website_slug": "privcy" - }, - { - "id": 3014, - "name": "RightMesh", - "symbol": "RMESH", - "website_slug": "rightmesh" - }, - { - "id": 3015, - "name": "Brickblock", - "symbol": "BBK", - "website_slug": "brickblock" - }, - { - "id": 3016, - "name": "NeuroChain", - "symbol": "NCC", - "website_slug": "neurochain" - }, - { - "id": 3017, - "name": "Coinvest", - "symbol": "COIN", - "website_slug": "coinvest" - }, - { - "id": 3018, - "name": "Kalkulus", - "symbol": "KLKS", - "website_slug": "kalkulus" - }, - { - "id": 3019, - "name": "Luna Stars", - "symbol": "LSTR", - "website_slug": "luna-stars" - }, - { - "id": 3020, - "name": "BHPCash", - "symbol": "BHPC", - "website_slug": "bhpcash" - }, - { - "id": 3021, - "name": "InternationalCryptoX", - "symbol": "INCX", - "website_slug": "internationalcryptox" - }, - { - "id": 3022, - "name": "ZMINE", - "symbol": "ZMN", - "website_slug": "zmine" - }, - { - "id": 3023, - "name": "Semux", - "symbol": "SEM", - "website_slug": "semux" - }, - { - "id": 3024, - "name": "Arionum", - "symbol": "ARO", - "website_slug": "arionum" - }, - { - "id": 3025, - "name": "ACRE", - "symbol": "ACRE", - "website_slug": "acre" - }, - { - "id": 3026, - "name": "Carlive Chain", - "symbol": "IOV", - "website_slug": "carlive-chain" - }, - { - "id": 3027, - "name": "Webcoin", - "symbol": "WEB", - "website_slug": "webcoin" - }, - { - "id": 3029, - "name": "ZelCash", - "symbol": "ZEL", - "website_slug": "zelcash" - }, - { - "id": 3030, - "name": "BrokerNekoNetwork", - "symbol": "BNN", - "website_slug": "brokernekonetwork" - }, - { - "id": 3031, - "name": "Orbis Token", - "symbol": "OBT", - "website_slug": "orbis-token" - }, - { - "id": 3033, - "name": "Latino Token", - "symbol": "LATINO", - "website_slug": "latino-token" - }, - { - "id": 3039, - "name": "Excaliburcoin", - "symbol": "EXC", - "website_slug": "excaliburcoin" - }, - { - "id": 3040, - "name": "CanonChain", - "symbol": "CZR", - "website_slug": "cononchain" - }, - { - "id": 3041, - "name": "FoodCoin", - "symbol": "FOOD", - "website_slug": "food" - }, - { - "id": 3042, - "name": "IDOL COIN", - "symbol": "IDOL", - "website_slug": "idol-coin" - }, - { - "id": 3043, - "name": "PitisCoin", - "symbol": "PTS", - "website_slug": "pitiscoin" - }, - { - "id": 3045, - "name": "OPCoinX", - "symbol": "OPCX", - "website_slug": "opcoinx" - }, - { - "id": 3046, - "name": "Blocknode", - "symbol": "BND", - "website_slug": "blocknode" - }, - { - "id": 3047, - "name": "UltraNote Coin", - "symbol": "XUN", - "website_slug": "ultranote-coin" - }, - { - "id": 3048, - "name": "Bitcoin Token", - "symbol": "BTK", - "website_slug": "bitcoin-token" - }, - { - "id": 3049, - "name": "ARLIZE", - "symbol": "ARLIZE", - "website_slug": "arlize" - }, - { - "id": 3050, - "name": "Dystem", - "symbol": "DTEM", - "website_slug": "dystem" - }, - { - "id": 3051, - "name": "Bitblocks", - "symbol": "BBK", - "website_slug": "bitblocks" - }, - { - "id": 3052, - "name": "Eligma Token", - "symbol": "ELI", - "website_slug": "eligma-token" - }, - { - "id": 3053, - "name": "YOU COIN", - "symbol": "YOU", - "website_slug": "you-coin" - }, - { - "id": 3054, - "name": "DACSEE", - "symbol": "DACS", - "website_slug": "dacsee" - }, - { - "id": 3055, - "name": "EBCoin", - "symbol": "EBC", - "website_slug": "ebcoin" - }, - { - "id": 3056, - "name": "Thore Cash", - "symbol": "TCH", - "website_slug": "thore-cash" - }, - { - "id": 3057, - "name": "Adrenaline", - "symbol": "ADN", - "website_slug": "adrenaline" - }, - { - "id": 3058, - "name": "Six Domain Chain", - "symbol": "SDA", - "website_slug": "six-domain-chain" - }, - { - "id": 3059, - "name": "EscrowCoin", - "symbol": "ESCO", - "website_slug": "escrowcoin" - }, - { - "id": 3060, - "name": "Yuan Chain Coin", - "symbol": "YCC", - "website_slug": "yuan-chain-coin" - }, - { - "id": 3061, - "name": "Promotion Coin", - "symbol": "PC", - "website_slug": "promotion-coin" - }, - { - "id": 3062, - "name": "GambleCoin", - "symbol": "GMCN", - "website_slug": "gamblecoin" - }, - { - "id": 3063, - "name": "Vitae", - "symbol": "VITAE", - "website_slug": "vitae" - }, - { - "id": 3064, - "name": "EPLUS Coin", - "symbol": "EPLUS", - "website_slug": "eplus-coin" - }, - { - "id": 3065, - "name": "ICE ROCK MINING", - "symbol": "ROCK2", - "website_slug": "ice-rock-mining" - }, - { - "id": 3066, - "name": "BitCapitalVendor", - "symbol": "BCV", - "website_slug": "bitcapitalvendor" - }, - { - "id": 3067, - "name": "XTRD", - "symbol": "XTRD", - "website_slug": "xtrd" - }, - { - "id": 3068, - "name": "BitcoiNote", - "symbol": "BTCN", - "website_slug": "bitcoinote" - }, - { - "id": 3069, - "name": "NAM COIN", - "symbol": "NAM", - "website_slug": "nam-coin" - }, - { - "id": 3070, - "name": "Litex", - "symbol": "LXT", - "website_slug": "litex" - }, - { - "id": 3071, - "name": "EUNO", - "symbol": "EUNO", - "website_slug": "euno" - }, - { - "id": 3072, - "name": "MassGrid", - "symbol": "MGD", - "website_slug": "massgrid" - }, - { - "id": 3073, - "name": "Esports Token", - "symbol": "EST", - "website_slug": "esports-token" - }, - { - "id": 3074, - "name": "Experience Token", - "symbol": "EXT", - "website_slug": "experience-token" - }, - { - "id": 3075, - "name": "Bitcoin Instant", - "symbol": "BTI", - "website_slug": "bitcoin-instant" - }, - { - "id": 3076, - "name": "Endorsit", - "symbol": "EDS", - "website_slug": "endorsit" - }, - { - "id": 3077, - "name": "VeChain", - "symbol": "VET", - "website_slug": "vechain" - }, - { - "id": 3078, - "name": "Kind Ads Token", - "symbol": "KIND", - "website_slug": "kind-ads-token" - }, - { - "id": 3079, - "name": "X8X Token", - "symbol": "X8X", - "website_slug": "x8x-token" - }, - { - "id": 3080, - "name": "Commercium", - "symbol": "CMM", - "website_slug": "commercium" - }, - { - "id": 3081, - "name": "Omnitude", - "symbol": "ECOM", - "website_slug": "omnitude" - }, - { - "id": 3082, - "name": "VINchain", - "symbol": "VIN", - "website_slug": "vinchain" - }, - { - "id": 3083, - "name": "Lina", - "symbol": "LINA", - "website_slug": "lina" - }, - { - "id": 3084, - "name": "Blocktrade", - "symbol": "BTT", - "website_slug": "blocktrade" - }, - { - "id": 3085, - "name": "INO COIN", - "symbol": "INO", - "website_slug": "ino-coin" - }, - { - "id": 3086, - "name": "Kora Network Token", - "symbol": "KNT", - "website_slug": "kora-network-token" - }, - { - "id": 3087, - "name": "CROAT", - "symbol": "CROAT", - "website_slug": "croat" - }, - { - "id": 3088, - "name": "BitCoin One", - "symbol": "BTCONE", - "website_slug": "bitcoin-one" - }, - { - "id": 3089, - "name": "AVINOC", - "symbol": "AVINOC", - "website_slug": "avinoc" - }, - { - "id": 3090, - "name": "Wiki Token", - "symbol": "WIKI", - "website_slug": "wiki-token" - }, - { - "id": 3091, - "name": "Sapien", - "symbol": "SPN", - "website_slug": "sapien" - }, - { - "id": 3092, - "name": "Nuggets", - "symbol": "NUG", - "website_slug": "nuggets" - }, - { - "id": 3093, - "name": "BBSCoin", - "symbol": "BBS", - "website_slug": "bbscoin" - }, - { - "id": 3094, - "name": "Scorum Coins", - "symbol": "SCR", - "website_slug": "scorum-coins" - }, - { - "id": 3095, - "name": "Niobium Coin", - "symbol": "NBC", - "website_slug": "niobium-coin" - }, - { - "id": 3096, - "name": "Pundi X NEM", - "symbol": "NPXSXEM", - "website_slug": "pundi-x-nem" - }, - { - "id": 3097, - "name": "XOVBank", - "symbol": "XOV", - "website_slug": "xovbank" - }, - { - "id": 3098, - "name": "XcelToken", - "symbol": "XCEL", - "website_slug": "xceltoken" - }, - { - "id": 3099, - "name": "Lynx", - "symbol": "LYNX", - "website_slug": "lynx" - }, - { - "id": 3100, - "name": "Ultra Salescloud", - "symbol": "UST", - "website_slug": "ultra-salescoud" - }, - { - "id": 3101, - "name": "OptiToken", - "symbol": "OPTI", - "website_slug": "optitoken" - }, - { - "id": 3103, - "name": "Swytch Energy Token", - "symbol": "SET", - "website_slug": "swytch-energy-token" - }, - { - "id": 3104, - "name": "Giant", - "symbol": "GIC", - "website_slug": "giant-coin" - }, - { - "id": 3105, - "name": "Atlantis Blue Digital Token", - "symbol": "ABDT", - "website_slug": "atlantis-blue-digital-token" - }, - { - "id": 3106, - "name": "PKG Token", - "symbol": "PKG", - "website_slug": "pkg-token" - }, - { - "id": 3107, - "name": "BingoCoin", - "symbol": "BOC", - "website_slug": "bingocoin" - }, - { - "id": 3108, - "name": "HighCoin", - "symbol": "HIGHT", - "website_slug": "highcoin" - }, - { - "id": 3109, - "name": "Ordocoin", - "symbol": "RDC", - "website_slug": "ordocoin" - }, - { - "id": 3110, - "name": "NewsToken", - "symbol": "NEWOS", - "website_slug": "newstoken" - }, - { - "id": 3111, - "name": "PayDay Coin", - "symbol": "PDX", - "website_slug": "payday-coin" - }, - { - "id": 3112, - "name": "Bitnation", - "symbol": "XPAT", - "website_slug": "bitnation" - }, - { - "id": 3113, - "name": "InterCrone", - "symbol": "ICR", - "website_slug": "intercrone" - }, - { - "id": 3114, - "name": "RusGas", - "symbol": "RGS", - "website_slug": "rusgas" - }, - { - "id": 3115, - "name": "Maximine Coin", - "symbol": "MXM", - "website_slug": "maximine-coin" - }, - { - "id": 3116, - "name": "Insight Chain", - "symbol": "INB", - "website_slug": "insight-chain" - }, - { - "id": 3117, - "name": "Social Lending Token", - "symbol": "SLT", - "website_slug": "social-lending-token" - }, - { - "id": 3118, - "name": "Graviocoin", - "symbol": "GIO", - "website_slug": "graviocoin" - }, - { - "id": 3119, - "name": "Alchemint Standards", - "symbol": "SDS", - "website_slug": "alchemint-standards" - }, - { - "id": 3120, - "name": "OWNDATA", - "symbol": "OWN", - "website_slug": "owndata" - }, - { - "id": 3121, - "name": "IGToken", - "symbol": "IG", - "website_slug": "igtoken" - }, - { - "id": 3122, - "name": "Help The Homeless Coin", - "symbol": "HTH", - "website_slug": "help-the-homeless-coin" - }, - { - "id": 3123, - "name": "GSENetwork", - "symbol": "GSE", - "website_slug": "gsenetwork" - }, - { - "id": 3124, - "name": "Dragonglass", - "symbol": "DGS", - "website_slug": "dragonglass" - }, - { - "id": 3125, - "name": "XDNA", - "symbol": "XDNA", - "website_slug": "xdna" - }, - { - "id": 3126, - "name": "ProximaX", - "symbol": "XPX", - "website_slug": "proximax" - }, - { - "id": 3127, - "name": "Themis", - "symbol": "GET", - "website_slug": "themis" - }, - { - "id": 3128, - "name": "SiaCashCoin", - "symbol": "SCC", - "website_slug": "siacashcoin" - }, - { - "id": 3129, - "name": "Nyerium", - "symbol": "NYEX", - "website_slug": "nyerium" - }, - { - "id": 3130, - "name": "Forkcoin", - "symbol": "FORK", - "website_slug": "forkcoin" - }, - { - "id": 3131, - "name": "Thingschain", - "symbol": "TIC", - "website_slug": "thingschain" - }, - { - "id": 3132, - "name": "EtherGem", - "symbol": "EGEM", - "website_slug": "ethergem" - }, - { - "id": 3133, - "name": "Arepacoin", - "symbol": "AREPA", - "website_slug": "arepacoin" - }, - { - "id": 3134, - "name": "ETERNAL TOKEN", - "symbol": "XET", - "website_slug": "external-token" - }, - { - "id": 3135, - "name": "CEDEX Coin", - "symbol": "CEDEX", - "website_slug": "cedex-coin" - }, - { - "id": 3136, - "name": "MEET.ONE", - "symbol": "MEETONE", - "website_slug": "meetone" - }, - { - "id": 3137, - "name": "KARMA", - "symbol": "KARMA", - "website_slug": "karma-eos" - }, - { - "id": 3138, - "name": "Noku", - "symbol": "NOKU", - "website_slug": "noku" - }, - { - "id": 3139, - "name": "DxChain Token", - "symbol": "DX", - "website_slug": "dxchain-token" - }, - { - "id": 3140, - "name": "Ubex", - "symbol": "UBEX", - "website_slug": "ubex" - }, - { - "id": 3141, - "name": "Blockpass", - "symbol": "PASS", - "website_slug": "blockpass" - }, - { - "id": 3142, - "name": "BaaSid", - "symbol": "BAAS", - "website_slug": "baasid" - }, - { - "id": 3143, - "name": "Pecunio", - "symbol": "PCO", - "website_slug": "pecunio" - }, - { - "id": 3144, - "name": "ThoreCoin", - "symbol": "THR", - "website_slug": "thorecoin" - }, - { - "id": 3145, - "name": "Ferron", - "symbol": "FRRN", - "website_slug": "ferron" - }, - { - "id": 3146, - "name": "CyberFM", - "symbol": "CYFM", - "website_slug": "cyberfm" - }, - { - "id": 3147, - "name": "HYCON", - "symbol": "HYC", - "website_slug": "hycon" - }, - { - "id": 3148, - "name": "MetaMorph", - "symbol": "METM", - "website_slug": "metamorph" - }, - { - "id": 3149, - "name": "NetKoin", - "symbol": "NTK", - "website_slug": "netkoin" - }, - { - "id": 3150, - "name": "C2C System", - "symbol": "C2C", - "website_slug": "c2c-system" - }, - { - "id": 3151, - "name": "Akroma", - "symbol": "AKA", - "website_slug": "akroma" - }, - { - "id": 3152, - "name": "Obitan Chain", - "symbol": "OBTC", - "website_slug": "obitan-chain" - }, - { - "id": 3153, - "name": "Twinkle", - "symbol": "TKT", - "website_slug": "twinkle" - }, - { - "id": 3154, - "name": "Davinci Coin", - "symbol": "DAC", - "website_slug": "davinci-coin" - }, - { - "id": 3155, - "name": "Quant", - "symbol": "QNT", - "website_slug": "quant" - }, - { - "id": 3156, - "name": "Airbloc", - "symbol": "ABL", - "website_slug": "airbloc" - }, - { - "id": 3157, - "name": "Smart Application Chain", - "symbol": "SAC", - "website_slug": "smart-application-chain" - }, - { - "id": 3158, - "name": "ZCore", - "symbol": "ZCR", - "website_slug": "zcore" - }, - { - "id": 3159, - "name": "Apollon", - "symbol": "XAP", - "website_slug": "apollon" - }, - { - "id": 3160, - "name": "Infinipay", - "symbol": "IFP", - "website_slug": "infinipay" - }, - { - "id": 3161, - "name": "savedroid", - "symbol": "SVD", - "website_slug": "savedroid" - }, - { - "id": 3162, - "name": "YoloCash", - "symbol": "YLC", - "website_slug": "yolocash" - }, - { - "id": 3163, - "name": "Mero", - "symbol": "MERO", - "website_slug": "mero" - }, - { - "id": 3164, - "name": "PumaPay", - "symbol": "PMA", - "website_slug": "pumapay" - }, - { - "id": 3165, - "name": "Arion", - "symbol": "ARION", - "website_slug": "arion" - }, - { - "id": 3166, - "name": "Bitcoin Incognito", - "symbol": "XBI", - "website_slug": "bitcoin-incognito" - }, - { - "id": 3167, - "name": "SGPay", - "symbol": "SGP", - "website_slug": "sgpay" - }, - { - "id": 3168, - "name": "FarmaTrust", - "symbol": "FTT", - "website_slug": "farmatrust" - }, - { - "id": 3169, - "name": "Hybrid Block", - "symbol": "HYB", - "website_slug": "hybrid-block" - }, - { - "id": 3170, - "name": "Talao", - "symbol": "TALAO", - "website_slug": "talao" - }, - { - "id": 3171, - "name": "HeartBout", - "symbol": "HB", - "website_slug": "heartbout" - }, - { - "id": 3172, - "name": "LogisCoin", - "symbol": "LGS", - "website_slug": "logiscoin" - }, - { - "id": 3173, - "name": "Trendercoin", - "symbol": "TDC", - "website_slug": "trendercoin" - }, - { - "id": 3174, - "name": "Fintab", - "symbol": "FNTB", - "website_slug": "fintab" - }, - { - "id": 3175, - "name": "TTC Protocol", - "symbol": "TTC", - "website_slug": "ttc-protocol" - }, - { - "id": 3176, - "name": "Alttex", - "symbol": "ALTX", - "website_slug": "alttex" - }, - { - "id": 3177, - "name": "Seal Network", - "symbol": "SEAL", - "website_slug": "seal-network" - }, - { - "id": 3178, - "name": "Linkey", - "symbol": "LKY", - "website_slug": "linkey" - }, - { - "id": 3179, - "name": "Arbidex", - "symbol": "ABX", - "website_slug": "arbidex" - }, - { - "id": 3180, - "name": "Compound Coin", - "symbol": "COMP", - "website_slug": "compound-coin" - }, - { - "id": 3181, - "name": "ShowHand", - "symbol": "HAND", - "website_slug": "showhand" - }, - { - "id": 3182, - "name": "HitChain", - "symbol": "HIT", - "website_slug": "hitchain" - }, - { - "id": 3183, - "name": "SecureCloudCoin", - "symbol": "SC2", - "website_slug": "securecloudcoin" - }, - { - "id": 3184, - "name": "Gold Poker", - "symbol": "GPKR", - "website_slug": "gold-poker" - }, - { - "id": 3185, - "name": "TWIST", - "symbol": "TWIST", - "website_slug": "twist" - }, - { - "id": 3186, - "name": "Zen Protocol", - "symbol": "ZP", - "website_slug": "zen-protocol" - }, - { - "id": 3187, - "name": "Mozo Token", - "symbol": "MOZO", - "website_slug": "mozo-token" - }, - { - "id": 3188, - "name": "SuperEdge", - "symbol": "ECT", - "website_slug": "superedge" - }, - { - "id": 3189, - "name": "Mainstream For The Underground", - "symbol": "MFTU", - "website_slug": "mainstream-for-the-underground" - }, - { - "id": 3190, - "name": "Defense", - "symbol": "DFS", - "website_slug": "defense" - }, - { - "id": 3191, - "name": "Rentledger", - "symbol": "RTL", - "website_slug": "rentledger" - }, - { - "id": 3192, - "name": "CatoCoin", - "symbol": "CATO", - "website_slug": "catocoin" - }, - { - "id": 3193, - "name": "RRCoin", - "symbol": "RRC", - "website_slug": "rrcoin" - }, - { - "id": 3194, - "name": "DPRating", - "symbol": "RATING", - "website_slug": "dprating" - }, - { - "id": 3195, - "name": "Credit Tag Chain", - "symbol": "CTC", - "website_slug": "credit-tag-chain" - }, - { - "id": 3196, - "name": "KNOW", - "symbol": "KNOW", - "website_slug": "know" - }, - { - "id": 3197, - "name": "Graphcoin", - "symbol": "GRPH", - "website_slug": "graphcoin" - }, - { - "id": 3198, - "name": "KingXChain", - "symbol": "KXC", - "website_slug": "kingxchain" - }, - { - "id": 3199, - "name": "Cashbery Coin", - "symbol": "CBC", - "website_slug": "cashbery-coin" - }, - { - "id": 3200, - "name": "Nasdacoin", - "symbol": "NSD", - "website_slug": "nasdacoin" - }, - { - "id": 3201, - "name": "Printex", - "symbol": "PRTX", - "website_slug": "printex" - }, - { - "id": 3202, - "name": "QYNO", - "symbol": "QNO", - "website_slug": "qyno" - }, - { - "id": 3203, - "name": "Lobstex", - "symbol": "LOBS", - "website_slug": "lobstex" - }, - { - "id": 3204, - "name": "Rubex Money", - "symbol": "RBMC", - "website_slug": "rubex-money" - }, - { - "id": 3205, - "name": "VeriDocGlobal", - "symbol": "VDG", - "website_slug": "veridocglobal" - }, - { - "id": 3206, - "name": "Mithril Ore", - "symbol": "MORE", - "website_slug": "mithril-ore" - }, - { - "id": 3208, - "name": "YUKI", - "symbol": "YUKI", - "website_slug": "yuki" - }, - { - "id": 3209, - "name": "4NEW", - "symbol": "KWATT", - "website_slug": "4new" - }, - { - "id": 3210, - "name": "MIB Coin", - "symbol": "MIB", - "website_slug": "mib-coin" - }, - { - "id": 3212, - "name": "CottonCoin", - "symbol": "COTN", - "website_slug": "cottoncoin" - }, - { - "id": 3213, - "name": "BitF", - "symbol": "BITF", - "website_slug": "bitf" - }, - { - "id": 3214, - "name": "Soniq", - "symbol": "SONIQ", - "website_slug": "soniq" - }, - { - "id": 3215, - "name": "Gentarium", - "symbol": "GTM", - "website_slug": "gentarium" - }, - { - "id": 3216, - "name": "DeltaChain", - "symbol": "DELTA", - "website_slug": "delta-chain" - }, - { - "id": 3217, - "name": "ONG", - "symbol": "ONG", - "website_slug": "ong" - }, - { - "id": 3218, - "name": "Energi", - "symbol": "NRG", - "website_slug": "energi" - }, - { - "id": 3219, - "name": "FUTURAX", - "symbol": "FTXT", - "website_slug": "futurax" - }, - { - "id": 3220, - "name": "DAV Token", - "symbol": "DAV", - "website_slug": "dav-token" - }, - { - "id": 3221, - "name": "ABLE", - "symbol": "ABLX", - "website_slug": "able" - }, - { - "id": 3222, - "name": "Bionic", - "symbol": "BNC0", - "website_slug": "bionic" - }, - { - "id": 3223, - "name": "DOWCOIN", - "symbol": "DOW", - "website_slug": "dowcoin" - }, - { - "id": 3224, - "name": "Qubitica", - "symbol": "QBIT", - "website_slug": "qubitica" - }, - { - "id": 3225, - "name": "BitNewChain", - "symbol": "BTN", - "website_slug": "bitnewchain" - }, - { - "id": 3226, - "name": "Adenz", - "symbol": "DNZ", - "website_slug": "adenz" - }, - { - "id": 3227, - "name": "Traceability Chain", - "symbol": "TAC", - "website_slug": "traceability-chain" - }, - { - "id": 3228, - "name": "Cryptosolartech", - "symbol": "CST", - "website_slug": "cryptosolartech" - }, - { - "id": 3229, - "name": "Centaure", - "symbol": "CEN", - "website_slug": "centaure" - }, - { - "id": 3230, - "name": "VULCANO", - "symbol": "VULC", - "website_slug": "vulcano" - }, - { - "id": 3231, - "name": "Blockchain Quotations Index Token", - "symbol": "BQT", - "website_slug": "blockchain-quotations-index-token" - }, - { - "id": 3232, - "name": "Staker", - "symbol": "STR", - "website_slug": "staker" - }, - { - "id": 3234, - "name": "Xriba", - "symbol": "XRA", - "website_slug": "xriba" - }, - { - "id": 3235, - "name": "FolmCoin", - "symbol": "FLM", - "website_slug": "folmcoin" - }, - { - "id": 3236, - "name": "WinToken", - "symbol": "WIN", - "website_slug": "wintoken" - }, - { - "id": 3237, - "name": "Timicoin", - "symbol": "TMC", - "website_slug": "timicoin" - }, - { - "id": 3238, - "name": "ABCC Token", - "symbol": "AT", - "website_slug": "abcc-token" - }, - { - "id": 3239, - "name": "EliteShipperToken", - "symbol": "ESHIP", - "website_slug": "eliteshippertoken" - }, - { - "id": 3240, - "name": "Ethersocial", - "symbol": "ESN", - "website_slug": "ethersocial" - }, - { - "id": 3241, - "name": "Knoxstertoken", - "symbol": "FKX", - "website_slug": "knoxstertoken" - }, - { - "id": 3243, - "name": "Moneytoken", - "symbol": "IMT", - "website_slug": "moneytoken" - } - ], - "metadata": { - "timestamp": 1536116707, - "num_cryptocurrencies": 1910, - "error": null - } -} diff --git a/Neuron/Sections/Dapp/WebView/AdvancedViewController.swift b/Neuron/Sections/Dapp/WebView/AdvancedViewController.swift deleted file mode 100644 index ed333ea7..00000000 --- a/Neuron/Sections/Dapp/WebView/AdvancedViewController.swift +++ /dev/null @@ -1,150 +0,0 @@ -// -// AdvancedViewController.swift -// Neuron -// -// Created by XiaoLu on 2018/11/1. -// Copyright © 2018 Cryptape. All rights reserved. -// - -import UIKit -import BigInt - -protocol AdvancedViewControllerDelegate: class { - func getCustomGas(gasPrice: BigUInt, gas: BigUInt) -} - -class AdvancedViewController: UIViewController { - var dataString = "" - var gasLimit = BigUInt() - private var gasPrice = BigUInt() - private var inputGasPrice: String? - weak var delegate: AdvancedViewControllerDelegate? - - @IBOutlet weak var backgroundView: UIView! - @IBOutlet weak var contentView: UIView! - @IBOutlet weak var ethereumSuggestLabel: UILabel! - @IBOutlet weak var gasPriceTextField: UITextField! - @IBOutlet weak var gasLabel: UILabel! - @IBOutlet weak var tabbedButtonView: TabbedButtonsView! - @IBOutlet weak var dataTextView: UITextView! - - override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - assignmentForUI() - backgroundView.alpha = 0.0 - contentView.transform = CGAffineTransform(translationX: 0, y: contentView.bounds.size.height) - UIView.animate(withDuration: CATransaction.animationDuration()) { - self.backgroundView.alpha = 0.5 - self.contentView.transform = CGAffineTransform.identity - } - } - - override func viewDidLoad() { - super.viewDidLoad() - tabbedButtonView.buttonTitles = ["HEX", "UTF8"] - tabbedButtonView.delegate = self - gasPriceTextField.delegate = self - } - - func assignmentForUI() { - dataTextView.text = dataString - Toast.showHUD() - DispatchQueue.global().async { - do { - let web3 = EthereumNetwork().getWeb3() - let gasPrice = try web3.eth.getGasPrice() - DispatchQueue.main.async { - self.gasPrice = gasPrice - let ethereumGasPrice = Web3Utils.formatToEthereumUnits(gasPrice, toUnits: .Gwei, decimals: 4, fallbackToScientific: false) ?? "8" - self.ethereumSuggestLabel.text = "以太坊推荐 " + ethereumGasPrice + "Gwei" - self.formatValue(gasPrice: gasPrice) - Toast.hideHUD() - } - } catch { - DispatchQueue.main.async { - self.ethereumSuggestLabel.text = "以太坊推荐 8" - self.gasPrice = BigUInt(8) - } - } - } - } - - func formatValue(gasPrice: BigUInt) { - let ethereumGasPrice = Web3Utils.formatToEthereumUnits(gasPrice, toUnits: .Gwei, decimals: 4, fallbackToScientific: false) ?? "8" - let gas = Web3Utils.formatToEthereumUnits(gasPrice * self.gasLimit, toUnits: .eth, decimals: 4, fallbackToScientific: true) ?? "0" - self.gasLabel.text = "Gas费用:\(gas) ETH = Gaslimit(\(self.gasLimit.description))*Gasprice(\(ethereumGasPrice))" - } - - @IBAction func textFieldValueChanged(_ sender: UITextField) { - if let gasPrice = sender.text { - inputGasPrice = gasPrice - let finalGasPrice = Web3Utils.parseToBigUInt(gasPrice, units: .Gwei)! - formatValue(gasPrice: finalGasPrice) - } - } - - func hideView() { - UIView.animate(withDuration: CATransaction.animationDuration(), animations: { - self.backgroundView.alpha = 0.0 - self.contentView.transform = CGAffineTransform(translationX: 0, y: self.contentView.bounds.size.height) - }, completion: { (_) in - self.dismiss(animated: false, completion: nil) - }) - } - - @IBAction func closeButton(_ sender: UIButton) { - hideView() - } - - @IBAction func sureAdvanceButton(_ sender: UIButton) { - guard let inputGasPrice = inputGasPrice else { - Toast.showToast(text: "请输入GasPrice") - return - } - let finalGasPrice = Web3Utils.parseToBigUInt(inputGasPrice, units: .Gwei)! - if finalGasPrice < gasPrice { - let gasPriceString = Web3Utils.formatToEthereumUnits(gasPrice, toUnits: .Gwei, decimals: 4, fallbackToScientific: true) ?? "0" - Toast.showToast(text: "请输入的GasPrice不小于\(gasPriceString) Gwei") - return - } - delegate?.getCustomGas(gasPrice: finalGasPrice, gas: finalGasPrice * self.gasLimit) - hideView() - } -} - -extension AdvancedViewController: UITextFieldDelegate { - func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { - if textField == gasPriceTextField { - let character: String - if (textField.text?.contains("."))! { - character = "0123456789" - } else { - character = "0123456789." - } - guard CharacterSet(charactersIn: character).isSuperset(of: CharacterSet(charactersIn: string)) else { - return false - } - return true - } else { - return true - } - } - - func textFieldDidEndEditing(_ textField: UITextField) { - if let gasPrice = textField.text { - inputGasPrice = gasPrice - let finalGasPrice = Web3Utils.parseToBigUInt(gasPrice, units: .Gwei)! - formatValue(gasPrice: finalGasPrice) - } - } -} - -extension AdvancedViewController: TabbedButtonsViewDelegate { - func tabbedButtonsView(_ view: TabbedButtonsView, didSelectButtonAt index: Int) { - if index == 0 { - dataTextView.text = dataString - } else { - dataTextView.text = String(decoding: Data.fromHex(dataString)!, as: UTF8.self) - } - } -} diff --git a/Neuron/Sections/Dapp/WebView/ContractController.swift b/Neuron/Sections/Dapp/WebView/ContractController.swift deleted file mode 100644 index b62e9c14..00000000 --- a/Neuron/Sections/Dapp/WebView/ContractController.swift +++ /dev/null @@ -1,318 +0,0 @@ -// -// ContractController.swift -// Neuron -// -// Created by XiaoLu on 2018/5/29. -// Copyright © 2018年 cryptape. All rights reserved. -// - -import UIKit -import BLTNBoard -import AppChain -import BigInt -import Web3swift -import EthereumAddress - -enum ChainType { - case appChain - case eth -} - -protocol ContractControllerDelegate: class { - func callBackWebView(id: Int, value: String, error: DAppError?) -} - -class ContractController: UITableViewController, TransactonSender { - var requestAddress: String = "" - var dappName: String = "" - var dappCommonModel: DAppCommonModel! - var paramBuilder: TransactionParamBuilder! - private var chainType: ChainType = .appChain - private var tokenModel = TokenModel() { - didSet { - paramBuilder = TransactionParamBuilder(token: tokenModel) - } - } - var advancedViewController: AdvancedViewController! - weak var delegate: ContractControllerDelegate? - - @IBOutlet weak var valueLabel: UILabel! - @IBOutlet weak var gasLabel: UILabel! - @IBOutlet weak var totlePayLabel: UILabel! - @IBOutlet weak var dappNameLabel: UILabel! - @IBOutlet weak var requestStringLabel: UILabel! - @IBOutlet weak var toLabel: UILabel! - @IBOutlet weak var fromLabel: UILabel! - - private var gasPrice = BigUInt() - private var gasLimit = BigUInt() - private var ethereumGas: String? - private var value: String! // both appChain'amount and Ethereum'amount - - private lazy var summaryPageItem: TxSummaryPageItem = { - return TxSummaryPageItem.create() - }() - private lazy var bulletinManager: BLTNItemManager = { - let passwordPageItem = createPasswordPageItem() - summaryPageItem.next = passwordPageItem - summaryPageItem.actionHandler = { item in - item.manager?.displayNextItem() - } - - return BLTNItemManager(rootItem: summaryPageItem) - }() - - override func viewDidLoad() { - super.viewDidLoad() - title = "支付详情" - getTokenModel() - } - - override func prepare(for segue: UIStoryboardSegue, sender: Any?) { - if segue.identifier == "AdvancedViewController" { - advancedViewController = segue.destination as? AdvancedViewController - advancedViewController.delegate = self - advancedViewController.dataString = dappCommonModel.eth?.data ?? "" - advancedViewController.gasLimit = gasLimit - } - } - - override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool { - if identifier == "AdvancedViewController" { - return false - } - return true - } - - func getTokenModel() { - let appModel = AppModel.current - appModel.nativeTokenList.forEach { (tokenModel) in - if dappCommonModel.chainType == "AppChain" { - if dappCommonModel.appChain!.chainId == Int(tokenModel.chainId) { - self.tokenModel = tokenModel - } - } else { - if dappCommonModel.eth!.chainId == Int(tokenModel.chainId) { - self.tokenModel = tokenModel - } - } - } - setUIData() - } - - func setUIData() { - let walletModel = AppModel.current.currentWallet! - fromLabel.text = walletModel.address - requestStringLabel.text = requestAddress - dappNameLabel.text = dappName - - if dappCommonModel.chainType == "AppChain" { - let appChainQuota = dappCommonModel.appChain?.quota!.toBigUInt() ?? 0 - chainType = .appChain - toLabel.text = dappCommonModel.appChain?.to - value = formatScientValue(value: dappCommonModel.appChain?.value?.toBigUInt() ?? 0) - valueLabel.text = value - gasLabel.text = getNervosTransactionCosted(with: appChainQuota) + tokenModel.symbol - totlePayLabel.text = getTotleValue(value: dappCommonModel.appChain?.value?.toBigUInt() ?? 0, gas: appChainQuota) + tokenModel.symbol - } else { - chainType = .eth - toLabel.text = dappCommonModel.eth?.to - value = formatScientValue(value: dappCommonModel.eth?.value?.toBigUInt() ?? "0") - valueLabel.text = value - getETHGas(ethGasPirce: dappCommonModel.eth?.gasPrice, ethGasLimit: dappCommonModel.eth?.gasLimit) - } - formatValueLabel(value: value) - } - - private func createPasswordPageItem() -> PasswordPageItem { - let passwordPageItem = PasswordPageItem.create() - - passwordPageItem.actionHandler = { [weak self] item in - item.manager?.displayActivityIndicator() - guard let self = self else { - return - } - self.sendTransaction(password: passwordPageItem.passwordField.text!) - } - - return passwordPageItem - } - - func formatValueLabel(value: String) { - let range = NSRange(location: valueLabel.text!.lengthOfBytes(using: .utf8), length: tokenModel.symbol.lengthOfBytes(using: .utf8) + 1) - valueLabel.text! += " " + tokenModel.symbol - let attributedText = NSMutableAttributedString(attributedString: valueLabel.attributedText!) - attributedText.addAttributes([NSAttributedString.Key.font: UIFont.systemFont(ofSize: 24)], range: range) - valueLabel.attributedText = attributedText - } - - func getNervosTransactionCosted(with quotaInput: BigUInt) -> String { - return Web3Utils.formatToEthereumUnits(quotaInput, toUnits: .eth, decimals: 1, fallbackToScientific: true)! - } - - func formatScientValue(value: BigUInt) -> String { - let format = Web3Utils.formatToEthereumUnits(value, toUnits: .eth, decimals: 8, fallbackToScientific: false)! - let finalValue = Double(format)! - return finalValue.trailingZerosTrimmed - } - - // gas is equal to appChain's quota - func getTotleValue(value: BigUInt, gas: BigUInt) -> String { - let finalValue = value + gas - let formatValue = Web3Utils.formatToEthereumUnits(finalValue, toUnits: .eth, decimals: 8, fallbackToScientific: true)! - return Double(formatValue)!.trailingZerosTrimmed - } - - func getETHGas(ethGasPirce: String?, ethGasLimit: String?) { - Toast.showHUD() - DispatchQueue.global().async { - let web3 = EthereumNetwork().getWeb3() - if ethGasPirce != nil { - self.gasPrice = ethGasLimit!.toBigUInt()! - } else { - do { - let gasPrice = try web3.eth.getGasPrice() - self.gasPrice = gasPrice - } catch { - self.gasPrice = BigUInt(0) - } - } - - if ethGasLimit != nil { - self.gasLimit = ethGasLimit!.toBigUInt()! - } else { - var options = TransactionOptions() - options.gasLimit = .limited(self.gasLimit) - options.from = EthereumAddress(self.dappCommonModel.eth?.from ?? "") - options.value = self.dappCommonModel.eth?.value?.toBigUInt() - let contract = web3.contract(Web3.Utils.coldWalletABI, at: EthereumAddress(self.dappCommonModel.eth?.to ?? ""))! - if let estimatedGas = try? contract.method(transactionOptions: options)!.estimateGas(transactionOptions: options) { - self.gasLimit = estimatedGas * 4 - } else { - self.gasLimit = BigUInt(0) - } - } - DispatchQueue.main.async { - let gas = self.gasPrice * self.gasLimit - self.ethereumGas = Web3Utils.formatToEthereumUnits(gas, toUnits: .eth, decimals: 8, fallbackToScientific: false) - self.gasLabel.text = Double(self.ethereumGas!)!.trailingZerosTrimmed + self.tokenModel.symbol - self.totlePayLabel.text = self.getTotleValue(value: self.dappCommonModel.eth?.value?.toBigUInt() ?? 0, gas: gas) + self.tokenModel.symbol - Toast.hideHUD() - } - } - } - - override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = super.tableView(tableView, cellForRowAt: indexPath) - if indexPath.section == 0 && indexPath.row == 0 { - if dappCommonModel.chainType == "ETH" { - cell.accessoryType = .disclosureIndicator - } else { - cell.accessoryType = .none - } - } - return cell - } - - override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - if dappCommonModel.chainType == "ETH" && indexPath.section == 0 && indexPath.row == 0 { - performSegue(withIdentifier: "AdvancedViewController", sender: indexPath.row) - } - } - - @IBAction func clickBackButton(_ sender: UIButton) { - delegate?.callBackWebView(id: dappCommonModel.id, value: "", error: DAppError.userCanceled) - navigationController?.popViewController(animated: true) - } - - @IBAction func didClickConfirmButton(_ sender: UIButton) { - guard let paramBuilder = paramBuilder else { - return - } - paramBuilder.from = AppModel.current.currentWallet!.address - paramBuilder.value = Double(value)!.toAmount(tokenModel.decimals) - paramBuilder.amount = NSDecimalNumber(string: value).doubleValue - - switch chainType { - case .appChain: - paramBuilder.gasLimit = 10000000 - paramBuilder.gasPrice = dappCommonModel.appChain?.quota?.toBigUInt() ?? 1000000 - paramBuilder.to = dappCommonModel.appChain?.to ?? "" - paramBuilder.data = Data(hex: dappCommonModel.appChain?.data ?? "") - case .eth: - paramBuilder.gasLimit = UInt64(gasLimit) - paramBuilder.gasPrice = gasPrice - paramBuilder.to = dappCommonModel.eth?.to ?? "" - paramBuilder.data = Data(hex: dappCommonModel.eth?.data ?? "") - } - - summaryPageItem.update(paramBuilder) - bulletinManager.showBulletin(above: self) - } -} - -private extension ContractController { - func sendTransaction(password: String) { - guard let paramBuilder = paramBuilder else { - return - } - DispatchQueue.global().async { - do { - let txHash: TxHash - if paramBuilder.tokenType == .ether || paramBuilder.tokenType == .erc20 { - txHash = try self.sendEthereumTransaction(password: password) - } else { - txHash = try self.sendAppChainTransaction(password: password) - } - - DispatchQueue.main.async { - let successPageItem = SuccessPageItem.create(title: "交易已发送") - successPageItem.actionHandler = { item in - self.transactionDidSend(txhash: txHash) - } - self.bulletinManager.push(item: successPageItem) - } - } catch let error { - DispatchQueue.main.async { - self.bulletinManager.hideActivityIndicator() - let passwordPageItem = self.createPasswordPageItem() - self.bulletinManager.push(item: passwordPageItem) - passwordPageItem.errorMessage = error.localizedDescription - } - } - } - } - - func transactionDidSend(txhash: TxHash?) { - if let txhash = txhash { - delegate?.callBackWebView(id: dappCommonModel.id, value: txhash.addHexPrefix(), error: nil) - track() - bulletinManager.dismissBulletin() - navigationController?.popViewController(animated: true) - } else { - delegate?.callBackWebView(id: dappCommonModel.id, value: "", error: DAppError.sendTransactionFailed) - } - } - - func track() { - SensorsAnalytics.Track.transaction( - chainType: tokenModel.chainId, - currencyType: tokenModel.symbol, - currencyNumber: Double(value) ?? 0.0, - receiveAddress: dappCommonModel.appChain?.to ?? "", - outcomeAddress: AppModel.current.currentWallet!.address, - transactionType: .normal - ) - } -} - -extension ContractController: AdvancedViewControllerDelegate { - func getCustomGas(gasPrice: BigUInt, gas: BigUInt) { - self.gasPrice = gasPrice - ethereumGas = Web3Utils.formatToEthereumUnits(gas, toUnits: .eth, decimals: 8, fallbackToScientific: true) - let bigUIntValue = Web3Utils.parseToBigUInt(value, units: .eth)! - let totlePay = getTotleValue(value: bigUIntValue, gas: gas) - totlePayLabel.text = totlePay + tokenModel.symbol - gasLabel.text = Double(ethereumGas ?? "")!.trailingZerosTrimmed + tokenModel.symbol - } -} diff --git a/Neuron/Sections/Transaction/PaymentViewController.swift b/Neuron/Sections/Transaction/PaymentViewController.swift deleted file mode 100644 index c998ca1c..00000000 --- a/Neuron/Sections/Transaction/PaymentViewController.swift +++ /dev/null @@ -1,232 +0,0 @@ -// -// PaymentViewController.swift -// Neuron -// -// Created by XiaoLu on 2018/9/13. -// Copyright © 2018年 Cryptape. All rights reserved. -// - -import UIKit -import web3swift -import struct BigInt.BigUInt -import IQKeyboardManagerSwift - -class PaymentViewController: UITableViewController { - @IBOutlet weak var iconImageView: UIImageView! - @IBOutlet weak var nameLabel: UILabel! - @IBOutlet weak var addressLabel: UILabel! - @IBOutlet weak var assetTypeLabel: UILabel! - @IBOutlet weak var balanceLabel: UILabel! - @IBOutlet weak var amountTextField: UITextField! - @IBOutlet weak var addressTextField: UITextField! - @IBOutlet weak var switchButton: UISwitch! - private var gasPageViewController: UIPageViewController! - private var simpleGasViewController: SimpleGasViewController! - private var ethGasViewController: EthGasViewController! - private var nervosQuotaViewController: NervosQuotaViewController! - var payCoverViewController: PayCoverViewController! - var tokenType: TokenType = .nervosToken - var tokenModel = TokenModel() - var ethGasPrice: BigUInt! - var payValue: String = "" - var destinationAddress: String = "" - var isUseQRCode = false - var extraData = Data() - var nervosQuota: BigUInt! - var gasCost: String = "" - - override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - IQKeyboardManager.shared.enable = false - } - - override func viewWillDisappear(_ animated: Bool) { - super.viewWillDisappear(animated) - IQKeyboardManager.shared.enable = true - } - - override func viewDidLoad() { - super.viewDidLoad() - title = "\(tokenModel.symbol)转账" - amountTextField.delegate = self - addressTextField.delegate = self - simpleGasViewController = storyboard!.instantiateViewController(withIdentifier: "simpleGasViewController") as? SimpleGasViewController - simpleGasViewController.delegate = self - simpleGasViewController.tokenModel = tokenModel - simpleGasViewController.tokenType = tokenType - ethGasViewController = storyboard!.instantiateViewController(withIdentifier: "ethGasViewController") as? EthGasViewController - ethGasViewController.delegate = self - nervosQuotaViewController = storyboard!.instantiateViewController(withIdentifier: "nervosQuotaViewController") as? NervosQuotaViewController - nervosQuotaViewController.delegate = self - payCoverViewController = storyboard!.instantiateViewController(withIdentifier: "confirmViewController") as? PayCoverViewController - payCoverViewController.delegate = self - nervosQuotaViewController.tokenModel = tokenModel - gasPageViewController.setViewControllers([simpleGasViewController], direction: .forward, animated: false) - getBaseData() - } - - func getBaseData() { - let walletModel = WalletRealmTool.getCurrentAppModel().currentWallet! - iconImageView.image = UIImage(data: walletModel.iconData) - nameLabel.text = walletModel.name - addressLabel.text = walletModel.address - assetTypeLabel.text = tokenModel.symbol - balanceLabel.text = tokenModel.tokenBalance + tokenModel.symbol - } - - override func prepare(for segue: UIStoryboardSegue, sender: Any?) { - if segue.identifier == "gasPageViewController" { - gasPageViewController = segue.destination as? UIPageViewController - } - } - - @IBAction func advancedSettingAction(_ sender: UISwitch) { - if sender.isOn { - switch tokenType { - case .nervosToken: - gasPageViewController.setViewControllers([nervosQuotaViewController], direction: .forward, animated: false) - default: - gasPageViewController.setViewControllers([ethGasViewController], direction: .forward, animated: false) - } - } else { - gasPageViewController.setViewControllers([simpleGasViewController], direction: .forward, animated: false) - } - } - - @IBAction func clickQRButton(_ sender: UIButton) { - let qRCodeViewController = QRCodeViewController() - qRCodeViewController.delegate = self - self.navigationController?.pushViewController(qRCodeViewController, animated: true) - } - - @IBAction func clickNextButton(_ sender: UIButton) { - if canProceedNextStep() { - let amount = payValue.hasPrefix(".") ? "0" + payValue : payValue - let walletModel = WalletRealmTool.getCurrentAppModel().currentWallet! - payCoverViewController.tokenModel = tokenModel - payCoverViewController.walletAddress = walletModel.address - payCoverViewController.amount = amount - payCoverViewController.toAddress = destinationAddress - payCoverViewController.gasCost = gasCost - payCoverViewController.tokenType = tokenType - payCoverViewController.isUseQRCode = isUseQRCode - switch tokenType { - case .ethereumToken: - payCoverViewController.extraData = extraData - payCoverViewController.gasPrice = ethGasPrice - case .nervosToken: - payCoverViewController.extraData = extraData - payCoverViewController.gasPrice = nervosQuota - payCoverViewController.gasCost = "1e-16 \(tokenModel.symbol)" - case .erc20Token: - payCoverViewController.gasPrice = ethGasPrice - payCoverViewController.contrackAddress = tokenModel.address - } - UIApplication.shared.keyWindow?.addSubview(payCoverViewController.view) - } - } - - private func canProceedNextStep() -> Bool { - if payValue.count == 0 { - Toast.showToast(text: "转账金额不能为空") - return false - } - if destinationAddress.count == 0 { - Toast.showToast(text: "转账地址不能为空") - return false - } - if destinationAddress.count != 40 && destinationAddress.count != 42 { - Toast.showToast(text: "您的地址错误,请重新输入") - return false - } - if destinationAddress != destinationAddress.lowercased() { - let checksumAddress = EthereumAddress.toChecksumAddress(destinationAddress) ?? "" - if checksumAddress != destinationAddress { - Toast.showToast(text: "您的地址错误,请重新输入") - return false - } - } - let walletModel = WalletRealmTool.getCurrentAppModel().currentWallet! - if destinationAddress == walletModel.address { - Toast.showToast(text: "发送地址和收款地址不能相同") - return false - } - let planPay = Double(payValue)! - let tokenBalance = Double(tokenModel.tokenBalance)! - if planPay > tokenBalance { - Toast.showToast(text: "余额不足") - return false - } - if !destinationAddress.hasPrefix("0x") || destinationAddress.count != 42 { - Toast.showToast(text: "地址有误:地址一般为0x开头的42位字符") - return false - } - return true - } -} - -extension PaymentViewController: PayCoverViewControllerDelegate { - func popToRootView() { - navigationController?.popViewController(animated: true) - } -} - -extension PaymentViewController: SimpleGasViewControllerDelegate, EthGasViewControllerDelegate, NervosQuotaViewControllerDelegate { - func getTransactionGasCost(gas: String) { - gasCost = gas - } - - func getNervosTransactionQuota(nervosQuotaViewController: NervosQuotaViewController, quota: BigUInt, data: Data) { - nervosQuota = quota - extraData = data - } - - func getTransactionGasPriceAndData(ethGasViewController: EthGasViewController, gasPrice: BigUInt, data: Data) { - ethGasPrice = gasPrice - extraData = data - } - - func getTransactionGasPrice(simpleGasViewController: SimpleGasViewController, gasPrice: BigUInt) { - if tokenType == .nervosToken { - nervosQuota = gasPrice - } else { - ethGasPrice = gasPrice - } - } -} - -extension PaymentViewController: QRCodeViewControllerDelegate { - func didBackQRCodeMessage(codeResult: String) { - addressTextField.text = codeResult - destinationAddress = codeResult - isUseQRCode = true - } -} - -extension PaymentViewController: UITextFieldDelegate { - func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { - if textField == amountTextField { - let character: String - if (textField.text?.contains("."))! { - character = "0123456789" - } else { - character = "0123456789." - } - guard CharacterSet(charactersIn: character).isSuperset(of: CharacterSet(charactersIn: string)) else { - return false - } - return true - } else { - return true - } - } - - func textFieldDidEndEditing(_ textField: UITextField) { - if textField == amountTextField { - payValue = textField.text ?? "" - } else { - destinationAddress = textField.text ?? "" - isUseQRCode = false - } - } -} diff --git a/Neuron/Sections/Transaction/TradeDetailsController.swift b/Neuron/Sections/Transaction/TradeDetailsController.swift deleted file mode 100644 index 169e28b1..00000000 --- a/Neuron/Sections/Transaction/TradeDetailsController.swift +++ /dev/null @@ -1,98 +0,0 @@ -// -// TradeDetailsController.swift -// Neuron -// -// Created by XiaoLu on 2018/5/25. -// Copyright © 2018年 cryptape. All rights reserved. -// - -import UIKit -import Web3swift - -class TradeDetailsController: UIViewController, UITableViewDataSource, UITableViewDelegate { - var transaction: TransactionDetails! { - didSet { - let dateformatter = DateFormatter() - dateformatter.dateFormat = "yyyy/MM/dd HH:mm:ss" - let dateText = dateformatter.string(from: transaction.date) - - if let ethereum = transaction as? EthereumTransactionDetails { - transactionType = "ETH" - let gasUsed = String(Double.fromAmount(ethereum.gasUsed * ethereum.gasPrice, decimals: ethereum.token.decimals)) - let gasPrice = Web3.Utils.formatToEthereumUnits(ethereum.gasPrice, toUnits: .Gwei, decimals: 8)! - titleArr = ["区块链网络", "接受方", "发送方", "手续费", "GasPrice", "交易流水号", "所在区块", "入块时间"] - subBtnArr = [ - "Ethereum Mainnet", - ethereum.to.count > 0 ? ethereum.to : "Contract Created", - ethereum.from, - gasUsed + "eth", - gasPrice + "Gwei", - ethereum.hash, - String(ethereum.blockNumber), - dateText - ] - } else if let appChain = transaction as? AppChainTransactionDetails { - transactionType = "AppChain" - let gasUsed = String(Double.fromAmount(appChain.gasUsed, decimals: 9)) - titleArr = ["区块链网络", "接受方", "发送方", "手续费", "交易流水号", "所在区块", "入块时间"] - subBtnArr = [ - appChain.chainName, - appChain.to.count > 0 ? appChain.to : "Contract Created", - appChain.from, - gasUsed + "NATT", - appChain.hash, - String(appChain.blockNumber), - dateText - ] - } - } - } - - private var titleArr = [""] - private var subBtnArr = [""] - private var transactionType = "" - @IBOutlet weak var amountLabel: UILabel! - @IBOutlet weak var addressLabel: UILabel! - @IBOutlet weak var nameLabel: UILabel! - @IBOutlet weak var iconImage: UIImageView! - @IBOutlet weak var headView: UIView! - @IBOutlet weak var tTable: UITableView! - - override func viewDidLoad() { - super.viewDidLoad() - title = "交易详情" - didSetUIDetail() - tTable.delegate = self - tTable.dataSource = self - let walletModel = AppModel.current.currentWallet - iconImage.image = UIImage(data: (walletModel?.iconData)!) - tTable.register(UINib.init(nibName: "TradeTableViewCell", bundle: nil), forCellReuseIdentifier: "ID") - amountLabel.text = Web3.Utils.formatToEthereumUnits(transaction.value, toUnits: .eth, decimals: 8)! - addressLabel.text = walletModel?.address - nameLabel.text = walletModel?.name - tTable.reloadData() - } - - func didSetUIDetail() { - headView.layer.shadowColor = UIColor(hex: "#ededed").cgColor - headView.layer.shadowOffset = CGSize(width: 0, height: 1) - headView.layer.shadowOpacity = 0.3 - headView.layer.shadowRadius = 2.75 - headView.layer.cornerRadius = 5 - headView.layer.borderWidth = 1 - headView.layer.borderColor = UIColor(hex: "#ededed").cgColor - } - - func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return titleArr.count - } - - func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCell(withIdentifier: "ID", for: indexPath) as! TradeTableViewCell - cell.ethOrNervos = transactionType - cell.selectIndex = indexPath as NSIndexPath - cell.titleStr = titleArr[indexPath.row] - cell.subTitleStr = subBtnArr[indexPath.row] - return cell - } -} diff --git a/Neuron/Sections/Transaction/TradeDetailsController.xib b/Neuron/Sections/Transaction/TradeDetailsController.xib deleted file mode 100644 index b0b43851..00000000 --- a/Neuron/Sections/Transaction/TradeDetailsController.xib +++ /dev/null @@ -1,151 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Neuron/Sections/Transaction/TransactionGasCostViewController.swift b/Neuron/Sections/Transaction/TransactionGasCostViewController.swift deleted file mode 100644 index d05c7fb1..00000000 --- a/Neuron/Sections/Transaction/TransactionGasCostViewController.swift +++ /dev/null @@ -1,122 +0,0 @@ -// -// TransactionGasCostViewController.swift -// Neuron -// -// Created by 晨风 on 2018/11/23. -// Copyright © 2018 Cryptape. All rights reserved. -// - -import UIKit -import Web3swift -//import EthereumAddress -import BigInt - -class TransactionGasCostViewController: UITableViewController { - @IBOutlet weak var gasPriceTextField: UITextField! - @IBOutlet weak var gasLimitTextField: UITextField! - @IBOutlet weak var gasCostLabel: UILabel! - @IBOutlet weak var gasCostDescLabel: UILabel! - @IBOutlet weak var dataTextView: UITextView! - @IBOutlet weak var dataTextPlaceholderLabel: UILabel! - @IBOutlet weak var confirmButton: UIButton! - var param: TransactionParamBuilder! - private var paramBuilder: TransactionParamBuilder! - private var observers = [NSKeyValueObservation]() - private let minGasPrice = 1.0 - - override func viewDidLoad() { - super.viewDidLoad() - paramBuilder = TransactionParamBuilder(builder: param) - observers.append(paramBuilder.observe(\.txFeeNatural, options: [.initial]) { [weak self](_, _) in - self?.updateGasCost() - }) - observers.append(param.observe(\.tokenPrice, options: [.initial]) { [weak self](_, _) in - self?.updateGasCost() - }) - if paramBuilder.tokenType == .erc20 { - dataTextView.isEditable = false - } - } - - @IBAction func confirm() { - let gasPrice = Double(gasPriceTextField.text!)! - if gasPrice < minGasPrice { - Toast.showToast(text: "您的GasPrice设置过低,建议输入推荐值以快速转账") - return - } - - if paramBuilder.tokenType == .ether { - if paramBuilder.data.count > 0 { - let estimateGasLimit = paramBuilder.estimateGasLimit() - if paramBuilder.gasLimit < UInt(estimateGasLimit) { - Toast.showToast(text: "请确保输入的gaslimit大于等于”\(estimateGasLimit)(估算值)*4”") - return - } - } else { - if paramBuilder.gasLimit < GasCalculator.defaultGasLimit { - Toast.showToast(text: "请确保输入的gaslimit大于等于\(GasCalculator.defaultGasLimit)") - return - } - } - } else if paramBuilder.tokenType == .erc20 { - let estimateGasLimit = paramBuilder.estimateGasLimit() - if paramBuilder.gasLimit < estimateGasLimit { - Toast.showToast(text: "请确保输入的gaslimit大于等于”\(estimateGasLimit)(估算值)*4”") - } - } - - param.gasPrice = paramBuilder.gasPrice - param.gasLimit = paramBuilder.gasLimit - param.data = dataTextView.text.data(using: .utf8) ?? Data() - navigationController?.popViewController(animated: true) - } - - private func updateGasCost() { - gasPriceTextField.text = paramBuilder.gasPrice.weiToGwei().trailingZerosTrimmed - gasLimitTextField.text = paramBuilder.gasLimit.description - gasCostLabel.text = "\(paramBuilder.txFeeNatural.decimal) \(paramBuilder.nativeCoinSymbol)" - gasCostDescLabel.text = "≈Gas Limit(\(gasLimitTextField.text!))*Gas Price(\(gasPriceTextField.text!) Gwei)" - if paramBuilder.tokenPrice > 0 { - gasCostLabel.text = gasCostLabel.text! + " ≈ \(paramBuilder.currencySymbol)" + String(format: "%.4lf", paramBuilder.tokenPrice * paramBuilder.txFeeNatural) - } - } - - override func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool { - return false - } -} - -extension TransactionGasCostViewController: UITextFieldDelegate { - func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { - var character = "0123456789" - if textField.text!.contains(".") { - character += "." - } - guard CharacterSet(charactersIn: character).isSuperset(of: CharacterSet(charactersIn: string)) else { - return false - } - return true - } - - func textFieldDidEndEditing(_ textField: UITextField) { - if textField == gasPriceTextField { - paramBuilder.gasPrice = Double(gasPriceTextField.text!)!.gweiToWei() - } else if textField == gasLimitTextField { - paramBuilder.gasLimit = UInt64(gasLimitTextField.text!) ?? GasCalculator.defaultGasLimit - } - } -} - -extension TransactionGasCostViewController: UITextPasteDelegate { -} - -extension TransactionGasCostViewController: UITextViewDelegate { - func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { - let character = "0123456789abcdefABCDEF" - guard CharacterSet(charactersIn: character).isSuperset(of: CharacterSet(charactersIn: text)) else { - return false - } - dataTextPlaceholderLabel.isHidden = textView.text.count + (text.count - range.length) > 0 - return true - } -} diff --git a/Neuron/Sections/Transaction/TransactionGasPriceViewController.swift b/Neuron/Sections/Transaction/TransactionGasPriceViewController.swift deleted file mode 100644 index ac08888e..00000000 --- a/Neuron/Sections/Transaction/TransactionGasPriceViewController.swift +++ /dev/null @@ -1,82 +0,0 @@ -// -// TransactionGasPriceViewController.swift -// Neuron -// -// Created by 晨风 on 2018/10/30. -// Copyright © 2018 Cryptape. All rights reserved. -// - -import UIKit - -class TransactionGasPriceViewController: UIViewController { - @IBOutlet weak var backgroundView: UIView! - @IBOutlet weak var contentView: UIView! - @IBOutlet weak var estimatedGasPriceLabel: UILabel! - @IBOutlet weak var gasPriceTextField: UITextField! - @IBOutlet weak var gasLimitTextField: UITextField! - var param: TransactionParamBuilder! - - private let minGasPrice = 1.0 - - override func viewDidLoad() { - super.viewDidLoad() - estimatedGasPriceLabel.text = "以太坊推荐值 \(param.fetchedGasPrice.weiToGwei().trailingZerosTrimmed)Gwei" - gasPriceTextField.text = param.gasPrice.weiToGwei().trailingZerosTrimmed - gasLimitTextField.text = param.gasLimit.description - gasPriceTextField.isEnabled = true - gasLimitTextField.isEnabled = true - } - - override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - backgroundView.alpha = 0.0 - contentView.transform = CGAffineTransform(translationX: 0, y: contentView.bounds.size.height) - UIView.animate(withDuration: CATransaction.animationDuration()) { - self.backgroundView.alpha = 1.0 - self.contentView.transform = CGAffineTransform.identity - } - } - - override func touchesEnded(_ touches: Set, with event: UIEvent?) { - dismiss() - } - - @IBAction func dismiss() { - UIView.animate(withDuration: CATransaction.animationDuration(), animations: { - self.backgroundView.alpha = 0.0 - self.contentView.transform = CGAffineTransform(translationX: 0, y: self.contentView.bounds.size.height) - }, completion: { (_) in - self.dismiss(animated: false, completion: nil) - }) - } - - @IBAction func confirm(_ sender: Any) { - let gasPrice = Double(gasPriceTextField.text!)! - if gasPrice < minGasPrice { - Toast.showToast(text: "您的GasPrice设置过低,建议输入推荐值以快速转账") - return - } - param.gasPrice = gasPrice.gweiToWei() - param.gasLimit = UInt64(gasLimitTextField.text!) ?? GasCalculator.defaultGasLimit - dismiss() - } -} - -extension TransactionGasPriceViewController: UITextFieldDelegate { - func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { - let character: String - if textField == gasPriceTextField { - if textField.text!.contains(".") { - character = "0123456789" - } else { - character = "0123456789." - } - } else { - character = "0123456789" - } - guard CharacterSet(charactersIn: character).isSuperset(of: CharacterSet(charactersIn: string)) else { - return false - } - return true - } -} diff --git a/Neuron/Sections/Transaction/TransactionHistoryPresenter.swift b/Neuron/Sections/Transaction/TransactionHistoryPresenter.swift deleted file mode 100644 index 4daa9147..00000000 --- a/Neuron/Sections/Transaction/TransactionHistoryPresenter.swift +++ /dev/null @@ -1,160 +0,0 @@ -// -// TransactionHistoryPresenter.swift -// Neuron -// -// Created by 晨风 on 2018/11/14. -// Copyright © 2018 Cryptape. All rights reserved. -// - -import UIKit - -protocol TransactionHistoryPresenterDelegate: NSObjectProtocol { - func didLoadTransactions(transaction: [TransactionDetails], insertions: [Int], error: Error?) - func updateTransactions(transaction: [TransactionDetails], updates: [Int], error: Error?) -} - -class TransactionHistoryPresenter: NSObject, TransactionStatusManagerDelegate { - private(set) var transactions = [TransactionDetails]() - let token: Token - typealias CallbackBlock = ([Int], Error?) -> Void - weak var delegate: TransactionHistoryPresenterDelegate? - private var hasMoreData = true - private var sentTransactions = [TransactionDetails]() - - init(token: Token) { - self.token = token - super.init() - TransactionStatusManager.manager.addDelegate(delegate: self) - } - - func reloadData(completion: CallbackBlock? = nil) { - guard !loading else { - return - } - page = 1 - hasMoreData = true - loadMoreData(completion: completion) - } - - func loadMoreData(completion: CallbackBlock? = nil) { - guard loading == false else { return } - guard hasMoreData else { - return - } - loading = true - DispatchQueue.global().async { - do { - var list = try self.loadData() - self.hasMoreData = list.count == self.pageSize - self.loading = false - if self.page == 1 { - self.transactions = [] - self.sentTransactions = TransactionStatusManager.manager.getTransactions(walletAddress: self.token.walletAddress, tokenType: self.token.type, tokenAddress: self.token.address, chainHosts: self.token.chainHosts) - } - self.page += 1 - - // merge - list = self.mergeSentTransactions(from: list) - list.forEach({ (trans) in - trans.token = self.token - }) - - var insertions = [Int]() - for idx in list.indices { - insertions.append(self.transactions.count + idx) - } - - self.transactions.append(contentsOf: list) - DispatchQueue.main.async { - completion?(insertions, nil) - self.delegate?.didLoadTransactions(transaction: self.transactions, insertions: insertions, error: nil) - } - } catch { - DispatchQueue.main.async { - completion?([], error) - self.delegate?.didLoadTransactions(transaction: self.transactions, insertions: [], error: error) - } - } - } - } - - // MARK: - Merge - private func mergeSentTransactions(from list: [TransactionDetails]) -> [TransactionDetails] { - var newList = [TransactionDetails]() - list.forEach { (trans) in - if !newList.contains(where: { $0.hash == trans.hash }) { - newList.append(trans) - } - } - - // Date range - let maxDate: Date = self.transactions.first?.date ?? Date.distantFuture - let minDate: Date - if self.hasMoreData { - minDate = newList.last?.date ?? Date.distantPast - } else { - minDate = Date.distantPast - } - let sentTransactions = self.sentTransactions - let sentList = sentTransactions.filter({ (sentTransaction) -> Bool in - // merge status - if let transaction = newList.first(where: { $0.hash == sentTransaction.hash }) { - self.sentTransactions.removeAll(where: { $0.hash == sentTransaction.hash }) - transaction.status = sentTransaction.status - return false - } - if sentTransaction.date < maxDate && sentTransaction.date > minDate { - self.sentTransactions.removeAll(where: { $0.hash == sentTransaction.hash }) - return true - } else { - return false - } - }) - return (newList + sentList).sorted(by: { $0.date > $1.date }) - } - - // MARK: - Load transactions - private var loading = false - private var page: UInt = 1 - private var pageSize: UInt = 10 - - private func loadData() throws -> [TransactionDetails] { - switch token.type { - case .appChain: - if token.symbol == "NATT" { - return try AppChainNetwork().getTransactionHistory(walletAddress: token.walletAddress, page: page, pageSize: pageSize) - } else { - return [] - } - case .ether: - return try EthereumNetwork().getTransactionHistory(walletAddress: token.walletAddress, page: page, pageSize: pageSize) - case .erc20: - return try EthereumNetwork().getErc20TransactionHistory(walletAddress: token.walletAddress, tokenAddress: token.address, page: page, pageSize: pageSize) - case .appChainErc20: - return try AppChainNetwork().getErc20TransactionHistory(walletAddress: token.walletAddress, tokenAddress: token.address, page: page, pageSize: pageSize) - } - } - - // MARK: - TransactionStatusManagerDelegate - func sentTransactionInserted(transaction: TransactionDetails) { - guard transaction.from == token.walletAddress else { - return - } - DispatchQueue.main.async { - transaction.token = self.token - self.transactions.insert(transaction, at: 0) - self.delegate?.didLoadTransactions(transaction: self.transactions, insertions: [0], error: nil) - } - } - - func sentTransactionStatusChanged(transaction: TransactionDetails) { - if let idx = transactions.firstIndex(where: { $0.hash == transaction.hash }) { - DispatchQueue.main.async { - transaction.token = self.token - self.transactions.remove(at: idx) - self.transactions.insert(transaction, at: idx) - self.delegate?.updateTransactions(transaction: self.transactions, updates: [idx], error: nil) - } - } - } -} diff --git a/Neuron/Sections/Transaction/Views/TradeTableViewCell.swift b/Neuron/Sections/Transaction/Views/TradeTableViewCell.swift deleted file mode 100644 index 5b948fab..00000000 --- a/Neuron/Sections/Transaction/Views/TradeTableViewCell.swift +++ /dev/null @@ -1,55 +0,0 @@ -// -// TradeTableViewCell.swift -// Neuron -// -// Created by XiaoLu on 2018/5/25. -// Copyright © 2018年 cryptape. All rights reserved. -// - -import UIKit - -class TradeTableViewCell: UITableViewCell { - var titleStr: String? { - didSet { - titleLabel.text = titleStr - } - } - var subTitleStr: String? { - didSet { - subButton.setTitle(subTitleStr, for: .normal) - } - } - var ethOrNervos: String = "" - var selectIndex: NSIndexPath? { - didSet { - if ethOrNervos == "ETH" { - if selectIndex?.row == 1 || selectIndex?.row == 2 || selectIndex?.row == 5 { - subButton.setImage(UIImage(named: "copy"), for: .normal) - subButton.setTitleColor(UIColor(hex: "#2e4af2"), for: .normal) - } else { - subButton.isEnabled = false - } - } else if ethOrNervos == "Nervos" { - if selectIndex?.row == 1 || selectIndex?.row == 2 || selectIndex?.row == 4 { - subButton.setImage(UIImage(named: "copy"), for: .normal) - subButton.setTitleColor(UIColor(hex: "#2e4af2"), for: .normal) - } else { - subButton.isEnabled = false - } - } - } - } - @IBOutlet weak var titleLabel: UILabel! - @IBOutlet weak var subButton: UIButton! - override func awakeFromNib() { - super.awakeFromNib() - } - - @IBAction func didClickSubButton(_ sender: UIButton) { - UIPasteboard.general.string = subTitleStr - Toast.showToast(text: "复制成功") - } - override func setSelected(_ selected: Bool, animated: Bool) { - super.setSelected(selected, animated: animated) - } -} diff --git a/Neuron/Sections/Transaction/Views/TradeTableViewCell.xib b/Neuron/Sections/Transaction/Views/TradeTableViewCell.xib deleted file mode 100644 index d69bd206..00000000 --- a/Neuron/Sections/Transaction/Views/TradeTableViewCell.xib +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Neuron/Sections/Transaction/Views/TransactionTableviewCell.swift b/Neuron/Sections/Transaction/Views/TransactionTableviewCell.swift deleted file mode 100644 index eeaf8f4d..00000000 --- a/Neuron/Sections/Transaction/Views/TransactionTableviewCell.swift +++ /dev/null @@ -1,29 +0,0 @@ -// -// Sub3TableViewCell.swift -// Neuron -// -// Created by XiaoLu on 2018/5/25. -// Copyright © 2018年 cryptape. All rights reserved. -// - -import UIKit - -class TransactionTableviewCell: UITableViewCell { - - @IBOutlet weak var iconImageV: UIImageView! - @IBOutlet weak var addressLabel: UILabel! - @IBOutlet weak var networkLabel: UILabel! - @IBOutlet weak var dateLabel: UILabel! - @IBOutlet weak var exchangeLabel: UILabel! - @IBOutlet weak var statusImageView: UIImageView! - override func awakeFromNib() { - super.awakeFromNib() - let walletModel = AppModel.current.currentWallet - iconImageV.image = UIImage(data: (walletModel?.iconData)!) - } - - override func setSelected(_ selected: Bool, animated: Bool) { - super.setSelected(selected, animated: animated) - - } -} diff --git a/Neuron/Sections/Wallet/AddWallet/SureMnemonicViewController.swift b/Neuron/Sections/Wallet/AddWallet/SureMnemonicViewController.swift deleted file mode 100644 index 049216e7..00000000 --- a/Neuron/Sections/Wallet/AddWallet/SureMnemonicViewController.swift +++ /dev/null @@ -1,108 +0,0 @@ -// -// SureMnemonicViewController.swift -// Neuron -// -// Created by XiaoLu on 2018/6/1. -// Copyright © 2018年 cryptape. All rights reserved. -// - -import UIKit - -class VerifyMnemonicViewController: UIViewController, ButtonTagViewDelegate, ButtonTagUpViewDelegate, SureMnemonicViewModelDelegate, NoScreenshot, EnterBackOverlayPresentable { - private var showView: ButtonTagView! = nil - private var selectView: ButtonTagUpView! = nil - private var selectArray: [String] = [] - - let sureButton = UIButton.init(type: .custom) - - private var titleArr: [String] = [] - var viewModel = SureMnemonicViewModel() - var password = "" - var mnemonic: String? { - didSet { - titleArr = (mnemonic?.components(separatedBy: " "))! - } - } - - var walletModel = WalletModel() { - didSet { - viewModel.walletModel = walletModel - } - } - - override func viewDidLoad() { - super.viewDidLoad() - title = "确认助记词" - didDrawSubViews() - viewModel.delegate = self - setupEnterBackOverlay() - } - - override func viewDidAppear(_ animated: Bool) { - super.viewDidAppear(animated) - showNoScreenshotAlert(titile: "禁止截屏!", message: "拥有助记词就能完全控制该地址下的资产,建议抄写并放在安全的地方!") - } - - func didDrawSubViews() { - selectView = ButtonTagUpView(frame: CGRect(x: 15, y: 15 + 35, width: ScreenSize.width - 30, height: 150)) - selectView.delegate = self - view.addSubview(selectView) - - showView = ButtonTagView(frame: CGRect(x: 15, y: 15 + 35 + 15 + 150, width: ScreenSize.width - 30, height: 150)) - showView.delegate = self - showView.titleArray = titleArr.shuffled() - showView.backgroundColor = .white - view.addSubview(showView) - - sureButton.frame = CGRect(x: 15, y: showView.frame.origin.y + showView.frame.size.height + 20, width: ScreenSize.width - 30, height: 44) - sureButton.backgroundColor = ColorFromString(hex: "#f2f2f2") - sureButton.setTitleColor(ColorFromString(hex: "#999999"), for: .normal) - sureButton.setTitle("完成备份", for: .normal) - sureButton.addTarget(self, action: #selector(didCompletBackupMnemonic), for: .touchUpInside) - sureButton.layer.cornerRadius = 5 - view.addSubview(sureButton) - } - - //选择按钮的时候返回的选择的数组 - func callBackSelectButtonArray(array: [NSMutableDictionary]) { - selectView.comArr = array - selectArray.removeAll() - for name in array { - selectArray.append(name.value(forKey: "buttonTitle") as! String) - } - if selectArray.count == 12 { - sureButton.isEnabled = true - sureButton.backgroundColor = AppColor.themeColor - sureButton.setTitleColor(.white, for: .normal) - } else { - sureButton.isEnabled = false - sureButton.backgroundColor = ColorFromString(hex: "#f2f2f2") - sureButton.setTitleColor(ColorFromString(hex: "#999999"), for: .normal) - } - } - - //点击删除按钮的时候 下方按钮改变选中状态 - func didDeleteSelectedButton(backDict: NSMutableDictionary) { - showView.deleteDict = backDict - selectArray = selectArray.filter({ (title) -> Bool in - return backDict.value(forKey: "buttonTitle") as! String != title - }) - } - - @objc func didCompletBackupMnemonic() { - if selectArray.count != titleArr.count { - Toast.showToast(text: "助记词验证失败") - return - } - let originalMnemonic = titleArr.joined() - let selectMnemonic = selectArray.joined() - let success = viewModel.compareMnemonic(original: originalMnemonic, current: selectMnemonic) - if success { - viewModel.importWallet(mnemonic: mnemonic!, password: password) - } - } - - func doPush() { - navigationController?.popToRootViewController(animated: true) - } -} diff --git a/Neuron/Sections/Wallet/Assets/AddAssetController.swift b/Neuron/Sections/Wallet/Assets/AddAssetController.swift deleted file mode 100644 index d8d4b41e..00000000 --- a/Neuron/Sections/Wallet/Assets/AddAssetController.swift +++ /dev/null @@ -1,166 +0,0 @@ -// -// AddAssetController.swift -// Neuron -// -// Created by XiaoLu on 2018/5/24. -// Copyright © 2018年 cryptape. All rights reserved. -// - -import UIKit -import RealmSwift - -class AddAssetController: UIViewController, UITableViewDelegate, UITableViewDataSource, AddAssetTableViewCellDelegate, NEPickerViewDelegate, QRCodeViewControllerDelegate { - let titleArray = ["区块链", "合约地址", "代币名称", "代币缩写", "小数位数"] - let placeholderArray = ["", "合约地址", "代币名称", "代币缩写", "小数位数"] - - let nView = NEPickerView.init() - var tokenArray: [TokenModel] = [] - @IBOutlet weak var addButton: UIButton! - @IBOutlet weak var aTable: UITableView! - var tokenModel = TokenModel() - - override func viewDidLoad() { - super.viewDidLoad() - title = "添加资产" - view.backgroundColor = UIColor(hex: "f5f5f5") - aTable.delegate = self - aTable.dataSource = self - aTable.register(UINib.init(nibName: "AddAssetTableViewCell", bundle: nil), forCellReuseIdentifier: "ID") - - aTable.tableHeaderView = UIView.init(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: CGFloat.leastNormalMagnitude)) - - } - - @IBAction func didClickAddButton(_ sender: UIButton) { - Toast.hideHUD() - if tokenModel.address.count != 40 && tokenModel.address.count != 42 { - Toast.showToast(text: "请输入正确的合约地址") - return - } - if tokenModel.name.isEmpty || tokenModel.symbol.isEmpty || String(tokenModel.decimals).isEmpty { - Toast.showToast(text: "Token信息不全,请核对合约地址是否正确") - return - } - if tokenArray.contains(where: { $0.address.lowercased() == tokenModel.address.lowercased() }) { - Toast.showToast(text: "不可重复添加") - return - } - let appModel = AppModel.current - tokenModel.address = tokenModel.address.addHexPrefix() - tokenModel.isNativeToken = false - if let id = TokenModel.identifier(for: tokenModel) { - tokenModel.identifier = id - } - let realm = try! Realm() - try? realm.write { - realm.add(tokenModel, update: true) - appModel.extraTokenList.append(tokenModel) - appModel.currentWallet?.selectTokenList.append(tokenModel) - } - navigationController?.popViewController(animated: true) - } - //tableview代理 - func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { - return 10 - } - - func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return 5 - } - - func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCell(withIdentifier: "ID", for: indexPath) as! AddAssetTableViewCell - cell.delegate = self - cell.indexP = indexPath as NSIndexPath - cell.headLabel.text = titleArray[indexPath.row] - cell.placeHolderStr = placeholderArray[indexPath.row] - cell.selectRow = indexPath.row - if indexPath.row == 0 { - cell.rightTextField.text = "以太坊" - } - cell.selectionStyle = .none - - switch indexPath.row { - case 0: - cell.rightTextField.text = "以太坊" - case 1: - cell.rightTextField.text = tokenModel.address - case 2: - cell.isEdit = false - cell.rightTextField.text = tokenModel.name - case 3: - cell.isEdit = false - cell.rightTextField.text = tokenModel.symbol - case 4: - cell.isEdit = false - cell.rightTextField.text = tokenModel.decimals == 0 ? "0" : String(tokenModel.decimals) - default: - break - } - return cell - } - - func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? { - return nil - } - - func didClickSelectCoinBtn() { - nView.frame = CGRect(origin: .zero, size: UIScreen.main.bounds.size) - nView.delegate = self - nView.dataArray = [["name": "以太坊eth", "id": "100"], ["name": "test-chain", "id": "101"]] - nView.selectDict = ["name": "以太坊eth", "id": "100"] - UIApplication.shared.keyWindow?.addSubview(nView) - } - - func callBackDictionnary(dict: [String: String]) { - } - - func didClickQRCodeBtn() { - let qrCodeViewController = QRCodeViewController() - qrCodeViewController.delegate = self - self.navigationController?.pushViewController(qrCodeViewController, animated: true) - } - - func didBackQRCodeMessage(codeResult: String) { - tokenModel.address = "" - let finalText = codeResult.replacingOccurrences(of: " ", with: "") - tokenModel.address = finalText - if finalText.count == 40 || finalText.count == 42 { - didGetERC20Token(token: finalText) - } - aTable.reloadData() - } - - func didGetTextFieldTextWithIndexAndText(text: String, index: NSIndexPath) { - let finalText = text.replacingOccurrences(of: " ", with: "") - tokenModel.address = finalText - if index.row == 1 { - if finalText.count == 40 || finalText.count == 42 { - didGetERC20Token(token: finalText) - } else { - } - } - } - - func didGetERC20Token(token: String) { - tokenModel.name = "" - tokenModel.symbol = "" - tokenModel.decimals = 0 - - let walletAddress = AppModel.current.currentWallet!.address - Toast.showHUD() - DispatchQueue.global().async { - let result = try? CustomERC20TokenService.searchTokenData(contractAddress: token, walletAddress: walletAddress) - DispatchQueue.main.async { - Toast.hideHUD() - if let tokenModel = result { - self.tokenModel = tokenModel - self.tokenModel.address = token - } else { - Toast.showToast(text: "未查询到代币信息,请核对合约地址是否正确") - } - self.aTable.reloadData() - } - } - } -} diff --git a/Neuron/Sections/Wallet/Assets/Assets.storyboard b/Neuron/Sections/Wallet/Assets/Assets.storyboard deleted file mode 100644 index 98025e99..00000000 --- a/Neuron/Sections/Wallet/Assets/Assets.storyboard +++ /dev/null @@ -1,228 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Neuron/Sections/Wallet/Assets/ManageAssetViewController.swift b/Neuron/Sections/Wallet/Assets/ManageAssetViewController.swift deleted file mode 100644 index 8ec1a497..00000000 --- a/Neuron/Sections/Wallet/Assets/ManageAssetViewController.swift +++ /dev/null @@ -1,130 +0,0 @@ -// -// ManageAssetViewController.swift -// Neuron -// -// Created by XiaoLu on 2018/5/23. -// Copyright © 2018年 cryptape. All rights reserved. -// - -import UIKit -import RealmSwift - -class ManageAssetViewController: UITableViewController, AssetTableViewCellDelegate { - var dataArray: [TokenModel] = [] - var selectArr: List? - var selectAddressArray: [String] = [] - - override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - didGetDataForList() - } - - override func viewDidLoad() { - super.viewDidLoad() - title = "ERC20列表" - } - - override func prepare(for segue: UIStoryboardSegue, sender: Any?) { - if segue.identifier == "AddAssetController" { - let controller = segue.destination as! AddAssetController - controller.tokenArray = dataArray - } - } - - func didGetDataForList() { - selectAddressArray.removeAll() - dataArray = getAssetListFromJSON() - selectArr = getSelectAsset() - for tokenItem in selectArr! { - selectAddressArray.append(tokenItem.address) - } - tableView.reloadData() - } - - func getAssetListFromJSON() -> [TokenModel] { - var tokenArray: [TokenModel] = [] - - let appModel = AppModel.current - let realm = try! Realm() - for tModel in appModel.extraTokenList { - try? realm.write { - realm.add(tModel, update: true) - } - tokenArray.append(tModel) - } - - let path = Bundle.main.path(forResource: "tokens-eth", ofType: "json")! - guard let jsonData = try? Data(contentsOf: URL(fileURLWithPath: path)) else { return [] } - guard let tokens = try? JSONDecoder().decode([TokenModel].self, from: jsonData) else { return [] } - - for token in tokens { - token.iconUrl = token.logo?.src ?? "" - tokenArray.append(token) - } - return tokenArray - } - - func getSelectAsset() -> List? { - let appModel = AppModel.current - return appModel.currentWallet?.selectTokenList - } - - override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return dataArray.count - } - - override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCell(withIdentifier: "assetTableviewCell") as! AssetTableViewCell - cell.delegate = self - let tokenModel = dataArray[indexPath.row] - cell.iconUrlStr = tokenModel.iconUrl - cell.symbolLabel.text = tokenModel.name - cell.addressLabel.text = tokenModel.address - cell.nameLabel.text = tokenModel.symbol - cell.selectionStyle = .none - cell.isSelected = selectAddressArray.contains(tokenModel.address) - - return cell - } - - func selectAsset(_ assetTableViewCell: UITableViewCell, didSelectAsset switch: UISwitch) { - let index = tableView.indexPath(for: assetTableViewCell)! - let model = dataArray[index.row] - selectedAsset(model: model) - } - - func selectedAsset(model: TokenModel) { - if selectAddressArray.contains(model.address) { - deleteSelectedToken(tokenM: model) - selectAddressArray = selectAddressArray.filter({ (item) -> Bool in - return item == model.address - }) - } else { - addSelectToken(tokenM: model) - } - didGetDataForList() - } - - func deleteSelectedToken(tokenM: TokenModel) { - let appModel = AppModel.current - let filterResult = appModel.currentWallet?.selectTokenList.filter("address = %@", tokenM.address) - let realm = try! Realm() - try? realm.write { - realm.add(tokenM, update: true) - filterResult?.forEach({ (tm) in - if let index = appModel.currentWallet?.selectTokenList.index(of: tm) { - appModel.currentWallet?.selectTokenList.remove(at: index) - } - }) - } - } - - func addSelectToken(tokenM: TokenModel) { - let appModel = AppModel.current - let realm = try! Realm() - try? realm.write { - realm.add(tokenM, update: true) - appModel.currentWallet?.selectTokenList.append(tokenM) - } - } -} diff --git a/Neuron/Sections/Wallet/TableViewCell/AddAssetTableViewCell.swift b/Neuron/Sections/Wallet/TableViewCell/AddAssetTableViewCell.swift deleted file mode 100644 index f727169f..00000000 --- a/Neuron/Sections/Wallet/TableViewCell/AddAssetTableViewCell.swift +++ /dev/null @@ -1,122 +0,0 @@ -// -// AddAssetTableViewCell.swift -// Neuron -// -// Created by XiaoLu on 2018/5/24. -// Copyright © 2018年 cryptape. All rights reserved. -// - -import UIKit - -@objc protocol AddAssetTableViewCellDelegate: NSObjectProtocol { - @objc optional func didClickSelectCoinBtn()//点击选择币种 - @objc optional func didClickQRCodeBtn()//点击扫码 - func didGetTextFieldTextWithIndexAndText(text: String, index: NSIndexPath) -} - -class AddAssetTableViewCell: UITableViewCell, UITextFieldDelegate { - - weak var delegate: AddAssetTableViewCellDelegate? - - //是否是密文 - var isSecretText: Bool = false {didSet {rightTextField.isSecureTextEntry = isSecretText}} - var isEdit: Bool = true {didSet {rightTextField.isEnabled = isEdit}} - var isOnlyNumberAndPoint: Bool = false - - var indexP = NSIndexPath.init() - // 设置属性来确定不同的cell有不同的状态 - var _selectRow: NSInteger = 0 - let placeholserAttributes = [NSAttributedString.Key.foregroundColor: UIColor(hex: "#999999"), NSAttributedString.Key.font: UIFont.systemFont(ofSize: 15)] - - let firstBtn = UIButton.init(type: .custom) - let secBtn = UIButton.init(type: .custom) - - @IBOutlet weak var headLabel: UILabel! - @IBOutlet weak var rightTextField: UITextField! - - override func awakeFromNib() { - super.awakeFromNib() - //监听textfield.text - rightTextField.addTarget(self, action: #selector(textFieldTextChanged(textField:)), for: .editingChanged) - rightTextField.delegate = self - } - - //重写set方法 - var placeHolderStr: String? { - didSet { - rightTextField.attributedPlaceholder = NSAttributedString(string: placeHolderStr!, attributes: placeholserAttributes) - } - } - var selectRow: NSInteger = 0 {//传入0就是下拉样式 传入1就是点击二维码 - didSet { - if selectRow == 0 { - rightTextField.rightViewMode = .always - rightTextField.tag = 3000 // 根据tag来跟别的textfield区分 - } else if selectRow == 1 { - rightTextField.rightViewMode = .always - secBtn.setImage(UIImage.init(named: "qr_code"), for: .normal) - secBtn.imageEdgeInsets = UIEdgeInsets(top: 0, left: 15, bottom: 0, right: -15) - secBtn.frame = CGRect(x: 0, y: 0, width: 50, height: 50) - rightTextField.tag = 3002 // 根据tag来跟别的textfield区分 - secBtn.addTarget(self, action: #selector(didPushQRCodeView), for: .touchUpInside) - rightTextField.rightView = secBtn - } else { - rightTextField.rightViewMode = .never -// rightTextField.removeGestureRecognizer(tap) - rightTextField.tag = 3001 - } - } - } - - @objc func textFieldTextChanged(textField: UITextField) { - delegate?.didGetTextFieldTextWithIndexAndText(text: textField.text!, index: indexP) - } - - //点击第一行按钮弹出pickerview选择币种 - @objc func didSetUpPickView() { - delegate?.didClickSelectCoinBtn!() - } - //点击第二行按钮跳转扫描二维码界面 - @objc func didPushQRCodeView() { - delegate?.didClickQRCodeBtn!() - } - - @objc func textFieldValueChange() { - - } - - //textfidel代理 - func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool { - if textField.tag == 3000 { - return false - } else { - return true - } - } - - func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { - if isOnlyNumberAndPoint { - guard CharacterSet(charactersIn: "0123456789.").isSuperset(of: CharacterSet(charactersIn: string)) else { - return false - } - if textField.text?.first == "." { - textField.text = "0." - return true - } - if (textField.text?.contains("."))! && string == "." { - return false - } - return true - } else { - return true - } - - } - - override func setSelected(_ selected: Bool, animated: Bool) { - super.setSelected(selected, animated: animated) - } - deinit { - - } -} diff --git a/Neuron/Sections/Wallet/TableViewCell/AddAssetTableViewCell.xib b/Neuron/Sections/Wallet/TableViewCell/AddAssetTableViewCell.xib deleted file mode 100644 index 7161a7c5..00000000 --- a/Neuron/Sections/Wallet/TableViewCell/AddAssetTableViewCell.xib +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Neuron/Services/AppChain/AppChain+TransactionStatus.swift b/Neuron/Services/AppChain/AppChain+TransactionStatus.swift deleted file mode 100644 index 1da35748..00000000 --- a/Neuron/Services/AppChain/AppChain+TransactionStatus.swift +++ /dev/null @@ -1,44 +0,0 @@ -// -// AppChain+TransactionStatus.swift -// Neuron -// -// Created by 晨风 on 2018/11/16. -// Copyright © 2018 Cryptape. All rights reserved. -// - -import Foundation -import Alamofire -import PromiseKit -import AppChain - -extension AppChainNetwork { - func getTransactionStatus(sentTransaction: SentTransaction) -> TransactionStateResult { - do { - let currentBlockNumber = try AppChainNetwork.appChain().rpc.blockNumber() - if let receipt = try? AppChainNetwork.appChain().rpc.getTransactionReceipt(txhash: sentTransaction.txHash) { - if let error = receipt.errorMessage { - print(error) - return .failure - } else { - if let transaction = try? AppChainNetwork().getTransaction(txhash: sentTransaction.txHash, account: sentTransaction.from, from: sentTransaction.from, to: sentTransaction.to) { - return .success(transaction: transaction) - } else { - if sentTransaction.blockNumber < currentBlockNumber { - return .failure - } else { - return .pending - } - } - } - } else { - if sentTransaction.blockNumber < currentBlockNumber { - return .failure - } else { - return .pending - } - } - } catch { - return .pending - } - } -} diff --git a/Neuron/Services/AppChain/AppChainNetwork.swift b/Neuron/Services/AppChain/AppChainNetwork.swift deleted file mode 100644 index ce01c3cb..00000000 --- a/Neuron/Services/AppChain/AppChainNetwork.swift +++ /dev/null @@ -1,23 +0,0 @@ -// -// AppChainNetwork.swift -// Neuron -// -// Created by XiaoLu on 2018/7/31. -// Copyright © 2018年 cryptape. All rights reserved. -// - -import Foundation -import AppChain - -struct AppChainNetwork { - private static let defaultNode = "http://121.196.200.225:1337" - - static func appChain(url: URL? = URL(string: defaultNode)!) -> AppChain { - let url = url == nil ? URL(string: defaultNode)! : url! - return AppChain(provider: HTTPProvider(url)!) - } - - func host() -> URL { - return URL(string: "https://microscope.cryptape.com:8888")! - } -} diff --git a/Neuron/Services/AppChain/AppChainTxSender.swift b/Neuron/Services/AppChain/AppChainTxSender.swift deleted file mode 100644 index 781f1fce..00000000 --- a/Neuron/Services/AppChain/AppChainTxSender.swift +++ /dev/null @@ -1,82 +0,0 @@ -// -// AppChainTxSender.swift -// Neuron -// -// Created by James Chen on 2018/11/06. -// Copyright © 2018 Cryptape. All rights reserved. -// - -import Foundation -import AppChain -import BigInt - -class AppChainTxSender { - private let appChain: AppChain - private let walletManager: WalletManager - private let from: Address - - init(appChain: AppChain, walletManager: WalletManager, from: String) throws { - self.appChain = appChain - self.walletManager = walletManager - guard let fromAddress = Address(from) else { - throw SendTransactionError.invalidSourceAddress - } - self.from = fromAddress - } - - func send( - to: String, - value: BigUInt, - quota: UInt64 = GasCalculator.defaultGasLimit, - data: Data, - chainId: BigUInt, - password: String - ) throws -> TxHash { - let destinationEthAddress = Address(to.addHexPrefix()) - if !to.isEmpty && destinationEthAddress == nil { - throw SendTransactionError.invalidDestinationAddress - } - - guard let meta = try? appChain.rpc.getMetaData() else { - throw SendTransactionError.createTransactionIssue - } - guard let blockNumber = try? appChain.rpc.blockNumber() else { - throw SendTransactionError.createTransactionIssue - } - if chainId.description != meta.chainId { - throw SendTransactionError.invalidChainId - } - - let transaction = Transaction( - to: destinationEthAddress, - nonce: UUID().uuidString, - quota: quota, - validUntilBlock: blockNumber + UInt64(88), - data: data, - value: value, - chainId: meta.chainId, - version: meta.version - ) - let signed = try sign(transaction: transaction, password: password) - let txHash = try appChain.rpc.sendRawTransaction(signedTx: signed) - let sentTransaction = SentTransaction(tokenType: .appChain, from: from.address, hash: txHash, transaction: transaction, chainHosts: appChain.provider.url.absoluteString) - TransactionStatusManager.manager.insertTransaction(transaction: sentTransaction) - return txHash - } - - func sendToken(transaction: Transaction, password: String) throws -> TxHash { - let signed = try sign(transaction: transaction, password: password) - return try appChain.rpc.sendRawTransaction(signedTx: signed) - } - - func sign(transaction: Transaction, password: String) throws -> String { - guard let wallet = walletManager.wallet(for: from.address) else { - throw SendTransactionError.noAvailableKeys - } - let privateKey = try walletManager.exportPrivateKey(wallet: wallet, password: password) - guard let signed = try? Signer().sign(transaction: transaction, with: privateKey) else { - throw SendTransactionError.signTXFailed - } - return signed - } -} diff --git a/Neuron/Services/AppChain/NervosNativeTokenService.swift b/Neuron/Services/AppChain/NervosNativeTokenService.swift deleted file mode 100644 index 2aab6293..00000000 --- a/Neuron/Services/AppChain/NervosNativeTokenService.swift +++ /dev/null @@ -1,28 +0,0 @@ -// -// NervosNativeTokenService.swift -// Neuron -// -// Created by XiaoLu on 2018/7/31. -// Copyright © 2018年 cryptape. All rights reserved. -// - -import Foundation -import AppChain -import BigInt - -struct NervosNativeTokenService { - static func getNervosNativeTokenMsg(blockNumber: String = "latest") throws -> TokenModel { - let appChain = AppChainNetwork.appChain() - let metaData = try appChain.rpc.getMetaData(blockNumber: blockNumber) - let tokenModel = TokenModel() - tokenModel.address = "" - tokenModel.chainId = metaData.chainId.description - tokenModel.chainName = metaData.chainName - tokenModel.iconUrl = metaData.tokenAvatar - tokenModel.isNativeToken = true - tokenModel.name = metaData.tokenName - tokenModel.symbol = metaData.tokenSymbol - tokenModel.decimals = NativeDecimals.nativeTokenDecimals - return tokenModel - } -} diff --git a/Neuron/Services/Common/SensorsAnalytics.swift b/Neuron/Services/Common/SensorsAnalytics.swift deleted file mode 100644 index 8fc13bd7..00000000 --- a/Neuron/Services/Common/SensorsAnalytics.swift +++ /dev/null @@ -1,203 +0,0 @@ -// -// SensorsAnalyticsService.swift -// Neuron -// -// Created by 晨风 on 2018/10/12. -// Copyright © 2018 Cryptape. All rights reserved. -// - -import Foundation -import SensorsAnalyticsSDK - -class SensorsAnalytics { - enum UserDefaultsKey: String { - case userId = "SensorsAnalyticsUserIdUserDefaultsKey" - case ipId = "SensorsAnalyticsIpIdUserDefaultsKey" - } - fileprivate let sensors: SensorsAnalyticsSDK - static let service = SensorsAnalytics() - - private init() { - #if DEBUG - sensors = SensorsAnalyticsSDK.sharedInstance(withServerURL: "https://banana.cryptape.com:8106/sa?project=default", andDebugMode: .andTrack) - #else - sensors = SensorsAnalyticsSDK.sharedInstance(withServerURL: "https://banana.cryptape.com:8106/sa?project=production", andDebugMode: .off) - #endif - sensors.enableLog(false) - sensors.registerSuperProperties(["platformType": "iOS", "ip_id": getIpId(), "$ip": ""]) - let eventType: SensorsAnalyticsAutoTrackEventType = [ - .eventTypeAppStart, - .eventTypeAppEnd, - .eventTypeAppViewScreen, - .eventTypeAppClick - ] - sensors.enableAutoTrack(eventType) - sensors.enableTrackGPSLocation(false) - sensors.enableTrackScreenOrientation(false) - sensors.login(getUserId()) - sensors.trackAppCrash() - - if var automaticProperties = sensors.value(forKey: "automaticProperties") as? [String: Any] { - automaticProperties["$device_id"] = "" - sensors.setValue(automaticProperties, forKey: "automaticProperties") - } - } - - static func configureSensors() { - _ = SensorsAnalytics.service - } - - func track(event: String, with properties: [String: Any]) { - sensors.track(event, withProperties: properties) - } - - private func getUserId() -> String { - if let userId = UserDefaults.standard.string(forKey: UserDefaultsKey.userId.rawValue) { - return userId - } - var userId = "" - for _ in 0...50 { - userId += "\(arc4random_uniform(10))" - } - userId += "\(Int(Date().timeIntervalSince1970 * 1000))" - UserDefaults.standard.set(userId, forKey: UserDefaultsKey.userId.rawValue) - return userId - } - - private func getIpId() -> String { - if let ipId = UserDefaults.standard.string(forKey: UserDefaultsKey.ipId.rawValue) { - return ipId - } - var ipId = "" - for _ in 0..<64 { - ipId += "\(arc4random_uniform(10))" - } - UserDefaults.standard.set(ipId, forKey: UserDefaultsKey.ipId.rawValue) - return ipId - } -} - -extension SensorsAnalytics { - enum ImportType: String { - case keystore = "1" - case mnemonic = "2" - case privateKey = "3" - } - - enum TransactionType: String { - case normal = "2" - case dApp = "1" - } - - enum ScanQRCodeType: String { - case none = "0" - case walletAddress = "1" - case privateKey = "2" - case keystore = "3" - case mnemonic = "4" - } - - class Track { - private init() { } - - fileprivate static func track(event: String, with properties: [String: Any]) { - SensorsAnalytics.service.track(event: event, with: properties) - } - - static func createWallet(address: String) { - track(event: "createWallet", with: ["create_address": address]) - } - - static func importWallet(type: ImportType, address: String?) { - track(event: "inputWallet", with: [ - "input_type": type.rawValue, - "input_result": address != nil, - "input_address": address ?? "" - ]) - } - - static func transaction(chainType: String, currencyType: String, currencyNumber: Double, receiveAddress: String, outcomeAddress: String, transactionType: TransactionType) { - track(event: "transfer_accounts", with: [ - "target_chain": chainType, - "target_currency": currencyType, - "target_currency_number": currencyNumber, - "receive_address": receiveAddress, - "outcome_address": outcomeAddress, - "transfer_type": transactionType.rawValue - ]) - } - - static func possessMoney(chainType: String, currencyType: String, currencyNumber: Double) { - track(event: "possess_money", with: [ - "currency_chain": chainType, - "currency_type": currencyType, - "currency_number": currencyNumber - ]) - } - - static func scanQRCode(scanType: ScanQRCodeType, scanResult: Bool) { - track(event: "scanQRcode", with: ["scan_type": scanType.rawValue, "scan_result": scanResult]) - } - - static func error(pageTitle: String, errorName: String, errorType: String, errorContent: String) { - track(event: "error", with: [ - "error_title": pageTitle, - "error_name": errorName, - "error_type": errorType, - "error_content": errorContent - ]) - } - } -} - -extension SensorsAnalytics.Track { - class DApp { - private init() { } - private static var startUseDates = [String: TimeInterval]() - - static func clickBanner(index: Int, name: String, chain: String, category: String) { - SensorsAnalytics.Track.track(event: "DApp_banner", with: [ - "banner_list": "\(index)", - "DApp_name": name, - "DApp_chain": chain, - "DApp_category": category - ]) - } - - static func clickButton(name: String, chain: String, category: String) { - SensorsAnalytics.Track.track(event: "DApp_button", with: [ - "DApp_name": name, - "DApp_chain": chain, - "DApp_category": category - ]) - } - - static func clickList(name: String, chain: String, category: String) { - SensorsAnalytics.Track.track(event: "DApp_list", with: [ - "DApp_name": name, - "DApp_chain": chain, - "DApp_category": category - ]) - } - - static func enterDetails(chain: String, category: String) { - SensorsAnalytics.Track.track(event: "DApp_Details", with: ["DApp_chain": chain, "DApp_category": category]) - } - - static func startUsing(name: String, chain: String, category: String) { - startUseDates["\(name)_\(chain)_\(category)"] = CACurrentMediaTime() - } - - static func stopUsing(name: String, chain: String, category: String) { - let useTimeKey = "\(name)_\(chain)_\(category)" - guard let startDate = startUseDates[useTimeKey] else { return } - startUseDates.removeValue(forKey: useTimeKey) - SensorsAnalytics.Track.track(event: "DApp_usetime", with: [ - "DApp_time": CACurrentMediaTime() - startDate, - "DApp_name": name, - "DApp_chain": chain, - "DApp_category": category - ]) - } - } -} diff --git a/Neuron/Services/Common/SentTransaction.swift b/Neuron/Services/Common/SentTransaction.swift deleted file mode 100644 index f8b93ccf..00000000 --- a/Neuron/Services/Common/SentTransaction.swift +++ /dev/null @@ -1,222 +0,0 @@ -// -// SentTransaction.swift -// Neuron -// -// Created by 晨风 on 2018/11/15. -// Copyright © 2018 Cryptape. All rights reserved. -// - -import UIKit -import RealmSwift -import BigInt -import Web3swift -import AppChain - -protocol ThreadSafeObject { -} - -private var threadSafeReferenceAssiciationKey: Int = 0 -private var realmConfigurationAssiciationKey: Int = 0 -private var realmThreadAssiciationKey: Int = 0 -extension ThreadSafeObject where Self: Object { - private var threadSafeReference: ThreadSafeReference? { - return objc_getAssociatedObject(self, &threadSafeReferenceAssiciationKey) as? ThreadSafeReference - } - private var realmConfiguration: Realm.Configuration? { - return objc_getAssociatedObject(self, &realmConfigurationAssiciationKey) as? Realm.Configuration - } - private var realmThread: Thread? { - return objc_getAssociatedObject(self, &realmThreadAssiciationKey) as? Thread - } - var threadSafe: Self { - guard let configuration = realmConfiguration, let threadSafeReference = threadSafeReference else { - fatalError("Need to call `setupThreadSafe`") - } - guard realmThread != Thread.current else { - return self - } - let realm = try! Realm(configuration: configuration) - let object = realm.resolve(threadSafeReference)! - objc_setAssociatedObject(object, &threadSafeReferenceAssiciationKey, threadSafeReference, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) - objc_setAssociatedObject(object, &realmConfigurationAssiciationKey, configuration, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) - objc_setAssociatedObject(object, &realmThreadAssiciationKey, Thread.current, .OBJC_ASSOCIATION_ASSIGN) - return object - } - - func setupThreadSafe() { - let threadSafeReference = ThreadSafeReference(to: self) - objc_setAssociatedObject(self, &threadSafeReferenceAssiciationKey, threadSafeReference, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) - if let realm = self.realm { - objc_setAssociatedObject(self, &realmConfigurationAssiciationKey, realm.configuration, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) - } else { - fatalError("realm is nil") - } - objc_setAssociatedObject(self, &realmThreadAssiciationKey, Thread.current, .OBJC_ASSOCIATION_ASSIGN) - } -} - -class SentTransaction: Object, ThreadSafeObject { - var tokenType: TokenType { - set { - privateTokenType = newValue.rawValue - } - get { - return TokenType(rawValue: privateTokenType) ?? .appChain - } - } - @objc dynamic var contractAddress: String = "" - @objc dynamic var txHash: String = "" - var blockNumber: BigUInt { - set { - privateBlockNumber = String(newValue) - } - get { - return BigUInt(privateBlockNumber) ?? 0 - } - } - var status: TransactionState { - set { - privateStatus = newValue.rawValue - } - get { - return TransactionState(rawValue: privateStatus)! - } - } - @objc dynamic var from: String = "" - @objc dynamic var to: String = "" - var amount: BigUInt { - set { - privateAmount = String(newValue) - } - get { - return BigUInt(privateAmount) ?? 0 - } - } - var txFee: BigUInt { - set { - privateTxFee = String(newValue) - } - get { - return BigUInt(privateTxFee) ?? 0 - } - } - @objc dynamic var date: Date = Date() - @objc dynamic var ethereumNetwork: String = "" - @objc dynamic var chainHosts: String! - - @objc dynamic private var privateBlockNumber: String = "" - @objc dynamic private var privateStatus: Int = 0 - @objc dynamic private var privateAmount: String = "" - @objc dynamic private var privateTxFee: String = "" - @objc dynamic private var privateTokenType: String = "" - - - @objc override class func primaryKey() -> String? { return "txHash" } - - @objc override class func ignoredProperties() -> [String] { - return ["tokenType", "blockNumber", "status", "amount", "txFee"] - } - - func readValues() { - let mirror = Mirror(reflecting: self) - for child in mirror.children { - _ = child.value - } - } - - // Ethereum - required convenience init(tokenType: TokenType, from: String, to: String = "", value: BigUInt = 0, txFee: BigUInt = 0, txHash: TxHash) { - self.init(contractAddress: "", tokenType: tokenType, from: from, to: to, value: value, txFee: txFee, txHash: txHash) - } - - // Erc20 - required convenience init(contractAddress: String, tokenType: TokenType, from: String, to: String = "", value: BigUInt = 0, txFee: BigUInt = 0, txHash: TxHash) { - self.init() - self.tokenType = tokenType - self.txHash = txHash - blockNumber = (try? EthereumNetwork().getWeb3().eth.getTransactionDetails(txHash))?.blockNumber ?? 0 - self.from = from - self.to = to - amount = value - self.txFee = txFee - self.contractAddress = contractAddress - status = .pending - ethereumNetwork = EthereumNetwork().host().absoluteString - } - - // AppChain - required convenience init(tokenType: TokenType, from: String, hash: String, transaction: Transaction, chainHosts: String) { - self.init() - txHash = hash - blockNumber = BigUInt(transaction.validUntilBlock) - self.from = from - to = transaction.to?.address ?? "" - amount = transaction.value - txFee = BigUInt(transaction.quota) - status = .pending - self.chainHosts = chainHosts - } - - // AppChainErc20 - - override var description: String { - return """ - tokenType: \(tokenType) - contractAddress: \(contractAddress) - hash: \(txHash) - blockNumber: \(blockNumber) - from: \(from) - to: \(to) - amount: \(amount) - txFee: \(txFee) - """ - } - - func isSendFromToken(token: TokenModel) -> Bool { - return token.type == tokenType && contractAddress == token.address - } - - func transactionDetails() -> TransactionDetails { - let details: TransactionDetails - if tokenType == .ether { - let ethereum = EthereumTransactionDetails() - details = ethereum - } else if tokenType == .erc20 { - let erc20 = Erc20TransactionDetails() - erc20.contractAddress = contractAddress - details = erc20 - } else if tokenType == .appChain { - let appChain = AppChainTransactionDetails() - details = appChain - } else { - fatalError() - } - details.hash = txHash - details.to = to - details.from = from - details.value = amount - details.date = date - details.blockNumber = blockNumber - details.status = status - return details - } -} - -extension SentTransaction { - public static func == (lhs: SentTransaction, rhs: SentTransaction) -> Bool { - return lhs.txHash == rhs.txHash - } - - override func isEqual(_ object: Any?) -> Bool { - guard let object = object as? SentTransaction else { - return false - } - return object.txHash == txHash - } -} - -extension TransactionDetails { - convenience init(sentTransaction: SentTransaction) { - self.init() - } -} diff --git a/Neuron/Services/Common/TransactionStatusManager.swift b/Neuron/Services/Common/TransactionStatusManager.swift deleted file mode 100644 index c67ad106..00000000 --- a/Neuron/Services/Common/TransactionStatusManager.swift +++ /dev/null @@ -1,209 +0,0 @@ -// -// TransactionStatusManager.swift -// Neuron -// -// Created by 晨风 on 2018/11/16. -// Copyright © 2018 Cryptape. All rights reserved. -// - -import Foundation -import RealmSwift -import BigInt -import Web3swift -import AppChain - -enum TransactionStateResult { - case pending - case success(transaction: TransactionDetails) - case failure -} - -protocol TransactionStatusManagerDelegate: NSObjectProtocol { - func sentTransactionInserted(transaction: TransactionDetails) - func sentTransactionStatusChanged(transaction: TransactionDetails) -} - -class TransactionStatusManager: NSObject { - static let manager = TransactionStatusManager() - private var transactions = [SentTransaction]() - - private override init() { - delegates = NSHashTable(options: .weakMemory) - super.init() - perform { - self.checkSentTransactionStatus() - } - } - - // MARK: - delegate - private let delegates: NSHashTable! - - func addDelegate(delegate: TransactionStatusManagerDelegate) { - delegates.add(delegate as? NSObject) - } - - func removeDelegate(delegate: TransactionStatusManagerDelegate) { - delegates.remove(delegate as? NSObject) - } - - // MARK: - Add transaction - func insertTransaction(transaction: SentTransaction) { - perform { - try? self.realm.write { - self.realm.add(transaction) - } - self.transactions.append(transaction) - let details = transaction.transactionDetails() - for delegate in self.delegates.allObjects { - if let delegate = delegate as? TransactionStatusManagerDelegate { - delegate.sentTransactionInserted(transaction: details) - } - } - if self.transactions.count == 1 { - self.checkSentTransactionStatus() - } - } - } - - // MARK: - - func getTransactions(walletAddress: String, tokenType: TokenType, tokenAddress: String, chainHosts: String) -> [TransactionDetails] { - let ethereumNetwork = EthereumNetwork().host().absoluteString - return self.realm.objects(SentTransaction.self).filter({ - $0.chainHosts == chainHosts && - $0.from == walletAddress && - $0.tokenType == tokenType && - $0.contractAddress == tokenAddress && - ($0.ethereumNetwork == "" || $0.ethereumNetwork == ethereumNetwork) - }).map({ $0.transactionDetails() }) - } - - // MARK: - Check transaction status - private let timeInterval: TimeInterval = 4.0 - - @objc private func checkSentTransactionStatus() { - NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(checkSentTransactionStatus), object: nil) - guard self.transactions.count > 0 else { - deleteTaskThread() - return - } - guard Thread.current == thread else { - perform { self.checkSentTransactionStatus() } - return - } - - let transactions = self.transactions - for sentTransaction in transactions { - let result: TransactionStateResult - switch sentTransaction.tokenType { - case .ether: - result = EthereumNetwork().getTransactionStatus(sentTransaction: sentTransaction) - case .erc20: - result = EthereumNetwork().getTransactionStatus(sentTransaction: sentTransaction) - case .appChain: - result = AppChainNetwork().getTransactionStatus(sentTransaction: sentTransaction) - default: - fatalError() - } - - switch result { - case .failure: - self.transactions.removeAll { $0 == sentTransaction } - try? self.realm.write { - sentTransaction.status = .failure - } - sentTransactionStatusChanged(transaction: sentTransaction.transactionDetails()) - case .success(let details): - self.transactions.removeAll { $0 == sentTransaction } - try? self.realm.write { - sentTransaction.status = .success - realm.delete(sentTransaction) - } - sentTransactionStatusChanged(transaction: details) - case .pending: - break - } - } - perform(#selector(checkSentTransactionStatus), with: nil, afterDelay: timeInterval) - } - - // MARK: - Callback - private func sentTransactionStatusChanged(transaction: TransactionDetails) { - for delegate in self.delegates.allObjects { - if let delegate = delegate as? TransactionStatusManagerDelegate { - delegate.sentTransactionStatusChanged(transaction: transaction) - } - } - } - - // MARK: - Thread - private var thread: Thread? - private var runLoop: RunLoop? - private typealias Block = () -> Void - private class Task: NSObject { - let block: Block - init(block: @escaping Block) { - self.block = block - } - } - - @objc private func perform(_ block: @escaping Block) { - let thread = getTaskThread() - if Thread.current == thread { - block() - return - } - let task = Task(block: block) - let sel = #selector(TransactionStatusManager.taskHandler(task:)) - self.perform(sel, on: thread, with: task, waitUntilDone: false) - } - - @objc private func syncPerform(_ block: @escaping Block) { - let thread = getTaskThread() - if Thread.current == thread { - block() - return - } - let task = Task(block: block) - let sel = #selector(TransactionStatusManager.taskHandler(task:)) - self.perform(sel, on: thread, with: task, waitUntilDone: true) - } - - @objc private func taskHandler(task: Task) { - task.block() - } - - private func getTaskThread() -> Thread { - if let thread = thread { - return thread - } - let group = DispatchGroup() - let queue = DispatchQueue(label: "") - group.enter() - queue.async { - self.thread = Thread.current - self.runLoop = RunLoop.current - Thread.current.name = String(describing: TransactionStatusManager.self) - RunLoop.current.add(NSMachPort(), forMode: .default) - group.leave() - CFRunLoopRun() - } - group.wait() - perform { - self.transactions = self.realm.objects(SentTransaction.self).filter({ (transaction) -> Bool in - return transaction.status == .pending - }) - } - return thread! - } - - private func deleteTaskThread() { - self.thread = nil - if let runloop = self.runLoop?.getCFRunLoop() { - CFRunLoopStop(runloop) - } - } - - private var realm: Realm! { - return try! Realm() - } -} diff --git a/Neuron/Services/Ethereum/Ethereum+TransactionStatus.swift b/Neuron/Services/Ethereum/Ethereum+TransactionStatus.swift deleted file mode 100644 index 2f12bded..00000000 --- a/Neuron/Services/Ethereum/Ethereum+TransactionStatus.swift +++ /dev/null @@ -1,63 +0,0 @@ -// -// Ethereum+TransactionStatus.swift -// Neuron -// -// Created by 晨风 on 2018/11/16. -// Copyright © 2018 Cryptape. All rights reserved. -// - -import Foundation -import BigInt -import Web3swift - -extension EthereumNetwork { - func getTransactionStatus(sentTransaction: SentTransaction) -> TransactionStateResult { - do { - let transactionDetails = try EthereumNetwork().getWeb3().eth.getTransactionDetails(sentTransaction.txHash) // TODO: cache - try? sentTransaction.realm?.write { - sentTransaction.blockNumber = transactionDetails.blockNumber ?? 0 - } - let blockNumber = try EthereumNetwork().getWeb3().eth.getBlockNumber() - if blockNumber - sentTransaction.blockNumber < 12 { - return .pending - } - - let receipt = try EthereumNetwork().getWeb3().eth.getTransactionReceipt(sentTransaction.txHash) - switch receipt.status { - case .ok: - let details: TransactionDetails = sentTransaction.transactionDetails() - if let ethereumTransaction = details as? EthereumTransactionDetails { - ethereumTransaction.nonce = transactionDetails.transaction.nonce - ethereumTransaction.blockHash = "0x" + String(BigUInt(receipt.blockHash), radix: 16) - ethereumTransaction.transactionIndex = receipt.transactionIndex - ethereumTransaction.gasPrice = transactionDetails.transaction.gasPrice - ethereumTransaction.gasUsed = receipt.gasUsed - ethereumTransaction.cumulativeGasUsed = receipt.cumulativeGasUsed - } else if let erc20Transaction = details as? Erc20TransactionDetails { - erc20Transaction.nonce = transactionDetails.transaction.nonce - erc20Transaction.blockHash = "0x" + String(BigUInt(receipt.blockHash), radix: 16) - erc20Transaction.transactionIndex = receipt.transactionIndex - erc20Transaction.gasPrice = transactionDetails.transaction.gasPrice - erc20Transaction.gasUsed = receipt.gasUsed - erc20Transaction.cumulativeGasUsed = receipt.cumulativeGasUsed - } - details.status = .success - return .success(transaction: details) - case .failed: - return .failure - case .notYetProcessed: - if sentTransaction.date.timeIntervalSince1970 + 60*60*48 < Date().timeIntervalSince1970 { - return .failure // timeout - } else { - return .pending - } - } - } catch { - if sentTransaction.date.timeIntervalSince1970 + 60*60*48 < Date().timeIntervalSince1970 { - return .failure // timeout - } else { - return .pending - } - } - } -} diff --git a/Neuron/Services/Ethereum/EthereumNetwork.swift b/Neuron/Services/Ethereum/EthereumNetwork.swift deleted file mode 100644 index 535f3ed0..00000000 --- a/Neuron/Services/Ethereum/EthereumNetwork.swift +++ /dev/null @@ -1,61 +0,0 @@ -// -// EthereumNetwork.swift -// Neuron -// -// Created by XiaoLu on 2018/7/6. -// Copyright © 2018年 cryptape. All rights reserved. -// - -import Foundation -import Web3swift - -struct EthereumNetwork { - func getWeb3() -> web3 { - switch currentNetwork { - case .mainnet: - return Web3.InfuraMainnetWeb3() - case .rinkeby: - return Web3.InfuraRinkebyWeb3() - case .ropsten: - return Web3.InfuraRopstenWeb3() - case .kovan: - let infura = InfuraProvider(.Kovan)! - return web3(provider: infura) - } - } - - func host() -> URL { - switch currentNetwork { - case .mainnet: - return URL(string: "http://api.etherscan.io")! - case .rinkeby: - return URL(string: "http://api-rinkeby.etherscan.io")! - case .ropsten: - return URL(string: "http://api-ropsten.etherscan.io")! - case .kovan: - return URL(string: "http://api-kovan.etherscan.io")! - } - } - - enum EthereumNetworkType: String, CaseIterable { - case mainnet - case rinkeby - case ropsten - case kovan - - static let allValues = allCases.map { $0.rawValue } - } - - private let currentNetworkKey = "selectedNetwork" - - var currentNetwork: EthereumNetworkType { - let network = UserDefaults.standard.string(forKey: currentNetworkKey) ?? "" - return EthereumNetworkType(rawValue: network) ?? .mainnet - } - - func switchNetwork(_ network: String) { - if let network = EthereumNetworkType(rawValue: network) { - UserDefaults.standard.set(network.rawValue, forKey: currentNetworkKey) - } - } -} diff --git a/Neuron/Services/Ethereum/TokenProfile.swift b/Neuron/Services/Ethereum/TokenProfile.swift deleted file mode 100644 index ef67eba1..00000000 --- a/Neuron/Services/Ethereum/TokenProfile.swift +++ /dev/null @@ -1,112 +0,0 @@ -// -// TokenProfile.swift -// Neuron -// -// Created by 晨风 on 2018/10/24. -// Copyright © 2018 Cryptape. All rights reserved. -// - -import Foundation -import Alamofire -import Web3swift -import EthereumAddress - -// TODO: Refactor -struct TokenProfile: Decodable { - let symbol: String - let address: String - var overview: Overview - var imageUrl: String? - var image: UIImage? - var possess: String? - var detailUrl: URL? - var price: Double? - var priceText: String? - - struct Overview: Decodable { - var zh: String - } - - enum CodingKeys: String, CodingKey { - case symbol - case address - case overview - case imageUrl - } -} - -extension TokenModel { - func getProfile(complection: @escaping (TokenProfile?) -> Void) { - switch type { - case .ether: - getEthereumProfile(complection: complection) - case .erc20: - getErc20Profile(complection: complection) - case .appChain, .appChainErc20: - complection(nil) - } - } - - private func getEthereumProfile(complection: @escaping (TokenProfile?) -> Void) { - let overview = TokenProfile.Overview(zh: "Ethereum是一个运行智能合约的去中心化平台,应用将完全按照程序运作,不存在任何欺诈,审查与第三方干预的可能。") - let detailUrl = URL(string: "https://ntp.staging.cryptape.com?coin=ethereum") - var profile = TokenProfile(symbol: self.symbol, address: address, overview: overview, imageUrl: nil, image: UIImage(named: "eth_logo"), possess: nil, detailUrl: detailUrl, price: nil, priceText: nil) - - let currencyType = LocalCurrencyService.shared.getLocalCurrencySelect().short - let symbol = self.symbol - DispatchQueue.global().async { - let price = TokenPriceLoader().getPrice(symbol: symbol, currency: currencyType) - DispatchQueue.main.async { - if let price = price { - let amount = self.tokenBalance * price - let possess = String(format: "%@ %.4f", LocalCurrencyService.shared.getLocalCurrencySelect().symbol, amount) - profile.possess = possess - profile.price = price - profile.priceText = String(format: "%@ %.4f", LocalCurrencyService.shared.getLocalCurrencySelect().symbol, price) - } - complection(profile) - } - } - } - - private func getErc20Profile(complection: @escaping (TokenProfile?) -> Void) { - let group = DispatchGroup() - var profile: TokenProfile? - var price: Double? - - group.enter() - let address = EthereumAddress.toChecksumAddress(self.address) ?? self.address - let urlString = "https://raw.githubusercontent.com/consenlabs/token-profile/master/erc20/\(address).json" - Alamofire.request(URL(string: urlString)!, method: .get, parameters: nil).responseData { (response) in - defer { group.leave() } - guard let data = response.data else { - return - } - profile = try? JSONDecoder().decode(TokenProfile.self, from: data) - profile?.imageUrl = "https://raw.githubusercontent.com/consenlabs/token-profile/master/images/\(address).png" - } - - group.enter() - let currency = LocalCurrencyService.shared.getLocalCurrencySelect() - let symbol = self.symbol - DispatchQueue.global().async { - price = TokenPriceLoader().getPrice(symbol: symbol, currency: currency.short) - group.leave() - } - - group.notify(queue: .main) { - profile?.detailUrl = URL(string: "https://ntp.staging.cryptape.com?token=\(address)") - if var profile = profile, let price = price { - let balance = self.tokenBalance - let amount = balance * price - let possess = String(format: "%@ %.4f", currency.symbol, amount) - profile.possess = possess - profile.price = price - profile.priceText = String(format: "%@ %.4f", LocalCurrencyService.shared.getLocalCurrencySelect().symbol, price) - complection(profile) - } else { - complection(profile) - } - } - } -} diff --git a/Neuron/en.lproj/Localizable.strings b/Neuron/en.lproj/Localizable.strings deleted file mode 100644 index 2a783714..00000000 --- a/Neuron/en.lproj/Localizable.strings +++ /dev/null @@ -1,109 +0,0 @@ -/* - Localizable.strings - Neuron - - Created by James Chen on 2018/11/03. - Copyright © 2018 Cryptape. All rights reserved. -*/ - -// Common -// --------------------------------------------------------- -"Common.Connection.ConnectionLost" = "The connection to the Internet is broken"; -"Common.Connection.FailToLoadPage" = "Failed to load the page"; - -// DApp -// --------------------------------------------------------- -"DApp.Home" = "DApp"; -"DApp.NFT.EmptyData" = "Empty Data"; - -// Settings -// --------------------------------------------------------- -"Settings.About.AboutUs" = "About us"; - -// DApp Transaction -// --------------------------------------------------------- -"DApp.SendTransactionError.emptyValue" = "Transaction's value format error"; -"DApp.SendTransactionError.emptyQuota" = "Transaction's quota format error"; -"DApp.SendTransactionError.emptyGasLimit" = "Transaction's gas limit format error"; -"DApp.SendTransactionError.emptyGasPrice" = "Transaction's gas price format error"; - - -// Mnemonic Validator -// --------------------------------------------------------- -"MnemonicValidator.emptyMnemonic" = "Empty Mnemonic"; -"MnemonicValidator.invalidMnemonic" = "Invalid Mnemonic"; - -// Wallet Manager Errors -// --------------------------------------------------------- -"WalletManager.Error.invalidPassword" = "Invalid password"; -"WalletManager.Error.invalidPrivateKey" = "Invalid Private Key"; -"WalletManager.Error.invalidKeystore" = "Invalid Keystore"; -"WalletManager.Error.invalidMnemonic" = "Invalid Mnemonic"; -"WalletManager.Error.emptyMnemonic" = "Empty Mnemonic"; -"WalletManager.Error.accountAlreadyExists" = "You already have this wallet"; -"WalletManager.Error.accountNotFound" = "Wallet not found"; -"WalletManager.Error.failedToDeleteAccount" = "Failed to delete wallet"; -"WalletManager.Error.failedToUpdatePassword" = "Failed to update wallet password"; -"WalletManager.Error.failedToSaveKeystore" = "Failed to save the keystore"; -"WalletManager.Error.unknown" = "Unknow error"; - -// Send Transactoin Error -// --------------------------------------------------------- -"SendTransactionError.invalidSourceAddress" = "Invalid source address"; -"SendTransactionError.invalidDestinationAddress" = "Invalid destination address"; -"SendTransactionError.invalidContractAddress" = "Invalid contract ADdress"; -"SendTransactionError.noAvailableKeys" = "Wallet not found"; -"SendTransactionError.createTransactionIssue" = "Failed to create transaction"; -"SendTransactionError.invalidChainId" = "Invalid chain ID"; -"SendTransactionError.signTXFailed" = "Failed to sign the transaction"; - -// Custom Token Error -// --------------------------------------------------------- -"CustomTokenError.wrongBalanceError" = "Wrong balance"; -"CustomTokenError.badNameError" = "Bad token name"; -"CustomTokenError.badSymbolError" = "Bad token symbol"; -"CustomTokenError.undefinedError" = "Undefined error"; - -// Sign Message Error -// --------------------------------------------------------- -"MessageSign.Error.walletNotFound" = "Wallet not found"; -"MessageSign.Error.signMessageFailed" = "Failed to sign the message"; - -// Wallet -// --------------------------------------------------------- -"Wallet" = "钱包"; -"Wallet.token" = "代币"; -"Wallet.addToken" = "添加资产"; -"Wallet.transaction" = "转账"; -"Wallet.receipt" = "收款"; -"Wallet.totalAmount" = "总资产"; -"Wallet.noAmount" = "暂无资产"; - -// Wallet QRCode -// --------------------------------------------------------- -"Wallet.QRCode.desc" = "此地址只接收AppChain、以太坊Token,发送其他币种到此地址将不可找回"; -"Wallet.QRCode.copy" = "复制"; -"Wallet.QRCode.copySuccess" = "地址已经复制到粘贴板"; - -// Authentication -// --------------------------------------------------------- -"Authentication.clickFaceIdAuth" = "点击进行验证 Face Id"; -"Authentication.clickTouchIdAuth" = "点击进行验证 Touch Id"; -"Authentication.authFaceIdTitle" = "请验证 Face ID"; -"Authentication.authTouchIdTitle" = "请验证 Touch ID"; - -"Authentication.selectWallet" = "选择钱包"; -"Authentication.walletPassword" = "钱包密码"; -"Authentication.confirmPassword" = "确定"; -"Authentication.walletPasswordError" = "密码不正确请重新输入"; - -"Authentication.openFaceIdAuthDesc" = "请开启刷脸验证,确保您的资产安全"; -"Authentication.openFaceIdAuth" = "开启刷脸验证"; -"Authentication.openTouchIdAuthDesc" = "请开启指纹验证,确保您的资产安全"; -"Authentication.openTouchIdAuth" = "开启指纹验证"; - -"Authentication.Error.touchIDNotEnrolled" = "未设置 Touch ID"; -"Authentication.Error.faceIDNotEnrolled" = "未设置 Face ID"; -"Authentication.Error.faceIDNotAvailable" = "您的Face ID未开启,请输入密码登陆"; -"Authentication.Error.biometryLockout" = "多次验证失败被锁定"; -"Authentication.Error.authFailed" = "验证失败,请重新验证"; diff --git a/Neuron/zh-Hans.lproj/Localizable.strings b/Neuron/zh-Hans.lproj/Localizable.strings deleted file mode 100644 index 1226f779..00000000 --- a/Neuron/zh-Hans.lproj/Localizable.strings +++ /dev/null @@ -1,108 +0,0 @@ -/* - Localizable.strings - Neuron - - Created by James Chen on 2018/11/03. - Copyright © 2018 Cryptape. All rights reserved. -*/ - -// Common -// --------------------------------------------------------- -"Common.Connection.ConnectionLost" = "似乎已断开与互联网的连接"; -"Common.Connection.FailToLoadPage" = "页面加载失败"; - -// DApp -// --------------------------------------------------------- -"DApp.Home" = "应用"; -"DApp.NFT.EmptyData" = "您还没有藏品数据"; - -// Settings -// --------------------------------------------------------- -"Settings.About.AboutUs" = "关于我们"; - -// DApp Transaction -// --------------------------------------------------------- -"DApp.SendTransactionError.emptyValue" = "Transaction's value format error"; -"DApp.SendTransactionError.emptyQuota" = "Transaction's quota format error"; -"DApp.SendTransactionError.emptyGasLimit" = "Transaction's gas limit format error"; -"DApp.SendTransactionError.emptyGasPrice" = "Transaction's gas price format error"; - -// Mnemonic Validator -// --------------------------------------------------------- -"MnemonicValidator.emptyMnemonic" = "助记词不能为空"; -"MnemonicValidator.invalidMnemonic" = "助记词不正确"; - -// Wallet Manager Errors -// --------------------------------------------------------- -"WalletManager.Error.invalidPassword" = "密码不正确"; -"WalletManager.Error.invalidPrivateKey" = "私钥不正确"; -"WalletManager.Error.invalidKeystore" = "Keystore不正确"; -"WalletManager.Error.invalidMnemonic" = "助记词不正确"; -"WalletManager.Error.emptyMnemonic" = "助记词不能为空"; -"WalletManager.Error.accountAlreadyExists" = "该钱包已存在"; -"WalletManager.Error.accountNotFound" = "未找到该钱包"; -"WalletManager.Error.failedToDeleteAccount" = "删除钱包失败"; -"WalletManager.Error.failedToUpdatePassword" = "修改密码失败"; -"WalletManager.Error.failedToSaveKeystore" = "保存keystore失败"; -"WalletManager.Error.unknown" = "未知错误"; - -// Send Transactoin Error -// --------------------------------------------------------- -"SendTransactionError.invalidSourceAddress" = "发送地址不正确"; -"SendTransactionError.invalidDestinationAddress" = "接收地址不正确"; -"SendTransactionError.invalidContractAddress" = "合约地址不正确"; -"SendTransactionError.noAvailableKeys" = "未找到该钱包"; -"SendTransactionError.createTransactionIssue" = "创建交易失败"; -"SendTransactionError.invalidChainId" = "Chain ID不正确"; -"SendTransactionError.signTXFailed" = "交易签名失败"; - -// Custom Token Error -// --------------------------------------------------------- -"CustomTokenError.wrongBalanceError" = "余额不正确"; -"CustomTokenError.badNameError" = "Token名称不正确"; -"CustomTokenError.badSymbolError" = "Token symbol不正确"; -"CustomTokenError.undefinedError" = "未知错误"; - -// Sign Message Error -// --------------------------------------------------------- -"MessageSign.Error.walletNotFound" = "未找到该钱包"; -"MessageSign.Error.signMessageFailed" = "签名失败"; - -// Wallet -// --------------------------------------------------------- -"Wallet" = "钱包"; -"Wallet.token" = "代币"; -"Wallet.addToken" = "添加资产"; -"Wallet.transaction" = "转账"; -"Wallet.receipt" = "收款"; -"Wallet.totalAmount" = "总资产"; -"Wallet.noAmount" = "暂无资产"; - -// Wallet QRCode -// --------------------------------------------------------- -"Wallet.QRCode.desc" = "此地址只接收AppChain、以太坊Token,发送其他币种到此地址将不可找回"; -"Wallet.QRCode.copy" = "复制"; -"Wallet.QRCode.copySuccess" = "地址已经复制到粘贴板"; - -// Authentication -// --------------------------------------------------------- -"Authentication.clickFaceIdAuth" = "点击进行验证 Face Id"; -"Authentication.clickTouchIdAuth" = "点击进行验证 Touch Id"; -"Authentication.authFaceIdTitle" = "请验证 Face ID"; -"Authentication.authTouchIdTitle" = "请验证 Touch ID"; - -"Authentication.selectWallet" = "选择钱包"; -"Authentication.walletPassword" = "钱包密码"; -"Authentication.confirmPassword" = "确定"; -"Authentication.walletPasswordError" = "密码不正确请重新输入"; - -"Authentication.openFaceIdAuthDesc" = "请开启刷脸验证,确保您的资产安全"; -"Authentication.openFaceIdAuth" = "开启刷脸验证"; -"Authentication.openTouchIdAuthDesc" = "请开启指纹验证,确保您的资产安全"; -"Authentication.openTouchIdAuth" = "开启指纹验证"; - -"Authentication.Error.touchIDNotEnrolled" = "未设置 Touch ID"; -"Authentication.Error.faceIDNotEnrolled" = "未设置 Face ID"; -"Authentication.Error.faceIDNotAvailable" = "您的Face ID未开启,请输入密码登陆"; -"Authentication.Error.biometryLockout" = "多次验证失败被锁定"; -"Authentication.Error.authFailed" = "验证失败,请重新验证"; diff --git a/NeuronTests/Extensions/Foundation/DoubleExtensionTests.swift b/NeuronTests/Extensions/Foundation/DoubleExtensionTests.swift deleted file mode 100644 index 7d959553..00000000 --- a/NeuronTests/Extensions/Foundation/DoubleExtensionTests.swift +++ /dev/null @@ -1,42 +0,0 @@ -// -// DoubleExtensionTests.swift -// NeuronTests -// -// Created by 晨风 on 2018/11/8. -// Copyright © 2018 Cryptape. All rights reserved. -// - -import XCTest -import BigInt -@testable import Neuron - -class DoubleExtensionTests: XCTestCase { - func testClean() { - XCTAssertEqual(0.001000.trailingZerosTrimmed, "0.001") - XCTAssertEqual(2233.001000.trailingZerosTrimmed, "2233.001") - XCTAssertEqual(2233.0010010.trailingZerosTrimmed, "2233.001001") - } - - func testToAmount() { - XCTAssertEqual(3.1415926.toAmount(18), BigUInt("3141592600000000000")!) - } - - func testFromAmount() { - XCTAssertEqual(Double.fromAmount(BigUInt("3141592600000000000")!, decimals: 18), 3.1415926) - } - - func testGweiToWei() { - XCTAssertEqual( - 20500000000, - 20.5.gweiToWei() - ) - } - - func testDecimalFormat() { - XCTAssertEqual(1.12345678.decimal, "1.12345678") - XCTAssertEqual(1.1234567899.decimal, "1.12345678") - XCTAssertEqual(1.123456784.decimal, "1.12345678") - XCTAssertEqual(1.1234.decimal, "1.1234") - XCTAssertEqual(4.decimal, "4") - } -} diff --git a/Podfile b/Podfile index 363c6242..c4cd81e6 100644 --- a/Podfile +++ b/Podfile @@ -1,31 +1,29 @@ source 'https://github.com/CocoaPods/Specs.git' platform :ios, '10.0' -target 'Neuron' do +target 'Cyton' do use_frameworks! inhibit_all_warnings! - pod 'AppChainSwift', git: "https://github.com/cryptape/appchain-swift", tag: "v0.20.5" + pod 'CITA', git: "https://github.com/cryptape/cita-sdk-swift", commit: "df1342916ca3a7621c6f68353f94094a36faeb4b" pod 'web3swift', "~> 2.0.1" pod 'RealmSwift' pod 'Alamofire' - pod 'SensorsAnalyticsSDK', git: "https://github.com/sensorsdata/sa-sdk-ios", branch: "v1.10.15" pod 'SDWebImage' pod 'IQKeyboardManagerSwift' pod 'EFQRCode' pod 'RSKPlaceholderTextView', "~> 4.0.0" pod 'BulletinBoard', git: "https://github.com/alexaubry/BulletinBoard", commit: "7086607d3476cea29cd77a65d13df5c8ed0da52e" # 3.0.0 pod 'Toast-Swift', "~> 4.0.0" - pod 'IGIdenticon', "~> 0.6" pod 'QRCodeReader.swift' - target 'NeuronTests' do + target 'CytonTests' do inherit! :search_paths # Pods for testing end - target 'NeuronUITests' do + target 'CytonUITests' do inherit! :search_paths # Pods for testing end diff --git a/Podfile.lock b/Podfile.lock index f7e7f4c1..48432de9 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,14 +1,14 @@ PODS: - Alamofire (4.7.3) - - AppChainSwift (0.20.5): + - BigInt (3.1.0): + - SipHash (~> 1.2) + - BulletinBoard (3.0.0) + - CITA (0.20.5): - BigInt (~> 3.1) - CryptoSwift (~> 0.13) - PromiseKit (~> 6.5) - secp256k1_swift (~> 1.0.3) - SwiftProtobuf (~> 1.2.0) - - BigInt (3.1.0): - - SipHash (~> 1.2) - - BulletinBoard (3.0.0) - CryptoSwift (0.13.0) - EFQRCode (4.3.0) - EthereumABI (1.1.1): @@ -17,7 +17,6 @@ PODS: - EthereumAddress (~> 1.0.0) - EthereumAddress (1.0.0): - CryptoSwift (~> 0.13) - - IGIdenticon (0.6) - IQKeyboardManagerSwift (6.2.0) - PromiseKit (6.5.2): - PromiseKit/CorePromise (= 6.5.2) @@ -41,9 +40,6 @@ PODS: - SDWebImage/Core (= 4.4.2) - SDWebImage/Core (4.4.2) - secp256k1_swift (1.0.3) - - SensorsAnalyticsSDK (1.10.15): - - SensorsAnalyticsSDK/core (= 1.10.15) - - SensorsAnalyticsSDK/core (1.10.15) - SipHash (1.2.2) - SwiftProtobuf (1.2.0) - SwiftRLP (1.2): @@ -61,16 +57,14 @@ PODS: DEPENDENCIES: - Alamofire - - AppChainSwift (from `https://github.com/cryptape/appchain-swift`, tag `v0.20.5`) - BulletinBoard (from `https://github.com/alexaubry/BulletinBoard`, commit `7086607d3476cea29cd77a65d13df5c8ed0da52e`) + - CITA (from `https://github.com/cryptape/cita-sdk-swift`, commit `df1342916ca3a7621c6f68353f94094a36faeb4b`) - EFQRCode - - IGIdenticon (~> 0.6) - IQKeyboardManagerSwift - QRCodeReader.swift - RealmSwift - RSKPlaceholderTextView (~> 4.0.0) - SDWebImage - - SensorsAnalyticsSDK (from `https://github.com/sensorsdata/sa-sdk-ios`, branch `v1.10.15`) - Toast-Swift (~> 4.0.0) - web3swift (~> 2.0.1) @@ -82,7 +76,6 @@ SPEC REPOS: - EFQRCode - EthereumABI - EthereumAddress - - IGIdenticon - IQKeyboardManagerSwift - PromiseKit - QRCodeReader.swift @@ -99,37 +92,30 @@ SPEC REPOS: - web3swift EXTERNAL SOURCES: - AppChainSwift: - :git: https://github.com/cryptape/appchain-swift - :tag: v0.20.5 BulletinBoard: :commit: 7086607d3476cea29cd77a65d13df5c8ed0da52e :git: https://github.com/alexaubry/BulletinBoard - SensorsAnalyticsSDK: - :branch: v1.10.15 - :git: https://github.com/sensorsdata/sa-sdk-ios + CITA: + :commit: df1342916ca3a7621c6f68353f94094a36faeb4b + :git: https://github.com/cryptape/cita-sdk-swift CHECKOUT OPTIONS: - AppChainSwift: - :git: https://github.com/cryptape/appchain-swift - :tag: v0.20.5 BulletinBoard: :commit: 7086607d3476cea29cd77a65d13df5c8ed0da52e :git: https://github.com/alexaubry/BulletinBoard - SensorsAnalyticsSDK: - :commit: f61088a6cdc661a6e5a3e9f361d624c48b50af01 - :git: https://github.com/sensorsdata/sa-sdk-ios + CITA: + :commit: df1342916ca3a7621c6f68353f94094a36faeb4b + :git: https://github.com/cryptape/cita-sdk-swift SPEC CHECKSUMS: Alamofire: c7287b6e5d7da964a70935e5db17046b7fde6568 - AppChainSwift: 0957a762aa81d31cee3276834096e0f6d4fca1fd BigInt: 76b5dfdfa3e2e478d4ffdf161aeede5502e2742f BulletinBoard: 927f4f9fd22503ceecd71bfc830fd65d5996593a + CITA: ea81e8443a879ca429fbd6c5ee7756525fd44fa1 CryptoSwift: 16e78bebf567bad1c87b2d58f6547f25b74c31aa EFQRCode: 51b67bd10952da9ef619ae0a396abb746b94263f EthereumABI: f040f5429e5a4366d028c88b88d9441e137593af EthereumAddress: f476e1320dca3a0024431e713ede7a09c7eb7796 - IGIdenticon: 5790befde4fe56296927c72c0efed3d07b21de8e IQKeyboardManagerSwift: b07ccf9d8cafe993dcd6cb794eb4ba34611a0c4e PromiseKit: 27c1601bfb73405871b805bcb8cf7e55c4dad3db QRCodeReader.swift: 96292a5612fbc2fd9a0b26f93fa5164c8d02f59d @@ -139,13 +125,12 @@ SPEC CHECKSUMS: scrypt: 3fe5b1a3b0976f97cd87488673a8f7c65708cc84 SDWebImage: 624d6e296c69b244bcede364c72ae0430ac14681 secp256k1_swift: 4fc5c4b2d2c6d21ee8ccb868cdc92da12f38bed9 - SensorsAnalyticsSDK: 206079ab1b4ecc451e12bc90c315a56c035b2a53 SipHash: fad90a4683e420c52ef28063063dbbce248ea6d4 SwiftProtobuf: 91a9856079044ef4ec762b2344c763cd9e5a73c1 SwiftRLP: 98a02b2210128353ca02e4c2f4d83e2a9796db4f Toast-Swift: 594b5c5e5129f15438e410207e43287f027b3c00 web3swift: 33f30ca0e061e0f89117dfb46f5ee9f626eff6d6 -PODFILE CHECKSUM: beb75d52d4fb090be32eb898fb3ca2ea9a3e4566 +PODFILE CHECKSUM: e6d95e03f992e05fdb2ddc4c592ff6fb063e1218 COCOAPODS: 1.5.3 diff --git a/README.md b/README.md index 6367bf3e..599cd607 100644 --- a/README.md +++ b/README.md @@ -1,50 +1,35 @@ -# Neuron Wallet (iOS) +# Cyton Wallet (iOS) -[![Travis](https://travis-ci.com/cryptape/neuron-ios.svg?branch=develop)](https://travis-ci.com/cryptape/neuron-ios) +[![Travis](https://travis-ci.com/cryptape/cyton-ios.svg?branch=develop)](https://travis-ci.com/cryptape/cyton-ios) [![Swift](https://img.shields.io/badge/Swift-4.2-orange.svg?style=flat)](https://developer.apple.com/swift/) -[![AppChain](https://img.shields.io/badge/made%20for-Nervos%20AppChain-blue.svg)](https://appchain.nervos.org) +[![CITA](https://img.shields.io/badge/made%20for-CITA-blue.svg)](https://www.citahub.com) -# Overview +Overview +=============== -Neuron is an open source blockchain wallet which supports Ethereum and [AppChain](https://docs.nervos.org/#/). It supports most tokens of Ethereum and [AppChain](https://docs.nervos.org/#/), such as ETH, ERC20, ERC721, and also supports most kinds of DApps of Ethereum and [AppChain](https://docs.nervos.org/#/) , such as cryptokitties, Fomo3D, 0xproject... +Cyton is an open source blockchain wallet which supports [Ethereum](https://www.ethereum.org/) and [CITA](https://github.com/cryptape/cita). It supports most tokens of Ethereum and CITA, such as ETH, ERC20, ERC721, and also supports most kinds of DApps of Ethereum and CITA , such as cryptokitties, Fomo3D, 0xproject... -# Usage - -## Private key and address - -Neuron is a blockchain wallet that supports both Ethereum and Nervos [AppChain](https://docs.nervos.org/#/), you can use a single private key and address to access your Ethereum and AppChain account. **Neuron never saves your private key directly, you need to input password to sign every transaction. If you forget your private key, Neuron can not find and recover it, so you should save private key (keystore and mnemonic) carefully.** - -Neuron supports importing wallet through private key, keystore and mnemonic, and supports exporting keystore. - -## Token - -Neuron is a blockchain wallet which supports Ethereum, so you can view your ERC20 token balances and tranfer tokens to other accounts. If you can not find certain ERC20 token, you can input contract address to load token information and add to your token list. - -Nervos [AppChain](https://docs.nervos.org/#/) is a blockchain solution which includes blockchain kernel CITA, Neuron wallet, blockchain browser [Microscope](https://github.com/cryptape/microscope), cache server [ReBirth](https://github.com/cryptape/re-birth) and SDKs of different programming languages. [AppChain](https://docs.nervos.org/#/) supports Ethereum solidity contract, so all ERC contracts can deploy to AppChain directly. - -AppChain is an open source blockchain solution, you can create your blockchain token by yourself and set any name(symbol) you like. All tokens on AppChain can display in Neuron wallet. - -## DApp - -Neuron is also a DApp browser, which supprts Ethereum and [AppChain](https://docs.nervos.org/#/) DApps. Most popular Ethereum DApps, such as cryptokitties, Fomo3D and 0xproject, can run in Neuron directly. Neuron also supports AppChain DApps, which can be easily migrated from Ethereum. You can get more information about [how to develop an AppChain DApp](https://docs.nervos.org/nervos-appchain-docs/#/quick-start/build-dapp). - -## Get Started +Getting Started +=============== +* Clone this repo to your machine. * From the project folder, run `pod install`. -* Open `Neuron.xcworkspace` with Xcode. -* Build and run the `Neuron` target. +* Open `Cyton.xcworkspace` with Xcode. +* Build and run the `Cyton` target. -Neuron supports iOS 10 and newer versions. +Cyton supports iOS 11 and newer versions. -## System Requirements +System Requirements +=================== -To build Neuron, you'll need: +To build Cyton, you'll need: * Swift 4.2 and later * Xcode 10 and later * [CocoaPods](https://cocoapods.org) -# Contributing +Contributing +============ We intend for this project to be an open source resource: we are excited to share our wins, mistakes, and methodology of iOS development as we work @@ -56,6 +41,7 @@ Please be sure to include your operating system, device, version number, and steps to reproduce reported bugs. Keep in mind that all participants will be expected to follow our code of conduct. -# MIT License +MIT License +=========== -Neuron is open sourced under MIT License. +Cyton is an open source project under MIT License.