diff --git a/.circleci/config.yml b/.circleci/config.yml index df18edb9..23bedfd8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -8,7 +8,7 @@ jobs: test_build: working_directory: ~/Waves/iOS macos: - xcode: "10.2.1" + xcode: "11.0.0" environment: BUNDLER_VERSION: 2.0.2 FL_OUTPUT_DIR: output @@ -16,21 +16,17 @@ jobs: steps: - add_ssh_keys: fingerprints: - - "aa:15:14:22:f4:fe:a3:3d:5c:52:5b:20:f4:1f:3f:52" - # - "43:eb:59:d6:49:f1:ae:81:cb:5a:ba:b8:01:64:19:39" + - "aa:15:14:22:f4:fe:a3:3d:5c:52:5b:20:f4:1f:3f:52" - checkout + - run: + name: Install Submodules + command: git submodule sync && git submodule update --init - restore_cache: key: 1-gems-{{ checksum "Gemfile.lock" }} name: "Restore Gemfile" - restore_cache: key: 1-gems-{{ checksum "Podfile.lock" }} - name: "Restore Podfile" - - run: - name: Configure Bundler - command: | - echo 'export BUNDLER_VERSION=$(cat Gemfile.lock | tail -1 | tr -d " ")' >> $BASH_ENV - source $BASH_ENV - sudo gem install bundler + name: "Restore Podfile" - run: name: Bundle install or check command: bundle check || bundle install --path vendor/bundle @@ -75,7 +71,7 @@ jobs: prod_build: working_directory: ~/Waves/iOS macos: - xcode: "10.2.1" + xcode: "11.0.0" environment: BUNDLER_VERSION: 2.0.2 FL_OUTPUT_DIR: output @@ -84,21 +80,17 @@ jobs: steps: - add_ssh_keys: fingerprints: - - "aa:15:14:22:f4:fe:a3:3d:5c:52:5b:20:f4:1f:3f:52" - # - "43:eb:59:d6:49:f1:ae:81:cb:5a:ba:b8:01:64:19:39" + - "aa:15:14:22:f4:fe:a3:3d:5c:52:5b:20:f4:1f:3f:52" - checkout + - run: + name: Install Submodules + command: git submodule sync && git submodule update --init - restore_cache: key: gems-{{ checksum "Gemfile.lock" }} name: "Restore Gemfile" - restore_cache: key: pods-{{ checksum "Podfile.lock" }} name: "Restore Podfile" - - run: - name: Configure Bundler - command: | - echo 'export BUNDLER_VERSION=$(cat Gemfile.lock | tail -1 | tr -d " ")' >> $BASH_ENV - source $BASH_ENV - sudo gem install bundler - run: name: Bundle install or check command: bundle check || bundle install --path vendor/bundle @@ -147,7 +139,7 @@ jobs: update_build: working_directory: ~/Waves/iOS macos: - xcode: "10.2.1" + xcode: "11.0.0" environment: BUNDLER_VERSION: 2.0.2 FL_OUTPUT_DIR: output @@ -158,15 +150,12 @@ jobs: fingerprints: - "aa:15:14:22:f4:fe:a3:3d:5c:52:5b:20:f4:1f:3f:52" - checkout + - run: + name: Install Submodules + command: git submodule sync && git submodule update --init - restore_cache: key: gems-{{ checksum "Gemfile.lock" }} - name: "Restore Gemfile" - - run: - name: Configure Bundler - command: | - echo 'export BUNDLER_VERSION=$(cat Gemfile.lock | tail -1 | tr -d " ")' >> $BASH_ENV - source $BASH_ENV - sudo gem install bundler + name: "Restore Gemfile" - run: name: Bundle install or check command: bundle check || bundle install --path vendor/bundle @@ -189,7 +178,7 @@ jobs: dev_build: working_directory: ~/Waves/iOS macos: - xcode: "10.2.1" + xcode: "11.0.0" environment: BUNDLER_VERSION: 2.0.2 FL_OUTPUT_DIR: output @@ -200,18 +189,15 @@ jobs: - "aa:15:14:22:f4:fe:a3:3d:5c:52:5b:20:f4:1f:3f:52" - "43:eb:59:d6:49:f1:ae:81:cb:5a:ba:b8:01:64:19:39" - checkout + - run: + name: Install Submodules + command: git submodule sync && git submodule update --init - restore_cache: key: gems-{{ checksum "Gemfile.lock" }} name: "Restore Gemfile" - restore_cache: key: pods-{{ checksum "Podfile.lock" }} - name: "Restore Podfile" - - run: - name: Configure Bundler - command: | - echo 'export BUNDLER_VERSION=$(cat Gemfile.lock | tail -1 | tr -d " ")' >> $BASH_ENV - source $BASH_ENV - sudo gem install bundler + name: "Restore Podfile" - run: name: Bundle install or check command: bundle check || bundle install --path vendor/bundle @@ -247,7 +233,7 @@ jobs: command: bundle exec fastlane download_bundle_enviroments --verbose - run: name: Fastlane Build - command: bundle exec fastlane prod_build_projet --verbose + command: bundle exec fastlane dev_build_projet --verbose no_output_timeout: 60m - store_artifacts: path: ~/Waves/iOS/Output @@ -256,7 +242,7 @@ jobs: dev_log: working_directory: ~/Waves/iOS macos: - xcode: "10.1.0" + xcode: "11.0.0" environment: BUNDLER_VERSION: 2.0.2 FL_OUTPUT_DIR: output @@ -266,18 +252,15 @@ jobs: fingerprints: - "43:eb:59:d6:49:f1:ae:81:cb:5a:ba:b8:01:64:19:39" - checkout + - run: + name: Install Submodules + command: git submodule sync && git submodule update --init - restore_cache: key: gems-{{ checksum "Gemfile.lock" }} name: "Restore Gemfile" - restore_cache: key: pods-{{ checksum "Podfile.lock" }} name: "Restore Podfile" - - run: - name: Configure Bundler - command: | - echo 'export BUNDLER_VERSION=$(cat Gemfile.lock | tail -1 | tr -d " ")' >> $BASH_ENV - source $BASH_ENV - sudo gem install bundler - run: name: Bundle install or check command: bundle check || bundle install --path vendor/bundle @@ -325,4 +308,4 @@ workflows: - dev_build: filters: branches: - only: develop \ No newline at end of file + only: feature/CI diff --git a/.gitignore b/.gitignore index f83e215a..3ed5df02 100644 --- a/.gitignore +++ b/.gitignore @@ -73,3 +73,19 @@ WavesWallet-iOS/Resources/Amplitude-Info.plist Output/ \.idea/ + +CommonResources/GoogleService-Info\.plist + +CommonResources/Amplitude-Info\.plist + +CommonResources/Appsflyer-Info\.plist + +CommonResources/Sentry-io-Info\.plist + +CommonResources/Fabric-Info\.plist + +CommonResources/AppSpector-Info\.plist + +Output/ + +\.idea/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..0932eebf --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "Vendors/WavesSDK"] + path = Vendors/WavesSDK + url = git@github.com:wavesplatform/WavesSDK-iOS.git diff --git a/CommonResources/Languages.json b/CommonResources/Languages.json new file mode 100644 index 00000000..891dc4bc --- /dev/null +++ b/CommonResources/Languages.json @@ -0,0 +1,88 @@ +[ + { + "title": "English", + "icon": "flag18Britain", + "code": "en" + }, + { + "title": "Русский", + "icon": "flag18Rus", + "code": "ru" + }, + { + "title": "한국어", + "icon": "flag18Korea", + "code": "ko" + }, + { + "title": "中文(简体)", + "icon": "flag18China", + "code": "zh-Hans-CN", + "titleCode": "ZH" + }, + { + "title": "Türkçe", + "icon": "flag18Turkey", + "code": "tr" + }, + { + "title": "Nederlands", + "icon": "flag18Nederland", + "code": "nl-NL", + "titleCode": "NL" + }, + { + "title": "हिन्दी", + "icon": "flag18Hindi", + "code": "hi-IN", + "titleCode": "HI" + }, + { + "title": "Español", + "icon": "flag18Spain", + "code": "es" + }, + { + "title": "Français", + "icon": "flag18France", + "code": "fr-FR", + "titleCode": "FR" + }, + { + "title": "Português", + "icon": "flag18Portugal", + "code": "pt-PT", + "titleCode": "PT" + }, + { + "title": "Português do Brasil", + "icon": "flag18Brazil", + "code": "pt-BR", + "titleCode": "BR" + }, + { + "title": "Polszczyzna", + "icon": "flag18Polszczyzna", + "code": "pl" + }, + { + "title": "Italiano", + "icon": "flag18Italiano", + "code": "it" + }, + { + "title": "Deutsch", + "icon": "flag18Germany", + "code": "de" + }, + { + "title": "Indonesia", + "icon": "flag18Indonesia", + "code": "id" + }, + { + "title": "日本語", + "icon": "flag18Japan", + "code": "ja" + } +] diff --git a/CommonResources/environment_mainnet.json b/CommonResources/environment_mainnet.json new file mode 100644 index 00000000..d886158f --- /dev/null +++ b/CommonResources/environment_mainnet.json @@ -0,0 +1,377 @@ +{ + "name": "Mainnet", + "servers": { + "nodeUrl": "https://nodes.wavesnodes.com", + "dataUrl": "https://api.wavesplatform.com", + "spamUrl": "https://github-proxy.wvservices.com/wavesplatform/waves-community/master/Scam%20tokens%20according%20to%20the%20opinion%20of%20Waves%20Community.csv", + "matcherUrl": "https://matcher.wavesplatform.com", + "gatewayUrl": "https://gw.wavesplatform.com/api" + }, + "scheme": "W", + "generalAssets": [ + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/waves.png" + }, + "assetId": "WAVES", + "displayName": "Waves", + "isFiat": false, + "isGateway": false, + "wavesId": "WAVES", + "gatewayId": "WAVES", + "gatewayType": "", + "addressRegEx": "" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/vostok.png" + }, + "assetId": "4LHHvYGNKJUg5hj65aGD5vgScvCBmLpdRFtjokvCjSL8", + "displayName": "WEST", + "isFiat": false, + "isGateway": true, + "wavesId": "Vostok", + "gatewayId": "Vostok", + "gatewayType": "gateway", + "addressRegEx": "" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/bitcoin.png" + }, + "assetId": "8LQW8f7P5d5PZM7GtZEBgaqRPGSzS3DfPuiXrURJ4AJS", + "displayName": "Bitcoin", + "isFiat": false, + "isGateway": true, + "wavesId": "WBTC", + "gatewayId": "BTC", + "gatewayType": "coinomat", + "addressRegEx": "^[13][a-km-zA-HJ-NP-Z1-9]{25,34}|(bc1)[a-z0-9]{25,90}" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/ethereum.png" + }, + "assetId": "474jTeYx2r2Va35794tCScAXWJG9hU2HcgxzMowaZUnu", + "displayName": "Ethereum", + "isFiat": false, + "isGateway": true, + "wavesId": "WETH", + "gatewayId": "ETH", + "gatewayType": "coinomat", + "addressRegEx": "^0x[0-9a-fA-F]{40}$" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/usd.png" + }, + "assetId": "Ft8X1v1LTa1ABafufpaCWyVj8KkaxUWE6xBhW6sNFJck", + "displayName": "US Dollar", + "isFiat": true, + "isGateway": true, + "wavesId": "WUSD", + "gatewayId": "USD", + "gatewayType": "coinomat", + "addressRegEx": "" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/euro.png" + }, + "assetId": "Gtb1WRznfchDnTh37ezoDTJ4wcoKaRsKqKjJjy7nm2zU", + "displayName": "Euro", + "isFiat": true, + "isGateway": true, + "wavesId": "WEUR", + "gatewayId": "EUR", + "gatewayType": "coinomat", + "addressRegEx": "" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/litecoin.png" + }, + "assetId": "HZk1mbfuJpmxU1Fs4AX5MWLVYtctsNcg6e2C6VKqK8zk", + "displayName": "Litecoin", + "isFiat": false, + "isGateway": true, + "wavesId": "WLTC", + "gatewayId": "LTC", + "gatewayType": "coinomat", + "addressRegEx": "^[LM3][a-km-zA-HJ-NP-Z1-9]{26,33}$" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/zec.png" + }, + "assetId": "BrjUWjndUanm5VsJkbUip8VRYy6LWJePtxya3FNv4TQa", + "displayName": "Zcash", + "isFiat": false, + "isGateway": true, + "wavesId": "WZEC", + "gatewayId": "ZEC", + "gatewayType": "coinomat", + "addressRegEx": "^t[a-zA-Z0-9]{34}$" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/bitcoincash.png" + }, + "assetId": "zMFqXuoyrn5w17PFurTqxB7GsS71fp9dfk6XFwxbPCy", + "displayName": "Bitcoin Cash", + "isFiat": false, + "isGateway": true, + "wavesId": "WBCH", + "gatewayId": "BCH", + "gatewayType": "coinomat", + "addressRegEx": "^([13][a-km-zA-HJ-NP-Z1-9]{25,34}|[qp][a-zA-Z0-9]{41})$" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/bitcoinsv.png" + }, + "assetId": "62LyMjcr2DtiyF5yVXFhoQ2q414VPPJXjsNYp72SuDCH", + "displayName": "Bitcoin SV", + "isFiat": false, + "isGateway": true, + "wavesId": "WBSV", + "gatewayId": "BSV", + "gatewayType": "coinomat", + "addressRegEx": "^([13][a-km-zA-HJ-NP-Z1-9]{25,34}|[qp][a-zA-Z0-9]{41})$" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/lira.png" + }, + "assetId": "2mX5DzVKWrAJw8iwdJnV2qtoeVG9h5nTDpTqC1wb1WEN", + "displayName": "TRY", + "isFiat": true, + "isGateway": true, + "wavesId": "WTRY", + "gatewayId": "TRY", + "gatewayType": "coinomat", + "addressRegEx": "" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/dash.png" + }, + "assetId": "B3uGHFRpSUuGEDWjqB9LWWxafQj8VTvpMucEyoxzws5H", + "displayName": "DASH", + "isFiat": false, + "isGateway": true, + "wavesId": "WDASH", + "gatewayId": "DASH", + "gatewayType": "coinomat", + "addressRegEx": "^X[a-km-zA-HJ-NP-Z1-9]{25,34}$" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/monero.png" + }, + "assetId": "5WvPKSJXzVE2orvbkJ8wsQmmQKqTv9sGBPksV4adViw3", + "displayName": "Monero", + "isFiat": false, + "isGateway": true, + "wavesId": "WXMR", + "gatewayId": "XMR", + "gatewayType": "coinomat", + "addressRegEx": "^([a-km-zA-HJ-NP-Z1-9]{95}|[a-km-zA-HJ-NP-Z1-9]{106})$" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/ergo.png" + }, + "assetId": "5dJj4Hn9t2Ve3tRpNGirUHy4yBK6qdJRAJYV21yPPuGz", + "displayName": "Ergo", + "isFiat": false, + "isGateway": true, + "wavesId": "ERG", + "gatewayId": "Ergo", + "gatewayType": "gateway", + "addressRegEx": "^9[a-km-zA-HJ-NP-Z1-9]{5,}$" + } + ], + "assets": [ + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/mtn.png" + }, + "assetId": "8HYDtqEuHj3RDcwR8yxEvPq1qQSB9FazC8wMHtRb2TFe", + "displayName": "Mytracknet", + "isFiat": false, + "isGateway": false, + "wavesId": "MTN", + "gatewayId": "", + "addressRegEx": "" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/rmob.png" + }, + "assetId": "BmcArNN9VnKAp3HbvpKaoE3utwEXqvP1UjunS9DVKdGS", + "displayName": "RewardMob", + "isFiat": false, + "isGateway": false, + "wavesId": "RMOB", + "gatewayId": "", + "addressRegEx": "" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/tks.png" + }, + "assetId": "BDMRyZsmDZpgKhdM7fUTknKcUbVVkDpMcqEj31PUzjMy", + "displayName": "Tokes Platform", + "isFiat": false, + "isGateway": false, + "wavesId": "TKS", + "gatewayId": "", + "addressRegEx": "" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/smq.png" + }, + "assetId": "CBik4JEmsoPZKKATnShULYj2ebUao5aada9N1XGznEET", + "displayName": "Simdaq", + "isFiat": false, + "isGateway": false, + "wavesId": "SMQ", + "gatewayId": "", + "addressRegEx": "" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/bolt.png" + }, + "assetId": "3mLdMgrg2DQiPfs6NpfB9uPBSdEnXmrWdfh8oyEfuQBu", + "displayName": "BolttCoin", + "isFiat": false, + "isGateway": false, + "wavesId": "BOLT", + "gatewayId": "", + "addressRegEx": "" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/ycht.png" + }, + "assetId": "Hm2VobU7tAX3uvqk18z8bTo44Spq3SpcFU5afe1vh69X", + "displayName": "Yachtco", + "isFiat": false, + "isGateway": false, + "wavesId": "YCHT", + "gatewayId": "", + "addressRegEx": "" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/ww.png" + }, + "assetId": "AbunLGErT5ctzVN8MVjb4Ad9YgjpubB8Hqb17VxzfAck", + "displayName": "Waves World", + "isFiat": false, + "isGateway": false, + "wavesId": "WW", + "gatewayId": "", + "addressRegEx": "" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/inct.png" + }, + "assetId": "FLbGXzrpqkvucZqsHDcNxePTkh2ChmEi4GdBfDRRJVof", + "displayName": "Incent Loyalty", + "isFiat": false, + "isGateway": false, + "wavesId": "INCT", + "gatewayId": "", + "addressRegEx": "" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/mrt.png" + }, + "assetId": "4uK8i4ThRGbehENwa6MxyLtxAjAo1Rj9fduborGExarC", + "displayName": "Miners Reward Token", + "isFiat": false, + "isGateway": false, + "wavesId": "MRT", + "gatewayId": "", + "addressRegEx": "" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/wrt.png" + }, + "assetId": "H1RmwqzeXsdQMt6jR6DPkGbZjA2PKUoofP4WjuCRz1st", + "displayName": "Waves Reward Token", + "isFiat": false, + "isGateway": false, + "wavesId": "WRT", + "gatewayId": "", + "addressRegEx": "" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/wct.png" + }, + "assetId": "DHgwrRvVyqJsepd32YbBqUeDH4GJ1N984X8QoekjgH8J", + "displayName": "WavesCommunity", + "isFiat": false, + "isGateway": false, + "wavesId": "WCT", + "gatewayId": "", + "addressRegEx": "" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/pbt.png" + }, + "assetId": "EdDvbhk4wJ1kL6pMCq1V36GbQE2nGE7Metb87zbaY2JL", + "displayName": "Primalbase", + "isFiat": false, + "isGateway": false, + "wavesId": "PBT", + "gatewayId": "", + "addressRegEx": "" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/cof.png" + }, + "assetId": "AcrRM9STdBu5PNiFveTCbRFTS8tADhKcsbC2KBp8A4tx", + "displayName": "CoffeeCoin", + "isFiat": false, + "isGateway": false, + "wavesId": "COF", + "gatewayId": "", + "addressRegEx": "" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/blxs.png" + }, + "assetId": "9FgLbjiwhn7wFEviVayHNpUV3WnDWJnox9HS5xpcHNDH", + "displayName": "Blockscart", + "isFiat": false, + "isGateway": false, + "wavesId": "BLXS", + "gatewayId": "", + "addressRegEx": "" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/xbbt.png" + }, + "assetId": "882VjGQB5mnaF8ydzNvFdHiqB7i2Bej1wG3B1fBweMAy", + "displayName": "BountyBustersv", + "isFiat": false, + "isGateway": false, + "wavesId": "XBBT", + "gatewayId": "", + "addressRegEx": "" + } + ] +} diff --git a/CommonResources/environment_stagenet.json b/CommonResources/environment_stagenet.json new file mode 100644 index 00000000..a29fb295 --- /dev/null +++ b/CommonResources/environment_stagenet.json @@ -0,0 +1,211 @@ +{ + "name": "Stagenet", + "servers": { + "nodeUrl": "https://nodes-stagenet.wavesnodes.com", + "dataUrl": "https://api-stagenet.wavesplatform.com", + "spamUrl": "https://github-proxy.wvservices.com/wavesplatform/waves-community/master/Scam%20tokens%20according%20to%20the%20opinion%20of%20Waves%20Community.csv", + "matcherUrl": "https://matcher-stagenet.wavesplatform.com", + "gatewayUrl": "https://gw-stagenet.wavesplatform.com/" + }, + "scheme": "S", + "generalAssets": [ + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/waves.png" + }, + "assetId": "WAVES", + "displayName": "Waves", + "isFiat": false, + "isGateway": false, + "wavesId": "WAVES", + "gatewayId": "WAVES", + "gatewayType": "", + "addressRegEx": "" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/wavesenterprise.png" + }, + "assetId": "4TokpX1hU9YVS8ivZxpSJRWQssaGtYUprQgBXfipxmAZ", + "displayName": "WEST", + "isFiat": false, + "isGateway": true, + "wavesId": "Vostok", + "gatewayId": "Vostok", + "gatewayType": "gateway", + "addressRegEx": "" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/bitcoin.png" + }, + "assetId": "yrdwwJJqTKoCt63krHFVZxJvNbUPgHcDeuJXPEGsJCx", + "displayName": "Bitcoin", + "isFiat": false, + "isGateway": true, + "wavesId": "WBTC", + "gatewayId": "BTC", + "gatewayType": "coinomat", + "addressRegEx": "^[13][a-km-zA-HJ-NP-Z1-9]{25,34}|(bc1)[a-z0-9]{25,90}" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/ethereum.png" + }, + "assetId": "Aze8nVXtkP7yoKkcZbpM8tY9HwqvSiWu8mxmPCs21ZC4", + "displayName": "Ethereum", + "isFiat": false, + "isGateway": true, + "wavesId": "WETH", + "gatewayId": "ETH", + "gatewayType": "coinomat", + "addressRegEx": "^0x[0-9a-fA-F]{40}$" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/usd.png" + }, + "assetId": "HETgTyfn5grcHWGRKHi7p3hvMB4QxWVrPD8Fnfi9tfD9", + "displayName": "US Dollar", + "isFiat": true, + "isGateway": true, + "wavesId": "WUSD", + "gatewayId": "USD", + "gatewayType": "coinomat", + "addressRegEx": "" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/euro.png" + }, + "assetId": "EqZfxiqYKkByP42hqNsvuPdXxVYMHaQDwfKgFnAz5D1x", + "displayName": "Euro", + "isFiat": true, + "isGateway": true, + "wavesId": "WEUR", + "gatewayId": "EUR", + "gatewayType": "coinomat", + "addressRegEx": "" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/zec.png" + }, + "assetId": "6xDpHLLhgPq7RrsXACQNwhNkpWcKFAAujv91tRyveVyR", + "displayName": "Zcash", + "isFiat": false, + "isGateway": true, + "wavesId": "WZEC", + "gatewayId": "ZEC", + "gatewayType": "coinomat", + "addressRegEx": "^t[a-zA-Z0-9]{34}$" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/bitcoincash.png" + }, + "assetId": "F9th5zKSTwtKaKEjf28A2Fj6Z6KMKoDX9jmZce6fsAhS", + "displayName": "Bitcoin Cash", + "isFiat": false, + "isGateway": true, + "wavesId": "WBCH", + "gatewayId": "BCH", + "gatewayType": "coinomat", + "addressRegEx": "^([13][a-km-zA-HJ-NP-Z1-9]{25,34}|[qp][a-zA-Z0-9]{41})$" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/bitcoinsv.png" + }, + "assetId": "FQMtkHFF89SasPui9wHxM4r1mwTq7quj6WkB1vZDTRo2", + "displayName": "Bitcoin SV", + "isFiat": false, + "isGateway": true, + "wavesId": "WBSV", + "gatewayId": "BSV", + "gatewayType": "coinomat", + "addressRegEx": "^([13][a-km-zA-HJ-NP-Z1-9]{25,34}|[qp][a-zA-Z0-9]{41})$" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/lira.png" + }, + "assetId": "2xiiermLh4rmr7iLiSCXyPAXrefMLDJRb6Nitn3K7MFo", + "displayName": "TRY", + "isFiat": true, + "isGateway": true, + "wavesId": "WTRY", + "gatewayId": "TRY", + "gatewayType": "coinomat", + "addressRegEx": "" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/dash.png" + }, + "assetId": "5moNQ8zistquaAbCtPoJMd1zKQnMpkvkqghD2vYSsDy6", + "displayName": "DASH", + "isFiat": false, + "isGateway": true, + "wavesId": "WDASH", + "gatewayId": "DASH", + "gatewayType": "coinomat", + "addressRegEx": "^X[a-km-zA-HJ-NP-Z1-9]{25,34}$" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/monero.png" + }, + "assetId": "DChAQFaggQJpyj1DWwfuuxLXoxeCs9R3kdaGfyHPn3PE", + "displayName": "Monero", + "isFiat": false, + "isGateway": true, + "wavesId": "WXMR", + "gatewayId": "XMR", + "gatewayType": "coinomat", + "addressRegEx": "^([a-km-zA-HJ-NP-Z1-9]{95}|[a-km-zA-HJ-NP-Z1-9]{106})$" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/ergo.png" + }, + "assetId": "ERCyLzH7vgqZQkQUsLBBqy3EHqHTxMqzKMe5z8hQR6uL", + "displayName": "Ergo", + "isFiat": false, + "isGateway": true, + "wavesId": "ERG", + "gatewayId": "Ergo", + "gatewayType": "gateway", + "addressRegEx": "^9[a-km-zA-HJ-NP-Z1-9]{5,}$" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/bancor.png" + }, + "assetId": "5oS1vs1x3pa6k9XrKuSoQHVs5zyQNakhHjXZAFUxYMS9", + "displayName": "Bancor", + "isFiat": false, + "isGateway": true, + "wavesId": "BNT", + "gatewayId": "BNT", + "gatewayType": "gateway", + "addressRegEx": "^0x[0-9a-fA-F]{40}$" + }, + { + "iconUrls": { + "default": "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/v3/litecoin.png" + }, + "assetId": "HFX6dpUHv9wWQKGa6wHi72WiEETndwvtsg1A2z8YSuzv", + "displayName": "Litecoin", + "isFiat": false, + "isGateway": true, + "wavesId": "WLTC", + "gatewayId": "LTC", + "gatewayType": "coinomat", + "addressRegEx": "^[LM3][a-km-zA-HJ-NP-Z1-9]{26,33}$" + } + ], + "assets": [ + + ] +} diff --git a/CommonResources/environment_testnet.json b/CommonResources/environment_testnet.json new file mode 100644 index 00000000..8f22cf32 --- /dev/null +++ b/CommonResources/environment_testnet.json @@ -0,0 +1,123 @@ +{ + "name": "Testnet", + "servers": { + "nodeUrl": "https://pool.testnet.wavesnodes.com", + "dataUrl": "https://api.testnet.wavesplatform.com", + "spamUrl": "https://github-proxy.wvservices.com/wavesplatform/waves-community/master/Scam%20tokens%20according%20to%20the%20opinion%20of%20Waves%20Community.csv", + "matcherUrl": "https://matcher.testnet.wavesnodes.com", + "gatewayUrl": "https://gateways-dev.wvservices.com/api" + }, + "scheme": "T", + "generalAssets": [ + { + "assetId": "WAVES", + "displayName": "Waves", + "isFiat": false, + "isGateway": false, + "wavesId": "WAVES", + "gatewayId": "WAVES", + "gatewayType": "", + "addressRegEx": "" + }, + { + "assetId": "DWgwcZTMhSvnyYCoWLRUXXSH1RSkzThXLJhww9gwkqdn", + "displayName": "Bitcoin", + "isFiat": false, + "isGateway": true, + "wavesId": "WBTC", + "gatewayId": "BTC", + "gatewayType": "coinomat", + "addressRegEx": "^[13][a-km-zA-HJ-NP-Z1-9]{25,34}|(bc1)[a-z0-9]{25,90}" + }, + { + "assetId": "BrmjyAWT5jjr3Wpsiyivyvg5vDuzoX2s93WgiexXetB3", + "displayName": "Ethereum", + "isFiat": false, + "isGateway": true, + "wavesId": "WETH", + "gatewayId": "ETH", + "gatewayType": "coinomat", + "addressRegEx": "^0x[a-fA-F0-9]{40}$" + }, + { + "assetId": "D6N2rAqWN6ZCWnCeNFWLGqqjS6nJLeK4m19XiuhdDenr", + "displayName": "US Dollar", + "isFiat": true, + "isGateway": true, + "wavesId": "WUSD", + "gatewayId": "USD", + "gatewayType": "coinomat", + "addressRegEx": "" + }, + { + "assetId": "AsuWyM9MUUsMmWkK7jS48L3ky6gA1pxx7QtEYPbfLjAJ", + "displayName": "Euro", + "isFiat": true, + "isGateway": true, + "wavesId": "WEUR", + "gatewayId": "EUR", + "gatewayType": "coinomat", + "addressRegEx": "" + }, + { + "assetId": "BNdAstuFogzSyN2rY3beJbnBYwYcu7RzTHFjW88g8roK", + "displayName": "Litecoin", + "isFiat": false, + "isGateway": true, + "wavesId": "WLTC", + "gatewayId": "LTC", + "gatewayType": "coinomat", + "addressRegEx": "^[LM3][a-km-zA-HJ-NP-Z1-9]{26,33}$" + }, + { + "assetId": "CFg2KQfkUgUVM2jFCMC5Xh8T8zrebvPc4HjHPfAugU1S", + "displayName": "Zcash", + "isFiat": false, + "isGateway": true, + "wavesId": "WZEC", + "gatewayId": "ZEC", + "gatewayType": "coinomat", + "addressRegEx": "^t1[a-zA-Z0-9]{33}" + }, + { + "assetId": "8HT8tXwrXAYqwm8XrZ2hywWWTUAXxobHB5DakVC1y6jn", + "displayName": "Bitcoin Cash", + "isFiat": false, + "isGateway": true, + "wavesId": "WBCH", + "gatewayId": "BCH", + "gatewayType": "coinomat", + "addressRegEx": "^[13][a-km-zA-HJ-NP-Z1-9]{33}" + }, + { + "assetId": "7itsmgdmomeTXvZzaaxqF3346h4FhciRoWceEw9asNV3", + "displayName": "TRY", + "isFiat": true, + "isGateway": true, + "wavesId": "WTRY", + "gatewayId": "TRY", + "gatewayType": "coinomat", + "addressRegEx": "" + }, + { + "assetId": "DGgBtwVoXKAKKvV2ayUpSoPzTJxt7jo9KiXMJRzTH2ET", + "displayName": "DASH", + "isFiat": false, + "isGateway": true, + "wavesId": "WDASH", + "gatewayId": "DASH", + "gatewayType": "coinomat", + "addressRegEx": "^X[1-9A-HJ-NP-Za-km-z]{33}" + }, + { + "assetId": "8oPbSCKFHkXBy1hCGSg9pJkSARE7zhTQTLpc8KZwdtr7", + "displayName": "Monero", + "isFiat": false, + "isGateway": true, + "wavesId": "WXMR", + "gatewayId": "XMR", + "gatewayType": "coinomat", + "addressRegEx": "^4[0-9AB][1-9A-HJ-NP-Za-km-z]{93}" + } + ] +} diff --git a/WavesWallet-iOS/Resources/spam.csv b/CommonResources/spam.csv similarity index 100% rename from WavesWallet-iOS/Resources/spam.csv rename to CommonResources/spam.csv diff --git a/DataLayer.podspec b/DataLayer.podspec new file mode 100644 index 00000000..7dced5ce --- /dev/null +++ b/DataLayer.podspec @@ -0,0 +1,51 @@ +Pod::Spec.new do |spec| + + spec.name = 'DataLayer' + spec.version = '0.1' + spec.ios.deployment_target = '11.0' + spec.requires_arc = true + spec.license = { :type => 'MIT' } + spec.homepage = 'https://wavesplatform.com' + spec.authors = { 'Mefilt' => 'Mefilt@gmail.com' } + spec.summary = 'DataLayer' + + spec.source_files = 'DataLayer/**/**/*.{swift}' + spec.source = { :git => ''} + + spec.ios.framework = 'Foundation' + + spec.static_framework = true + + # External Service + spec.dependency 'Firebase' + + spec.dependency 'Firebase/Core' + spec.dependency 'Firebase/Database' + spec.dependency 'Firebase/Auth' + spec.dependency 'Firebase/InAppMessagingDisplay' + + spec.dependency 'Fabric' + spec.dependency 'Crashlytics' + spec.dependency 'Amplitude-iOS' + spec.dependency 'AppsFlyerFramework' + spec.dependency 'Sentry' + + # DB + spec.dependency 'RealmSwift' + spec.dependency 'RxRealm' + spec.dependency 'Moya/RxSwift' + + + # Assisstant + spec.dependency 'RxSwift' + spec.dependency 'RxSwiftExt' + spec.dependency 'RxOptional' + spec.dependency 'CSV.swift' + + # Waves + spec.dependency 'WavesSDKExtensions' + spec.dependency 'WavesSDK' + spec.dependency 'WavesSDKCrypto' + spec.dependency 'Extensions' + spec.dependency 'DomainLayer' +end diff --git a/DataLayer/DataLayer.h b/DataLayer/DataLayer.h new file mode 100644 index 00000000..7fc4ddd7 --- /dev/null +++ b/DataLayer/DataLayer.h @@ -0,0 +1,19 @@ +// +// DataLayer.h +// DataLayer +// +// Created by rprokofev on 17.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +#import + +//! Project version number for DataLayer. +FOUNDATION_EXPORT double DataLayerVersionNumber; + +//! Project version string for DataLayer. +FOUNDATION_EXPORT const unsigned char DataLayerVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/DataLayer/Info.plist b/DataLayer/Info.plist new file mode 100644 index 00000000..cc02ce1c --- /dev/null +++ b/DataLayer/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + 3901 + + diff --git a/DataLayer/Sources/Assisstants/AnalyticManager.swift b/DataLayer/Sources/Assisstants/AnalyticManager.swift new file mode 100644 index 00000000..6d13ad12 --- /dev/null +++ b/DataLayer/Sources/Assisstants/AnalyticManager.swift @@ -0,0 +1,39 @@ +// +// UseCasesFactory.instance.analyticManagerswift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 3/22/19. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import DomainLayer +import Amplitude_iOS +import FirebaseAnalytics +import AppsFlyerLib +import WavesSDKCrypto + +private struct Constants { + static let AUUIDKey: String = "AUUID" +} + +public final class AnalyticManager: AnalyticManagerProtocol { + + private var auuid: String? = nil + + public func setAUUID(_ AUUID: String) { + self.auuid = AUUID + } + + public func trackEvent(_ event: AnalyticManagerEvent) { + + var params = event.params + if let auuid = auuid { + params[Constants.AUUIDKey] = auuid + } + + Amplitude.instance().logEvent(event.name, withEventProperties: params) + Analytics.logEvent(event.name.replacingOccurrences(of: " ", with: "_"), parameters: params) + AppsFlyerTracker.shared()?.trackEvent(event.name, withValues: params) + } +} diff --git a/WavesWallet-iOS/Extensions/DatabaseReference+Rx.swift b/DataLayer/Sources/Assisstants/DatabaseReference+Rx.swift similarity index 100% rename from WavesWallet-iOS/Extensions/DatabaseReference+Rx.swift rename to DataLayer/Sources/Assisstants/DatabaseReference+Rx.swift diff --git a/DataLayer/Sources/Assisstants/MoyaProvider+Helper.swift b/DataLayer/Sources/Assisstants/MoyaProvider+Helper.swift new file mode 100644 index 00000000..d8d606b8 --- /dev/null +++ b/DataLayer/Sources/Assisstants/MoyaProvider+Helper.swift @@ -0,0 +1,19 @@ +// +// NodeTargetType.swift +// WavesWallet-iOS +// +// Created by mefilt on 09.07.2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import Result +import Moya + +extension MoyaProvider { + final class func anyMoyaProvider() -> MoyaProvider { + + return MoyaProvider(callbackQueue: nil, + plugins: [SentryNetworkLoggerPlugin()]) + } +} diff --git a/WavesWallet-iOS/DataLayer/Assisstants/NodePlugin.swift b/DataLayer/Sources/Assisstants/NodePlugin.swift similarity index 98% rename from WavesWallet-iOS/DataLayer/Assisstants/NodePlugin.swift rename to DataLayer/Sources/Assisstants/NodePlugin.swift index 78e7f0b1..6f88356b 100644 --- a/WavesWallet-iOS/DataLayer/Assisstants/NodePlugin.swift +++ b/DataLayer/Sources/Assisstants/NodePlugin.swift @@ -9,7 +9,7 @@ import Foundation import Result import Moya -import WavesSDKExtension +import WavesSDKExtensions private struct NodeHeaders: Encodable, Decodable, TSUD { diff --git a/WavesWallet-iOS/Extensions/Results+Limit.swift b/DataLayer/Sources/Assisstants/Results+Limit.swift similarity index 96% rename from WavesWallet-iOS/Extensions/Results+Limit.swift rename to DataLayer/Sources/Assisstants/Results+Limit.swift index ab2aea29..e3e87e4a 100644 --- a/WavesWallet-iOS/Extensions/Results+Limit.swift +++ b/DataLayer/Sources/Assisstants/Results+Limit.swift @@ -8,7 +8,7 @@ import Foundation import RealmSwift -extension Results { +public extension Results { func get(offset: Int, limit: Int) -> Array { diff --git a/DataLayer/Sources/Assisstants/SentryManager.swift b/DataLayer/Sources/Assisstants/SentryManager.swift new file mode 100644 index 00000000..bcaac111 --- /dev/null +++ b/DataLayer/Sources/Assisstants/SentryManager.swift @@ -0,0 +1,77 @@ +// +// SentryService.swift +// WavesWallet-iOS +// +// Created by rprokofev on 27/02/2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import Sentry +import WavesSDKExtensions + +public class SentryManager { + + typealias Event = Sentry.Event + + typealias Level = SweetLoggerLevel + + private static var shared: SentryManager! + + private var client: Client? = nil + + init(sentryIoInfoPath: String) { + + guard let dsn = NSDictionary(contentsOfFile: sentryIoInfoPath)?["DSN_URL"] as? String else { + print("Sentry DSN Not found") + return + } + + do { + let client = try Client(dsn: dsn) + self.client = client + Client.shared = self.client + } catch let error { + print("Sentry Not Loading :( \(error)") + } + + do { + try Client.shared?.startCrashHandler() + } catch let error { + print("Centry startCrashHandler :( \(error)") + } + + Client.shared?.enableAutomaticBreadcrumbTracking() + } + + class func initialization(sentryIoInfoPath: String) { + shared = SentryManager(sentryIoInfoPath: sentryIoInfoPath) + } + + static var currentUser: Sentry.User { + + let user = Sentry.User.init(userId: UIDevice.uuid) + user.userId = UIDevice.uuid + return user + } + + static func send(event: Event) { + + event.timestamp = Date() + event.user = currentUser + + if let client = SentryManager.shared.client { + client.send(event: event, completion: { error in + + if let error = error { + print("SweetLogger :( \(String(describing: error))") + } else { + print("SweetLogger :) event") + } + }) + } else { + print("SentryManager Not Loading") + } + } +} + diff --git a/WavesWallet-iOS/Extensions/Type/SentryNetworkLoggerPlugin.swift b/DataLayer/Sources/Assisstants/SentryNetworkLoggerPlugin.swift similarity index 94% rename from WavesWallet-iOS/Extensions/Type/SentryNetworkLoggerPlugin.swift rename to DataLayer/Sources/Assisstants/SentryNetworkLoggerPlugin.swift index 667a3cf3..6bad5615 100644 --- a/WavesWallet-iOS/Extensions/Type/SentryNetworkLoggerPlugin.swift +++ b/DataLayer/Sources/Assisstants/SentryNetworkLoggerPlugin.swift @@ -9,6 +9,11 @@ import Foundation import Result import Moya +private struct Cosntants { + + static let notFoundHTTPError: Int = 404 +} + public final class SentryNetworkLoggerPlugin: PluginType { public func willSend(_ request: RequestType, target: TargetType) {} @@ -29,7 +34,7 @@ public final class SentryNetworkLoggerPlugin: PluginType { statusCode = error.statusCode case .success(let value): if let statusCode = value.response?.statusCode, - statusCode < 300 { + (statusCode < 300 || statusCode == Cosntants.notFoundHTTPError) { return } @@ -38,7 +43,7 @@ public final class SentryNetworkLoggerPlugin: PluginType { } guard let unwrapMessage = message else { return } - + let event = SentryManager.Event(level: .error) if let statusCode = statusCode { diff --git a/WavesWallet-iOS/DataLayer/Assisstants/SpamCSV+Assisstants.swift b/DataLayer/Sources/Assisstants/SpamCSV+Assisstants.swift similarity index 100% rename from WavesWallet-iOS/DataLayer/Assisstants/SpamCSV+Assisstants.swift rename to DataLayer/Sources/Assisstants/SpamCSV+Assisstants.swift diff --git a/DataLayer/Sources/Assisstants/String+NormalizeAssetId.swift b/DataLayer/Sources/Assisstants/String+NormalizeAssetId.swift new file mode 100644 index 00000000..18368224 --- /dev/null +++ b/DataLayer/Sources/Assisstants/String+NormalizeAssetId.swift @@ -0,0 +1,36 @@ +// +// String+NormalizeAssetId.swift +// WavesWallet-iOS +// +// Created by Prokofev Ruslan on 08/09/2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import WavesSDK +import DomainLayer + +public extension Optional where Wrapped == String { + + var normalizeAssetId: String { + if let id = self { + return id + } else { + return WavesSDKConstants.wavesAssetId + } + } +} + +public extension String { + + func normalizeAddress(environment: WalletEnvironment) -> String { + + if let range = self.range(of: environment.aliasScheme), self.contains(environment.aliasScheme) { + var newString = self + newString.removeSubrange(range) + return newString + } + + return self + } +} diff --git a/WavesWallet-iOS/Extensions/Type/SweetLoggerSentry.swift b/DataLayer/Sources/Assisstants/SweetLoggerSentry.swift similarity index 80% rename from WavesWallet-iOS/Extensions/Type/SweetLoggerSentry.swift rename to DataLayer/Sources/Assisstants/SweetLoggerSentry.swift index 352dc32b..bc060b9e 100644 --- a/WavesWallet-iOS/Extensions/Type/SweetLoggerSentry.swift +++ b/DataLayer/Sources/Assisstants/SweetLoggerSentry.swift @@ -7,18 +7,18 @@ // import Foundation import Sentry -import WavesSDKExtension +import WavesSDKExtensions -final class SweetLoggerSentry: SweetLoggerProtocol { +public final class SweetLoggerSentry: SweetLoggerProtocol { - var visibleLevels: [SweetLoggerLevel] = [] + public private(set) var visibleLevels: [SweetLoggerLevel] = [] - init(visibleLevels: [SweetLoggerLevel]) { + public init(visibleLevels: [SweetLoggerLevel]) { self.visibleLevels = visibleLevels } - func send(message: @escaping @autoclosure () -> Any, + public func send(message: @escaping @autoclosure () -> Any, level: SweetLoggerLevel, file: String, function: String, @@ -30,7 +30,7 @@ final class SweetLoggerSentry: SweetLoggerProtocol { let event = Sentry.Event(level: level.sentrySeverity) event.message = "\(message())" - + SentryManager.send(event: event) } } diff --git a/DataLayer/Sources/Assisstants/TransactionSenderAssistant.swift b/DataLayer/Sources/Assisstants/TransactionSenderAssistant.swift new file mode 100644 index 00000000..a8cd071c --- /dev/null +++ b/DataLayer/Sources/Assisstants/TransactionSenderAssistant.swift @@ -0,0 +1,375 @@ +// +// TransactionAssistant.swift +// DataLayer +// +// Created by Pavel Gubin on 06.07.2019. +// + +import Foundation +import DomainLayer +import WavesSDK +import WavesSDKExtensions +import WavesSDKCrypto + +extension TransactionSenderSpecifications { + + private func chainId(servicesEnvironment: ApplicationEnviroment, + specifications: TransactionSenderSpecifications, + wallet: DomainLayer.DTO.SignedWallet) -> String { + + let walletEnvironment = servicesEnvironment.walletEnvironment + + + return specifications.chainId ?? walletEnvironment.scheme + } + + private func timestamp(specifications: TransactionSenderSpecifications) -> Date { + return specifications.timestamp ?? Date() + } + + func broadcastSpecification(servicesEnvironment: ApplicationEnviroment, + wallet: DomainLayer.DTO.SignedWallet, + specifications: TransactionSenderSpecifications) -> NodeService.Query.Transaction? { + + let walletEnvironment = servicesEnvironment.walletEnvironment + let timestampServerDiff = servicesEnvironment.timestampServerDiff + + let scheme = chainId(servicesEnvironment: servicesEnvironment, + specifications: specifications, + wallet: wallet) + + let timestamp = self.timestamp(specifications: specifications) + .millisecondsSince1970(timestampDiff: timestampServerDiff) + + var signature = self.signature(timestamp: timestamp, + scheme: scheme, + publicKey: wallet.publicKey.publicKey) + + do { + signature = try wallet.sign(input: signature, kind: [.none]) + } catch let e { + SweetLogger.error(e) + return nil + } + + let proofs = [Base58Encoder.encode(signature)] + + let broadcastSpecification = self.continueBroadcastSpecification(timestamp: timestamp, + environment: walletEnvironment, + publicKey: wallet.publicKey.getPublicKeyStr(), + proofs: proofs) + return broadcastSpecification + } + + private func continueBroadcastSpecification(timestamp: Int64, + environment: WalletEnvironment, + publicKey: String, + proofs: [String]) -> NodeService.Query.Transaction { + + switch self { + + case .burn(let model): + + return .burn(NodeService.Query.Transaction.Burn(version: self.version, + chainId: environment.scheme, + fee: model.fee, + assetId: model.assetID, + quantity: model.quantity, + timestamp: timestamp, + senderPublicKey: publicKey, + proofs: proofs)) + + case .createAlias(let model): + + return .createAlias(NodeService.Query.Transaction.Alias(version: self.version, + chainId: environment.scheme, + name: model.alias, + fee: model.fee, + timestamp: timestamp, + senderPublicKey: publicKey, + proofs: proofs)) + case .lease(let model): + + var recipient = "" + if model.recipient.count <= WavesSDKConstants.aliasNameMaxLimitSymbols { + recipient = environment.aliasScheme + model.recipient + } else { + recipient = model.recipient + } + return .startLease(NodeService.Query.Transaction.Lease(version: self.version, + chainId: environment.scheme, + fee: model.fee, + recipient: recipient, + amount: model.amount, + timestamp: timestamp, + senderPublicKey: publicKey, + proofs: proofs)) + case .cancelLease(let model): + + return .cancelLease(NodeService.Query.Transaction.LeaseCancel(version: self.version, + chainId: environment.scheme, + fee: model.fee, + leaseId: model.leaseId, + timestamp: timestamp, + senderPublicKey: publicKey, + proofs: proofs)) + + case .data(let model): + + return .data(NodeService.Query.Transaction.Data(version: self.version, + fee: model.fee, + timestamp: timestamp, + senderPublicKey: publicKey, + proofs: proofs, + data: model.dataForNode, + chainId: environment.scheme)) + + case .send(let model): + + var recipient = "" + if model.recipient.count <= WavesSDKConstants.aliasNameMaxLimitSymbols { + recipient = environment.aliasScheme + model.recipient + } else { + recipient = model.recipient + } + + return .transfer(NodeService.Query.Transaction.Transfer(version: self.version, + recipient: recipient, + assetId: model.assetId, + amount: model.amount, + fee: model.fee, + attachment: Base58Encoder.encode(Array(model.attachment.utf8)), + feeAssetId: model.getFeeAssetID, + timestamp: timestamp, + senderPublicKey: publicKey, + proofs: proofs, + chainId: environment.scheme)) + + case .invokeScript(let model): + + + var call: NodeService.Query.Transaction.InvokeScript.Call? = nil + + if let localCall = model.call { + + let args = localCall.args.map({ (arg) -> NodeService.Query.Transaction.InvokeScript.Arg in + + let value: NodeService.Query.Transaction.InvokeScript.Arg.Value = { () -> NodeService.Query.Transaction.InvokeScript.Arg.Value in + + switch arg.value { + case .binary(let value): + return .binary(value) + + case .bool(let value): + return .bool(value) + + case .integer(let value): + return .integer(value) + + case .string(let value): + return .string(value) + } + + }() + + return .init(value: value) + }) + + call = NodeService.Query.Transaction.InvokeScript.Call(function: localCall.function, + args: args) + } + + let payment = model.payment.map { NodeService.Query.Transaction.InvokeScript.Payment.init(amount: $0.amount, assetId: $0.assetId) } + + return .invokeScript(.init(version: self.version, + chainId: environment.scheme, + fee: model.fee, + timestamp: timestamp, + senderPublicKey: publicKey, + feeAssetId: model.feeAssetId, + proofs: proofs, + dApp: model.dApp, + call: call, + payment: payment)) +} + + } + + func signature(timestamp: Int64, scheme: String, publicKey: [UInt8]) -> [UInt8] { + + switch self { + + case .data(let model): + + let bytes = TransactionSignatureV1.data(.init(fee: model.fee, + data: model.dataForSignature, + chainId: scheme, + senderPublicKey: Base58Encoder.encode(publicKey), + timestamp: timestamp)).bytesStructure + + return bytes + + case .burn(let model): + + let bytes = TransactionSignatureV2.burn(.init(assetID: model.assetID, + quantity: model.quantity, + fee: model.fee, + chainId: scheme, + senderPublicKey: Base58Encoder.encode(publicKey), + timestamp: timestamp)).bytesStructure + + return bytes + + case .cancelLease(let model): + + let bytes = TransactionSignatureV2.cancelLease(.init(leaseId: model.leaseId, + fee: model.fee, + chainId: scheme, + senderPublicKey: Base58Encoder.encode(publicKey), + timestamp: timestamp)).bytesStructure + + return bytes + + + case .createAlias(let model): + + let bytes = TransactionSignatureV2.createAlias(.init(alias: model.alias, + fee: model.fee, + chainId: scheme, + senderPublicKey: Base58Encoder.encode(publicKey), + timestamp: timestamp)).bytesStructure + + return bytes + + case .lease(let model): + + let bytes = TransactionSignatureV2.startLease(.init(recipient: model.recipient, + amount: model.amount, + fee: model.fee, + chainId: scheme, + senderPublicKey: Base58Encoder.encode(publicKey), + timestamp: timestamp)).bytesStructure + + return bytes + + case .send(let model): + + let bytes = TransactionSignatureV2.transfer(.init(senderPublicKey: Base58Encoder.encode(publicKey), + recipient: model.recipient, + assetId: model.assetId, + amount: model.amount, + fee: model.fee, + attachment: Base58Encoder.encode(Array(model.attachment.utf8)), + feeAssetID: model.feeAssetID, + chainId: scheme, + timestamp: timestamp)) + .bytesStructure + + return bytes + + case .invokeScript(let model): + + var call: TransactionSignatureV1.Structure.InvokeScript.Call? + + if let localCall = model.call { + + let args = localCall.args.map { (arg) -> TransactionSignatureV1.Structure.InvokeScript.Arg in + + let value = { () -> TransactionSignatureV1.Structure.InvokeScript.Arg.Value in + + switch arg.value { + case .binary(let value): + return .binary(value) + + case .integer(let value): + return .integer(value) + + case .bool(let value): + return .bool(value) + + case .string(let value): + return .string(value) + } + }() + + return TransactionSignatureV1.Structure.InvokeScript.Arg.init(value: value) + } + + call = TransactionSignatureV1.Structure.InvokeScript.Call.init(function: localCall.function, + args: args) + } + + let payment = model.payment.map { TransactionSignatureV1.Structure.InvokeScript.Payment.init(amount: $0.amount, assetId: $0.assetId) } + + let bytes = TransactionSignatureV1.invokeScript(.init(senderPublicKey: Base58Encoder.encode(publicKey), + fee: model.fee, + chainId: scheme, + timestamp: timestamp, + feeAssetId: model.feeAssetId, + dApp: model.dApp, + call: call, + payment: payment)) + .bytesStructure + + return bytes + } + } +} + + +private extension SendTransactionSender { + + var getFeeAssetID: String { + return feeAssetID == WavesSDKConstants.wavesAssetId ? "" : feeAssetID + } +} + +private extension DataTransactionSender { + + var dataForSignature: [TransactionSignatureV1.Structure.Data.Value] { + return self.data.map({ (value) -> TransactionSignatureV1.Structure.Data.Value in + + var kind: TransactionSignatureV1.Structure.Data.Value.Kind! + + switch value.value { + case .binary(let data): + kind = .binary(data) + + case .integer(let number): + kind = .integer(number) + + case .boolean(let flag): + kind = .boolean(flag) + + case .string(let str): + kind = .string(str) + } + + return TransactionSignatureV1.Structure.Data.Value.init(key: value.key, value: kind) + + }) + } + + var dataForNode: [NodeService.Query.Transaction.Data.Value] { + return self.data.map { (value) -> NodeService.Query.Transaction.Data.Value in + + var kind: NodeService.Query.Transaction.Data.Value.Kind! + + switch value.value { + case .binary(let data): + kind = .binary(data) + + case .integer(let number): + kind = .integer(number) + + case .boolean(let flag): + kind = .boolean(flag) + + case .string(let str): + kind = .string(str) + } + + return NodeService.Query.Transaction.Data.Value(key: value.key, value: kind) + } + } +} diff --git a/DataLayer/Sources/Assisstants/Types/Signature.swift b/DataLayer/Sources/Assisstants/Types/Signature.swift new file mode 100644 index 00000000..f3d7df30 --- /dev/null +++ b/DataLayer/Sources/Assisstants/Types/Signature.swift @@ -0,0 +1,40 @@ +// +// Signature.swift +// WavesWallet-iOS +// +// Created by mefilt on 23.07.2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import WavesSDKExtensions +import WavesSDKCrypto +import DomainLayer +import Extensions + +//TODO: Signature Protocol need remove and is using Signature Protocol from SDK +protocol SignatureProtocol { + + var signedWallet: DomainLayer.DTO.SignedWallet { get } + + var toSign: [UInt8] { get } + + func signature() -> [UInt8] + + func signature() -> String +} + +extension SignatureProtocol { + + var publicKey: PublicKeyAccount { + return signedWallet.publicKey + } + + func signature() -> [UInt8] { + return (try? signedWallet.sign(input: toSign, kind: [.none])) ?? [] + } + + func signature() -> String { + return Base58Encoder.encode(signature()) + } +} diff --git a/DataLayer/Sources/Assisstants/Types/TimestampSignature.swift b/DataLayer/Sources/Assisstants/Types/TimestampSignature.swift new file mode 100644 index 00000000..6795c01e --- /dev/null +++ b/DataLayer/Sources/Assisstants/Types/TimestampSignature.swift @@ -0,0 +1,136 @@ +// +// TimestampSignature.swift +// WavesWallet-iOS +// +// Created by mefilt on 23.07.2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import WavesSDKExtensions +import WavesSDK +import WavesSDKCrypto +import DomainLayer +import Extensions + +fileprivate enum Constants { + static let timestamp = "timestamp" + static let senderPublicKey = "senderPublicKey" + static let signature = "signature" +} + +struct TimestampSignature: SignatureProtocol { + + private(set) var signedWallet: DomainLayer.DTO.SignedWallet + + private(set) var timestamp: Int64 + + var toSign: [UInt8] { + let s1 = signedWallet.publicKey.publicKey + let s2 = toByteArray(timestamp) + return s1 + s2 + } + + var parameters: [String: String] { + return [Constants.senderPublicKey: signedWallet.publicKey.getPublicKeyStr(), + Constants.timestamp: "\(timestamp)", + Constants.signature: signature()] + } +} + +extension TimestampSignature { + init(signedWallet: DomainLayer.DTO.SignedWallet, timestampServerDiff: Int64) { + self.init(signedWallet: signedWallet, + timestamp: Date().millisecondsSince1970(timestampDiff: timestampServerDiff)) + } +} + +struct CreateOrderSignature: SignatureProtocol { + + struct AssetPair { + let priceAssetId: String + let amountAssetId: String + + func assetIdBytes(_ id: String) -> [UInt8] { + return (id == WavesSDKConstants.wavesAssetId) ? [UInt8(0)] : ([UInt8(1)] + Base58Encoder.decode(id)) + } + + var bytes: [UInt8] { + return assetIdBytes(amountAssetId) + assetIdBytes(priceAssetId) + } + } + + enum OrderType { + + case buy + case sell + + var bytes: [UInt8] { + switch self { + case .sell: return [UInt8(1)] + case .buy: return [UInt8(0)] + } + } + } + + enum Version: Int { + case V2 = 2 + case V3 = 3 + } + + private(set) var signedWallet: DomainLayer.DTO.SignedWallet + + private(set) var timestamp: Int64 + + private(set) var matcherPublicKey: PublicKeyAccount + + private(set) var assetPair: AssetPair + + private(set) var orderType: OrderType + + private(set) var price: Int64 + + private(set) var amount: Int64 + + private(set) var expiration: Int64 + + private(set) var matcherFee: Int64 + + private(set) var matcherFeeAsset: String + + private(set) var version: Version + + var toSign: [UInt8] { + + let s1 = toByteArray(UInt8(version.rawValue)) + signedWallet.publicKey.publicKey + matcherPublicKey.publicKey + let s2 = assetPair.bytes + orderType.bytes + let s3 = toByteArray(price) + toByteArray(amount) + let s4 = toByteArray(timestamp) + toByteArray(expiration) + toByteArray(matcherFee) + + var result = s1 + s2 + s3 + s4 + + if version == .V3 { + result += [UInt8(1)] + (WavesCrypto.shared.base58decode(input: matcherFeeAsset) ?? []) + } + + return result + } + + private var id: [UInt8] { + return Hash.fastHash(toSign) + } +} + +struct CancelOrderSignature: SignatureProtocol { + + private(set) var signedWallet: DomainLayer.DTO.SignedWallet + + private(set) var orderId: String + + var toSign: [UInt8] { + let s1 = signedWallet.publicKey.publicKey + let s2 = Base58Encoder.decode(orderId) + return s1 + s2 + } +} + diff --git a/WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/AccountEnvironment.swift b/DataLayer/Sources/DataBase/Wallet/Model/AccountEnvironment.swift similarity index 100% rename from WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/AccountEnvironment.swift rename to DataLayer/Sources/DataBase/Wallet/Model/AccountEnvironment.swift diff --git a/WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/AccountSettings.swift b/DataLayer/Sources/DataBase/Wallet/Model/AccountSettings.swift similarity index 100% rename from WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/AccountSettings.swift rename to DataLayer/Sources/DataBase/Wallet/Model/AccountSettings.swift diff --git a/WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/AddressBook.swift b/DataLayer/Sources/DataBase/Wallet/Model/AddressBook.swift similarity index 100% rename from WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/AddressBook.swift rename to DataLayer/Sources/DataBase/Wallet/Model/AddressBook.swift diff --git a/WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Alias.swift b/DataLayer/Sources/DataBase/Wallet/Model/Alias.swift similarity index 100% rename from WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Alias.swift rename to DataLayer/Sources/DataBase/Wallet/Model/Alias.swift diff --git a/WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Asset.swift b/DataLayer/Sources/DataBase/Wallet/Model/Asset.swift similarity index 96% rename from WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Asset.swift rename to DataLayer/Sources/DataBase/Wallet/Model/Asset.swift index 7e62b58b..ac859027 100644 --- a/WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Asset.swift +++ b/DataLayer/Sources/DataBase/Wallet/Model/Asset.swift @@ -34,6 +34,8 @@ final class Asset: Object { @objc dynamic var iconLogoUrl: String? @objc dynamic var hasScript: Bool = false @objc dynamic var minSponsoredFee: Int64 = 0 + @objc dynamic var gatewayType: String? + override class func primaryKey() -> String? { return "id" } diff --git a/WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/AssetBalance.swift b/DataLayer/Sources/DataBase/Wallet/Model/AssetBalance.swift similarity index 100% rename from WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/AssetBalance.swift rename to DataLayer/Sources/DataBase/Wallet/Model/AssetBalance.swift diff --git a/WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/AssetBalanceSettings.swift b/DataLayer/Sources/DataBase/Wallet/Model/AssetBalanceSettings.swift similarity index 100% rename from WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/AssetBalanceSettings.swift rename to DataLayer/Sources/DataBase/Wallet/Model/AssetBalanceSettings.swift diff --git a/WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/DexAssetPair.swift b/DataLayer/Sources/DataBase/Wallet/Model/DexAssetPair.swift similarity index 98% rename from WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/DexAssetPair.swift rename to DataLayer/Sources/DataBase/Wallet/Model/DexAssetPair.swift index 77058ed4..c28c5e74 100644 --- a/WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/DexAssetPair.swift +++ b/DataLayer/Sources/DataBase/Wallet/Model/DexAssetPair.swift @@ -8,6 +8,7 @@ import Foundation import RealmSwift +import DomainLayer final class DexAsset: Object { @objc dynamic var id: String = "" diff --git a/WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/AliasTransaction.swift b/DataLayer/Sources/DataBase/Wallet/Model/Transaction/AliasTransaction.swift similarity index 100% rename from WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/AliasTransaction.swift rename to DataLayer/Sources/DataBase/Wallet/Model/Transaction/AliasTransaction.swift diff --git a/WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/AnyTransaction.swift b/DataLayer/Sources/DataBase/Wallet/Model/Transaction/AnyTransaction.swift similarity index 100% rename from WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/AnyTransaction.swift rename to DataLayer/Sources/DataBase/Wallet/Model/Transaction/AnyTransaction.swift diff --git a/WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/AssetScriptTransaction.swift b/DataLayer/Sources/DataBase/Wallet/Model/Transaction/AssetScriptTransaction.swift similarity index 100% rename from WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/AssetScriptTransaction.swift rename to DataLayer/Sources/DataBase/Wallet/Model/Transaction/AssetScriptTransaction.swift diff --git a/WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/BurnTransaction.swift b/DataLayer/Sources/DataBase/Wallet/Model/Transaction/BurnTransaction.swift similarity index 100% rename from WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/BurnTransaction.swift rename to DataLayer/Sources/DataBase/Wallet/Model/Transaction/BurnTransaction.swift diff --git a/WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/DataTransaction.swift b/DataLayer/Sources/DataBase/Wallet/Model/Transaction/DataTransaction.swift similarity index 100% rename from WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/DataTransaction.swift rename to DataLayer/Sources/DataBase/Wallet/Model/Transaction/DataTransaction.swift diff --git a/WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/ExchangeTransaction.swift b/DataLayer/Sources/DataBase/Wallet/Model/Transaction/ExchangeTransaction.swift similarity index 95% rename from WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/ExchangeTransaction.swift rename to DataLayer/Sources/DataBase/Wallet/Model/Transaction/ExchangeTransaction.swift index bbaaa3ee..ca7a131d 100644 --- a/WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/ExchangeTransaction.swift +++ b/DataLayer/Sources/DataBase/Wallet/Model/Transaction/ExchangeTransaction.swift @@ -32,6 +32,7 @@ final class ExchangeTransactionOrder: Object { @objc dynamic var expiration: Int64 = 0 @objc dynamic var matcherFee: Int64 = 0 @objc dynamic var signature: String? = nil + @objc dynamic var matcherFeeAssetId: String? = nil } final class ExchangeTransactionAssetPair: Object { diff --git a/WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/InvokeScriptTransaction.swift b/DataLayer/Sources/DataBase/Wallet/Model/Transaction/InvokeScriptTransaction.swift similarity index 100% rename from WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/InvokeScriptTransaction.swift rename to DataLayer/Sources/DataBase/Wallet/Model/Transaction/InvokeScriptTransaction.swift diff --git a/WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/IssueTransaction.swift b/DataLayer/Sources/DataBase/Wallet/Model/Transaction/IssueTransaction.swift similarity index 100% rename from WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/IssueTransaction.swift rename to DataLayer/Sources/DataBase/Wallet/Model/Transaction/IssueTransaction.swift diff --git a/WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/LeaseCancelTransaction.swift b/DataLayer/Sources/DataBase/Wallet/Model/Transaction/LeaseCancelTransaction.swift similarity index 100% rename from WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/LeaseCancelTransaction.swift rename to DataLayer/Sources/DataBase/Wallet/Model/Transaction/LeaseCancelTransaction.swift diff --git a/WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/LeaseTransaction.swift b/DataLayer/Sources/DataBase/Wallet/Model/Transaction/LeaseTransaction.swift similarity index 100% rename from WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/LeaseTransaction.swift rename to DataLayer/Sources/DataBase/Wallet/Model/Transaction/LeaseTransaction.swift diff --git a/WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/MassTransferTransaction.swift b/DataLayer/Sources/DataBase/Wallet/Model/Transaction/MassTransferTransaction.swift similarity index 100% rename from WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/MassTransferTransaction.swift rename to DataLayer/Sources/DataBase/Wallet/Model/Transaction/MassTransferTransaction.swift diff --git a/WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/ReissueTransaction.swift b/DataLayer/Sources/DataBase/Wallet/Model/Transaction/ReissueTransaction.swift similarity index 100% rename from WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/ReissueTransaction.swift rename to DataLayer/Sources/DataBase/Wallet/Model/Transaction/ReissueTransaction.swift diff --git a/WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/ScriptTransaction.swift b/DataLayer/Sources/DataBase/Wallet/Model/Transaction/ScriptTransaction.swift similarity index 100% rename from WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/ScriptTransaction.swift rename to DataLayer/Sources/DataBase/Wallet/Model/Transaction/ScriptTransaction.swift diff --git a/WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/SponsorshipTransaction.swift b/DataLayer/Sources/DataBase/Wallet/Model/Transaction/SponsorshipTransaction.swift similarity index 100% rename from WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/SponsorshipTransaction.swift rename to DataLayer/Sources/DataBase/Wallet/Model/Transaction/SponsorshipTransaction.swift diff --git a/WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/Transaction.swift b/DataLayer/Sources/DataBase/Wallet/Model/Transaction/Transaction.swift similarity index 100% rename from WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/Transaction.swift rename to DataLayer/Sources/DataBase/Wallet/Model/Transaction/Transaction.swift diff --git a/WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/TransferTransaction.swift b/DataLayer/Sources/DataBase/Wallet/Model/Transaction/TransferTransaction.swift similarity index 100% rename from WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/TransferTransaction.swift rename to DataLayer/Sources/DataBase/Wallet/Model/Transaction/TransferTransaction.swift diff --git a/WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/UnrecognisedTransaction.swift b/DataLayer/Sources/DataBase/Wallet/Model/Transaction/UnrecognisedTransaction.swift similarity index 100% rename from WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/UnrecognisedTransaction.swift rename to DataLayer/Sources/DataBase/Wallet/Model/Transaction/UnrecognisedTransaction.swift diff --git a/WavesWallet-iOS/DataLayer/DataBase/Wallet/WalletRealmFactory.swift b/DataLayer/Sources/DataBase/Wallet/WalletRealmFactory.swift similarity index 87% rename from WavesWallet-iOS/DataLayer/DataBase/Wallet/WalletRealmFactory.swift rename to DataLayer/Sources/DataBase/Wallet/WalletRealmFactory.swift index fd993a52..c0991b49 100644 --- a/WavesWallet-iOS/DataLayer/DataBase/Wallet/WalletRealmFactory.swift +++ b/DataLayer/Sources/DataBase/Wallet/WalletRealmFactory.swift @@ -8,8 +8,9 @@ import Foundation import RealmSwift -import WavesSDKExtension -import WavesSDKCrypto +import WavesSDK +import WavesSDKExtensions +import DomainLayer fileprivate enum SchemaVersions: UInt64 { case version_1 = 1 // Release old version @@ -22,10 +23,9 @@ fileprivate enum SchemaVersions: UInt64 { case version_2_2 = 11 // v2.2 case version_2_3 = 12 // v2.3 case version_2_4 = 13 // v2.4 + case version_2_5 = 14 // v2.5 - static let currentVersion: SchemaVersions = .version_2_4 - - static let schemaWalletsVersion: UInt64 = 7 + static let currentVersion: SchemaVersions = .version_2_5 } fileprivate enum Constants { @@ -42,7 +42,9 @@ enum WalletRealmFactory { static func create(accountAddress: String) -> Realm.Configuration { var config = Realm.Configuration() - config.fileURL = config.fileURL!.deletingLastPathComponent() + + config.fileURL = config.fileURL?.deletingLastPathComponent() + .appendingPathComponent("\(accountAddress).realm") config.schemaVersion = SchemaVersions.currentVersion.rawValue config.objectTypes = [Transaction.self, @@ -93,7 +95,7 @@ enum WalletRealmFactory { guard var assetId = oldObject?[Constants.assetIdKey] as? String else { return } guard let isSpam = oldObject?[Constants.isSpamKey] as? Bool else { return } - assetId = assetId.count == 0 ? WavesSDKCryptoConstants.wavesAssetId : assetId + assetId = assetId.count == 0 ? WavesSDKConstants.wavesAssetId : assetId let assetBalanceSettings = migration.create(AssetBalanceSettings.className()) assetBalanceSettings[Constants.assetIdKey] = assetId @@ -152,6 +154,11 @@ enum WalletRealmFactory { if oldSchemaVersion < SchemaVersions.version_2_4.rawValue { removeTransaction(migration: migration) } + + if oldSchemaVersion < SchemaVersions.version_2_5.rawValue { + removeAsset(migration: migration) + removeTransaction(migration: migration) + } } return config @@ -215,36 +222,3 @@ extension Migration { } } } - -extension WalletRealmFactory { - - enum Configuration { - static var walletsConfig: Realm.Configuration? { - - var config = Realm.Configuration() - config.objectTypes = [WalletEncryption.self, WalletItem.self] - config.schemaVersion = UInt64(SchemaVersions.schemaWalletsVersion) - - guard let fileURL = config.fileURL else { - SweetLogger.error("File Realm is nil") - return nil - } - - config.fileURL = fileURL - .deletingLastPathComponent() - .appendingPathComponent("wallets_\(Environment.current.scheme).realm") - - config.migrationBlock = { migration, oldSchemaVersion in - - migration.enumerateObjects(ofType: WalletItem.className()) { _ , newObject in - - newObject?[WalletItem.isNeedShowWalletCleanBannerKey] = true - } - - SweetLogger.debug("Migration!!! \(oldSchemaVersion)") - } - - return config - } - } -} diff --git a/WavesWallet-iOS/DataLayer/DataBase/WalletSeed/SeedItem.swift b/DataLayer/Sources/DataBase/WalletSeed/SeedItem.swift similarity index 80% rename from WavesWallet-iOS/DataLayer/DataBase/WalletSeed/SeedItem.swift rename to DataLayer/Sources/DataBase/WalletSeed/SeedItem.swift index 13eee967..d27f009c 100644 --- a/WavesWallet-iOS/DataLayer/DataBase/WalletSeed/SeedItem.swift +++ b/DataLayer/Sources/DataBase/WalletSeed/SeedItem.swift @@ -8,9 +8,10 @@ import Foundation import RealmSwift -import Base58 -import WavesSDKExtension import WavesSDKCrypto +import WavesSDKExtensions +import DomainLayer +import Extensions class SeedItem: Object { @objc dynamic var publicKey: String = "" @@ -25,6 +26,6 @@ class SeedItem: Object { } var publicKeyAccount: PublicKeyAccount { - return PublicKeyAccount(publicKey: Base58.decode(publicKey)) + return PublicKeyAccount(publicKey: Base58Encoder.decode(publicKey)) } } diff --git a/WavesWallet-iOS/DataLayer/DataBase/Wallets/Model/WalletEncryption.swift b/DataLayer/Sources/DataBase/Wallets/Model/WalletEncryption.swift similarity index 100% rename from WavesWallet-iOS/DataLayer/DataBase/Wallets/Model/WalletEncryption.swift rename to DataLayer/Sources/DataBase/Wallets/Model/WalletEncryption.swift diff --git a/WavesWallet-iOS/DataLayer/DataBase/Wallets/WalletItem.swift b/DataLayer/Sources/DataBase/Wallets/WalletItem.swift similarity index 100% rename from WavesWallet-iOS/DataLayer/DataBase/Wallets/WalletItem.swift rename to DataLayer/Sources/DataBase/Wallets/WalletItem.swift diff --git a/DataLayer/Sources/DataBase/Wallets/WalletsRealmFactory.swift b/DataLayer/Sources/DataBase/Wallets/WalletsRealmFactory.swift new file mode 100644 index 00000000..b9c22369 --- /dev/null +++ b/DataLayer/Sources/DataBase/Wallets/WalletsRealmFactory.swift @@ -0,0 +1,50 @@ +// +// WalletsRealmFactory.swift +// DataLayer +// +// Created by rprokofev on 12.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import RealmSwift +import WavesSDK +import WavesSDKExtensions +import DomainLayer + +fileprivate enum SchemaVersions: UInt64 { + case version_2_5 = 7 + static let currentVersion: SchemaVersions = .version_2_5 +} + + +enum WalletsRealmFactory { + + static func walletsConfig(scheme: String) -> Realm.Configuration? { + + var config = Realm.Configuration() + config.objectTypes = [WalletEncryption.self, WalletItem.self] + config.schemaVersion = UInt64(SchemaVersions.currentVersion.rawValue) + + guard let fileURL = config.fileURL else { + SweetLogger.error("File Realm is nil") + return nil + } + + config.fileURL = fileURL + .deletingLastPathComponent() + .appendingPathComponent("wallets_\(scheme).realm") + + config.migrationBlock = { migration, oldSchemaVersion in + + migration.enumerateObjects(ofType: WalletItem.className()) { _ , newObject in + + newObject?[WalletItem.isNeedShowWalletCleanBannerKey] = true + } + + SweetLogger.debug("Migration!!! \(oldSchemaVersion)") + } + + return config + } +} diff --git a/WavesWallet-iOS/DataLayer/Mapper/AccountSettings+Mapper.swift b/DataLayer/Sources/Mapper/AccountSettings+Mapper.swift similarity index 84% rename from WavesWallet-iOS/DataLayer/Mapper/AccountSettings+Mapper.swift rename to DataLayer/Sources/Mapper/AccountSettings+Mapper.swift index df2a5720..3c8bd30d 100644 --- a/WavesWallet-iOS/DataLayer/Mapper/AccountSettings+Mapper.swift +++ b/DataLayer/Sources/Mapper/AccountSettings+Mapper.swift @@ -8,6 +8,7 @@ import Foundation import RealmSwift +import DomainLayer extension AccountSettings { @@ -20,6 +21,6 @@ extension AccountSettings { extension DomainLayer.DTO.AccountSettings { init(_ settings: AccountSettings) { - self.isEnabledSpam = settings.isEnabledSpam + self.init(isEnabledSpam: settings.isEnabledSpam) } } diff --git a/WavesWallet-iOS/DataLayer/Mapper/Asset+Mapper.swift b/DataLayer/Sources/Mapper/Asset+Mapper.swift similarity index 52% rename from WavesWallet-iOS/DataLayer/Mapper/Asset+Mapper.swift rename to DataLayer/Sources/Mapper/Asset+Mapper.swift index ab3ec95c..628f785c 100644 --- a/WavesWallet-iOS/DataLayer/Mapper/Asset+Mapper.swift +++ b/DataLayer/Sources/Mapper/Asset+Mapper.swift @@ -7,6 +7,7 @@ // import Foundation +import DomainLayer extension Asset { @@ -40,31 +41,33 @@ extension Asset { } extension DomainLayer.DTO.Asset { - + init(_ asset: Asset) { - self.modified = asset.modified - self.id = asset.id - self.wavesId = asset.wavesId - self.gatewayId = asset.gatewayId - self.displayName = asset.displayName - self.precision = asset.precision - self.description = asset.descriptionAsset - self.height = asset.height - self.timestamp = asset.timestamp - self.sender = asset.sender - self.quantity = asset.quantity - self.ticker = asset.ticker - self.isReusable = asset.isReusable - self.isSpam = asset.isSpam - self.isFiat = asset.isFiat - self.isGeneral = asset.isGeneral - self.isMyWavesToken = asset.isMyWavesToken - self.isWavesToken = asset.isWavesToken - self.isGateway = asset.isGateway - self.isWaves = asset.isWaves - self.addressRegEx = asset.addressRegEx - self.iconLogoUrl = asset.iconLogoUrl - self.hasScript = asset.hasScript - self.minSponsoredFee = asset.minSponsoredFee + + self.init(id: asset.id, + gatewayId: asset.gatewayId, + wavesId: asset.wavesId, + displayName: asset.displayName, + precision: asset.precision, + description: asset.descriptionAsset, + height: asset.height, + timestamp: asset.timestamp, + sender: asset.sender, + quantity: asset.quantity, + ticker: asset.ticker, + isReusable: asset.isReusable, + isSpam: asset.isSpam, + isFiat: asset.isFiat, + isGeneral: asset.isGeneral, + isMyWavesToken: asset.isMyWavesToken, + isWavesToken: asset.isWavesToken, + isGateway: asset.isGateway, + isWaves: asset.isWaves, + modified: asset.modified, + addressRegEx: asset.addressRegEx, + iconLogoUrl: asset.iconLogoUrl, + hasScript: asset.hasScript, + minSponsoredFee: asset.minSponsoredFee, + gatewayType: asset.gatewayType) } } diff --git a/DataLayer/Sources/Mapper/DexAssetPairDomainDTO+Mapper.swift b/DataLayer/Sources/Mapper/DexAssetPairDomainDTO+Mapper.swift new file mode 100644 index 00000000..14b2f095 --- /dev/null +++ b/DataLayer/Sources/Mapper/DexAssetPairDomainDTO+Mapper.swift @@ -0,0 +1,76 @@ +// +// DexMarketDomainDTO+Mapper.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 12/27/18. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import RealmSwift +import WavesSDK +import DomainLayer + + +extension DomainLayer.DTO.Dex.SmartPair { + + init(_ pair: DexAssetPair, isChecked: Bool) { + + let amountAsset = DomainLayer.DTO.Dex.Asset(id: pair.amountAsset.id, + name: pair.amountAsset.name, + shortName: pair.amountAsset.shortName, + decimals: pair.amountAsset.decimals) + + let priceAsset = DomainLayer.DTO.Dex.Asset(id: pair.priceAsset.id, + name: pair.priceAsset.name, + shortName: pair.priceAsset.shortName, + decimals: pair.priceAsset.decimals) + + + self.init(id: pair.id, + amountAsset: amountAsset, + priceAsset: priceAsset, + isChecked: isChecked, + isGeneral: pair.isGeneral, + sortLevel: pair.sortLevel) + } +} + +public extension DomainLayer.DTO.Dex.SmartPair { + + init(amountAsset: DomainLayer.DTO.Dex.Asset, priceAsset: DomainLayer.DTO.Dex.Asset, isChecked: Bool, isGeneral: Bool, sortLevel: Int) { + + let id = amountAsset.id + priceAsset.id + + self.init(id: id, + amountAsset: amountAsset, + priceAsset: priceAsset, + isChecked: isChecked, + isGeneral: isGeneral, + sortLevel: sortLevel) + } + +} + +extension DomainLayer.DTO.Dex.SmartPair { + + init(amountAsset: DomainLayer.DTO.Dex.Asset, priceAsset: DomainLayer.DTO.Dex.Asset, realm: Realm) { + + let id = amountAsset.id + priceAsset.id + let isChecked = realm.object(ofType: DexAssetPair.self, forPrimaryKey: id) != nil + let sortLevel = realm.object(ofType: DexAssetPair.self, forPrimaryKey: id)?.sortLevel ?? 0 + + let isGeneralAmount = realm.objects(Asset.self) + .filter(NSPredicate(format: "id == %@ AND isGeneral == true", amountAsset.id)).count > 0 + let isGeneralPrice = realm.objects(Asset.self) + .filter(NSPredicate(format: "id == %@ AND isGeneral == true", priceAsset.id)).count > 0 + let isGeneral = isGeneralAmount && isGeneralPrice + + self.init(id: id, + amountAsset: amountAsset, + priceAsset: priceAsset, + isChecked: isChecked, + isGeneral: isGeneral, + sortLevel: sortLevel) + } +} diff --git a/DataLayer/Sources/Mapper/DexMyOrders+Mapper.swift b/DataLayer/Sources/Mapper/DexMyOrders+Mapper.swift new file mode 100644 index 00000000..2e2f3ef2 --- /dev/null +++ b/DataLayer/Sources/Mapper/DexMyOrders+Mapper.swift @@ -0,0 +1,60 @@ +// +// DexMyOrders+Mapper.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 1/14/19. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import WavesSDK +import DomainLayer +import Extensions + +extension DomainLayer.DTO.Dex.MyOrder { + + init(_ model: MatcherService.DTO.Order, priceAsset: DomainLayer.DTO.Dex.Asset, amountAsset: DomainLayer.DTO.Dex.Asset) { + + let price = Money.price(amount: model.price, amountDecimals: amountAsset.decimals, priceDecimals: priceAsset.decimals) + + let amount = Money(model.amount, amountAsset.decimals) + + let filled = Money(model.filled, amountAsset.decimals) + + var status: DomainLayer.DTO.Dex.MyOrder.Status! + + if model.status == .Accepted { + status = .accepted + } else if model.status == .PartiallyFilled { + status = .partiallyFilled + } else if model.status == .Filled { + status = .filled + } else { + status = .cancelled + } + + var type: DomainLayer.DTO.Dex.OrderType! + + if model.type == .sell { + type = DomainLayer.DTO.Dex.OrderType.sell + } else { + type = DomainLayer.DTO.Dex.OrderType.buy + } + + let percentFilled = status == .filled ? 100 : Int(filled.amount * 100 / amount.amount) + + self.init(id: model.id, + time: model.timestamp, + status: status, + price: price, + amount: amount, + filled: filled, + type: type, + amountAsset: amountAsset, + priceAsset: priceAsset, + percentFilled: percentFilled, + fee: model.fee, + feeAsset: model.feeAsset) + } +} + diff --git a/DataLayer/Sources/Mapper/Transactions/AliasTransaction+Mapper.swift b/DataLayer/Sources/Mapper/Transactions/AliasTransaction+Mapper.swift new file mode 100644 index 00000000..5973ce58 --- /dev/null +++ b/DataLayer/Sources/Mapper/Transactions/AliasTransaction+Mapper.swift @@ -0,0 +1,70 @@ +// +// AliasTransaction+Mapper.swift +// WavesWallet-iOS +// +// Created by mefilt on 30.08.2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import WavesSDK +import DomainLayer + +extension AliasTransaction { + + convenience init(transaction: DomainLayer.DTO.AliasTransaction) { + self.init() + type = transaction.type + id = transaction.id + sender = transaction.sender + senderPublicKey = transaction.senderPublicKey + fee = transaction.fee + timestamp = transaction.timestamp + version = transaction.version + height = transaction.height ?? -1 + modified = transaction.modified + if let proofs = transaction.proofs { + self.proofs.append(objectsIn: proofs) + } + signature = transaction.signature + alias = transaction.alias + status = transaction.status.rawValue + } +} + +extension DomainLayer.DTO.AliasTransaction { + + init(transaction: NodeService.DTO.AliasTransaction, status: DomainLayer.DTO.TransactionStatus, environment: WalletEnvironment) { + + self.init(type: transaction.type, + id: transaction.id, + sender: transaction.sender.normalizeAddress(environment: environment), + senderPublicKey: transaction.senderPublicKey, + fee: transaction.fee, + timestamp: transaction.timestamp, + version: transaction.version, + height: transaction.height, + signature: transaction.signature, + proofs: transaction.proofs, + alias: transaction.alias, + modified: Date(), + status: status) + } + + init(transaction: AliasTransaction) { + + self.init(type: transaction.type, + id: transaction.id, + sender: transaction.sender, + senderPublicKey: transaction.senderPublicKey, + fee: transaction.fee, + timestamp: transaction.timestamp, + version: transaction.version, + height: transaction.height, + signature: transaction.signature, + proofs: transaction.proofs.toArray(), + alias: transaction.alias, + modified: transaction.modified, + status: DomainLayer.DTO.TransactionStatus(rawValue: transaction.status) ?? .completed) + } +} diff --git a/WavesWallet-iOS/DataLayer/Mapper/Transactions/AnyTransaction+Mapper.swift b/DataLayer/Sources/Mapper/Transactions/AnyTransaction+Mapper.swift similarity index 95% rename from WavesWallet-iOS/DataLayer/Mapper/Transactions/AnyTransaction+Mapper.swift rename to DataLayer/Sources/Mapper/Transactions/AnyTransaction+Mapper.swift index 30b3d1ab..89f05c7b 100644 --- a/WavesWallet-iOS/DataLayer/Mapper/Transactions/AnyTransaction+Mapper.swift +++ b/DataLayer/Sources/Mapper/Transactions/AnyTransaction+Mapper.swift @@ -7,12 +7,14 @@ // import Foundation -import WavesSDKExtension -import WavesSDKCrypto +import WavesSDKExtensions +import WavesSDK +import DomainLayer +import Extensions -extension Node.DTO.Transaction { +extension NodeService.DTO.Transaction { - func anyTransaction(status: DomainLayer.DTO.TransactionStatus, environment: Environment) -> DomainLayer.DTO.AnyTransaction { + func anyTransaction(status: DomainLayer.DTO.TransactionStatus, environment: WalletEnvironment) -> DomainLayer.DTO.AnyTransaction { switch self { case .unrecognised(let transaction): @@ -63,9 +65,9 @@ extension Node.DTO.Transaction { } } -extension Node.DTO.TransactionContainers { +extension NodeService.DTO.TransactionContainers { - func anyTransactions(status: DomainLayer.DTO.TransactionStatus, environment: Environment) -> [DomainLayer.DTO.AnyTransaction] { + func anyTransactions(status: DomainLayer.DTO.TransactionStatus, environment: WalletEnvironment) -> [DomainLayer.DTO.AnyTransaction] { var anyTransactions = [DomainLayer.DTO.AnyTransaction]() diff --git a/DataLayer/Sources/Mapper/Transactions/AssetScriptTransaction+Mapper.swift b/DataLayer/Sources/Mapper/Transactions/AssetScriptTransaction+Mapper.swift new file mode 100644 index 00000000..3a86b413 --- /dev/null +++ b/DataLayer/Sources/Mapper/Transactions/AssetScriptTransaction+Mapper.swift @@ -0,0 +1,79 @@ +// +// AssetScriptTransaction+Mapper.swift +// WavesWallet-iOS +// +// Created by mefilt on 22/01/2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import WavesSDKExtensions +import WavesSDK +import DomainLayer +import Extensions + +extension AssetScriptTransaction { + + convenience init(transaction: DomainLayer.DTO.AssetScriptTransaction) { + self.init() + type = transaction.type + id = transaction.id + sender = transaction.sender + senderPublicKey = transaction.sender + fee = transaction.fee + timestamp = transaction.timestamp + height = transaction.height + signature = transaction.signature + version = transaction.version + script = transaction.script + assetId = transaction.assetId + + if let proofs = transaction.proofs { + self.proofs.append(objectsIn: proofs) + } + modified = transaction.modified + status = transaction.status.rawValue + } +} + +extension DomainLayer.DTO.AssetScriptTransaction { + + init(transaction: NodeService.DTO.SetAssetScriptTransaction, status: DomainLayer.DTO.TransactionStatus, environment: WalletEnvironment) { + + self.init(type: transaction.type, + id: transaction.id, + sender: transaction.sender.normalizeAddress(environment: environment), + senderPublicKey: transaction.senderPublicKey, + fee: transaction.fee, + timestamp: transaction.timestamp, + height: transaction.height ?? -1, + signature: transaction.signature, + proofs: transaction.proofs, + chainId: transaction.chainId, + version: transaction.version, + script: transaction.script, + assetId: transaction.assetId, + modified: Date(), + status: status) + } + + init(transaction: AssetScriptTransaction) { + + self.init(type: transaction.type, + id: transaction.id, + sender: transaction.sender, + senderPublicKey: transaction.senderPublicKey, + fee: transaction.fee, + timestamp: transaction.timestamp, + height: transaction.height, + signature: transaction.signature, + proofs: transaction.proofs.toArray(), + chainId: transaction.chainId.value, + version: transaction.version, + script: transaction.script, + assetId: transaction.assetId, + modified: transaction.modified, + status: DomainLayer.DTO.TransactionStatus(rawValue: transaction.status) ?? .completed) + } +} + diff --git a/DataLayer/Sources/Mapper/Transactions/BurnTransaction+Mapper.swift b/DataLayer/Sources/Mapper/Transactions/BurnTransaction+Mapper.swift new file mode 100644 index 00000000..1d30c8a9 --- /dev/null +++ b/DataLayer/Sources/Mapper/Transactions/BurnTransaction+Mapper.swift @@ -0,0 +1,77 @@ +// +// BurnTransaction+Mapper.swift +// WavesWallet-iOS +// +// Created by mefilt on 30.08.2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import WavesSDK +import DomainLayer + +extension BurnTransaction { + + convenience init(transaction: DomainLayer.DTO.BurnTransaction) { + self.init() + type = transaction.type + id = transaction.id + sender = transaction.sender + senderPublicKey = transaction.senderPublicKey + fee = transaction.fee + timestamp = transaction.timestamp + version = transaction.version + height = transaction.height + modified = transaction.modified + + assetId = transaction.assetId + + if let proofs = transaction.proofs { + self.proofs.append(objectsIn: proofs) + } + + amount = transaction.amount + status = transaction.status.rawValue + } +} + +extension DomainLayer.DTO.BurnTransaction { + + init(transaction: NodeService.DTO.BurnTransaction, status: DomainLayer.DTO.TransactionStatus, environment: WalletEnvironment) { + + self.init(type: transaction.type, + id: transaction.id, + sender: transaction.sender.normalizeAddress(environment: environment), + senderPublicKey: transaction.senderPublicKey, + fee: transaction.fee, + timestamp: transaction.timestamp, + version: transaction.version, + height: transaction.height ?? -1, + signature: transaction.signature, + proofs: transaction.proofs, + chainId: transaction.chainId, + assetId: transaction.assetId, + amount: transaction.amount, + modified: Date(), + status: status) + } + + init(transaction: BurnTransaction) { + + self.init(type: transaction.type, + id: transaction.id, + sender: transaction.sender, + senderPublicKey: transaction.senderPublicKey, + fee: transaction.fee, + timestamp: transaction.timestamp, + version: transaction.version, + height: transaction.height, + signature: transaction.signature, + proofs: transaction.proofs.toArray(), + chainId: transaction.chainId.value, + assetId: transaction.assetId, + amount: transaction.amount, + modified: transaction.modified, + status: DomainLayer.DTO.TransactionStatus(rawValue: transaction.status) ?? .completed) + } +} diff --git a/WavesWallet-iOS/DataLayer/Mapper/Transactions/DataTransaction+Mapper.swift b/DataLayer/Sources/Mapper/Transactions/DataTransaction+Mapper.swift similarity index 63% rename from WavesWallet-iOS/DataLayer/Mapper/Transactions/DataTransaction+Mapper.swift rename to DataLayer/Sources/Mapper/Transactions/DataTransaction+Mapper.swift index d391307a..c70d7a73 100644 --- a/WavesWallet-iOS/DataLayer/Mapper/Transactions/DataTransaction+Mapper.swift +++ b/DataLayer/Sources/Mapper/Transactions/DataTransaction+Mapper.swift @@ -7,8 +7,10 @@ // import Foundation -import WavesSDKExtension -import WavesSDKCrypto +import WavesSDKExtensions +import WavesSDK +import DomainLayer +import Extensions extension DataTransaction { @@ -35,7 +37,8 @@ extension DataTransaction { case .bool(let value): txData.boolean.value = value case .integer(let value): - txData.integer.value = value + //TODO: Change bd + txData.integer.value = (value as? Int) ?? 0 case .string(let value): txData.string = value case .binary(let value): @@ -53,17 +56,9 @@ extension DataTransaction { extension DomainLayer.DTO.DataTransaction { - init(transaction: Node.DTO.DataTransaction, status: DomainLayer.DTO.TransactionStatus, environment: Environment) { + init(transaction: NodeService.DTO.DataTransaction, status: DomainLayer.DTO.TransactionStatus, environment: WalletEnvironment) { - type = transaction.type - id = transaction.id - sender = transaction.sender.normalizeAddress(environment: environment) - senderPublicKey = transaction.senderPublicKey - fee = transaction.fee - timestamp = transaction.timestamp - version = transaction.version - height = transaction.height - modified = Date() + let dataList = transaction.data.map { data -> DomainLayer.DTO.DataTransaction.Data in @@ -83,24 +78,23 @@ extension DomainLayer.DTO.DataTransaction { type: data.type) } - proofs = transaction.proofs - data = dataList - - self.status = status + self.init(type: transaction.type, + id: transaction.id, + sender: transaction.sender.normalizeAddress(environment: environment), + senderPublicKey: transaction.senderPublicKey, + fee: transaction.fee, + timestamp: transaction.timestamp, + height: transaction.height, + version: transaction.version, + proofs: transaction.proofs, + data: dataList, + modified: Date(), + status: status, + chainId: transaction.chainId) } init(transaction: DataTransaction) { - type = transaction.type - id = transaction.id - sender = transaction.sender - senderPublicKey = transaction.sender - fee = transaction.fee - timestamp = transaction.timestamp - version = transaction.version - height = transaction.height - modified = transaction.modified - - proofs = transaction.proofs.toArray() + let dataList = transaction.data.toArray().map { data -> DomainLayer.DTO.DataTransaction.Data in var dataValue: DomainLayer.DTO.DataTransaction.Data.Value! @@ -108,7 +102,7 @@ extension DomainLayer.DTO.DataTransaction { if let value = data.binary { dataValue = .binary(value) } else if let value = data.integer.value { - dataValue = .integer(value) + dataValue = .integer(Int64(value)) } else if let value = data.string { dataValue = .string(value) } else if let value = data.boolean.value { @@ -117,7 +111,20 @@ extension DomainLayer.DTO.DataTransaction { return DomainLayer.DTO.DataTransaction.Data(key: data.key, value: dataValue, type: data.type) } - data = dataList - status = DomainLayer.DTO.TransactionStatus(rawValue: transaction.status) ?? .completed + + //TODO: Chain id + self.init(type: transaction.type, + id: transaction.id, + sender: transaction.sender, + senderPublicKey: transaction.senderPublicKey, + fee: transaction.fee, + timestamp: transaction.timestamp, + height: transaction.height, + version: transaction.version, + proofs: transaction.proofs.toArray(), + data: dataList, + modified: transaction.modified, + status: DomainLayer.DTO.TransactionStatus(rawValue: transaction.status) ?? .completed, + chainId: "") } } diff --git a/DataLayer/Sources/Mapper/Transactions/ExchangeTransaction+Mapper.swift b/DataLayer/Sources/Mapper/Transactions/ExchangeTransaction+Mapper.swift new file mode 100644 index 00000000..b37ac6eb --- /dev/null +++ b/DataLayer/Sources/Mapper/Transactions/ExchangeTransaction+Mapper.swift @@ -0,0 +1,186 @@ +// +// ExchangeTransaction+Mapper.swift +// WavesWallet-iOS +// +// Created by mefilt on 30.08.2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import WavesSDK +import DomainLayer + +extension ExchangeTransaction { + + convenience init(transaction: DomainLayer.DTO.ExchangeTransaction) { + self.init() + type = transaction.type + id = transaction.id + sender = transaction.sender + senderPublicKey = transaction.sender + fee = transaction.fee + timestamp = transaction.timestamp + version = transaction.version + height = transaction.height + modified = transaction.modified + + if let proofs = transaction.proofs { + self.proofs.append(objectsIn: proofs) + } + signature = transaction.signature + amount = transaction.amount + price = transaction.price + signature = transaction.signature + buyMatcherFee = transaction.buyMatcherFee + sellMatcherFee = transaction.sellMatcherFee + + order1 = ExchangeTransactionOrder(order: transaction.order1) + order2 = ExchangeTransactionOrder(order: transaction.order2) + status = transaction.status.rawValue + } +} + +extension DomainLayer.DTO.ExchangeTransaction { + + init(transaction: NodeService.DTO.ExchangeTransaction, status: DomainLayer.DTO.TransactionStatus, environment: WalletEnvironment) { + + let order1 = DomainLayer.DTO.ExchangeTransaction.Order(order: transaction.order1, environment: environment) + let order2 = DomainLayer.DTO.ExchangeTransaction.Order(order: transaction.order2, environment: environment) + + self.init(type: transaction.type, + id: transaction.id, + sender: transaction.sender.normalizeAddress(environment: environment), + senderPublicKey: transaction.senderPublicKey, + fee: transaction.fee, + timestamp: transaction.timestamp, + height: transaction.height, + signature: transaction.signature, + proofs: nil, + order1: order1, + order2: order2, + price: transaction.price, + amount: transaction.amount, + buyMatcherFee: transaction.buyMatcherFee, + sellMatcherFee: transaction.sellMatcherFee, + modified: Date(), + status: status, + version: transaction.version) + } + + init(transaction: ExchangeTransaction) { + + let order1 = DomainLayer.DTO.ExchangeTransaction.Order(order: transaction.order1!) + let order2 = DomainLayer.DTO.ExchangeTransaction.Order(order: transaction.order2!) + + self.init(type: transaction.type, + id: transaction.id, + sender: transaction.sender, + senderPublicKey: transaction.senderPublicKey, + fee: transaction.fee, + timestamp: transaction.timestamp, + height: transaction.height, + signature: transaction.signature, + proofs: transaction.proofs.toArray(), + order1: order1, + order2: order2, + price: transaction.price, + amount: transaction.amount, + buyMatcherFee: transaction.buyMatcherFee, + sellMatcherFee: transaction.sellMatcherFee, + modified: transaction.modified, + status: DomainLayer.DTO.TransactionStatus(rawValue: transaction.status) ?? .completed, + version: transaction.version) + } +} + +fileprivate extension DomainLayer.DTO.ExchangeTransaction.Order.Kind { + + init(key: String) { + if key == "sell" { + self = .sell + } else { + self = .buy + } + } + + var key: String { + switch self { + case .sell: + return "sell" + case .buy: + return "buy" + } + } +} + +extension ExchangeTransactionOrder { + + convenience init(order: DomainLayer.DTO.ExchangeTransaction.Order) { + self.init() + + id = order.id + sender = order.sender + senderPublicKey = order.sender + matcherPublicKey = order.matcherPublicKey + orderType = order.orderType.key + price = order.price + amount = order.amount + timestamp = order.timestamp + expiration = order.expiration + matcherFee = order.matcherFee + signature = order.signature + + let assetPair = ExchangeTransactionAssetPair() + assetPair.amountAsset = order.assetPair.amountAsset + assetPair.priceAsset = order.assetPair.priceAsset + self.assetPair = assetPair + matcherFeeAssetId = order.matcherFeeAssetId + } +} + +extension DomainLayer.DTO.ExchangeTransaction.Order { + + init(order: NodeService.DTO.ExchangeTransaction.Order, environment: WalletEnvironment) { + + let assetPair = DomainLayer.DTO.ExchangeTransaction.AssetPair(amountAsset: order.assetPair.amountAsset.normalizeAssetId, + priceAsset: order.assetPair.priceAsset.normalizeAssetId) + self.init(id: order.id, + sender: order.sender.normalizeAddress(environment: environment), + senderPublicKey: order.senderPublicKey, + matcherPublicKey: order.matcherPublicKey, + assetPair: assetPair, + orderType: .init(key: order.orderType), + price: order.price, + amount: order.amount, + timestamp: order.timestamp, + expiration: order.expiration, + matcherFee: order.matcherFee, + signature: order.signature, + matcherFeeAssetId: order.matcherFeeAssetId) + } + + init(order: ExchangeTransactionOrder) { + + let amountAssetId = order.assetPair?.amountAsset + let priceAssetId = order.assetPair?.priceAsset + + let assetPair = DomainLayer.DTO.ExchangeTransaction.AssetPair(amountAsset: amountAssetId.normalizeAssetId, + priceAsset: priceAssetId.normalizeAssetId) + + self.init(id: order.id, + sender: order.sender, + senderPublicKey: order.senderPublicKey, + matcherPublicKey: order.matcherPublicKey, + assetPair: assetPair, + orderType: .init(key: order.orderType), + price: order.price, + amount: order.amount, + timestamp: order.timestamp, + expiration: order.expiration, + matcherFee: order.matcherFee, + signature: order.signature, + matcherFeeAssetId: order.matcherFeeAssetId) + + } +} + diff --git a/DataLayer/Sources/Mapper/Transactions/InvokeScriptTransaction+Mapper.swift b/DataLayer/Sources/Mapper/Transactions/InvokeScriptTransaction+Mapper.swift new file mode 100644 index 00000000..5959bba8 --- /dev/null +++ b/DataLayer/Sources/Mapper/Transactions/InvokeScriptTransaction+Mapper.swift @@ -0,0 +1,116 @@ +// +// InvokeScriptTransaction+Mapper.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 4/9/19. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import WavesSDK +import DomainLayer + +extension InvokeScriptTransaction { + + convenience init(transaction: DomainLayer.DTO.InvokeScriptTransaction) { + self.init() + + type = transaction.type + id = transaction.id + sender = transaction.sender + senderPublicKey = transaction.sender + fee = transaction.fee + timestamp = transaction.timestamp + height = transaction.height + version = transaction.version + + if let proofs = transaction.proofs { + self.proofs.append(objectsIn: proofs) + } + feeAssetId = transaction.feeAssetId + dappAddress = transaction.dappAddress + + modified = transaction.modified + status = transaction.status.rawValue + + if let txPayment = transaction.payment { + payment = InvokeScriptTransactionPayment() + payment?.amount = txPayment.amount + payment?.assetId = txPayment.assetId + } + + } +} +extension DomainLayer.DTO.InvokeScriptTransaction { + + init(transaction: NodeService.DTO.InvokeScriptTransaction, status: DomainLayer.DTO.TransactionStatus, environment: WalletEnvironment) { + + + var call: DomainLayer.DTO.InvokeScriptTransaction.Call? = nil + + if let localCall = transaction.call { + let args = localCall.args.map { (arg) -> DomainLayer.DTO.InvokeScriptTransaction.Call.Args in + + let value = { () -> DomainLayer.DTO.InvokeScriptTransaction.Call.Args.Value in + + switch arg.value { + case .binary(let value): + return .binary(value) + + case .bool(let value): + return .bool(value) + + case .integer(let value): + return .integer(value) + + case .string(let value): + return .string(value) + } + }() + + return .init(type: arg.type, value: value) + } + + call = DomainLayer.DTO.InvokeScriptTransaction.Call.init(function: localCall.function, args: args) + } + + self.init(type: transaction.type, + id: transaction.id, + sender: transaction.sender.normalizeAddress(environment: environment), + senderPublicKey: transaction.senderPublicKey, + fee: transaction.fee, + feeAssetId: transaction.feeAssetId, + timestamp: transaction.timestamp, + proofs: transaction.proofs, + version: transaction.version, + dappAddress: transaction.dApp, + payment: transaction.payment.first.map { .init(amount: $0.amount, assetId: $0.assetId) }, + height: transaction.height ?? 0, + modified: Date(), + status: status, + chainId: transaction.chainId, + call: call) + } + + init(transaction: InvokeScriptTransaction) { + + //TODO: chainId: String + //TODO: Call to bd + self.init(type: transaction.type, + id: transaction.id, + sender: transaction.sender, + senderPublicKey: transaction.senderPublicKey, + fee: transaction.fee, + feeAssetId: transaction.feeAssetId, + timestamp: transaction.timestamp, + proofs: transaction.proofs.toArray(), + version: transaction.version, + dappAddress: transaction.dappAddress, + payment: transaction.payment.map { .init(amount: $0.amount, assetId: $0.assetId) }, + height: transaction.height, + modified: transaction.modified, + status: DomainLayer.DTO.TransactionStatus(rawValue: transaction.status) ?? .completed, + chainId: "", + call: nil) + } +} diff --git a/DataLayer/Sources/Mapper/Transactions/IssueTransaction+Mapper.swift b/DataLayer/Sources/Mapper/Transactions/IssueTransaction+Mapper.swift new file mode 100644 index 00000000..307ec044 --- /dev/null +++ b/DataLayer/Sources/Mapper/Transactions/IssueTransaction+Mapper.swift @@ -0,0 +1,92 @@ +// +// TransactionContainers.swift +// WavesWallet-iOS +// +// Created by mefilt on 30.08.2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import WavesSDKExtensions +import WavesSDK +import DomainLayer + +extension IssueTransaction { + + convenience init(transaction: DomainLayer.DTO.IssueTransaction) { + self.init() + type = transaction.type + id = transaction.id + sender = transaction.sender + senderPublicKey = transaction.senderPublicKey + fee = transaction.fee + timestamp = transaction.timestamp + version = transaction.version + height = transaction.height + signature = transaction.signature + chainId.value = transaction.chainId + if let proofs = transaction.proofs { + self.proofs.append(objectsIn: proofs) + } + assetId = transaction.assetId + name = transaction.name + quantity = transaction.quantity + reissuable = transaction.reissuable + decimals = transaction.decimals + assetDescription = transaction.description + script = transaction.script + modified = transaction.modified + status = transaction.status.rawValue + } +} + +extension DomainLayer.DTO.IssueTransaction { + + init(transaction: NodeService.DTO.IssueTransaction, status: DomainLayer.DTO.TransactionStatus, environment: WalletEnvironment) { + + self.init(type: transaction.type, + id: transaction.id, + sender: transaction.sender.normalizeAddress(environment: environment), + senderPublicKey: transaction.senderPublicKey, + fee: transaction.fee, + timestamp: transaction.timestamp, + version: transaction.version, + height: transaction.height ?? 0, + chainId: nil, + signature: transaction.signature, + proofs: transaction.proofs, + assetId: transaction.assetId, + name: transaction.name, + quantity: transaction.quantity, + reissuable: transaction.reissuable, + decimals: transaction.decimals, + description: transaction.description, + script: transaction.script, + modified: Date(), + status: status) + } + + init(transaction: IssueTransaction) { + + self.init(type: transaction.type, + id: transaction.id, + sender: transaction.sender, + senderPublicKey: transaction.senderPublicKey, + fee: transaction.fee, + timestamp: transaction.timestamp, + version: transaction.version, + height: transaction.height, + chainId: transaction.chainId.value, + signature: transaction.signature, + proofs: transaction.proofs.toArray(), + assetId: transaction.assetId, + name: transaction.name, + quantity: transaction.quantity, + reissuable: transaction.reissuable, + decimals: transaction.decimals, + description: transaction.assetDescription, + script: transaction.script, + modified: transaction.modified, + status: DomainLayer.DTO.TransactionStatus(rawValue: transaction.status) ?? .completed) + } +} diff --git a/DataLayer/Sources/Mapper/Transactions/LeaseCancelTransaction+Mapper.swift b/DataLayer/Sources/Mapper/Transactions/LeaseCancelTransaction+Mapper.swift new file mode 100644 index 00000000..83f989bd --- /dev/null +++ b/DataLayer/Sources/Mapper/Transactions/LeaseCancelTransaction+Mapper.swift @@ -0,0 +1,97 @@ +// +// LeaseCancelTransaction+Mapper.swift +// WavesWallet-iOS +// +// Created by mefilt on 30.08.2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import WavesSDK +import DomainLayer + +extension LeaseCancelTransaction { + + convenience init(transaction: DomainLayer.DTO.LeaseCancelTransaction) { + self.init() + type = transaction.type + id = transaction.id + sender = transaction.sender + senderPublicKey = transaction.senderPublicKey + fee = transaction.fee + timestamp = transaction.timestamp + version = transaction.version + height = transaction.height + modified = transaction.modified + + if let proofs = transaction.proofs { + self.proofs.append(objectsIn: proofs) + } + + signature = transaction.signature + chainId.value = transaction.chainId + leaseId = transaction.leaseId + if let lease = transaction.lease { + if let leaseFromBD = self.realm?.object(ofType: LeaseTransaction.self, forPrimaryKey: leaseId) { + self.lease = leaseFromBD + } else { + self.lease = LeaseTransaction(transaction: lease) + } + } + status = transaction.status.rawValue + } +} + +extension DomainLayer.DTO.LeaseCancelTransaction { + + init(transaction: NodeService.DTO.LeaseCancelTransaction, status: DomainLayer.DTO.TransactionStatus, environment: WalletEnvironment) { + + var leaseTx: DomainLayer.DTO.LeaseTransaction? = nil + + if let lease = transaction.lease { + leaseTx = DomainLayer.DTO.LeaseTransaction(transaction: lease, status: .completed, environment: environment) + } + + self.init(type: transaction.type, + id: transaction.id, + sender: transaction.sender.normalizeAddress(environment: environment), + senderPublicKey: transaction.senderPublicKey, + fee: transaction.fee, + timestamp: transaction.timestamp, + version: transaction.version, + height: transaction.height ?? -1, + signature: transaction.signature, + proofs: transaction.proofs, + chainId: transaction.chainId, + leaseId: transaction.leaseId, + lease: leaseTx, + modified: Date(), + status: status) + + } + + init(transaction: LeaseCancelTransaction) { + + var leaseTx: DomainLayer.DTO.LeaseTransaction? = nil + + if let lease = transaction.lease { + leaseTx = DomainLayer.DTO.LeaseTransaction(transaction: lease) + } + + self.init(type: transaction.type, + id: transaction.id, + sender: transaction.sender, + senderPublicKey: transaction.senderPublicKey, + fee: transaction.fee, + timestamp: transaction.timestamp, + version: transaction.version, + height: transaction.height, + signature: transaction.signature, + proofs: transaction.proofs.toArray(), + chainId: transaction.chainId.value, + leaseId: transaction.leaseId, + lease: leaseTx, + modified: transaction.modified, + status: DomainLayer.DTO.TransactionStatus(rawValue: transaction.status) ?? .completed) + } +} diff --git a/DataLayer/Sources/Mapper/Transactions/LeaseTransaction+Mapper.swift b/DataLayer/Sources/Mapper/Transactions/LeaseTransaction+Mapper.swift new file mode 100644 index 00000000..ad8d7cc8 --- /dev/null +++ b/DataLayer/Sources/Mapper/Transactions/LeaseTransaction+Mapper.swift @@ -0,0 +1,77 @@ +// +// LeasingTransaction+Mapper.swift +// WavesWallet-iOS +// +// Created by mefilt on 19.07.2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import WavesSDKExtensions +import WavesSDK +import DomainLayer + +extension LeaseTransaction { + + convenience init(transaction: DomainLayer.DTO.LeaseTransaction) { + self.init() + type = transaction.type + id = transaction.id + sender = transaction.sender + senderPublicKey = transaction.senderPublicKey + fee = transaction.fee + timestamp = transaction.timestamp + height = transaction.height + chainId.value = transaction.chainId + signature = transaction.signature + if let proofs = transaction.proofs { + self.proofs.append(objectsIn: proofs) + } + amount = transaction.amount + recipient = transaction.recipient + modified = transaction.modified + status = transaction.status.rawValue + + } +} + +extension DomainLayer.DTO.LeaseTransaction { + + init(transaction: NodeService.DTO.LeaseTransaction, status: DomainLayer.DTO.TransactionStatus, environment: WalletEnvironment) { + + self.init(type: transaction.type, + id: transaction.id, + sender: transaction.sender.normalizeAddress(environment: environment), + senderPublicKey: transaction.senderPublicKey, + fee: transaction.fee, + timestamp: transaction.timestamp, + version: transaction.version, + height: transaction.height ?? -1, + chainId: nil, + signature: transaction.signature, + proofs: transaction.proofs, + amount: transaction.amount, + recipient: transaction.recipient.normalizeAddress(environment: environment), + modified: Date(), + status: status) + } + + init(transaction: LeaseTransaction) { + + self.init(type: transaction.type, + id: transaction.id, + sender: transaction.sender, + senderPublicKey: transaction.senderPublicKey, + fee: transaction.fee, + timestamp: transaction.timestamp, + version: transaction.version, + height: transaction.height, + chainId: transaction.chainId.value, + signature: transaction.signature, + proofs: transaction.proofs.toArray(), + amount: transaction.amount, + recipient: transaction.recipient, + modified: transaction.modified, + status: DomainLayer.DTO.TransactionStatus(rawValue: transaction.status) ?? .completed) + } +} diff --git a/DataLayer/Sources/Mapper/Transactions/MassTransferTransaction+Mapper.swift b/DataLayer/Sources/Mapper/Transactions/MassTransferTransaction+Mapper.swift new file mode 100644 index 00000000..e0ccd9aa --- /dev/null +++ b/DataLayer/Sources/Mapper/Transactions/MassTransferTransaction+Mapper.swift @@ -0,0 +1,107 @@ +// +// MassTransferTransaction+Mapper.swift +// WavesWallet-iOS +// +// Created by mefilt on 30.08.2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import WavesSDKExtensions +import WavesSDK +import DomainLayer + +extension MassTransferTransaction { + + convenience init(transaction: DomainLayer.DTO.MassTransferTransaction) { + self.init() + type = transaction.type + id = transaction.id + sender = transaction.sender + senderPublicKey = transaction.senderPublicKey + fee = transaction.fee + timestamp = transaction.timestamp + version = transaction.version + height = transaction.height + modified = transaction.modified + + assetId = transaction.assetId + attachment = transaction.attachment + transferCount = transaction.transferCount + totalAmount = transaction.totalAmount + + if let proofs = transaction.proofs { + self.proofs.append(objectsIn: proofs) + } + let transfers = transaction + .transfers + .map { model -> MassTransferTransactionTransfer in + let info = MassTransferTransactionTransfer() + info.recipient = model.recipient + info.amount = model.amount + return info + } + + self.transfers.append(objectsIn: transfers) + + status = transaction.status.rawValue + } +} + +extension DomainLayer.DTO.MassTransferTransaction { + + init(transaction: NodeService.DTO.MassTransferTransaction, + status: DomainLayer.DTO.TransactionStatus, + environment: WalletEnvironment) { + + let transfers: [DomainLayer.DTO.MassTransferTransaction.Transfer] = transaction + .transfers + .map { .init(recipient: $0.recipient.normalizeAddress(environment: environment), + amount: $0.amount) } + + self.init(type: transaction.type, + id: transaction.id, + sender: transaction.sender.normalizeAddress(environment: environment), + senderPublicKey: transaction.senderPublicKey, + fee: transaction.fee, + timestamp: transaction.timestamp, + version: transaction.version, + height: transaction.height ?? 0, + proofs: transaction.proofs, + assetId: transaction.assetId.normalizeAssetId, + attachment: transaction.attachment, + transferCount: transaction.transferCount, + totalAmount: transaction.totalAmount, + transfers: transfers, + modified: Date(), + status: status) + + self.status = status + } + + init(transaction: MassTransferTransaction) { + + let transfers = transaction + .transfers + .toArray() + .map { DomainLayer.DTO.MassTransferTransaction.Transfer(recipient: $0.recipient, + amount: $0.amount) } + + self.init(type: transaction.type, + id: transaction.id, + sender: transaction.sender, + senderPublicKey: transaction.senderPublicKey, + fee: transaction.fee, + timestamp: transaction.timestamp, + version: transaction.version, + height: transaction.height, + proofs: transaction.proofs.toArray(), + assetId: transaction.assetId.normalizeAssetId, + attachment: transaction.attachment, + transferCount: transaction.transferCount, + totalAmount: transaction.totalAmount, + transfers: transfers, + modified: transaction.modified, + status: DomainLayer.DTO.TransactionStatus(rawValue: transaction.status) ?? .completed) + } +} diff --git a/DataLayer/Sources/Mapper/Transactions/ReissueTransaction+Mapper.swift b/DataLayer/Sources/Mapper/Transactions/ReissueTransaction+Mapper.swift new file mode 100644 index 00000000..329d87f4 --- /dev/null +++ b/DataLayer/Sources/Mapper/Transactions/ReissueTransaction+Mapper.swift @@ -0,0 +1,79 @@ +// +// ReissueTransaction+Mapper.swift +// WavesWallet-iOS +// +// Created by mefilt on 30.08.2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import WavesSDK +import DomainLayer + +extension ReissueTransaction { + + convenience init(transaction: DomainLayer.DTO.ReissueTransaction) { + self.init() + type = transaction.type + id = transaction.id + sender = transaction.sender + senderPublicKey = transaction.senderPublicKey + fee = transaction.fee + timestamp = transaction.timestamp + version = transaction.version + height = transaction.height + modified = transaction.modified + if let proofs = transaction.proofs { + self.proofs.append(objectsIn: proofs) + } + signature = transaction.signature + assetId = transaction.assetId + chainId.value = transaction.chainId + quantity = transaction.quantity + reissuable = transaction.reissuable + status = transaction.status.rawValue + } +} + +extension DomainLayer.DTO.ReissueTransaction { + + init(transaction: NodeService.DTO.ReissueTransaction, status: DomainLayer.DTO.TransactionStatus, environment: WalletEnvironment) { + + self.init(type: transaction.type, + id: transaction.id, + sender: transaction.sender.normalizeAddress(environment: environment), + senderPublicKey: transaction.senderPublicKey, + fee: transaction.fee, + timestamp: transaction.timestamp, + version: transaction.version, + height: transaction.height ?? 0, + signature: transaction.signature, + proofs: transaction.proofs, + chainId: transaction.chainId, + assetId: transaction.assetId, + quantity: transaction.quantity, + reissuable: transaction.reissuable, + modified: Date(), + status: status) + } + + init(transaction: ReissueTransaction) { + + self.init(type: transaction.type, + id: transaction.id, + sender: transaction.sender, + senderPublicKey: transaction.senderPublicKey, + fee: transaction.fee, + timestamp: transaction.timestamp, + version: transaction.version, + height: transaction.height, + signature: transaction.signature, + proofs: transaction.proofs.toArray(), + chainId: transaction.chainId.value, + assetId: transaction.assetId, + quantity: transaction.quantity, + reissuable: transaction.reissuable, + modified: transaction.modified, + status: DomainLayer.DTO.TransactionStatus(rawValue: transaction.status) ?? .completed) + } +} diff --git a/DataLayer/Sources/Mapper/Transactions/ScriptTransaction+Mapper.swift b/DataLayer/Sources/Mapper/Transactions/ScriptTransaction+Mapper.swift new file mode 100644 index 00000000..4951a4ab --- /dev/null +++ b/DataLayer/Sources/Mapper/Transactions/ScriptTransaction+Mapper.swift @@ -0,0 +1,74 @@ +// +// ScriptTransaction+Mapper.swift +// WavesWallet-iOS +// +// Created by mefilt on 22/01/2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import WavesSDKExtensions +import WavesSDK +import DomainLayer + +extension ScriptTransaction { + + convenience init(transaction: DomainLayer.DTO.ScriptTransaction) { + self.init() + type = transaction.type + id = transaction.id + sender = transaction.sender + senderPublicKey = transaction.sender + fee = transaction.fee + timestamp = transaction.timestamp + version = 1 + height = transaction.height ?? -1 + chainId.value = transaction.chainId + signature = transaction.signature + if let proofs = transaction.proofs { + self.proofs.append(objectsIn: proofs) + } + script = transaction.script + modified = transaction.modified + status = transaction.status.rawValue + } +} + +extension DomainLayer.DTO.ScriptTransaction { + + init(transaction: NodeService.DTO.SetScriptTransaction, status: DomainLayer.DTO.TransactionStatus, environment: WalletEnvironment) { + + self.init(type: transaction.type, + id: transaction.id, + sender: transaction.sender.normalizeAddress(environment: environment), + senderPublicKey: transaction.senderPublicKey, + fee: transaction.fee, + timestamp: transaction.timestamp, + version: transaction.version, + height: transaction.height, + chainId: transaction.chainId, + signature: transaction.signature, + proofs: transaction.proofs, + script: transaction.script, + modified: Date(), + status: status) + } + + init(transaction: ScriptTransaction) { + + self.init(type: transaction.type, + id: transaction.id, + sender: transaction.sender, + senderPublicKey: transaction.senderPublicKey, + fee: transaction.fee, + timestamp: transaction.timestamp, + version: transaction.version, + height: transaction.height, + chainId: transaction.chainId.value, + signature: transaction.signature, + proofs: transaction.proofs.toArray(), + script: transaction.script, + modified: transaction.modified, + status: DomainLayer.DTO.TransactionStatus(rawValue: transaction.status) ?? .completed) + } +} diff --git a/DataLayer/Sources/Mapper/Transactions/SponsorshipTransaction+Mapper.swift b/DataLayer/Sources/Mapper/Transactions/SponsorshipTransaction+Mapper.swift new file mode 100644 index 00000000..67b21d66 --- /dev/null +++ b/DataLayer/Sources/Mapper/Transactions/SponsorshipTransaction+Mapper.swift @@ -0,0 +1,78 @@ +// +// SponsorshipTransaction+Mapper.swift +// WavesWallet-iOS +// +// Created by Prokofev Ruslan on 05/02/2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import WavesSDKExtensions +import WavesSDK +import DomainLayer + +extension SponsorshipTransaction { + + convenience init(transaction: DomainLayer.DTO.SponsorshipTransaction) { + self.init() + type = transaction.type + id = transaction.id + sender = transaction.sender + senderPublicKey = transaction.sender + fee = transaction.fee + timestamp = transaction.timestamp + height = transaction.height ?? -1 + signature = transaction.signature + version = transaction.version + minSponsoredAssetFee.value = transaction.minSponsoredAssetFee + assetId = transaction.assetId + + if let proofs = transaction.proofs { + self.proofs.append(objectsIn: proofs) + } + modified = transaction.modified + status = transaction.status.rawValue + } +} + +extension DomainLayer.DTO.SponsorshipTransaction { + + init(transaction: NodeService.DTO.SponsorshipTransaction, status: DomainLayer.DTO.TransactionStatus, environment: WalletEnvironment) { + + self.init(type: transaction.type, + id: transaction.id, + sender: transaction.sender.normalizeAddress(environment: environment), + senderPublicKey: transaction.senderPublicKey, + fee: transaction.fee, + timestamp: transaction.timestamp, + version: transaction.version, + height: transaction.height, + signature: transaction.signature, + proofs: transaction.proofs, + assetId: transaction.assetId, + minSponsoredAssetFee: transaction.minSponsoredAssetFee, + modified: Date(), + status: status) + } + + init(transaction: SponsorshipTransaction) { + + self.init(type: transaction.type, + id: transaction.id, + sender: transaction.sender, + senderPublicKey: transaction.senderPublicKey, + fee: transaction.fee, + timestamp: transaction.timestamp, + version: transaction.version, + height: transaction.height, + signature: transaction.signature, + proofs: transaction.proofs.toArray(), + assetId: transaction.assetId, + minSponsoredAssetFee: transaction.minSponsoredAssetFee.value, + modified: transaction.modified, + status: DomainLayer.DTO.TransactionStatus(rawValue: transaction.status) ?? .completed) + } +} + + + diff --git a/DataLayer/Sources/Mapper/Transactions/TransferTransaction+Mapper.swift b/DataLayer/Sources/Mapper/Transactions/TransferTransaction+Mapper.swift new file mode 100644 index 00000000..b09c0592 --- /dev/null +++ b/DataLayer/Sources/Mapper/Transactions/TransferTransaction+Mapper.swift @@ -0,0 +1,88 @@ +// +// TransferTransaction+Mapper.swift +// WavesWallet-iOS +// +// Created by mefilt on 30.08.2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import WavesSDKExtensions +import WavesSDK +import DomainLayer +import Extensions + +extension TransferTransaction { + + convenience init(transaction: DomainLayer.DTO.TransferTransaction) { + self.init() + type = transaction.type + id = transaction.id + sender = transaction.sender + senderPublicKey = transaction.senderPublicKey + fee = transaction.fee + timestamp = transaction.timestamp + version = transaction.version + height = transaction.height + signature = transaction.signature + if let proofs = transaction.proofs { + self.proofs.append(objectsIn: proofs) + } + assetId = transaction.assetId + modified = transaction.modified + + recipient = transaction.recipient + feeAssetId = transaction.feeAssetId + feeAsset = transaction.feeAsset + amount = transaction.amount + attachment = transaction.attachment + status = transaction.status.rawValue + } +} + +extension DomainLayer.DTO.TransferTransaction { + + init(transaction: NodeService.DTO.TransferTransaction, status: DomainLayer.DTO.TransactionStatus, environment: WalletEnvironment) { + + self.init(type: transaction.type, + id: transaction.id, + sender: transaction.sender.normalizeAddress(environment: environment), + senderPublicKey: transaction.senderPublicKey, + fee: transaction.fee, + timestamp: transaction.timestamp, + version: transaction.version, + height: transaction.height ?? -1, + signature: transaction.signature, + proofs: transaction.proofs, + recipient: transaction.recipient.normalizeAddress(environment: environment), + assetId: transaction.assetId.normalizeAssetId, + feeAssetId: transaction.feeAssetId.normalizeAssetId, + feeAsset: transaction.feeAssetId, + amount: transaction.amount, + attachment: transaction.attachment, + modified: Date(), + status: status) + } + + init(transaction: TransferTransaction) { + + self.init(type: transaction.type, + id: transaction.id, + sender: transaction.sender, + senderPublicKey: transaction.senderPublicKey, + fee: transaction.fee, + timestamp: transaction.timestamp, + version: transaction.version, + height: transaction.height, + signature: transaction.signature, + proofs: transaction.proofs.toArray(), + recipient: transaction.recipient, + assetId: transaction.assetId.normalizeAssetId, + feeAssetId: transaction.feeAssetId.normalizeAssetId, + feeAsset: transaction.feeAsset.normalizeAssetId, + amount: transaction.amount, + attachment: transaction.attachment, + modified: transaction.modified, + status: DomainLayer.DTO.TransactionStatus(rawValue: transaction.status) ?? .completed) + } +} diff --git a/DataLayer/Sources/Mapper/Transactions/UnrecognisedTransaction+Mapper.swift b/DataLayer/Sources/Mapper/Transactions/UnrecognisedTransaction+Mapper.swift new file mode 100644 index 00000000..da8f55c8 --- /dev/null +++ b/DataLayer/Sources/Mapper/Transactions/UnrecognisedTransaction+Mapper.swift @@ -0,0 +1,57 @@ +// +// UnrecognisedTransaction+Mapper.swift +// WavesWallet-iOS +// +// Created by mefilt on 31.08.2018.1 +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import WavesSDK +import DomainLayer + +extension UnrecognisedTransaction { + + convenience init(transaction: DomainLayer.DTO.UnrecognisedTransaction) { + self.init() + type = transaction.type + id = transaction.id + sender = transaction.sender + senderPublicKey = transaction.sender + fee = transaction.fee + timestamp = transaction.timestamp + version = 1 + height = transaction.height + modified = transaction.modified + status = transaction.status.rawValue + } +} + +extension DomainLayer.DTO.UnrecognisedTransaction { + + init(transaction: NodeService.DTO.UnrecognisedTransaction, status: DomainLayer.DTO.TransactionStatus, environment: WalletEnvironment) { + + self.init(type: transaction.type, + id: transaction.id, + sender: transaction.sender.normalizeAddress(environment: environment), + senderPublicKey: transaction.senderPublicKey, + fee: transaction.fee, + timestamp: transaction.timestamp, + height: transaction.height, + modified: Date(), + status: status) + } + + init(transaction: UnrecognisedTransaction) { + + self.init(type: transaction.type, + id: transaction.id, + sender: transaction.sender, + senderPublicKey: transaction.senderPublicKey, + fee: transaction.fee, + timestamp: transaction.timestamp, + height: transaction.height, + modified: transaction.modified, + status: DomainLayer.DTO.TransactionStatus(rawValue: transaction.status) ?? .completed) + } +} diff --git a/WavesWallet-iOS/DataLayer/Mapper/Wallet+Mapper.swift b/DataLayer/Sources/Mapper/Wallet+Mapper.swift similarity index 63% rename from WavesWallet-iOS/DataLayer/Mapper/Wallet+Mapper.swift rename to DataLayer/Sources/Mapper/Wallet+Mapper.swift index 97c82119..7b2baaf9 100644 --- a/WavesWallet-iOS/DataLayer/Mapper/Wallet+Mapper.swift +++ b/DataLayer/Sources/Mapper/Wallet+Mapper.swift @@ -7,6 +7,7 @@ // import Foundation +import DomainLayer extension WalletEncryption { convenience init(wallet: DomainLayer.DTO.WalletEncryption) { @@ -20,14 +21,16 @@ extension WalletEncryption { extension DomainLayer.DTO.WalletEncryption { init(wallet: WalletEncryption) { - self.publicKey = wallet.publicKey - + + var kind: DomainLayer.DTO.WalletEncryption.Kind = .none + if let secret = wallet.secret { - self.kind = .passcode(secret: secret) - } else { - self.kind = .none + kind = .passcode(secret: secret) } - self.seedId = wallet.seedId + + self.init(publicKey: wallet.publicKey, + kind: kind, + seedId: wallet.seedId) } } @@ -50,14 +53,14 @@ extension DomainLayer.DTO.Wallet { init(wallet: WalletItem) { - self.publicKey = wallet.publicKey - self.name = wallet.name - self.isLoggedIn = wallet.isLoggedIn - self.isBackedUp = wallet.isBackedUp - self.address = wallet.address - self.hasBiometricEntrance = wallet.hasBiometricEntrance - self.id = wallet.id - self.isNeedShowWalletCleanBanner = wallet.isNeedShowWalletCleanBanner + self.init(name: wallet.name, + address: wallet.address, + publicKey: wallet.publicKey, + isLoggedIn: wallet.isLoggedIn, + isBackedUp: wallet.isBackedUp, + hasBiometricEntrance: wallet.hasBiometricEntrance, + id: wallet.id, + isNeedShowWalletCleanBanner: wallet.isNeedShowWalletCleanBanner) } } @@ -74,8 +77,9 @@ extension SeedItem { extension DomainLayer.DTO.WalletSeed { init(seed: SeedItem) { - self.publicKey = seed.publicKey - self.seed = seed.seed - self.address = seed.address + + self.init(publicKey: seed.publicKey, + seed: seed.seed, + address: seed.address) } } diff --git a/WavesWallet-iOS/DataLayer/Repositories/AccountBalance/AccountBalanceRepositoryLocal.swift b/DataLayer/Sources/Repositories/AccountBalance/AccountBalanceRepositoryLocal.swift similarity index 92% rename from WavesWallet-iOS/DataLayer/Repositories/AccountBalance/AccountBalanceRepositoryLocal.swift rename to DataLayer/Sources/Repositories/AccountBalance/AccountBalanceRepositoryLocal.swift index 64445afa..494bdc01 100644 --- a/WavesWallet-iOS/DataLayer/Repositories/AccountBalance/AccountBalanceRepositoryLocal.swift +++ b/DataLayer/Sources/Repositories/AccountBalance/AccountBalanceRepositoryLocal.swift @@ -10,7 +10,9 @@ import Foundation import RealmSwift import RxRealm import RxSwift -import WavesSDKExtension +import WavesSDKExtensions +import DomainLayer +import Extensions final class AccountBalanceRepositoryLocal: AccountBalanceRepositoryProtocol { @@ -140,13 +142,13 @@ fileprivate extension DomainLayer.DTO.AssetBalance { init(balance: AssetBalance) { - self.modified = balance.modified - self.assetId = balance.assetId - self.totalBalance = balance.balance - self.leasedBalance = balance.leasedBalance - self.inOrderBalance = balance.inOrderBalance - self.sponsorBalance = balance.sponsorBalance - self.minSponsoredAssetFee = balance.minSponsoredAssetFee + self.init(assetId: balance.assetId, + totalBalance: balance.balance, + leasedBalance: balance.leasedBalance, + inOrderBalance: balance.inOrderBalance, + modified: balance.modified, + sponsorBalance: balance.sponsorBalance, + minSponsoredAssetFee: balance.minSponsoredAssetFee) } } diff --git a/DataLayer/Sources/Repositories/AccountBalance/AccountBalanceRepositoryRemote.swift b/DataLayer/Sources/Repositories/AccountBalance/AccountBalanceRepositoryRemote.swift new file mode 100644 index 00000000..0f15e6bd --- /dev/null +++ b/DataLayer/Sources/Repositories/AccountBalance/AccountBalanceRepositoryRemote.swift @@ -0,0 +1,261 @@ +// +// AccountBalanceRepositoryRemote.swift +// WavesWallet-iOS +// +// Created by Prokofev Ruslan on 05/08/2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import Moya +import RxSwift +import WavesSDKExtensions +import WavesSDK +import WavesSDKCrypto +import DomainLayer + +private struct SponsoredAssetDetail { + let minSponsoredAssetFee: Int64? + let sponsoredBalance: Int64 +} + +final class AccountBalanceRepositoryRemote: AccountBalanceRepositoryProtocol { + + private let environmentRepository: EnvironmentRepositoryProtocols + + init(environmentRepository: EnvironmentRepositoryProtocols) { + self.environmentRepository = environmentRepository + } + + func balances(by wallet: DomainLayer.DTO.SignedWallet) -> Observable<[DomainLayer.DTO.AssetBalance]> { + + let walletAddress = wallet.address + let assetsBalance = self.assetsBalance(by: walletAddress) + let accountBalance = self.accountBalance(by: walletAddress) + let matcherBalances = self.matcherBalances(by: walletAddress, wallet: wallet) + + return Observable + .zip(assetsBalance, + accountBalance, + matcherBalances) + .map { DomainLayer.DTO.AssetBalance.map(assets: $0.0, + account: $0.1, + matcherBalances: $0.2) } + } + + func balance(by assetId: String, wallet: DomainLayer.DTO.SignedWallet) -> Observable { + + let matcherBalances = self.matcherBalances(by: wallet.address, wallet: wallet) + + if assetId == WavesSDKConstants.wavesAssetId { + let accountBalance = self.accountBalance(by: wallet.address) + + return Observable + .zip(accountBalance, + matcherBalances) + .map({ (accountBalance, matcher) -> DomainLayer.DTO.AssetBalance in + let inOrderBalance = matcher[WavesSDKConstants.wavesAssetId] ?? 0 + return DomainLayer.DTO.AssetBalance(accountBalance: accountBalance, inOrderBalance: inOrderBalance) + }) + } else { + let assetBalance = self.assetBalance(by: wallet.address, assetId: assetId) + let sponsorBalance = self.sponsorBalance(assetId: assetId, walletAddress: wallet.address) + + return Observable + .zip(assetBalance, + matcherBalances, + sponsorBalance) + .map({ (assetBalance, matcher, sponsorBalance) -> DomainLayer.DTO.AssetBalance in + let inOrderBalance = matcher[WavesSDKConstants.wavesAssetId] ?? 0 + return DomainLayer.DTO.AssetBalance(model: assetBalance, + inOrderBalance: inOrderBalance, + sponsoredAssetDetail: sponsorBalance) + }) + } + } + + func deleteBalances(_ balances:[DomainLayer.DTO.AssetBalance], accountAddress: String) -> Observable { + assertMethodDontSupported() + return Observable.never() + } + + func saveBalances(_ balances: [DomainLayer.DTO.AssetBalance], accountAddress: String) -> Observable { + assertMethodDontSupported() + return Observable.never() + } + + func saveBalance(_ balance: DomainLayer.DTO.AssetBalance, accountAddress: String) -> Observable { + assertMethodDontSupported() + return Observable.never() + } + + func listenerOfUpdatedBalances(by accountAddress: String) -> Observable<[DomainLayer.DTO.AssetBalance]> { + assertMethodDontSupported() + return Observable.never() + } +} + +private extension AccountBalanceRepositoryRemote { + + func matcherBalances(by walletAddress: String, + wallet: DomainLayer.DTO.SignedWallet) -> Observable<[String: Int64]> { + + return environmentRepository + .servicesEnvironment() + .flatMap({ (servicesEnvironment) -> Observable<[String: Int64]> in + + let signature = TimestampSignature(signedWallet: wallet, + timestampServerDiff: servicesEnvironment.timestampServerDiff) + + return servicesEnvironment + .wavesServices + .matcherServices + .balanceMatcherService + .balanceReserved(query: .init(senderPublicKey: wallet.publicKey.getPublicKeyStr(), + signature: Base58Encoder.encode(signature.signature()), + timestamp: signature.timestamp)) + }) + } + + func assetBalance(by walletAddress: String, + assetId: String) -> Observable { + + return environmentRepository + .servicesEnvironment() + .flatMap({ (servicesEnvironment) -> Observable in + + return servicesEnvironment + .wavesServices + .nodeServices + .assetsNodeService + .assetBalance(address: walletAddress, + assetId: assetId) + }) + + } + + //TODO: https://wavesplatform.atlassian.net/browse/NODE-1488 + func sponsorBalance(assetId: String, walletAddress: String) -> Observable { + return assetDetail(assetId: assetId, + walletAddress: walletAddress) + .flatMap { [weak self] (detail) -> Observable in + + guard let self = self else { return Observable.never() } + + return self.balance(for: detail.issuer, + myWalletAddress: walletAddress) + .map({ (balance) -> SponsoredAssetDetail in + return SponsoredAssetDetail(minSponsoredAssetFee: detail.minSponsoredAssetFee, + sponsoredBalance: balance.balance) + }) + } + } + + func assetDetail(assetId: String, walletAddress: String) -> Observable { + + return environmentRepository + .servicesEnvironment() + .flatMap({ (servicesEnvironment) -> Observable in + + return servicesEnvironment + .wavesServices + .nodeServices + .assetsNodeService + .assetDetails(assetId: assetId) + }) + } + + func balance(for walletAddress: String, myWalletAddress: String) -> Observable { + + return environmentRepository + .servicesEnvironment() + .flatMap({ (servicesEnvironment) -> Observable in + + return servicesEnvironment + .wavesServices + .nodeServices + .addressesNodeService + .addressBalance(address: walletAddress) + }) + } + + func assetsBalance(by walletAddress: String) -> Observable { + + return environmentRepository + .servicesEnvironment() + .flatMap({ (servicesEnvironment) -> Observable in + + return servicesEnvironment + .wavesServices + .nodeServices + .assetsNodeService + .assetsBalances(address: walletAddress) + + }) + } + + func accountBalance(by walletAddress: String) -> Observable { + + return environmentRepository + .servicesEnvironment() + .flatMap({ (servicesEnvironment) -> Observable in + + return servicesEnvironment + .wavesServices + .nodeServices + .addressesNodeService + .addressBalance(address: walletAddress) + }) + } +} + +private extension DomainLayer.DTO.AssetBalance { + + init(accountBalance: NodeService.DTO.AddressBalance, inOrderBalance: Int64) { + + self.init(assetId: WavesSDKConstants.wavesAssetId, + totalBalance: accountBalance.balance, + leasedBalance: 0, + inOrderBalance: inOrderBalance, + modified: Date(), + sponsorBalance: 0, + minSponsoredAssetFee: 0) + } + + init(model: NodeService.DTO.AssetBalance, inOrderBalance: Int64) { + + self.init(assetId: model.assetId, + totalBalance: model.balance, + leasedBalance: 0, + inOrderBalance: inOrderBalance, + modified: Date(), + sponsorBalance: model.sponsorBalance ?? 0, + minSponsoredAssetFee: model.minSponsoredAssetFee ?? 0) + } + + init(model: NodeService.DTO.AddressAssetBalance, inOrderBalance: Int64, sponsoredAssetDetail: SponsoredAssetDetail) { + + self.init(assetId: model.assetId, + totalBalance: model.balance, + leasedBalance: 0, + inOrderBalance: inOrderBalance, + modified: Date(), + sponsorBalance: sponsoredAssetDetail.sponsoredBalance, + minSponsoredAssetFee: sponsoredAssetDetail.minSponsoredAssetFee ?? 0) + } + + static func map(assets: NodeService.DTO.AddressAssetsBalance, + account: NodeService.DTO.AddressBalance, + matcherBalances: [String: Int64]) -> [DomainLayer.DTO.AssetBalance] { + + let assetsBalance = assets.balances.map { DomainLayer.DTO.AssetBalance(model: $0, inOrderBalance: matcherBalances[$0.assetId] ?? 0) } + let accountBalance = DomainLayer.DTO.AssetBalance(accountBalance: account, + inOrderBalance: matcherBalances[WavesSDKConstants.wavesAssetId] ?? 0) + + var list = [DomainLayer.DTO.AssetBalance]() + list.append(contentsOf: assetsBalance) + list.append(accountBalance) + + return list + } +} diff --git a/DataLayer/Sources/Repositories/AccountSettingsRepository.swift b/DataLayer/Sources/Repositories/AccountSettingsRepository.swift new file mode 100644 index 00000000..bc9f5fc0 --- /dev/null +++ b/DataLayer/Sources/Repositories/AccountSettingsRepository.swift @@ -0,0 +1,175 @@ +// +// AccountEnvironmentRepository.swift +// WavesWallet-iOS +// +// Created by Prokofev Ruslan on 22/10/2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import RxRealm +import RealmSwift +import WavesSDKExtensions +import DomainLayer +import Extensions +import Moya + +final class AccountSettingsRepository: AccountSettingsRepositoryProtocol { + + private let spamAssetsService: SpamAssetsService = SpamAssetsService() + + func accountSettings(accountAddress: String) -> Observable { + return Observable.create({ observer -> Disposable in + + do { + let realm = try WalletRealmFactory.realm(accountAddress: accountAddress) + let result = realm.objects(AccountSettings.self) + + if let settings = result.toArray().first { + observer.onNext(DomainLayer.DTO.AccountSettings(settings)) + observer.onCompleted() + } else { + observer.onNext(nil) + observer.onCompleted() + } + + return Disposables.create() + } catch let e { + SweetLogger.debug(e) + observer.onError(AccountSettingsRepositoryError.invalid) + return Disposables.create() + } + }) + } + + func saveAccountSettings(accountAddress: String, settings: DomainLayer.DTO.AccountSettings) -> Observable { + return Observable.create({ observer -> Disposable in + + do { + let realm = try WalletRealmFactory.realm(accountAddress: accountAddress) + try realm.write { + + let result = realm.objects(AccountSettings.self) + realm.delete(result) + + realm.add(AccountSettings(settings)) + } + + observer.onNext(settings) + observer.onCompleted() + + return Disposables.create() + + } catch let e { + SweetLogger.debug(e) + observer.onError(AccountSettingsRepositoryError.invalid) + return Disposables.create() + } + + }) + } + + func setSpamURL(_ url: String, by accountAddress: String) -> Observable { + return Observable.create({ [weak self] (observer) -> Disposable in + + guard let self = self else { + return Disposables.create() + } + + guard url.isValidUrl else { + observer.onError(EnvironmentRepositoryError.invalidURL) + return Disposables.create() + } + + guard let link = URL(string: url) else { + observer.onError(EnvironmentRepositoryError.invalidURL) + return Disposables.create() + } + + let disposable = self + .spamAssetsService + .spamAssets(by: link) + .catchError({ _ -> Observable<[SpamAssetId]> in + return Observable.error(EnvironmentRepositoryError.invalidResponse) + }) + .flatMap({ [weak self] _ -> Observable in + + guard let self = self else { + return Observable.never() + } + return self.accountEnvironment(accountAddress: accountAddress) + }) + .flatMap({ [weak self] account -> Observable in + + guard let self = self else { + return Observable.never() + } + + let newAccount = account ?? DomainLayer.DTO.AccountEnvironment(nodeUrl: "", + dataUrl: "", + spamUrl: url, + matcherUrl: "") + + return self.saveAccountEnvironment(newAccount, accountAddress: accountAddress) + }) + .subscribe(observer) + + return Disposables.create([disposable]) + }) + } + + func accountEnvironment(accountAddress: String) -> Observable { + + return Observable.create { observer -> Disposable in + + //TODO: Error + let realm = try! WalletRealmFactory.realm(accountAddress: accountAddress) + + let result = realm.objects(AccountEnvironment.self) + + guard let environment = result.toArray().first else { + observer.onNext(nil) + observer.onCompleted() + return Disposables.create() + } + + observer.onNext(.init(nodeUrl: environment.nodeUrl, + dataUrl: environment.dataUrl, + spamUrl: environment.spamUrl, + matcherUrl: environment.matcherUrl)) + observer.onCompleted() + + return Disposables.create() + } + } + + func saveAccountEnvironment(_ accountEnvironment: DomainLayer.DTO.AccountEnvironment, + accountAddress: String) -> Observable { + return Observable.create { observer -> Disposable in + + //TODO: Error + let realm = try! WalletRealmFactory.realm(accountAddress: accountAddress) + + try? realm.write { + realm + .objects(AccountEnvironment.self) + .toArray() + .forEach({ account in + account.realm?.delete(account) + }) + + let environment = AccountEnvironment() + environment.dataUrl = accountEnvironment.dataUrl + environment.matcherUrl = accountEnvironment.matcherUrl + environment.nodeUrl = accountEnvironment.nodeUrl + environment.spamUrl = accountEnvironment.spamUrl + realm.add(environment, update: false) + } + observer.onNext(true) + observer.onCompleted() + + return Disposables.create() + } + } +} diff --git a/DataLayer/Sources/Repositories/AddressBook/AddressBookRepository.swift b/DataLayer/Sources/Repositories/AddressBook/AddressBookRepository.swift new file mode 100644 index 00000000..d6fd51f5 --- /dev/null +++ b/DataLayer/Sources/Repositories/AddressBook/AddressBookRepository.swift @@ -0,0 +1,140 @@ +// +// AddressBookRepositoryLocal.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 9/26/18. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import RxRealm +import RealmSwift +import DomainLayer +import Extensions + +final class AddressBookRepository: AddressBookRepositoryProtocol { + + func contact(by address: String, accountAddress: String) -> Observable { + + return Observable.create({ observer -> Disposable in + + do { + + let realm = try WalletRealmFactory.realm(accountAddress: accountAddress) + if let object = realm.object(ofType: AddressBook.self, forPrimaryKey: address) { + observer.onNext(DomainLayer.DTO.Contact(name: object.name, address: object.address)) + } else { + observer.onNext(nil) + } + observer.onCompleted() + + } catch _ { + observer.onError(RepositoryError.fail) + } + + + return Disposables.create() + }) + } + + func listListener(by accountAddress: String) -> Observable<[DomainLayer.DTO.Contact]> { + return Observable.create({ observer -> Disposable in + + do { + let realm = try WalletRealmFactory.realm(accountAddress: accountAddress) + let result = realm.objects(AddressBook.self) + let collection = Observable.collection(from: result) + .skip(1) + .map { $0.toArray() } + .map({ list -> [DomainLayer.DTO.Contact] in + return list.map { return DomainLayer.DTO.Contact(name: $0.name, address: $0.address) } + }) + .bind(to: observer) + + return Disposables.create([collection]) + + } catch _ { + observer.onError(RepositoryError.fail) + } + + return Disposables.create() + }) + .subscribeOn(Schedulers.realmThreadScheduler) + } + + func list(by accountAddress: String) -> Observable<[DomainLayer.DTO.Contact]> { + return Observable.create({ observer -> Disposable in + + do { + let realm = try WalletRealmFactory.realm(accountAddress: accountAddress) + + let list = realm.objects(AddressBook.self).toArray().map { + return DomainLayer.DTO.Contact(name: $0.name, address: $0.address) + } + observer.onNext(list) + observer.onCompleted() + + } catch _ { + observer.onError(RepositoryError.fail) + } + + return Disposables.create() + }) + } + + func save(contact: DomainLayer.DTO.Contact, accountAddress: String) -> Observable { + + return Observable.create({ observer -> Disposable in + + do { + let realm = try WalletRealmFactory.realm(accountAddress: accountAddress) + + try realm.write { + realm.add(AddressBook(contact), update: true) + } + + observer.onNext(true) + observer.onCompleted() + + } catch _ { + observer.onError(RepositoryError.fail) + } + + return Disposables.create() + }) + } + + func delete(contact: DomainLayer.DTO.Contact, accountAddress: String) -> Observable { + + return Observable.create({ observer -> Disposable in + //TODO: Remove ! + let realm = try! WalletRealmFactory.realm(accountAddress: accountAddress) + + guard let user = realm.object(ofType: AddressBook.self, + forPrimaryKey: contact.address) else { + observer.onNext(true) + observer.onCompleted() + return Disposables.create() + } + + try! realm.write { + realm.delete(user) + } + + observer.onNext(true) + observer.onCompleted() + + return Disposables.create() + }) + } +} + +private extension AddressBook { + + convenience init(_ from: DomainLayer.DTO.Contact) { + self.init() + self.address = from.address + self.name = from.name + } +} diff --git a/DataLayer/Sources/Repositories/AddressRepositoryRemote.swift b/DataLayer/Sources/Repositories/AddressRepositoryRemote.swift new file mode 100644 index 00000000..28681f5f --- /dev/null +++ b/DataLayer/Sources/Repositories/AddressRepositoryRemote.swift @@ -0,0 +1,38 @@ +// +// AddressRepositoryRemote.swift +// WavesWallet-iOS +// +// Created by mefilt on 21/01/2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import Moya +import WavesSDK +import DomainLayer +import Extensions + +final class AddressRepositoryRemote: AddressRepositoryProtocol { + + private let environmentRepository: EnvironmentRepositoryProtocols + + init(environmentRepository: EnvironmentRepositoryProtocols) { + self.environmentRepository = environmentRepository + } + + func isSmartAddress(accountAddress: String) -> Observable { + + return environmentRepository + .servicesEnvironment() + .flatMapLatest({ (servicesEnvironment) -> Observable in + + return servicesEnvironment + .wavesServices + .nodeServices + .addressesNodeService + .scriptInfo(address: accountAddress) + .map { ($0.extraFee ?? 0) > 0 } + }) + } +} diff --git a/DataLayer/Sources/Repositories/Aliases/AliasesRepository.swift b/DataLayer/Sources/Repositories/Aliases/AliasesRepository.swift new file mode 100644 index 00000000..70062c21 --- /dev/null +++ b/DataLayer/Sources/Repositories/Aliases/AliasesRepository.swift @@ -0,0 +1,78 @@ +// +// AliasRepositoryRemote.swift +// WavesWallet-iOS +// +// Created by Prokofev Ruslan on 27/10/2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import Moya +import WavesSDKExtensions +import WavesSDK +import DomainLayer + +final class AliasesRepository: AliasesRepositoryProtocol { + + private let environmentRepository: EnvironmentRepositoryProtocols + + init(environmentRepository: EnvironmentRepositoryProtocols) { + self.environmentRepository = environmentRepository + } + + func aliases(accountAddress: String) -> Observable<[DomainLayer.DTO.Alias]> { + + return environmentRepository + .servicesEnvironment() + .flatMapLatest({ (servicesEnvironment) -> Observable<(aliases: [DataService.DTO.Alias], environment: WalletEnvironment)> in + + return servicesEnvironment + .wavesServices + .dataServices + .aliasDataService + .aliases(address: accountAddress) + .map { (aliases: $0, environment: servicesEnvironment.walletEnvironment) } + }) + .map({ data -> [DomainLayer.DTO.Alias] in + + let list = data.aliases + let aliasScheme = data.environment.aliasScheme + + return list.map({ alias -> DomainLayer.DTO.Alias? in + + let name = alias.alias + let originalName = aliasScheme + name + return DomainLayer.DTO.Alias(name: name, originalName: originalName) + }) + .compactMap { $0 } + }) + } + + func alias(by name: String, accountAddress: String) -> Observable { + return environmentRepository + .servicesEnvironment() + .flatMapLatest({ (servicesEnvironment) -> Observable in + + return servicesEnvironment + .wavesServices + .dataServices + .aliasDataService + .alias(name: name) + .map { $0.address } + .catchError({ (error) -> Observable in + + if let error = error as? NetworkError, error == .notFound { + return Observable.error(AliasesRepositoryError.dontExist) + } + + return Observable.error(AliasesRepositoryError.invalid) + }) + }) + } + + func saveAliases(by accountAddress: String, aliases: [DomainLayer.DTO.Alias]) -> Observable { + assertMethodDontSupported() + return Observable.never() + } +} diff --git a/WavesWallet-iOS/DataLayer/Repositories/Aliases/AliasesRepositoryLocal.swift b/DataLayer/Sources/Repositories/Aliases/AliasesRepositoryLocal.swift similarity index 98% rename from WavesWallet-iOS/DataLayer/Repositories/Aliases/AliasesRepositoryLocal.swift rename to DataLayer/Sources/Repositories/Aliases/AliasesRepositoryLocal.swift index e4950143..7fe3934c 100644 --- a/WavesWallet-iOS/DataLayer/Repositories/Aliases/AliasesRepositoryLocal.swift +++ b/DataLayer/Sources/Repositories/Aliases/AliasesRepositoryLocal.swift @@ -8,7 +8,8 @@ import Foundation import RxSwift -import WavesSDKExtension +import WavesSDKExtensions +import DomainLayer private enum Constants { static var notFoundCode = 404 diff --git a/DataLayer/Sources/Repositories/ApplicationVersionRepository.swift b/DataLayer/Sources/Repositories/ApplicationVersionRepository.swift new file mode 100644 index 00000000..f490db46 --- /dev/null +++ b/DataLayer/Sources/Repositories/ApplicationVersionRepository.swift @@ -0,0 +1,55 @@ +// +// ApplicationVersionRepository.swift +// WavesWallet-iOS +// +// Created by rprokofev on 30/05/2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import RxSwiftExt +import Moya +import DomainLayer + +private struct Constants { + static let lastVersion: String = "last_version" + static let forceUpdateVersion: String = "force_update_version" +} + +final class ApplicationVersionRepository: ApplicationVersionRepositoryProtocol { + + private let applicationVersionService: MoyaProvider = .anyMoyaProvider() + + func version() -> Observable { + return versionByMappingKey(key: Constants.lastVersion) + } + + func forceUpdateVersion() -> Observable { + return versionByMappingKey(key: Constants.forceUpdateVersion) + } +} + +private extension ApplicationVersionRepository { + + func versionByMappingKey(key: String) -> Observable { + return applicationVersionService + .rx + .request(.get(isDebug: ApplicationDebugSettings.isEnableVersionUpdateTest, hasProxy: true)) + .catchError({ [weak self] (_) -> PrimitiveSequence in + guard let self = self else { return Single.never() } + return self + .applicationVersionService + .rx + .request(.get(isDebug: ApplicationDebugSettings.isEnableVersionUpdateTest, hasProxy: false)) + }) + .map([String: String].self) + .map { $0[key] } + .asObservable() + .flatMap({ (version) -> Observable in + guard let version = version else { return Observable.error(RepositoryError.fail) } + + return Observable.just(version) + }) + } +} diff --git a/WavesWallet-iOS/DataLayer/Repositories/Assets/AssetsBalanceSettingsRepositoryLocal.swift b/DataLayer/Sources/Repositories/Assets/AssetsBalanceSettingsRepositoryLocal.swift similarity index 95% rename from WavesWallet-iOS/DataLayer/Repositories/Assets/AssetsBalanceSettingsRepositoryLocal.swift rename to DataLayer/Sources/Repositories/Assets/AssetsBalanceSettingsRepositoryLocal.swift index b4a07db4..55018ab8 100644 --- a/WavesWallet-iOS/DataLayer/Repositories/Assets/AssetsBalanceSettingsRepositoryLocal.swift +++ b/DataLayer/Sources/Repositories/Assets/AssetsBalanceSettingsRepositoryLocal.swift @@ -10,7 +10,9 @@ import Foundation import RxSwift import RealmSwift import RxRealm -import WavesSDKExtension +import WavesSDKExtensions +import DomainLayer +import Extensions final class AssetsBalanceSettingsRepositoryLocal: AssetsBalanceSettingsRepositoryProtocol { @@ -137,10 +139,11 @@ final class AssetsBalanceSettingsRepositoryLocal: AssetsBalanceSettingsRepositor private extension DomainLayer.DTO.AssetBalanceSettings { init(_ settings: AssetBalanceSettings) { - self.assetId = settings.assetId - self.sortLevel = settings.sortLevel - self.isHidden = settings.isHidden - self.isFavorite = settings.isFavorite + + self.init(assetId: settings.assetId, + sortLevel: settings.sortLevel, + isHidden: settings.isHidden, + isFavorite: settings.isFavorite) } } diff --git a/WavesWallet-iOS/DataLayer/Repositories/Assets/AssetsRepositoryLocal.swift b/DataLayer/Sources/Repositories/Assets/AssetsRepositoryLocal.swift similarity index 92% rename from WavesWallet-iOS/DataLayer/Repositories/Assets/AssetsRepositoryLocal.swift rename to DataLayer/Sources/Repositories/Assets/AssetsRepositoryLocal.swift index 62a8da9a..5475f861 100644 --- a/WavesWallet-iOS/DataLayer/Repositories/Assets/AssetsRepositoryLocal.swift +++ b/DataLayer/Sources/Repositories/Assets/AssetsRepositoryLocal.swift @@ -10,10 +10,16 @@ import Foundation import RxSwift import RealmSwift import RxRealm -import WavesSDKExtension +import WavesSDKExtensions +import DomainLayer final class AssetsRepositoryLocal: AssetsRepositoryProtocol { + func searchAssets(search: String) -> Observable<[DomainLayer.DTO.Asset]> { + assertMethodDontSupported() + return Observable.never() + } + func assets(by ids: [String], accountAddress: String) -> Observable<[DomainLayer.DTO.Asset]> { return Observable.create({ (observer) -> Disposable in diff --git a/DataLayer/Sources/Repositories/Assets/AssetsRepositoryRemote.swift b/DataLayer/Sources/Repositories/Assets/AssetsRepositoryRemote.swift new file mode 100644 index 00000000..306922f3 --- /dev/null +++ b/DataLayer/Sources/Repositories/Assets/AssetsRepositoryRemote.swift @@ -0,0 +1,222 @@ +// +// AssetsRepositoryRemote.swift +// WavesWallet-iOS +// +// Created by Prokofev Ruslan on 04/08/2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import Moya +import CSV +import WavesSDKExtensions +import WavesSDK +import DomainLayer +import Extensions + +private enum Constants { + static let searchAssetsLimit: Int = 100 + static let vostokAssetDescription = "Waves Enterprise System Token." + static let vostokAssetId = "Vostok" +} + +final class AssetsRepositoryRemote: AssetsRepositoryProtocol { + + private let environmentRepository: EnvironmentRepositoryProtocols + + private let spamAssetsRepository: SpamAssetsRepositoryProtocol + + init(environmentRepository: EnvironmentRepositoryProtocols, + spamAssetsRepository: SpamAssetsRepositoryProtocol) { + self.environmentRepository = environmentRepository + self.spamAssetsRepository = spamAssetsRepository + } + + func assets(by ids: [String], accountAddress: String) -> Observable<[DomainLayer.DTO.Asset]> { + + return environmentRepository + .servicesEnvironment() + .flatMap({ [weak self] (servicesEnvironment) -> Observable<[DomainLayer.DTO.Asset]> in + + guard let self = self else { return Observable.empty() } + + let walletEnviroment = servicesEnvironment.walletEnvironment + + let spamAssets = self + .spamAssetsRepository + .spamAssets(accountAddress: accountAddress) + + let assetsList = servicesEnvironment + .wavesServices + .dataServices + .assetsDataService + .assets(ids: ids) + + return Observable.zip(assetsList, spamAssets) + .map({ (assets, spamAssets) -> [DomainLayer.DTO.Asset] in + + let map = walletEnviroment.hashMapAssets() + let mapGeneralAssets = walletEnviroment.hashMapGeneralAssets() + + let spamIds = spamAssets.reduce(into: [String: Bool](), {$0[$1] = true }) + + return assets.map { DomainLayer.DTO.Asset(asset: $0, + info: map[$0.id], + isSpam: spamIds[$0.id] == true, + isMyWavesToken: $0.sender == accountAddress, + isGeneral: mapGeneralAssets[$0.id] != nil) } + }) + }) + } + + //TODO: Refactor method + func searchAssets(search: String) -> Observable<[DomainLayer.DTO.Asset]> { + + // + let accountAddress: String = "" + + return environmentRepository + .servicesEnvironment() + .flatMap({ [weak self] (servicesEnvironment) -> Observable<[DomainLayer.DTO.Asset]> in + + guard let self = self else { return Observable.empty() } + + let walletEnviroment = servicesEnvironment.walletEnvironment + + let spamAssets = self + .spamAssetsRepository + .spamAssets(accountAddress: accountAddress) + + let assetsList = servicesEnvironment + .wavesServices + .dataServices + .assetsDataService + .searchAssets(search: search, limit: Constants.searchAssetsLimit) + + return Observable.zip(assetsList, spamAssets) + .map({ (assets, spamAssets) -> [DomainLayer.DTO.Asset] in + + let map = walletEnviroment.hashMapAssets() + let mapGeneralAssets = walletEnviroment.hashMapGeneralAssets() + + let spamIds = spamAssets.reduce(into: [String: Bool](), {$0[$1] = true }) + + return assets.map { DomainLayer.DTO.Asset(asset: $0, + info: map[$0.id], + isSpam: spamIds[$0.id] == true, + isMyWavesToken: $0.sender == accountAddress, + isGeneral: mapGeneralAssets[$0.id] != nil) } + }) + }) + } + + func saveAssets(_ assets:[DomainLayer.DTO.Asset], by accountAddress: String) -> Observable { + assertMethodDontSupported() + return Observable.never() + } + + func saveAsset(_ asset: DomainLayer.DTO.Asset, by accountAddress: String) -> Observable { + assertMethodDontSupported() + return Observable.never() + } + + func isSmartAsset(_ assetId: String, by accountAddress: String) -> Observable { + + if assetId == WavesSDKConstants.wavesAssetId { + return Observable.just(false) + } + + return environmentRepository + .servicesEnvironment() + .map { $0.wavesServices } + .flatMap({ (wavesServices) -> Observable in + + return wavesServices + .nodeServices + .assetsNodeService + .assetDetails(assetId: assetId) + .map { $0.scripted == true } + }) + } +} + +fileprivate extension WalletEnvironment { + + func hashMapAssets() -> [String: WalletEnvironment.AssetInfo] { + + var allAssets = generalAssets + if let additionalAssets = assets { + allAssets.append(contentsOf: additionalAssets) + } + + return allAssets.reduce([String: WalletEnvironment.AssetInfo](), { map, info -> [String: WalletEnvironment.AssetInfo] in + var new = map + new[info.assetId] = info + return new + }) + } + + func hashMapGeneralAssets() -> [String: WalletEnvironment.AssetInfo] { + + let allAssets = generalAssets + + return allAssets.reduce([String: WalletEnvironment.AssetInfo](), { map, info -> [String: WalletEnvironment.AssetInfo] in + var new = map + new[info.assetId] = info + return new + }) + } +} + +fileprivate extension DomainLayer.DTO.Asset { + + init(asset: DataService.DTO.Asset, info: WalletEnvironment.AssetInfo?, isSpam: Bool, isMyWavesToken: Bool, isGeneral: Bool) { + var isWaves = false + var isFiat = false + let isGateway = info?.isGateway ?? false + let isWavesToken = isFiat == false && isGateway == false && isWaves == false + var name = asset.name + var description = asset.description + + //TODO: Current code need move to AssetsInteractor! + if let info = info { + if info.assetId == WavesSDKConstants.wavesAssetId { + isWaves = true + } + + if info.gatewayId == Constants.vostokAssetId { + description = Constants.vostokAssetDescription + } + + name = info.displayName + isFiat = info.isFiat + } + + self.init(id: asset.id, + gatewayId: info?.gatewayId, + wavesId: info?.wavesId, + displayName: name, + precision: asset.precision, + description: description, + height: asset.height, + timestamp: asset.timestamp, + sender: asset.sender, + quantity: asset.quantity, + ticker: asset.ticker, + isReusable: asset.reissuable, + isSpam: isSpam, + isFiat: isFiat, + isGeneral: isGeneral, + isMyWavesToken: isMyWavesToken, + isWavesToken: isWavesToken, + isGateway: isGateway, + isWaves: isWaves, + modified: Date(), + addressRegEx: info?.addressRegEx ?? "", + iconLogoUrl: info?.iconUrls?.default, + hasScript: asset.hasScript, + minSponsoredFee: asset.minSponsoredFee ?? 0, + gatewayType: info?.gatewayType) + } +} diff --git a/WavesWallet-iOS/DataLayer/Repositories/AuthenticationRepositoryRemote.swift b/DataLayer/Sources/Repositories/AuthenticationRepositoryRemote.swift similarity index 99% rename from WavesWallet-iOS/DataLayer/Repositories/AuthenticationRepositoryRemote.swift rename to DataLayer/Sources/Repositories/AuthenticationRepositoryRemote.swift index dd071d82..53a6ff4f 100644 --- a/WavesWallet-iOS/DataLayer/Repositories/AuthenticationRepositoryRemote.swift +++ b/DataLayer/Sources/Repositories/AuthenticationRepositoryRemote.swift @@ -11,6 +11,8 @@ import FirebaseCore import FirebaseDatabase import Foundation import RxSwift +import WavesSDK +import DomainLayer fileprivate enum Constants { #if DEBUG diff --git a/DataLayer/Sources/Repositories/BlockRepositoryRemote.swift b/DataLayer/Sources/Repositories/BlockRepositoryRemote.swift new file mode 100644 index 00000000..594479cf --- /dev/null +++ b/DataLayer/Sources/Repositories/BlockRepositoryRemote.swift @@ -0,0 +1,37 @@ +// +// BlockRepositoryRemote.swift +// WavesWallet-iOS +// +// Created by mefilt on 10.09.2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import Moya +import WavesSDK +import DomainLayer + +final class BlockRepositoryRemote: BlockRepositoryProtocol { + + private let environmentRepository: EnvironmentRepositoryProtocols + + init(environmentRepository: EnvironmentRepositoryProtocols) { + self.environmentRepository = environmentRepository + } + + func height(accountAddress: String) -> Observable { + + return environmentRepository + .servicesEnvironment() + .flatMap({ (servicesEnvironment) -> Observable in + + return servicesEnvironment + .wavesServices + .nodeServices + .blocksNodeService + .height(address: accountAddress) + .map { $0.height } + }) + } +} diff --git a/WavesWallet-iOS/DataLayer/Repositories/CoinomatRepository.swift b/DataLayer/Sources/Repositories/CoinomatRepository.swift similarity index 95% rename from WavesWallet-iOS/DataLayer/Repositories/CoinomatRepository.swift rename to DataLayer/Sources/Repositories/CoinomatRepository.swift index ca70e21e..f6bf4fc8 100644 --- a/WavesWallet-iOS/DataLayer/Repositories/CoinomatRepository.swift +++ b/DataLayer/Sources/Repositories/CoinomatRepository.swift @@ -9,8 +9,9 @@ import Foundation import RxSwift import Moya -import WavesSDKExtension -import WavesSDKCrypto +import WavesSDK +import DomainLayer +import Extensions private enum Response { @@ -46,7 +47,7 @@ private enum Response { final class CoinomatRepository: CoinomatRepositoryProtocol { - private let coinomatProvider: MoyaProvider = .nodeMoyaProvider() + private let coinomatProvider: MoyaProvider = .anyMoyaProvider() func tunnelInfo(asset: DomainLayer.DTO.Asset, currencyFrom: String, currencyTo: String, walletTo: String, moneroPaymentID: String?) -> Observable { @@ -101,7 +102,7 @@ final class CoinomatRepository: CoinomatRepositoryProtocol { func cardLimits(address: String, fiat: String) -> Observable { - let cardLimit = Coinomat.Service.CardLimit(crypto: WavesSDKCryptoConstants.wavesAssetId, + let cardLimit = Coinomat.Service.CardLimit(crypto: WavesSDKConstants.wavesAssetId, address: address, fiat: fiat) return coinomatProvider.rx @@ -110,8 +111,8 @@ final class CoinomatRepository: CoinomatRepositoryProtocol { .map(Response.CardLimit.self) .asObservable() .map({ (limit) -> DomainLayer.DTO.Coinomat.CardLimit in - let min = Money(value: Decimal(limit.min), WavesSDKCryptoConstants.FiatDecimals) - let max = Money(value: Decimal(limit.max), WavesSDKCryptoConstants.FiatDecimals) + let min = Money(value: Decimal(limit.min), WavesSDKConstants.FiatDecimals) + let max = Money(value: Decimal(limit.max), WavesSDKConstants.FiatDecimals) return DomainLayer.DTO.Coinomat.CardLimit(min: min, max: max) }) } @@ -128,13 +129,13 @@ final class CoinomatRepository: CoinomatRepositoryProtocol { .map({ (response) -> Money in let string = String(data: response.data, encoding: .utf8) ?? "" - return Money(value: Decimal((string as NSString).doubleValue), WavesSDKCryptoConstants.WavesDecimals) + return Money(value: Decimal((string as NSString).doubleValue), WavesSDKConstants.WavesDecimals) }) } func generateBuyLink(address: String, amount: Double, fiat: String) -> Observable { - let params = ["crypto" : WavesSDKCryptoConstants.wavesAssetId, + let params = ["crypto" : WavesSDKConstants.wavesAssetId, "address" : address, "amount" : String(amount), "fiat" : fiat] diff --git a/DataLayer/Sources/Repositories/Dex/CandlesRepositoryRemote.swift b/DataLayer/Sources/Repositories/Dex/CandlesRepositoryRemote.swift new file mode 100644 index 00000000..f6fcc760 --- /dev/null +++ b/DataLayer/Sources/Repositories/Dex/CandlesRepositoryRemote.swift @@ -0,0 +1,117 @@ +// +// CandlesRepositoryProtocol.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 12/5/18. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import Moya +import WavesSDK +import DomainLayer +import Extensions + + +private extension DomainLayer.DTO.Candle.TimeFrameType { + + var value: String { + switch self { + case .m5: + return "5m" + + case .m15: + return "15m" + + case .m30: + return "30m" + + case .h1: + return "1h" + + case .h3: + return "3h" + + case .h24: + return "1d" + } + } +} + + +final class CandlesRepositoryRemote: CandlesRepositoryProtocol { + + private let environmentRepository: EnvironmentRepositoryProtocols + private let matcherRepository: MatcherRepositoryProtocol + + init(environmentRepository: EnvironmentRepositoryProtocols, matcherRepository: MatcherRepositoryProtocol) { + self.environmentRepository = environmentRepository + self.matcherRepository = matcherRepository + } + + func candles(amountAsset: String, + priceAsset: String, + timeStart: Date, + timeEnd: Date, + timeFrame: DomainLayer.DTO.Candle.TimeFrameType) -> Observable<[DomainLayer.DTO.Candle]> { + + + return Observable.zip(environmentRepository.servicesEnvironment(), matcherRepository.matcherPublicKey()) + .flatMap({ [weak self] (servicesEnvironment, publicKeyAccount) -> Observable<[DomainLayer.DTO.Candle]> in + guard let self = self else { return Observable.empty() } + + + let timestampServerDiff = servicesEnvironment.timestampServerDiff + + let candles = DataService.Query.CandleFilters(amountAsset: amountAsset, + priceAsset: priceAsset, + timeStart: timeStart.millisecondsSince1970(timestampDiff: timestampServerDiff), + timeEnd: timeEnd.millisecondsSince1970(timestampDiff: timestampServerDiff), + interval: timeFrame.value, + matcher: publicKeyAccount.address) + return servicesEnvironment + .wavesServices + .dataServices + .candlesDataService + .candles(query: candles) + .map({ (chart) -> [DomainLayer.DTO.Candle] in + var models: [DomainLayer.DTO.Candle] = [] + + for model in chart.candles { + + guard let volume = model.volume, + let high = model.high, + let low = model.low, + let open = model.open, + let close = model.close else { + continue + } + + if volume > 0 { + let timestamp = self.convertTimestamp(Int64(model.time.timeIntervalSince1970 * 1000), timeFrame: timeFrame) + + let model = DomainLayer.DTO.Candle(close: close, + high: high, + low: low, + open: open, + timestamp: timestamp, + volume: volume) + models.append(model) + } + } + + return models + }) + }) + } +} + +private extension CandlesRepositoryRemote { + + func convertTimestamp(_ timestamp: Int64, timeFrame: DomainLayer.DTO.Candle.TimeFrameType) -> Double { + return Double(timestamp / Int64(1000 * 60 * timeFrame.rawValue)) + } +} + + diff --git a/DataLayer/Sources/Repositories/Dex/DexOrderBookRepositoryRemote.swift b/DataLayer/Sources/Repositories/Dex/DexOrderBookRepositoryRemote.swift new file mode 100644 index 00000000..50ee4d9a --- /dev/null +++ b/DataLayer/Sources/Repositories/Dex/DexOrderBookRepositoryRemote.swift @@ -0,0 +1,260 @@ +// +// DexOrderBookRepositoryRemote.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 12/17/18. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import Moya +import RealmSwift +import WavesSDK +import DomainLayer +import Extensions + +private enum Constants { + static let baseFee: Int64 = 300000 + static let WavesRate: Double = 1 +} + +final class DexOrderBookRepositoryRemote: DexOrderBookRepositoryProtocol { + + private let environmentRepository: EnvironmentRepositoryProtocols + + private let spamAssetsRepository: SpamAssetsRepositoryProtocol + + init(environmentRepository: EnvironmentRepositoryProtocols, + spamAssetsRepository: SpamAssetsRepositoryProtocol) { + self.environmentRepository = environmentRepository + self.spamAssetsRepository = spamAssetsRepository + } + + func orderBook(amountAsset: String, + priceAsset: String) -> Observable { + + return environmentRepository + .servicesEnvironment() + .flatMapLatest({ (servicesEnvironment) -> Observable in + + return servicesEnvironment + .wavesServices + .matcherServices + .orderBookMatcherService + .orderBook(amountAsset: amountAsset, + priceAsset: priceAsset) + .flatMap({ (orderBook) -> Observable in + + let bids = orderBook.bids.map { DomainLayer.DTO.Dex.OrderBook.Value(amount: $0.amount, + price: $0.price)} + + let asks = orderBook.asks.map { DomainLayer.DTO.Dex.OrderBook.Value(amount: $0.amount, + price: $0.price)} + + return Observable.just(DomainLayer.DTO.Dex.OrderBook(bids: bids, asks: asks)) + }) + }) + } + + func markets(wallet: DomainLayer.DTO.SignedWallet, pairs: [DomainLayer.DTO.Dex.Pair]) -> Observable<[DomainLayer.DTO.Dex.SmartPair]> { + + return environmentRepository + .servicesEnvironment() + .flatMap({ [weak self] (appEnvironment) -> Observable<[DomainLayer.DTO.Dex.SmartPair]> in + guard let self = self else { return Observable.empty() } + + let queryPairs = pairs.map {DataService.Query.PairsPrice.Pair(amountAssetId: $0.amountAsset.id, priceAssetId: $0.priceAsset.id)} + return appEnvironment + .wavesServices + .dataServices + .pairsPriceDataService + .pairsPrice(query: .init(pairs: queryPairs)) + .map({ [weak self] (pairsPrice) -> [DomainLayer.DTO.Dex.SmartPair] in + + guard let self = self, let realm = try? WalletRealmFactory.realm(accountAddress: wallet.address) else { + return [] + } + + var smartPairs: [DomainLayer.DTO.Dex.SmartPair] = [] + + for (index, pair) in pairsPrice.enumerated() { + if pair != nil { + let amountAsset = pairs[index].amountAsset + let priceAsset = pairs[index].priceAsset + smartPairs.append(.init(amountAsset: amountAsset, priceAsset: priceAsset, realm: realm)) + } + } + return self.sort(pairs: smartPairs, realm: realm) + }) + + }) + } + + func myOrders(wallet: DomainLayer.DTO.SignedWallet, + amountAsset: DomainLayer.DTO.Dex.Asset, + priceAsset: DomainLayer.DTO.Dex.Asset) -> Observable<[DomainLayer.DTO.Dex.MyOrder]> { + + return environmentRepository + .servicesEnvironment() + .flatMapLatest({ (servicesEnvironment) -> Observable<[DomainLayer.DTO.Dex.MyOrder]> in + + let signature = TimestampSignature(signedWallet: wallet, + timestampServerDiff: servicesEnvironment.timestampServerDiff) + + return servicesEnvironment + .wavesServices + .matcherServices + .orderBookMatcherService + .myOrders(query: .init(amountAsset: amountAsset.id, + priceAsset: priceAsset.id, + publicKey: wallet.publicKey.getPublicKeyStr(), + signature: signature.signature(), + timestamp: signature.timestamp)) + .map({ (orders) -> [DomainLayer.DTO.Dex.MyOrder] in + + var myOrders: [DomainLayer.DTO.Dex.MyOrder] = [] + + for order in orders { + myOrders.append(DomainLayer.DTO.Dex.MyOrder(order, + priceAsset: priceAsset, + amountAsset: amountAsset)) + + } + return myOrders + }) + }) + } + + func cancelOrder(wallet: DomainLayer.DTO.SignedWallet, + orderId: String, + amountAsset: String, + priceAsset: String) -> Observable { + + return environmentRepository + .servicesEnvironment() + .flatMapLatest({ (servicesEnvironment) -> Observable in + + let signature = CancelOrderSignature(signedWallet: wallet, orderId: orderId) + + return servicesEnvironment + .wavesServices + .matcherServices + .orderBookMatcherService + .cancelOrder(query: .init(orderId: orderId, + amountAsset: amountAsset, + priceAsset: priceAsset, + signature: signature.signature(), + senderPublicKey: wallet.publicKey.getPublicKeyStr())) + }) + } + + func createOrder(wallet: DomainLayer.DTO.SignedWallet, + order: DomainLayer.Query.Dex.CreateOrder) -> Observable { + + return environmentRepository + .servicesEnvironment() + .flatMapLatest({ (servicesEnvironment) -> Observable in + + let timestamp = order.timestamp - servicesEnvironment.timestampServerDiff + + let expirationTimestamp = timestamp + order.expiration * 60 * 1000 + + let isWavesFee = order.matcherFeeAsset == WavesSDKConstants.wavesAssetId + + let createOrderSignature = CreateOrderSignature(signedWallet: wallet, + timestamp: timestamp, + matcherPublicKey: order.matcherPublicKey, + assetPair: .init(priceAssetId: order.priceAsset, + amountAssetId: order.amountAsset), + orderType: (order.orderType == .sell ? .sell : .buy), + price: order.price, + amount: order.amount, + expiration: expirationTimestamp, + matcherFee: order.matcherFee, + matcherFeeAsset: order.matcherFeeAsset, + version: isWavesFee ? .V2 : .V3) + + return servicesEnvironment + .wavesServices + .matcherServices + .orderBookMatcherService + .createOrder(query: .init(matcherPublicKey: order.matcherPublicKey.getPublicKeyStr(), + senderPublicKey: wallet.publicKey.getPublicKeyStr(), + assetPair: .init(amountAssetId: order.amountAsset, priceAssetId: order.priceAsset), + amount: order.amount, + price: order.price, + orderType: (order.orderType == .sell ? .sell : .buy), + matcherFee: order.matcherFee, + timestamp: timestamp, + expirationTimestamp: expirationTimestamp, + proofs: [createOrderSignature.signature()], + matcherFeeAsset: order.matcherFeeAsset)) + }) + } + + func orderSettingsFee() -> Observable { + + return environmentRepository + .servicesEnvironment() + .flatMap({ (appEnvironment) -> Observable in + return appEnvironment + .wavesServices + .matcherServices + .orderBookMatcherService + .settingsRatesFee() + .map({ (ratesFee) -> DomainLayer.DTO.Dex.SettingsOrderFee in + + let assets = ratesFee.map{ DomainLayer.DTO.Dex.SettingsOrderFee.Asset(assetId: $0.assetId, rate: $0.rate) } + + return DomainLayer.DTO.Dex.SettingsOrderFee(baseFee: Constants.baseFee, feeAssets: assets) + }) + }) + .catchError({ (error) -> Observable in + + //TODO: remove code after MainNet will be support custom fee at matcher + + let wavesAsset = DomainLayer.DTO.Dex.SettingsOrderFee.Asset(assetId: WavesSDKConstants.wavesAssetId, + rate: Constants.WavesRate) + let settings = DomainLayer.DTO.Dex.SettingsOrderFee(baseFee: Constants.baseFee, feeAssets: [wavesAsset]) + return Observable.just(settings) + }) + } +} + +//MARK: - Markets Sort +private extension DexOrderBookRepositoryRemote { + + func sort(pairs: [DomainLayer.DTO.Dex.SmartPair], realm: Realm) -> [DomainLayer.DTO.Dex.SmartPair] { + + var sortedPairs: [DomainLayer.DTO.Dex.SmartPair] = [] + + let generalBalances = realm + .objects(Asset.self) + .filter(NSPredicate(format: "isGeneral == true")) + .toArray() + .reduce(into: [String: Asset](), { $0[$1.id] = $1 }) + + let settingsList = realm + .objects(AssetBalanceSettings.self) + .toArray() + .filter { (asset) -> Bool in + return generalBalances[asset.assetId]?.isGeneral == true + } + .sorted(by: { $0.sortLevel < $1.sortLevel }) + + for settings in settingsList { + sortedPairs.append(contentsOf: pairs.filter({$0.amountAsset.id == settings.assetId && $0.isGeneral == true })) + } + + var sortedIds = sortedPairs.map {$0.id} + sortedPairs.append(contentsOf: pairs.filter { $0.isGeneral == true && !sortedIds.contains($0.id) } ) + + sortedIds = sortedPairs.map {$0.id} + sortedPairs.append(contentsOf: pairs.filter { !sortedIds.contains($0.id) } ) + + return sortedPairs + } +} + + diff --git a/DataLayer/Sources/Repositories/Dex/DexPairsPriceRepositoryRemote.swift b/DataLayer/Sources/Repositories/Dex/DexPairsPriceRepositoryRemote.swift new file mode 100644 index 00000000..7ad0aaf5 --- /dev/null +++ b/DataLayer/Sources/Repositories/Dex/DexPairsPriceRepositoryRemote.swift @@ -0,0 +1,169 @@ +// +// DexListRepositoryRemote.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 12/17/18. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import Moya +import WavesSDK +import DomainLayer +import Extensions + +final class DexPairsPriceRepositoryRemote: DexPairsPriceRepositoryProtocol { + + private let environmentRepository: EnvironmentRepositoryProtocols + + init(environmentRepository: EnvironmentRepositoryProtocols) { + self.environmentRepository = environmentRepository + } + + func search(by accountAddress: String, searchText: String) -> Observable<[DomainLayer.DTO.Dex.SimplePair]> { + + var kind: DataService.Query.PairsPriceSearch.Kind! + + var searchCompoments = searchText.components(separatedBy: "/") + if searchCompoments.count == 1 { + searchCompoments = searchText.components(separatedBy: "\\") + } + + if searchCompoments.count == 1 { + let searchWords = searchCompoments[0].components(separatedBy: " ").filter {$0.count > 0} + if searchWords.count > 0 { + kind = .byAsset(searchWords[0]) + } + else { + return Observable.just([]) + } + } + else if searchCompoments.count >= 2 { + let searchAmountWords = searchCompoments[0].components(separatedBy: " ").filter {$0.count > 0} + let searchPriceWords = searchCompoments[1].components(separatedBy: " ").filter {$0.count > 0} + + if searchAmountWords.count > 0 && searchPriceWords.count > 0 { + kind = .byAssets(firstName: searchAmountWords[0], secondName: searchPriceWords[0]) + } + else if searchAmountWords.count > 0 { + kind = .byAsset(searchAmountWords[0]) + } + else if searchPriceWords.count > 0 { + kind = .byAsset(searchPriceWords[0]) + } + else { + return Observable.just([]) + } + } + + return environmentRepository + .servicesEnvironment() + .flatMap({ (servicesEnvironment) -> Observable<[DomainLayer.DTO.Dex.SimplePair]> in + return servicesEnvironment + .wavesServices + .dataServices + .pairsPriceDataService + .searchByAsset(query: .init(kind: kind)) + .map({ (pairs) -> [DomainLayer.DTO.Dex.SimplePair] in + + var simplePairs: [DomainLayer.DTO.Dex.SimplePair] = [] + for pair in pairs { + if !simplePairs.contains(where: {$0.amountAsset == pair.amountAsset && $0.priceAsset == pair.priceAsset}) { + simplePairs.append(.init(amountAsset: pair.amountAsset, priceAsset: pair.priceAsset)) + } + } + return simplePairs + }) + }) + } + + func list(pairs: [DomainLayer.DTO.Dex.Pair]) -> Observable<[DomainLayer.DTO.Dex.PairPrice]> { + + return environmentRepository + .servicesEnvironment() + .flatMapLatest({ (servicesEnvironment) -> Observable<[DomainLayer.DTO.Dex.PairPrice]> in + + let pairsForQuery = pairs.map { DataService.Query.PairsPrice.Pair(amountAssetId: $0.amountAsset.id, + priceAssetId: $0.priceAsset.id) } + + let query = DataService.Query.PairsPrice(pairs: pairsForQuery) + + return servicesEnvironment + .wavesServices + .dataServices + .pairsPriceDataService + .pairsPrice(query: query) + .map({ (list) -> [DomainLayer.DTO.Dex.PairPrice] in + + var listPairs: [DomainLayer.DTO.Dex.PairPrice] = [] + + for (index, pairElement) in list.enumerated() { + + let localPair = pairs[index] + + let priceAsset = localPair.priceAsset + let firstPrice = Money(value: Decimal(pairElement?.firstPrice ?? 0), priceAsset.decimals) + let lastPrice = Money(value: Decimal(pairElement?.lastPrice ?? 0), priceAsset.decimals) + + let pairPrice = DomainLayer.DTO.Dex.PairPrice(firstPrice: firstPrice, + lastPrice: lastPrice, + amountAsset: localPair.amountAsset, + priceAsset: priceAsset) + listPairs.append(pairPrice) + } + + return listPairs + }) + }) + } + + func searchPairs(_ query: DomainLayer.Query.Dex.SearchPairs) -> Observable { + + return environmentRepository + .servicesEnvironment() + .flatMapLatest({ (servicesEnvironment) -> Observable in + + //TODO: Others type kinds + guard case let .pairs(pairs) = query.kind else { return Observable.never() } + + + let pairsForQuery = pairs.map { DataService.Query.PairsPrice.Pair(amountAssetId: $0.amountAsset, + priceAssetId: $0.priceAsset) } + + let query = DataService.Query.PairsPrice(pairs: pairsForQuery) + + return servicesEnvironment + .wavesServices + .dataServices + .pairsPriceDataService + .pairsPrice(query: query) + .map({ (pairsSearch) -> DomainLayer.DTO.Dex.PairsSearch in + + + let pairs = pairsSearch.map({ (pairPrice) -> DomainLayer + .DTO + .Dex + .PairsSearch + .Pair? in + + guard let pairPrice = pairPrice else { return nil } + + return DomainLayer + .DTO + .Dex + .PairsSearch + .Pair.init(firstPrice: pairPrice.firstPrice, + lastPrice: pairPrice.lastPrice, + volume: pairPrice.volume, + volumeWaves: pairPrice.volumeWaves, + quoteVolume: pairPrice.quoteVolume) + }) + + + + return DomainLayer.DTO.Dex.PairsSearch(pairs: pairs) + }) + }) + } +} diff --git a/WavesWallet-iOS/DataLayer/Repositories/Dex/DexRealmRepositoryLocal.swift b/DataLayer/Sources/Repositories/Dex/DexRealmRepositoryLocal.swift similarity index 98% rename from WavesWallet-iOS/DataLayer/Repositories/Dex/DexRealmRepositoryLocal.swift rename to DataLayer/Sources/Repositories/Dex/DexRealmRepositoryLocal.swift index 7ce03eae..622aecf7 100644 --- a/WavesWallet-iOS/DataLayer/Repositories/Dex/DexRealmRepositoryLocal.swift +++ b/DataLayer/Sources/Repositories/Dex/DexRealmRepositoryLocal.swift @@ -8,6 +8,7 @@ import Foundation import RxSwift +import DomainLayer final class DexRealmRepositoryLocal: DexRealmRepositoryProtocol { @@ -48,8 +49,7 @@ final class DexRealmRepositoryLocal: DexRealmRepositoryProtocol { } } subscribe.onNext(newPairs) - } - catch let error { + } catch let error { subscribe.onError(error) } diff --git a/DataLayer/Sources/Repositories/Dex/LastTradesRepositoryRemote.swift b/DataLayer/Sources/Repositories/Dex/LastTradesRepositoryRemote.swift new file mode 100644 index 00000000..83d3b18a --- /dev/null +++ b/DataLayer/Sources/Repositories/Dex/LastTradesRepositoryRemote.swift @@ -0,0 +1,67 @@ +// +// LastTradesRepository.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 12/5/18. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import Moya +import WavesSDK +import DomainLayer +import Extensions + +final class LastTradesRepositoryRemote: LastTradesRepositoryProtocol { + + private let environmentRepository: EnvironmentRepositoryProtocols + private let matcherRepository: MatcherRepositoryProtocol + + init(environmentRepository: EnvironmentRepositoryProtocols, matcherRepository: MatcherRepositoryProtocol) { + self.environmentRepository = environmentRepository + self.matcherRepository = matcherRepository + } + + func lastTrades(amountAsset: DomainLayer.DTO.Dex.Asset, + priceAsset: DomainLayer.DTO.Dex.Asset, + limit: Int) -> Observable<[DomainLayer.DTO.Dex.LastTrade]> { + + return Observable.zip(environmentRepository.servicesEnvironment(), matcherRepository.matcherPublicKey()) + .flatMap({ (servicesEnvironment, publicKeyAccount) -> Observable<[DomainLayer.DTO.Dex.LastTrade]> in + + let query = DataService.Query.ExchangeFilters(matcher: publicKeyAccount.address, + sender: nil, + timeStart: nil, + timeEnd: nil, + amountAsset: amountAsset.id, + priceAsset: priceAsset.id, + after: nil, + limit: limit) + + return servicesEnvironment + .wavesServices + .dataServices + .transactionsDataService + .transactionsExchange(query: query) + .flatMap({ (transactions) -> Observable<[DomainLayer.DTO.Dex.LastTrade]> in + + var trades: [DomainLayer.DTO.Dex.LastTrade] = [] + for tx in transactions { + + let sum = Money(value: Decimal(tx.price * tx.amount), priceAsset.decimals) + let orderType: DomainLayer.DTO.Dex.OrderType = tx.orderType == .sell ? .sell : .buy + + let model = DomainLayer.DTO.Dex.LastTrade(time: tx.timestamp, + price: Money(value: Decimal(tx.price), priceAsset.decimals), + amount: Money(value: Decimal(tx.amount), amountAsset.decimals), + sum: sum, + type: orderType) + trades.append(model) + } + + return Observable.just(trades) + }) + }) + } +} diff --git a/DataLayer/Sources/Repositories/Dex/MatcherRepositoryLocal.swift b/DataLayer/Sources/Repositories/Dex/MatcherRepositoryLocal.swift new file mode 100644 index 00000000..c7e758ee --- /dev/null +++ b/DataLayer/Sources/Repositories/Dex/MatcherRepositoryLocal.swift @@ -0,0 +1,61 @@ +// +// MatcherRepositoryLocal.swift +// DataLayer +// +// Created by Pavel Gubin on 12.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import DomainLayer +import RxSwift +import WavesSDKExtensions + +final class MatcherRepositoryLocal: MatcherRepositoryProtocol { + + private var internalPublicKeyAccount: PublicKeyAccount? + + private var publicKeyAccount: PublicKeyAccount? { + get { + objc_sync_enter(self) + defer { objc_sync_exit(self) } + return internalPublicKeyAccount + } + + set { + objc_sync_enter(self) + defer { objc_sync_exit(self) } + internalPublicKeyAccount = newValue + } + } + + private let matcherRepositoryRemote: MatcherRepositoryProtocol + + init(matcherRepositoryRemote: MatcherRepositoryProtocol) { + self.matcherRepositoryRemote = matcherRepositoryRemote + } + + func matcherPublicKey() -> Observable { + + if let publicKey = publicKeyAccount { + return Observable.just(publicKey) + } + + return matcherPublicKeyShare + .flatMap({ [weak self] (publicKey) -> Observable in + guard let self = self else { return Observable.empty() } + + self.publicKeyAccount = publicKey + return Observable.just(publicKey) + }) + } + + private lazy var matcherPublicKeyShare: Observable = { + return matcherRepositoryRemote.matcherPublicKey() + .share(replay: 1, scope: SubjectLifetimeScope.whileConnected) + }() + + func settingsIdsPairs() -> Observable<[String]> { + return matcherRepositoryRemote.settingsIdsPairs() + } +} diff --git a/DataLayer/Sources/Repositories/Dex/MatcherRepositoryRemote.swift b/DataLayer/Sources/Repositories/Dex/MatcherRepositoryRemote.swift new file mode 100644 index 00000000..0bb9d2f0 --- /dev/null +++ b/DataLayer/Sources/Repositories/Dex/MatcherRepositoryRemote.swift @@ -0,0 +1,58 @@ +// +// MatcherRepositoryRemote.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 12/26/18. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import Moya +import WavesSDKCrypto +import WavesSDK +import DomainLayer +import Extensions + +final class MatcherRepositoryRemote: MatcherRepositoryProtocol { + + private let environmentRepository: EnvironmentRepositoryProtocols + + init(environmentRepository: EnvironmentRepositoryProtocols) { + self.environmentRepository = environmentRepository + } + + func matcherPublicKey() -> Observable { + + return environmentRepository + .servicesEnvironment() + .flatMapLatest({ (servicesEnvironment) -> Observable in + + return servicesEnvironment + .wavesServices + .matcherServices + .publicKeyMatcherService + .publicKey() + .map { + return PublicKeyAccount(publicKey: Base58Encoder.decode($0)) + } + }) + } + + func settingsIdsPairs() -> Observable<[String]> { + + return environmentRepository + .servicesEnvironment() + .flatMapLatest({ (servicesEnvironment) -> Observable<[String]> in + + return servicesEnvironment + .wavesServices + .matcherServices + .orderBookMatcherService + .settings() + .map { + return $0.priceAssets + } + }) + } +} diff --git a/DataLayer/Sources/Repositories/EnvironmentRepository.swift b/DataLayer/Sources/Repositories/EnvironmentRepository.swift new file mode 100644 index 00000000..bf2c3340 --- /dev/null +++ b/DataLayer/Sources/Repositories/EnvironmentRepository.swift @@ -0,0 +1,341 @@ +// +// EnvironmentRepositoryRemote.swift +// WavesWallet-iOS +// +// Created by mefilt on 18/10/2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import Moya +import RxSwift +import WavesSDKExtensions +import WavesSDK +import DomainLayer +import Extensions + +private enum Constants { + static let minServerTimestampDiff: Int64 = 1000 * 30 +} + +private struct EnvironmentKey: Hashable { + let chainId: String +} + +private extension WalletEnvironment.Kind { + var gitHubServiceEnvironment: GitHub.Service.Environment.Kind { + switch self { + case .mainnet: + return .mainnet + + case .testnet: + return .testnet + + case .stagenet: + return .stagenet + } + } +} + +public final class ApplicationEnviroment: ApplicationEnvironmentProtocol { + + public let wavesServices: WavesServicesProtocol + public private(set) var walletEnvironment: WalletEnvironment + public private(set) var timestampServerDiff: Int64 + + init(wavesServices: WavesServicesProtocol, walletEnvironment: WalletEnvironment, timestampServerDiff: Int64) { + self.wavesServices = wavesServices + self.timestampServerDiff = timestampServerDiff + self.walletEnvironment = walletEnvironment + } +} + +protocol ServicesEnvironmentRepositoryProtocol { + func servicesEnvironment() -> Observable +} + +final class EnvironmentRepository: EnvironmentRepositoryProtocol, ServicesEnvironmentRepositoryProtocol { + + private var internalServerTimestampDiff: Int64? = nil + + private var serverTimestampDiff: Int64? { + + get { + objc_sync_enter(self) + defer { objc_sync_exit(self) } + return internalServerTimestampDiff + } + + set { + objc_sync_enter(self) + defer { objc_sync_exit(self) } + internalServerTimestampDiff = newValue + } + } + + private let environmentRepository: MoyaProvider = .anyMoyaProvider() + + private lazy var remoteAccountEnvironmentShare: Observable = { + return remoteEnvironment().share(replay: 1, scope: SubjectLifetimeScope.whileConnected) + }() + + private lazy var setupServicesEnviromentShare: Observable = self.setupServicesEnviroment().share(replay: 1, scope: SubjectLifetimeScope.whileConnected) + + private var localEnvironments: BehaviorSubject<[EnvironmentKey: WalletEnvironment]> = BehaviorSubject<[EnvironmentKey: WalletEnvironment]>(value: [:]) + + init() { + NotificationCenter.default.addObserver(self, selector: #selector(timeDidChange), name: UIApplication.significantTimeChangeNotification, object: nil) + + updateEnviroment(kind: environmentKind) + } + + func deffaultEnvironment() -> Observable { + return remoteAccountEnvironmentShare + } + + func walletEnvironment() -> Observable { + return setupServicesEnviromentShare.map { $0.walletEnvironment } + } + + func applicationEnvironment() -> Observable { + return setupServicesEnviromentShare.map { $0 as ApplicationEnvironmentProtocol } + } + + func servicesEnvironment() -> Observable { + return setupServicesEnviromentShare + } + + var environmentKind: WalletEnvironment.Kind { + + get { + let chainId = UserDefaults.standard.string(forKey: "wallet.environment.kind") ?? "" + return WalletEnvironment.Kind(rawValue: chainId) ?? .mainnet + } + + set { + UserDefaults.standard.set(newValue.rawValue, forKey: "wallet.environment.kind") + UserDefaults.standard.synchronize() + + updateEnviroment(kind: newValue) + } + } + + private func updateEnviroment(kind: WalletEnvironment.Kind) { + + //TODO: Need refactor address class + switch environmentKind { + case .mainnet: + Address.walletEnvironment = WalletEnvironment.Mainnet + + case .testnet: + Address.walletEnvironment = WalletEnvironment.Testnet + + case .stagenet: + Address.walletEnvironment = WalletEnvironment.Stagenet + } + } +} + +private extension EnvironmentRepository { + + private func setupServicesEnviroment() -> Observable { + + return self.ifNeedRemoteEnvironment() + .flatMap { [weak self] (enviroment) -> Observable in + + guard let self = self else { + return Observable.never() + } + return self.saveEnvironmentToMemory(environment: enviroment) + } + .flatMap { [weak self] (enviroment) -> Observable in + + guard let self = self else { + return Observable.never() + } + + return self.initializationService(environment: enviroment) + .map { services in ApplicationEnviroment(wavesServices: services, + walletEnvironment: enviroment, + timestampServerDiff: 0) } + } + .flatMap { [weak self] (servicesEnviroment) -> Observable in + + guard let self = self else { + return Observable.never() + } + + if let serverTimestampDiff = self.serverTimestampDiff { + return Observable.just(ApplicationEnviroment(wavesServices: servicesEnviroment.wavesServices, + walletEnvironment: servicesEnviroment.walletEnvironment, + timestampServerDiff: serverTimestampDiff)) + } else { + return self.timestampServerDiff(wavesServices: servicesEnviroment.wavesServices) + .do(onNext: { [weak self] (serverTimestampDiff) in + guard let self = self else { + return + } + self.serverTimestampDiff = serverTimestampDiff + }) + .map { time in + return ApplicationEnviroment(wavesServices: servicesEnviroment.wavesServices, + walletEnvironment: servicesEnviroment.walletEnvironment, + timestampServerDiff: time) + } + } + } + .flatMap({ (enviroment) -> Observable in + + var enviromentService = WavesSDK.shared.enviroment + enviromentService.timestampServerDiff = enviroment.timestampServerDiff + WavesSDK.shared.enviroment = enviromentService + + Address.walletEnvironment = enviroment.walletEnvironment + return Observable.just(enviroment) + }) + + } + + private func initializationService(environment: WalletEnvironment) -> Observable { + + return Observable.create { (observer) -> Disposable in + + + let server: Enviroment.Server = .custom(node: environment.servers.nodeUrl, + matcher: environment.servers.matcherUrl, + data: environment.servers.dataUrl, + scheme: environment.scheme) + if WavesSDK.isInitialized() { + + var enviromentService = WavesSDK.shared.enviroment + enviromentService.server = server + + WavesSDK.shared.enviroment = enviromentService + + observer.onNext(WavesSDK.shared.services) + observer.onCompleted() + return Disposables.create() + } + + WavesSDK.initialization(servicesPlugins: .init(data: [SentryNetworkLoggerPlugin()], + node: [NodePlugin(), SentryNetworkLoggerPlugin()], + matcher: [SentryNetworkLoggerPlugin()]), + enviroment: .init(server: server, timestampServerDiff: 0)) + + observer.onNext(WavesSDK.shared.services) + observer.onCompleted() + + return Disposables.create() + } + } + + private func saveEnvironmentToMemory(environment: WalletEnvironment) -> Observable { + return Observable.create { [weak self] (observer) -> Disposable in + + guard let self = self else { + return Disposables.create() + } + + let key = EnvironmentKey(chainId: self.environmentKind.rawValue) + + //TODO: mutex + if let value = try? self.localEnvironments.value() { + var newValue = value + newValue[key] = environment + self.localEnvironments.onNext(newValue) + } else { + self.localEnvironments.onNext([key: environment]) + } + + observer.onNext(environment) + observer.onCompleted() + + return Disposables.create() + } + } + + private func ifNeedRemoteEnvironment() -> Observable { + + return Observable.create({ [weak self] (observer) -> Disposable in + + guard let self = self else { + return Disposables.create() + } + + let key = EnvironmentKey(chainId: self.environmentKind.rawValue) + + var disposables: [Disposable] = .init() + + if let enviroment = self.localEnvironment(by: key) { + observer.onNext(enviroment) + observer.onCompleted() + } else { + let disposable = self.remoteAccountEnvironmentShare.bind(to: observer) + disposables.append(disposable) + } + + return Disposables.create(disposables) + }) + } + + private func remoteEnvironment() -> Observable { + + return environmentRepository + .rx + .request(.get(kind: environmentKind.gitHubServiceEnvironment, hasProxy: true, isDebug: ApplicationDebugSettings.isEnableEnviromentTest)) + .catchError({ [weak self] (_) -> PrimitiveSequence in + guard let self = self else { return Single.never() } + return self + .environmentRepository + .rx + .request(.get(kind: self.environmentKind.gitHubServiceEnvironment, hasProxy: false, isDebug: ApplicationDebugSettings.isEnableEnviromentTest)) + }) + .map(WalletEnvironment.self) + .catchError { [weak self] error -> Single in + guard let self = self else { return Single.never() } + switch self.environmentKind { + case .mainnet: + return Single.just(WalletEnvironment.Mainnet) + + case .stagenet: + return Single.just(WalletEnvironment.Stagenet) + + case .testnet: + return Single.just(WalletEnvironment.Testnet) + } + } + .asObservable() + } + + private func localEnvironment(by key: EnvironmentKey) -> WalletEnvironment? { + + if let value = try? localEnvironments.value() { + return value[key] + } + + return nil + } +} + +private extension EnvironmentRepository { + + @objc func timeDidChange() { + serverTimestampDiff = nil + } + + func timestampServerDiff(wavesServices: WavesServicesProtocol) -> Observable { + + return wavesServices + .nodeServices + .utilsNodeService + .time() + .flatMap({ (time) -> Observable in + + let localTimestamp = Int64(Date().timeIntervalSince1970 * 1000) + let diff = localTimestamp - time.NTP + let timestamp = abs(diff) > Constants.minServerTimestampDiff ? diff : 0 + + return Observable.just(timestamp) + }) + } +} diff --git a/DataLayer/Sources/Repositories/GatewayRepository.swift b/DataLayer/Sources/Repositories/GatewayRepository.swift new file mode 100644 index 00000000..7e6763bf --- /dev/null +++ b/DataLayer/Sources/Repositories/GatewayRepository.swift @@ -0,0 +1,106 @@ +// +// GatewayRepository.swift +// InternalDataLayer +// +// Created by Pavel Gubin on 22.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import DomainLayer +import Moya +import Extensions +import WavesSDK + +final class GatewayRepository: GatewayRepositoryProtocol { + + private let gatewayProvider: MoyaProvider = .anyMoyaProvider() + + private let environmentRepository: EnvironmentRepositoryProtocols + + init(environmentRepository: EnvironmentRepositoryProtocols) { + self.environmentRepository = environmentRepository + } + + func startWithdrawProcess(address: String, asset: DomainLayer.DTO.Asset) -> Observable { + + let startProcess = Gateway.Service.StartProcess(userAddress: address, assetId: asset.id) + + return environmentRepository.servicesEnvironment() + .flatMap({ [weak self] (servicesEnvironment) -> Observable in + guard let self = self else { return Observable.empty() } + + let url = servicesEnvironment.walletEnvironment.servers.gatewayUrl + + return self.gatewayProvider.rx + .request(.startWithdrawProcess(baseURL: url, withdrawProcess: startProcess), + callbackQueue: DispatchQueue.global(qos: .userInteractive)) + .filterSuccessfulStatusAndRedirectCodes() + .map(Gateway.DTO.Withdraw.self) + .asObservable() + .map({ (startWithdraw) -> DomainLayer.DTO.Gateway.StartWithdrawProcess in + return DomainLayer.DTO.Gateway.StartWithdrawProcess( + recipientAddress: startWithdraw.recipientAddress, + minAmount: Money(startWithdraw.minAmount, asset.precision), + maxAmount: Money(startWithdraw.maxAmount, asset.precision), + fee: Money(startWithdraw.fee, asset.precision), + processId: startWithdraw.processId) + + }) + }) + } + + func startDepositProcess(address: String, asset: DomainLayer.DTO.Asset) -> Observable { + let startProcess = Gateway.Service.StartProcess(userAddress: address, assetId: asset.id) + + return environmentRepository.servicesEnvironment() + .flatMap({ [weak self] (servicesEnvironment) -> Observable in + guard let self = self else { return Observable.empty() } + + let url = servicesEnvironment.walletEnvironment.servers.gatewayUrl + + return self.gatewayProvider.rx + .request(.startDepositProcess(baseURL: url, depositProcess: startProcess), + callbackQueue: DispatchQueue.global(qos: .userInteractive)) + .filterSuccessfulStatusAndRedirectCodes() + .map(Gateway.DTO.Deposit.self) + .asObservable() + .map({ (startDeposit) -> DomainLayer.DTO.Gateway.StartDepositProcess in + + return DomainLayer.DTO.Gateway.StartDepositProcess( + address: startDeposit.address, + minAmount: Money(startDeposit.minAmount, asset.precision), + maxAmount: Money(startDeposit.maxAmount, asset.precision)) + }) + }) + } + + + func send(by specifications: TransactionSenderSpecifications, wallet: DomainLayer.DTO.SignedWallet) -> Observable { + + return environmentRepository + .servicesEnvironment().flatMap({ [weak self] (servicesEnvironment) -> Observable in + guard let self = self else { return Observable.empty() } + + let url = servicesEnvironment.walletEnvironment.servers.gatewayUrl + + //TODO: - remove vostok scheme + let specs = specifications.broadcastSpecification(servicesEnvironment: servicesEnvironment, + wallet: wallet, + specifications: specifications) + + guard let broadcastSpecification = specs else { return Observable.empty() } + + return self.gatewayProvider.rx + .request(.send(baseURL: url, transaction: broadcastSpecification, accountAddress: wallet.address), + callbackQueue: DispatchQueue.global(qos: .userInteractive)) + .filterSuccessfulStatusAndRedirectCodes() + .asObservable() + .map({ (response) -> Bool in + return true + }) + }) + } + +} diff --git a/DataLayer/Sources/Repositories/MobileKeeperRepository.swift b/DataLayer/Sources/Repositories/MobileKeeperRepository.swift new file mode 100644 index 00000000..84eba309 --- /dev/null +++ b/DataLayer/Sources/Repositories/MobileKeeperRepository.swift @@ -0,0 +1,842 @@ +// +// MobileKeeperRepository.swift +// DataLayer +// +// Created by rprokofev on 01.09.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import DomainLayer +import Extensions +import WavesSDK +import WavesSDKExtensions +import WavesSDKCrypto + +//Rename to UseCase + +public class MobileKeeperRepository: MobileKeeperRepositoryProtocol { + + private var repositoriesFactory: RepositoriesFactoryProtocol + + init(repositoriesFactory: RepositoriesFactoryProtocol) { + self.repositoriesFactory = repositoriesFactory + } + + public func prepareRequest(_ request: DomainLayer.DTO.MobileKeeper.Request, + signedWallet: DomainLayer.DTO.SignedWallet, + timestamp: Date) -> Observable { + + + guard let signature = request.transactionSignature(signedWallet: signedWallet, + timestamp: timestamp) else { + return Observable.error(MobileKeeperUseCaseError.transactionDontSupport) + } + + //TODO: Error + let proof = (try? signedWallet.sign(input: signature.bytesStructure, kind: [.none])) ?? [] + + let transaction = request.transaction.transactionNormalization(proof: proof, timestamp: timestamp, publicKey: signedWallet.publicKey.getPublicKeyStr()) ?? request.transaction + + let requestNorm = DomainLayer + .DTO + .MobileKeeper.Request.init(dApp: request.dApp, action: request.action, transaction: transaction, id: request.id) + + let prepareRequest = DomainLayer + .DTO + .MobileKeeper + .PrepareRequest.init(request: requestNorm, + timestamp: timestamp, + proof: proof, + txId: signature.id, + signedWallet: signedWallet) + + return Observable.just(prepareRequest) + } + + public func completeRequest(_ prepareRequest: DomainLayer.DTO.MobileKeeper.PrepareRequest) -> Observable { + + let action = prepareRequest.request.action + + switch action { + case .send: + + return repositoriesFactory + .transactionsRepositoryRemote + .send(by: prepareRequest.request.transaction, + wallet: prepareRequest.signedWallet) + .flatMap({ (tx) -> Observable in + + let completedRequest = prepareRequest.completedRequest(response: .success(.send(tx)), + signedWallet: prepareRequest.signedWallet) + return Observable.just(completedRequest) + }) + .catchError({ (error) -> Observable in + + if let networkError = error as? NetworkError { + + let title = { () -> String in + switch networkError { + case .message(let message): + return message + default: + return "" + } + }() + + let completedRequest = prepareRequest.completedRequest(response: .error(.message(title, 0)), + signedWallet: prepareRequest.signedWallet) + return Observable.just(completedRequest) + } + + let completedRequest = prepareRequest.completedRequest(response: .error(.reject), + signedWallet: prepareRequest.signedWallet) + return Observable.just(completedRequest) + }) + + case .sign: + + let completedRequest = prepareRequest.completedRequest(response: .success(.sign(prepareRequest.request.transaction)), + signedWallet: prepareRequest.signedWallet) + return Observable.just(completedRequest) + } + } + + + public func approveRequest(_ completedRequest: DomainLayer.DTO.MobileKeeper.CompletedRequest) -> Observable { + + return returnResponse(for: completedRequest.request.dApp, + completedRequest: completedRequest) + } + + public func rejectRequest(_ request: DomainLayer.DTO.MobileKeeper.Request) -> Observable { + + return returnError(for: request.dApp, + requestId: request.id, + error: .reject) + } + + public func errorRequest(_ request: DomainLayer.DTO.MobileKeeper.Request, error: DomainLayer.DTO.MobileKeeper.Error) -> Observable { + + return returnError(for: request.dApp, + requestId: request.id, + error: error) + } + + public func decodableRequest(_ url: URL) -> Observable { + + var requestOptional: WavesKeeper.Request? = nil + + do { + requestOptional = try self.decodableKeeperRequest(url) + } catch let error as MobileKeeperUseCaseError { + return Observable.error(error) + } catch _ { + return Observable.just(nil) + } + + guard let request = requestOptional else { return Observable.just(nil) } + guard let transactionSenderSpecifications = request.transaction.transactionSenderSpecifications else { + return Observable.error(MobileKeeperUseCaseError.transactionDontSupport) + } + + let mobileKeeperRequest = DomainLayer + .DTO + .MobileKeeper + .Request + .init(dApp: .init(name: request.dApp.name, + iconUrl: request.dApp.iconUrl, + scheme: request.dApp.schemeUrl), + action: (request.action == .send ? .send : .sign), + transaction: transactionSenderSpecifications, + id: request.id) + + return Observable.just(mobileKeeperRequest) + } + + + private func returnError(for dApp: DomainLayer.DTO.MobileKeeper.Application, + requestId: String, + error: DomainLayer.DTO.MobileKeeper.Error) -> Observable { + + return Observable.create({ (observer) -> Disposable in + + let wavesKeeperReponse: WavesKeeper.Response = .init(requestId: requestId, + kind: .error(error.wavesKeeperError)) + + let wavesKeeperApplication = dApp.wavesKeeperApplication + + guard let url = wavesKeeperReponse.url(app: wavesKeeperApplication) else { + observer.onNext(false) + observer.onCompleted() + return Disposables.create() + } + + UIApplication.shared.open(url, options: .init(), completionHandler: { (flag) in + if flag == false { + observer.onError(MobileKeeperUseCaseError.dAppDontOpen) + } else { + observer.onNext(flag) + observer.onCompleted() + } + }) + + return Disposables.create() + }) + } + + private func returnResponse(for dApp: DomainLayer.DTO.MobileKeeper.Application, + completedRequest: DomainLayer.DTO.MobileKeeper.CompletedRequest) -> Observable { + + return Observable.create({ (observer) -> Disposable in + + let wavesKeeperApplication = dApp.wavesKeeperApplication + guard let wavesKeeperResponse = completedRequest.wavesKeeperResponse else { + observer.onNext(false) + observer.onCompleted() + return Disposables.create() + } + + guard let url = wavesKeeperResponse.url(app: wavesKeeperApplication) else { + observer.onNext(false) + observer.onCompleted() + return Disposables.create() + } + + UIApplication.shared.open(url, options: .init(), completionHandler: { (flag) in + + if flag == false { + observer.onError(MobileKeeperUseCaseError.dAppDontOpen) + } else { + observer.onNext(flag) + } + observer.onCompleted() + }) + + return Disposables.create() + }) + } + + private func decodableKeeperRequest(_ url: URL) throws -> WavesKeeper.Request? { + return try url.request() + } +} + + +fileprivate extension DomainLayer.DTO.MobileKeeper.Application { + + var wavesKeeperApplication: WavesKeeper.Application { + return .init(name: name, iconUrl: iconUrl, schemeUrl: scheme) + } +} + +extension DomainLayer.DTO.MobileKeeper.CompletedRequest { + + var wavesKeeperResponse: WavesKeeper.Response? { + + guard let wavesKeeperResponseKind = self.wavesKeeperResponseKind else { return nil } + + return WavesKeeper.Response.init(requestId: request.id, + kind: wavesKeeperResponseKind) + } + + var wavesKeeperResponseKind: WavesKeeper.Response.Kind? { + + switch self.response.kind { + + case .error(let error): + return .error(error.wavesKeeperError) + + case .success(let result): + switch result { + case .send(let model): + guard let tx = model.transactionNodeService else { return nil } + + return .success(.send(tx)) + + case .sign(let model): + + guard let tx = model.nodeQuery(proof: proof, + timestamp: timestamp, + publicKey: publicKey) else { return nil } + + return .success(.sign(tx)) + } + } + } +} + +extension DomainLayer.DTO.MobileKeeper.Error { + + var wavesKeeperError: WavesKeeper.Error { + + switch self { + case .message(let message, let code): + return .message(.init(message: message, code: code)) + + case .reject: + return .reject + + case .invalidRequest: + return .invalidRequest + + case .transactionDontSupport: + return .transactionDontSupport + } + } +} + +fileprivate extension NodeService.Query.Transaction.InvokeScript.Call { + + var argsSender: [InvokeScriptTransactionSender.Arg] { + + return self.args.map({ (arg) -> InvokeScriptTransactionSender.Arg in + + let value = { () -> InvokeScriptTransactionSender.Arg.Value in + + switch arg.value { + case .binary(let value): + return .binary(value) + + case .bool(let value): + return .bool(value) + + case .integer(let value): + return .integer(value) + + case .string(let value): + return .string(value) + } + }() + + return InvokeScriptTransactionSender.Arg(value: value) + }) + } + + var callSender: InvokeScriptTransactionSender.Call { + return InvokeScriptTransactionSender.Call(function: self.function, + args: self.argsSender) + } +} + +fileprivate extension TransactionSenderSpecifications { + + func transactionNormalization(proof: Bytes, timestamp: Date, publicKey: String) -> TransactionSenderSpecifications? { + + switch self { + case .send(let sender): + return .send(SendTransactionSender.init(recipient: sender.recipient, + assetId: sender.assetId, + amount: sender.amount, + fee: sender.fee, + attachment: sender.attachment, + feeAssetID: sender.feeAssetID, + chainId: sender.chainId, + timestamp: timestamp)) + case .invokeScript(let model): + + return .invokeScript(.init(fee: model.fee, + feeAssetId: model.feeAssetId, + dApp: model.dApp, + call: model.call, + payment: model.payment, + chainId: model.chainId, + timestamp: timestamp)) + + case .data(let model): + return .data(.init(fee: model.fee, + data: model.data, + chainId: model.chainId, + timestamp: timestamp)) + + default: + return nil + } + } + + func nodeQuery(proof: Bytes, timestamp: Date, publicKey: String) -> NodeService.Query.Transaction? { + + let proofs = [Base58Encoder.encode(proof)] + + switch self { + case .send(let model): + + let transfer = NodeService.Query.Transaction.Transfer.init(recipient: model.recipient, + assetId: model.assetId, + amount: model.amount, + fee: model.fee, + attachment: model.attachment, + feeAssetId: model.feeAssetID, + timestamp: timestamp.millisecondsSince1970, + senderPublicKey: publicKey, + proofs: proofs, + chainId: model.chainId ?? "") + + return .transfer(transfer) + + case .invokeScript(let model): + + var call: NodeService.Query.Transaction.InvokeScript.Call? = nil + + if let callLocal = model.call { + let args = callLocal.args.map({ (arg) -> NodeService.Query.Transaction.InvokeScript.Arg in + + let value = { () -> NodeService.Query.Transaction.InvokeScript.Arg.Value in + + switch arg.value { + case .binary(let value): + return .binary(value) + + case .bool(let value): + return .bool(value) + + case .integer(let value): + return .integer(value) + + case .string(let value): + return .string(value) + + } + }() + + return .init(value: value) + }) + + call = .init(function: callLocal.function, args: args) + } + + let payment = model.payment.map { NodeService.Query.Transaction.InvokeScript.Payment.init(amount: $0.amount, assetId: $0.assetId) } + + let invokeScript = NodeService.Query.Transaction.InvokeScript.init(chainId: model.chainId ?? "", + fee: model.fee, + timestamp: timestamp.millisecondsSince1970, + senderPublicKey: publicKey, + feeAssetId: model.feeAssetId, + proofs: proofs, + dApp: model.dApp, + call: call, + payment: payment) + + return .invokeScript(invokeScript) + + case .data(let model): + + let values = model.data.map { (value) -> NodeService.Query.Transaction.Data.Value in + + let kind = { () -> NodeService.Query.Transaction.Data.Value.Kind in + switch value.value { + case .binary(let value): + return .binary(value) + + case .boolean(let value): + return .boolean(value) + + case .integer(let value): + return .integer(value) + + case .string(let value): + return .string(value) + } + }() + + return NodeService.Query.Transaction.Data.Value.init(key: value.key, value: kind) + } + + let data = NodeService.Query.Transaction.Data.init(fee: model.fee, + timestamp: timestamp.millisecondsSince1970, + senderPublicKey: publicKey, + proofs: proofs, + data: values, + chainId: model.chainId ?? "") + + return .data(data) + default: + return nil + } + } +} + +fileprivate extension DomainLayer.DTO.DataTransaction { + + var dataTransactionNodeService: NodeService.DTO.DataTransaction { + + let data = self.data.map { (element) -> NodeService.DTO.DataTransaction.Data in + + let value = { () -> NodeService.DTO.DataTransaction.Data.Value in + + switch element.value { + case .binary(let value): + return .binary(value) + + case .bool(let value): + return .bool(value) + + case .integer(let value): + return .integer(value) + + case .string(let value): + return .string(value) + } + + }() + + return NodeService.DTO.DataTransaction.Data.init(key: element.key, type: element.type, value: value) + } + + return .init(type: type, + id: id, + chainId: chainId, + sender: sender, + senderPublicKey: senderPublicKey, + fee: fee, + timestamp: timestamp, + height: height, + version: version, + proofs: proofs, + data: data) + } +} + +fileprivate extension DomainLayer.DTO.InvokeScriptTransaction { + + var invokeScriptTransactionNodeService: NodeService.DTO.InvokeScriptTransaction { + + var call: NodeService.DTO.InvokeScriptTransaction.Call? = nil + + if let localCall = self.call { + let args = localCall.args.map { (arg) -> NodeService.DTO.InvokeScriptTransaction.Call.Args in + let value = { () -> NodeService.DTO.InvokeScriptTransaction.Call.Args.Value in + + switch arg.value { + case .binary(let value): + return .binary(value) + + case .bool(let value): + return .bool(value) + + case .integer(let value): + return .integer(value) + + case .string(let value): + return .string(value) + } + }() + + return .init(type: arg.type, value: value) + } + + call = .init(function: localCall.function, args: args) + } + + //TODO: Payment Many + + var payments: NodeService.DTO.InvokeScriptTransaction.Payment? = nil + + if let pay = payment { + payments = NodeService.DTO.InvokeScriptTransaction.Payment.init(amount: pay.amount, assetId: pay.assetId) + } + + return NodeService.DTO.InvokeScriptTransaction(type: self.type, + id: self.id, + chainId: self.chainId, + sender: self.sender, + senderPublicKey: self.senderPublicKey, + fee: self.fee, + timestamp: self.timestamp, + proofs: self.proofs, + version: self.version, + height: self.height, + feeAssetId: self.feeAssetId, + dApp: self.dappAddress, + call: call, + payment: payments != nil ? [payments!] : []) + } + +} + +fileprivate extension DomainLayer.DTO.AnyTransaction { + + //TODO: Incorect chainID + var transactionNodeService: NodeService.DTO.Transaction? { + + switch self { + case .transfer(let model): + return NodeService.DTO.Transaction.transfer(.init(type: model.type, + id: model.id, + sender: model.sender, + senderPublicKey: model.senderPublicKey, + fee: model.fee, + timestamp: model.timestamp, + version: model.version, + height: model.height, + signature: model.signature, + proofs: model.proofs, + recipient: model.recipient, + assetId: model.assetId, + feeAssetId: model.feeAssetId, + amount: model.amount, + attachment: model.attachment)) + + case .invokeScript(let model): + return .invokeScript(model.invokeScriptTransactionNodeService) + + case .data(let model): + return .data(model.dataTransactionNodeService) + + default: + return nil + } + } +} + + +fileprivate extension NodeService.Query.Transaction.InvokeScript { + + var paymentSender: [InvokeScriptTransactionSender.Payment] { + return self.payment.map { InvokeScriptTransactionSender.Payment.init(amount: $0.amount, assetId: $0.assetId) } + } +} + +fileprivate extension NodeService.Query.Transaction.Data { + + var valueSender: [DataTransactionSender.Value] { + + return self.data.map { (data) -> DataTransactionSender.Value in + + let kind = { () -> DataTransactionSender.Value.Kind in + switch data.value { + case .binary(let value): + return .binary(value) + + case .boolean(let value): + return .boolean(value) + + case .integer(let value): + return .integer(value) + + case .string(let value): + return .string(value) + } + }() + + return DataTransactionSender.Value.init(key: data.key, value: kind) + } + } +} + + +fileprivate extension NodeService.Query.Transaction { + + var transactionSenderSpecifications: TransactionSenderSpecifications? { + + switch self { + case .invokeScript(let model): + + let sender = InvokeScriptTransactionSender(fee: model.fee, + feeAssetId: model.feeAssetId, + dApp: model.dApp, + call: model.call?.callSender, + payment: model.paymentSender, + chainId: model.chainId, + timestamp: Date.init(milliseconds: model.timestamp)) + + return .invokeScript(sender) + + case .transfer(let model): + + let sender = SendTransactionSender.init(recipient: model.recipient, + assetId: model.assetId, + amount: model.amount, + fee: model.fee, + attachment: model.attachment, + feeAssetID: model.feeAssetId, + chainId: model.chainId, + timestamp: Date.init(milliseconds: model.timestamp)) + + return .send(sender) + + case .data(let model): + + let sender = DataTransactionSender.init(fee: model.fee, + data: model.valueSender, + chainId: model.chainId, + timestamp: Date.init(milliseconds: model.timestamp)) + + return .data(sender) + + default: + return nil + } + } +} + +fileprivate extension DomainLayer.DTO.MobileKeeper.PrepareRequest { + + + func completedRequest(response: DomainLayer.DTO.MobileKeeper.Response.Kind, + signedWallet: DomainLayer.DTO.SignedWallet) -> DomainLayer.DTO.MobileKeeper.CompletedRequest { + + + let completedRequest = DomainLayer.DTO.MobileKeeper.CompletedRequest(request: request, + timestamp: timestamp, + proof: proof, + txId: txId, + publicKey: signedWallet.publicKey.getPublicKeyStr(), + response: .init(requestId: request.id, + kind: response)) + + return completedRequest + } + + +} + + +fileprivate extension DomainLayer.DTO.MobileKeeper.Request { + + func transactionSignature(signedWallet: DomainLayer.DTO.SignedWallet, + timestamp: Date) -> TransactionSignatureProtocol? { + + let senderPublicKey = signedWallet.publicKey.getPublicKeyStr() + + switch self.transaction { + case .data(let tx): + + let signature = TransactionSignatureV1.data(.init(fee: tx.fee, + data: tx.data.map { $0.valueSignatureV1() }, + chainId: tx.chainId ?? "", + senderPublicKey: senderPublicKey, + timestamp: timestamp.millisecondsSince1970)) + + return signature + + case .invokeScript(let tx): + + let signature = TransactionSignatureV1.invokeScript(.init(senderPublicKey: senderPublicKey, + fee: tx.fee, + chainId: tx.chainId ?? "", + timestamp: timestamp.millisecondsSince1970, + feeAssetId: tx.feeAssetId, + dApp: tx.dApp, + call: tx.call?.callSigantureV1(), + payment: tx.payment.map { $0.paymentSigantureV1() })) + + return signature + case .send(let tx): + + let signature = TransactionSignatureV2.transfer(.init(senderPublicKey: senderPublicKey, + recipient: tx.recipient, + assetId: tx.assetId, + amount: tx.amount, + fee: tx.fee, + attachment: tx.attachment, + feeAssetID: tx.feeAssetID, + chainId: tx.chainId ?? "", + timestamp: timestamp.millisecondsSince1970)) + return signature + + default: + return nil + } + } +} + +fileprivate extension DataTransactionSender.Value { + + func valueSignatureV1() -> TransactionSignatureV1.Structure.Data.Value { + + switch self.value { + case .binary(let value): + return .init(key: self.key, value: .binary(value)) + + case .boolean(let value): + return .init(key: self.key, value: .boolean(value)) + + case .integer(let value): + return .init(key: self.key, value: .integer(value)) + + case .string(let value): + return .init(key: self.key, value: .string(value)) + } + } +} + +fileprivate extension InvokeScriptTransactionSender.Arg.Value { + + func argValueSigantureV1() -> TransactionSignatureV1.Structure.InvokeScript.Arg.Value { + + switch self { + case .binary(let value): + return .binary(value) + + case .bool(let value): + return .bool(value) + + case .integer(let value): + return .integer(value) + + case .string(let value): + return .string(value) + } + } +} + +fileprivate extension InvokeScriptTransactionSender.Payment { + + func paymentSigantureV1() -> TransactionSignatureV1.Structure.InvokeScript.Payment { + return .init(amount: amount, assetId: assetId) + } +} + +fileprivate extension InvokeScriptTransactionSender.Arg { + + func argSigantureV1() -> TransactionSignatureV1.Structure.InvokeScript.Arg { + + return TransactionSignatureV1.Structure.InvokeScript.Arg(value: value.argValueSigantureV1()) + } +} + +fileprivate extension InvokeScriptTransactionSender.Call { + + func callSigantureV1() -> TransactionSignatureV1.Structure.InvokeScript.Call { + + return .init(function: function, + args: args.map { $0.argSigantureV1() }) + } + +} + +private extension URL { + + func request() throws -> WavesKeeper.Request? { + + guard let component = URLComponents.init(url: self, resolvingAgainstBaseURL: true) else { return nil } + guard component.path == "keeper/v1/request" else { throw MobileKeeperUseCaseError.dataIncorrect } + guard let item = (component.queryItems?.first { $0.name == "data" }) else { throw MobileKeeperUseCaseError.dataIncorrect } + guard let value = item.value else { throw MobileKeeperUseCaseError.dataIncorrect } + + guard let request: WavesKeeper.Request = value.decodableBase64ToObject() else { + throw MobileKeeperUseCaseError.dataIncorrect + } + + return request + } +} + +private extension WavesKeeper.Response { + + func url(app: WavesKeeper.Application) -> URL? { + + guard let base64 = self.encodableToBase64 else { return nil } + + var component = URLComponents(string: "") + + component?.scheme = app.schemeUrl.components(separatedBy: CharacterSet.urlFragmentAllowed.inverted).joined().lowercased() + component?.path = "keeper/v1/response" + component?.queryItems = [URLQueryItem(name: "data", value: base64)] + + return try? component?.asURL() + } +} + diff --git a/WavesWallet-iOS/DataLayer/Repositories/NotificationNewsRepository.swift b/DataLayer/Sources/Repositories/NotificationNewsRepository.swift similarity index 90% rename from WavesWallet-iOS/DataLayer/Repositories/NotificationNewsRepository.swift rename to DataLayer/Sources/Repositories/NotificationNewsRepository.swift index 0d0b22e2..71419a95 100644 --- a/WavesWallet-iOS/DataLayer/Repositories/NotificationNewsRepository.swift +++ b/DataLayer/Sources/Repositories/NotificationNewsRepository.swift @@ -9,10 +9,11 @@ import Foundation import RxSwift import Moya +import DomainLayer final class NotificationNewsRepository: NotificationNewsRepositoryProtocol { - private let applicationNews: MoyaProvider = .nodeMoyaProvider() + private let applicationNews: MoyaProvider = .anyMoyaProvider() func notificationNews() -> Observable<[DomainLayer.DTO.NotificationNews]> { @@ -33,13 +34,13 @@ final class NotificationNewsRepository: NotificationNewsRepositoryProtocol { return applicationNews .rx - .request(.get(isDebug: ApplicationDebugSettings.isEnableNotificationsSettingDev, hasProxy: true), callbackQueue: DispatchQueue.global(qos: .userInteractive)) + .request(.get(isDebug: ApplicationDebugSettings.isEnableNotificationsSettingTest, hasProxy: true), callbackQueue: DispatchQueue.global(qos: .userInteractive)) .catchError({ [weak self] (_) -> PrimitiveSequence in guard let self = self else { return Single.never() } return self .applicationNews .rx - .request(.get(isDebug: ApplicationDebugSettings.isEnableNotificationsSettingDev, hasProxy: false), callbackQueue: DispatchQueue.global(qos: .userInteractive)) + .request(.get(isDebug: ApplicationDebugSettings.isEnableNotificationsSettingTest, hasProxy: false), callbackQueue: DispatchQueue.global(qos: .userInteractive)) }) .asObservable() .filterSuccessfulStatusAndRedirectCodes() diff --git a/DataLayer/Sources/Repositories/RepositoriesFactory.swift b/DataLayer/Sources/Repositories/RepositoriesFactory.swift new file mode 100644 index 00000000..c3c7a665 --- /dev/null +++ b/DataLayer/Sources/Repositories/RepositoriesFactory.swift @@ -0,0 +1,154 @@ +// +// FactoryRepositories.swift +// WavesWallet-iOS +// +// Created by mefilt on 06.08.2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import DomainLayer +import WavesSDKExtensions + +import FirebaseCore +import FirebaseDatabase +import FirebaseInAppMessaging + +import Fabric +import Crashlytics +import AppsFlyerLib +import Amplitude_iOS + +//TODO: Rename Local Repository and protocol +typealias EnvironmentRepositoryProtocols = EnvironmentRepositoryProtocol & ServicesEnvironmentRepositoryProtocol + +public final class RepositoriesFactory: RepositoriesFactoryProtocol { + + private lazy var environmentRepositoryInternal: EnvironmentRepository = EnvironmentRepository() + + public private(set) lazy var environmentRepository: EnvironmentRepositoryProtocol = environmentRepositoryInternal + + public private(set) lazy var assetsRepositoryLocal: AssetsRepositoryProtocol = AssetsRepositoryLocal() + + public private(set) lazy var assetsRepositoryRemote: AssetsRepositoryProtocol = AssetsRepositoryRemote(environmentRepository: environmentRepositoryInternal, spamAssetsRepository: spamAssets) + + public private(set) lazy var accountBalanceRepositoryLocal: AccountBalanceRepositoryProtocol = AccountBalanceRepositoryLocal() + + public private(set) lazy var accountBalanceRepositoryRemote: AccountBalanceRepositoryProtocol = AccountBalanceRepositoryRemote(environmentRepository: environmentRepositoryInternal) + + public private(set) lazy var transactionsRepositoryLocal: TransactionsRepositoryProtocol = TransactionsRepositoryLocal() + + public private(set) lazy var transactionsRepositoryRemote: TransactionsRepositoryProtocol = TransactionsRepositoryRemote(environmentRepository: environmentRepositoryInternal) + + public private(set) lazy var blockRemote: BlockRepositoryProtocol = BlockRepositoryRemote(environmentRepository: environmentRepositoryInternal) + + public private(set) lazy var walletsRepositoryLocal: WalletsRepositoryProtocol = WalletsRepositoryLocal(environmentRepository: environmentRepositoryInternal) + + public private(set) lazy var walletSeedRepositoryLocal: WalletSeedRepositoryProtocol = WalletSeedRepositoryLocal() + + public private(set) lazy var authenticationRepositoryRemote: AuthenticationRepositoryProtocol = AuthenticationRepositoryRemote() + + public private(set) lazy var accountSettingsRepository: AccountSettingsRepositoryProtocol = AccountSettingsRepository() + + public private(set) lazy var addressBookRepository: AddressBookRepositoryProtocol = AddressBookRepository() + + public private(set) lazy var dexRealmRepository: DexRealmRepositoryProtocol = DexRealmRepositoryLocal() + + public private(set) lazy var dexPairsPriceRepository: DexPairsPriceRepositoryProtocol = DexPairsPriceRepositoryRemote(environmentRepository: environmentRepositoryInternal) + + public private(set) lazy var dexOrderBookRepository: DexOrderBookRepositoryProtocol = DexOrderBookRepositoryRemote(environmentRepository: environmentRepositoryInternal, spamAssetsRepository: spamAssets) + + public private(set) lazy var aliasesRepositoryRemote: AliasesRepositoryProtocol = AliasesRepository(environmentRepository: environmentRepositoryInternal) + + public private(set) lazy var aliasesRepositoryLocal: AliasesRepositoryProtocol = AliasesRepositoryLocal() + + public private(set) lazy var assetsBalanceSettingsRepositoryLocal: AssetsBalanceSettingsRepositoryProtocol = AssetsBalanceSettingsRepositoryLocal() + + public private(set) lazy var candlesRepository: CandlesRepositoryProtocol = CandlesRepositoryRemote(environmentRepository: environmentRepositoryInternal, matcherRepository: matcherRepository) + + public private(set) lazy var lastTradesRespository: LastTradesRepositoryProtocol = LastTradesRepositoryRemote(environmentRepository: environmentRepositoryInternal, matcherRepository: matcherRepository) + + public private(set) lazy var coinomatRepository: CoinomatRepositoryProtocol = CoinomatRepository() + + public private(set) lazy var addressRepository: AddressRepositoryProtocol = AddressRepositoryRemote(environmentRepository: environmentRepositoryInternal) + + public private(set) lazy var notificationNewsRepository: NotificationNewsRepositoryProtocol = NotificationNewsRepository() + + public private(set) lazy var applicationVersionRepository: ApplicationVersionRepositoryProtocol = ApplicationVersionRepository() + + public private(set) lazy var analyticManager: AnalyticManagerProtocol = { + return AnalyticManager() + }() + + public private(set) lazy var spamAssets: SpamAssetsRepositoryProtocol = { + return SpamAssetsRepository(environmentRepository: environmentRepositoryInternal, + accountSettingsRepository: accountSettingsRepository) + }() + + public private(set) lazy var gatewayRepository: GatewayRepositoryProtocol = GatewayRepository(environmentRepository: environmentRepositoryInternal) + + public private(set) lazy var widgetSettingsStorage: WidgetSettingsRepositoryProtocol = WidgetSettingsRepositoryStorage() + + public private(set) lazy var matcherRepository: MatcherRepositoryProtocol = MatcherRepositoryLocal(matcherRepositoryRemote: matcherRepositoryRemote) + + public private(set) lazy var matcherRepositoryRemote: MatcherRepositoryProtocol = MatcherRepositoryRemote(environmentRepository: environmentRepositoryInternal) + + public private(set) lazy var mobileKeeperRepository: MobileKeeperRepositoryProtocol = MobileKeeperRepository(repositoriesFactory: self) + + public struct Resources { + + public typealias PathForFile = String + + let googleServiceInfo: PathForFile + let appsflyerInfo: PathForFile + let amplitudeInfo: PathForFile + let sentryIoInfoPath: PathForFile + + public init(googleServiceInfo: PathForFile, + appsflyerInfo: PathForFile, + amplitudeInfo: PathForFile, + sentryIoInfoPath: PathForFile) { + + self.googleServiceInfo = googleServiceInfo + self.appsflyerInfo = appsflyerInfo + self.amplitudeInfo = amplitudeInfo + self.sentryIoInfoPath = sentryIoInfoPath + } + } + + public init(resources: Resources) { + + if let options = FirebaseOptions(contentsOfFile: resources.googleServiceInfo) { + + FirebaseApp.configure(options: options) + + Database.database().isPersistenceEnabled = false + Fabric.with([Crashlytics.self]) + } + + if let root = NSDictionary(contentsOfFile: resources.appsflyerInfo)?["Appsflyer"] as? NSDictionary { + if let devKey = root["AppsFlyerDevKey"] as? String, + let appId = root["AppleAppID"] as? String { + AppsFlyerTracker.shared().appsFlyerDevKey = devKey + AppsFlyerTracker.shared().appleAppID = appId + } + } + + if let apiKey = NSDictionary(contentsOfFile: resources.amplitudeInfo)?["API_KEY"] as? String { + Amplitude.instance()?.initializeApiKey(apiKey) + Amplitude.instance()?.setDeviceId(UIDevice.uuid) + } + + SentryManager.initialization(sentryIoInfoPath: resources.sentryIoInfoPath) + + #if DEBUG || TEST + SweetLogger.current.add(plugin: SweetLoggerConsole(visibleLevels: [.warning, .debug, .error], + isShortLog: true)) + + AppsFlyerTracker.shared()?.isDebug = true + #else + AppsFlyerTracker.shared()?.isDebug = false + #endif + + } +} diff --git a/DataLayer/Sources/Repositories/SpamAssetsRepository.swift b/DataLayer/Sources/Repositories/SpamAssetsRepository.swift new file mode 100644 index 00000000..a00697ff --- /dev/null +++ b/DataLayer/Sources/Repositories/SpamAssetsRepository.swift @@ -0,0 +1,81 @@ +// +// SpamAssetsRepositoryProtocol.swift +// WavesWallet-iOS +// +// Created by rprokofev on 25.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import DomainLayer +import Moya +import RxSwift + +private enum Constants { + + static let urlSpam: URL = URL(string: "https://raw.githubusercontent.com/wavesplatform/waves-community/master/Scam%20tokens%20according%20to%20the%20opinion%20of%20Waves%20Community.csv")! + static let urlSpamProxy: URL = URL(string: "https://github-proxy.wvservices.com/wavesplatform/waves-community/master/Scam%20tokens%20according%20to%20the%20opinion%20of%20Waves%20Community.csv")! +} + + +final class SpamAssetsRepository: SpamAssetsRepositoryProtocol { + + private let spamService: SpamAssetsService = SpamAssetsService() + + private let environmentRepository: EnvironmentRepositoryProtocols + private let accountSettingsRepository: AccountSettingsRepositoryProtocol + + init(environmentRepository: EnvironmentRepositoryProtocols, + accountSettingsRepository: AccountSettingsRepositoryProtocol) { + + self.environmentRepository = environmentRepository + self.accountSettingsRepository = accountSettingsRepository + } + + func spamAssets(accountAddress: String) -> Observable<[SpamAssetId]> { + + return accountSettingsRepository + .accountEnvironment(accountAddress: accountAddress) + .flatMap({ [weak self] (accountEnviroment) -> Observable<[SpamAssetId]> in + + guard let self = self else { return Observable.never() } + + if let accountEnviroment = accountEnviroment, + let spamPath = accountEnviroment.spamUrl, + let spamUrl = URL(string: spamPath) { + return self.downloadSpamAssets(by: spamUrl) + } else { + return self.downloadDeffaultSpamAssets() + } + }) + } + + private func downloadDeffaultSpamAssets() -> Observable<[SpamAssetId]> { + + return environmentRepository.walletEnvironment() + .flatMap({ [weak self] (environment) -> Observable<[String]> in + + guard let self = self else { return Observable.empty() } + + return self + .spamService + .spamAssets(by: Constants.urlSpamProxy) + .catchError({ [weak self] _ -> Observable<[String]> in + + guard let self = self else { return Observable.empty() } + + return self.spamService.spamAssets(by: Constants.urlSpam) + }) + + }) + } + + private func downloadSpamAssets(by url: URL) -> Observable<[SpamAssetId]> { + + return environmentRepository.walletEnvironment() + .flatMap({ [weak self] (environment) -> Observable<[String]> in + guard let self = self else { return Observable.empty() } + return self.spamService.spamAssets(by: url) + }) + } +} diff --git a/WavesWallet-iOS/DataLayer/Repositories/Transactions/TransactionsRepositoryLocal.swift b/DataLayer/Sources/Repositories/Transactions/TransactionsRepositoryLocal.swift similarity index 96% rename from WavesWallet-iOS/DataLayer/Repositories/Transactions/TransactionsRepositoryLocal.swift rename to DataLayer/Sources/Repositories/Transactions/TransactionsRepositoryLocal.swift index 70db1c55..33e9e1bf 100644 --- a/WavesWallet-iOS/DataLayer/Repositories/Transactions/TransactionsRepositoryLocal.swift +++ b/DataLayer/Sources/Repositories/Transactions/TransactionsRepositoryLocal.swift @@ -11,8 +11,10 @@ import RealmSwift import RxRealm import RxSwift import RxOptional -import WavesSDKExtension -import WavesSDKCrypto +import WavesSDK +import WavesSDKExtensions +import DomainLayer +import Extensions extension Realm { func filter(parentType: ParentType.Type, @@ -28,9 +30,9 @@ extension Realm { fileprivate extension TransactionType { // The types using only waves assetId static var waves: [TransactionType] { - return [.lease, - .leaseCancel, - .alias, + return [.createLease, + .cancelLease, + .createAlias, .data, .script] } @@ -38,7 +40,7 @@ fileprivate extension TransactionType { func predicate(from specifications: TransactionsSpecifications, myAddress: DomainLayer.DTO.Address) -> NSPredicate { switch self { - case .alias: + case .createAlias: return AliasTransaction.predicate(specifications, myAddress: myAddress) case .issue: @@ -56,10 +58,10 @@ fileprivate extension TransactionType { case .exchange: return ExchangeTransaction.predicate(specifications, myAddress: myAddress) - case .lease: + case .createLease: return LeaseTransaction.predicate(specifications, myAddress: myAddress) - case .leaseCancel: + case .cancelLease: return LeaseCancelTransaction.predicate(specifications, myAddress: myAddress) case .massTransfer: @@ -79,16 +81,13 @@ fileprivate extension TransactionType { case .invokeScript: return InvokeScriptTransaction.predicate(specifications, myAddress: myAddress) - - default: - return UnrecognisedTransaction.predicate(specifications, myAddress: myAddress) } } func anyTransaction(from transaction: AnyTransaction) -> DomainLayer.DTO.AnyTransaction? { switch self { - case .alias: + case .createAlias: guard let aliasTransaction = transaction.aliasTransaction else { return nil } return .alias(.init(transaction: aliasTransaction)) @@ -112,11 +111,11 @@ fileprivate extension TransactionType { guard let exchangeTransaction = transaction.exchangeTransaction else { return nil } return .exchange(.init(transaction: exchangeTransaction)) - case .lease: + case .createLease: guard let leaseTransaction = transaction.leaseTransaction else { return nil } return .lease(.init(transaction: leaseTransaction)) - case .leaseCancel: + case .cancelLease: guard let leaseCancelTransaction = transaction.leaseCancelTransaction else { return nil } return .leaseCancel(.init(transaction: leaseCancelTransaction)) @@ -143,10 +142,6 @@ fileprivate extension TransactionType { case .invokeScript: guard let invokeScriptTransaction = transaction.invokeScriptTransaction else { return nil } return .invokeScript(.init(transaction: invokeScriptTransaction)) - - default: - guard let unrecognisedTransaction = transaction.unrecognisedTransaction else { return nil } - return .unrecognised(.init(transaction: unrecognisedTransaction)) } } } @@ -189,7 +184,7 @@ final class TransactionsRepositoryLocal: TransactionsRepositoryProtocol { specifications: TransactionsSpecifications, realm: Realm) -> Results { - let wavesAssetId = WavesSDKCryptoConstants.wavesAssetId + let wavesAssetId = WavesSDKConstants.wavesAssetId let hasWaves = specifications.assets.contains(wavesAssetId) @@ -215,7 +210,7 @@ final class TransactionsRepositoryLocal: TransactionsRepositoryProtocol { private func mapping(result: Results, by specifications: TransactionsSpecifications) -> [DomainLayer.DTO.AnyTransaction] { var txs: [AnyTransaction] = [] - if let page = specifications.page { + if let page = specifications.page { txs = result.get(offset: page.offset, limit: page.limit) } else { txs = result.toArray() @@ -229,7 +224,7 @@ final class TransactionsRepositoryLocal: TransactionsRepositoryProtocol { var transactions = [DomainLayer.DTO.AnyTransaction]() for any in txs { - guard let type = TransactionType(rawValue: any.type) else { continue } + guard let type = TransactionType(rawValue: Int8(any.type)) else { continue } guard let tx = type.anyTransaction(from: any) else { continue } transactions.append(tx) } @@ -286,7 +281,7 @@ final class TransactionsRepositoryLocal: TransactionsRepositoryProtocol { specifications: TransactionsSpecifications(page: nil, assets: .init(), senders: .init(), - types: [TransactionType.lease])) + types: [TransactionType.createLease])) .map({ txs -> [DomainLayer.DTO.LeaseTransaction] in return txs.map({ tx -> DomainLayer.DTO.LeaseTransaction? in if case .lease(let leaseTx) = tx { diff --git a/DataLayer/Sources/Repositories/Transactions/TransactionsRepositoryRemote.swift b/DataLayer/Sources/Repositories/Transactions/TransactionsRepositoryRemote.swift new file mode 100644 index 00000000..bdb0cbaf --- /dev/null +++ b/DataLayer/Sources/Repositories/Transactions/TransactionsRepositoryRemote.swift @@ -0,0 +1,246 @@ +// +// TransactionsRepositoryRemote.swift +// WavesWallet-iOS +// +// Created by mefilt on 30.08.2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import Moya +import CryptoSwift +import WavesSDKExtensions +import WavesSDK +import DomainLayer + +fileprivate enum Constants { + static let maxLimit: Int = 10000 +} + +extension TransactionSenderSpecifications { + + var version: Int { + switch self { + case .createAlias: + return 2 + + case .lease: + return 2 + + case .burn: + return 2 + + case .cancelLease: + return 2 + + case .data: + return 1 + + case .send: + return 2 + + case .invokeScript: + return 1 + } + } + + var type: TransactionType { + switch self { + + case .invokeScript: + return TransactionType.invokeScript + + case .createAlias: + return TransactionType.createAlias + + case .lease: + return TransactionType.createLease + + case .burn: + return TransactionType.burn + + case .cancelLease: + return TransactionType.cancelLease + + case .data: + return TransactionType.data + + case .send: + return TransactionType.transfer + } + } +} + +final class TransactionsRepositoryRemote: TransactionsRepositoryProtocol { + + private let transactionRules: MoyaProvider = .anyMoyaProvider() + + private let environmentRepository: EnvironmentRepositoryProtocols + + init(environmentRepository: EnvironmentRepositoryProtocols) { + self.environmentRepository = environmentRepository + } + + func transactions(by address: DomainLayer.DTO.Address, + offset: Int, + limit: Int) -> Observable<[DomainLayer.DTO.AnyTransaction]> { + + return environmentRepository + .servicesEnvironment() + .flatMapLatest({ [weak self] (servicesEnvironment) -> Observable<[DomainLayer.DTO.AnyTransaction]> in + + guard let self = self else { return Observable.never() } + + let limit = min(Constants.maxLimit, offset + limit) + + return servicesEnvironment + .wavesServices + .nodeServices + .transactionNodeService + .transactions(by: address.address, + offset: 0, + limit: limit) + .map { $0.anyTransactions(status: .completed, environment: servicesEnvironment.walletEnvironment) } + }) + } + + func activeLeasingTransactions(by accountAddress: String) -> Observable<[DomainLayer.DTO.LeaseTransaction]> { + + return environmentRepository + .servicesEnvironment() + .flatMapLatest({ [weak self] (servicesEnvironment) -> Observable<[DomainLayer.DTO.LeaseTransaction]> in + + guard let self = self else { return Observable.never() } + + return servicesEnvironment + .wavesServices + .nodeServices + .leasingNodeService + .leasingActiveTransactions(by: accountAddress) + .map { $0.map { tx in + return DomainLayer.DTO.LeaseTransaction(transaction: tx, + status: .activeNow, + environment: servicesEnvironment.walletEnvironment) + } + } + .asObservable() + }) + } + + func send(by specifications: TransactionSenderSpecifications, + wallet: DomainLayer.DTO.SignedWallet) -> Observable { + + return environmentRepository + .servicesEnvironment() + .flatMapLatest({ (servicesEnvironment) -> Observable in + + let walletEnvironment = servicesEnvironment.walletEnvironment + + let specs = specifications.broadcastSpecification(servicesEnvironment: servicesEnvironment, + wallet: wallet, + specifications: specifications) + + guard let broadcastSpecification = specs else { return Observable.empty() } + + return servicesEnvironment + .wavesServices + .nodeServices + .transactionNodeService + .transactions(query: broadcastSpecification) + .map({ $0.anyTransaction(status: .unconfirmed, environment: walletEnvironment) }) + .asObservable() + }) + } + +// MARK - - Dont support + func newTransactions(by address: DomainLayer.DTO.Address, + specifications: TransactionsSpecifications) -> Observable<[DomainLayer.DTO.AnyTransaction]> { + assertMethodDontSupported() + return Observable.never() + } + + func transactions(by address: DomainLayer.DTO.Address, + specifications: TransactionsSpecifications) -> Observable<[DomainLayer.DTO.AnyTransaction]> { + assertMethodDontSupported() + return Observable.never() + } + + func saveTransactions(_ transactions: [DomainLayer.DTO.AnyTransaction], accountAddress: String) -> Observable { + assertMethodDontSupported() + return Observable.never() + } + + func isHasTransactions(by accountAddress: String, ignoreUnconfirmed: Bool) -> Observable { + assertMethodDontSupported() + return Observable.never() + } + + func isHasTransaction(by id: String, accountAddress: String, ignoreUnconfirmed: Bool) -> Observable { + assertMethodDontSupported() + return Observable.never() + } + + func isHasTransactions(by ids: [String], accountAddress: String, ignoreUnconfirmed: Bool) -> Observable { + assertMethodDontSupported() + return Observable.never() + } + + func feeRules() -> Observable { + return transactionRules + .rx + .request(.get(hasProxy: true)) + .catchError({ [weak self] (_) -> PrimitiveSequence in + guard let self = self else { return Single.never() } + return self + .transactionRules + .rx + .request(.get(hasProxy: false)) + }) + .map(GitHub.DTO.TransactionFeeRules.self) + .asObservable() + .map({ (txRules) -> DomainLayer.DTO.TransactionFeeRules in + + let deffault = txRules.calculate_fee_rules[TransactionFeeDefaultRule] + + let rules = TransactionType + .all + .reduce(into: [TransactionType: DomainLayer.DTO.TransactionFeeRules.Rule](), { (result, type) in + + let rule = txRules.calculate_fee_rules["\(type.rawValue)"] + + let addSmartAssetFee = (rule?.add_smart_asset_fee ?? deffault?.add_smart_asset_fee) ?? false + let addSmartAccountFee = (rule?.add_smart_account_fee ?? deffault?.add_smart_account_fee) ?? false + let minPriceStep = (rule?.min_price_step ?? deffault?.min_price_step) ?? 0 + let fee = (rule?.fee ?? deffault?.fee) ?? 0 + let pricePerTransfer = (rule?.price_per_transfer ?? deffault?.price_per_transfer) ?? 0 + let pricePerKb = (rule?.price_per_kb ?? deffault?.price_per_kb) ?? 0 + + let newRule = DomainLayer.DTO.TransactionFeeRules.Rule(addSmartAssetFee: addSmartAssetFee, + addSmartAccountFee: addSmartAccountFee, + minPriceStep: minPriceStep, + fee: fee, + pricePerTransfer: pricePerTransfer, + pricePerKb: pricePerKb) + + result[type] = newRule + }) + + + let newDefaultRule = DomainLayer.DTO.TransactionFeeRules.Rule(addSmartAssetFee: deffault?.add_smart_asset_fee ?? false, + addSmartAccountFee: deffault?.add_smart_account_fee ?? false, + minPriceStep: deffault?.min_price_step ?? 0, + fee: deffault?.fee ?? 0, + pricePerTransfer: deffault?.price_per_transfer ?? 0, + pricePerKb: deffault?.price_per_kb ?? 0) + + + let newRules = DomainLayer.DTO.TransactionFeeRules(smartAssetExtraFee: txRules.smart_asset_extra_fee, + smartAccountExtraFee: txRules.smart_account_extra_fee, + defaultRule: newDefaultRule, + rules: rules) + + return newRules + }) + } +} diff --git a/WavesWallet-iOS/DataLayer/Repositories/Wallets/WalletSeedRepositoryLocal.swift b/DataLayer/Sources/Repositories/Wallets/WalletSeedRepositoryLocal.swift similarity index 98% rename from WavesWallet-iOS/DataLayer/Repositories/Wallets/WalletSeedRepositoryLocal.swift rename to DataLayer/Sources/Repositories/Wallets/WalletSeedRepositoryLocal.swift index 516f9653..52deb3fb 100644 --- a/WavesWallet-iOS/DataLayer/Repositories/Wallets/WalletSeedRepositoryLocal.swift +++ b/DataLayer/Sources/Repositories/Wallets/WalletSeedRepositoryLocal.swift @@ -9,8 +9,9 @@ import Foundation import RxSwift import RealmSwift -import WavesSDKExtension -import WavesSDKCrypto +import WavesSDKExtensions +import DomainLayer +import Extensions fileprivate enum Constants { static let schemaVersion: UInt64 = 4 diff --git a/WavesWallet-iOS/DataLayer/Repositories/Wallets/WalletsRepositoryLocal.swift b/DataLayer/Sources/Repositories/Wallets/WalletsRepositoryLocal.swift similarity index 94% rename from WavesWallet-iOS/DataLayer/Repositories/Wallets/WalletsRepositoryLocal.swift rename to DataLayer/Sources/Repositories/Wallets/WalletsRepositoryLocal.swift index c97a77d2..c571e5ef 100644 --- a/WavesWallet-iOS/DataLayer/Repositories/Wallets/WalletsRepositoryLocal.swift +++ b/DataLayer/Sources/Repositories/Wallets/WalletsRepositoryLocal.swift @@ -9,10 +9,17 @@ import Foundation import RxSwift import RealmSwift -import WavesSDKExtension +import WavesSDKExtensions +import DomainLayer final class WalletsRepositoryLocal: WalletsRepositoryProtocol { + private var environmentRepository: EnvironmentRepositoryProtocol + + init(environmentRepository: EnvironmentRepositoryProtocol) { + self.environmentRepository = environmentRepository + } + func wallets() -> Observable<[DomainLayer.DTO.Wallet]> { return Observable.create({ [weak self] (observer) -> Disposable in @@ -240,6 +247,11 @@ final class WalletsRepositoryLocal: WalletsRepositoryProtocol { observer.onError(WalletsRepositoryError.notFound) SweetLogger.error(WalletsRepositoryError.notFound) } + + let realm = try? WalletRealmFactory.realm(accountAddress: wallet.address) + try? realm?.write { + realm?.deleteAll() + } } catch let error { SweetLogger.error(error) observer.onNext(false) @@ -307,9 +319,10 @@ final class WalletsRepositoryLocal: WalletsRepositoryProtocol { } private extension WalletsRepositoryLocal { - + var realm: Realm? { - guard let config = WalletRealmFactory.Configuration.walletsConfig else { + + guard let config = WalletsRealmFactory.walletsConfig(scheme: "\(environmentRepository.environmentKind.rawValue)") else { SweetLogger.error("Realm Configuration is nil") return nil } diff --git a/DataLayer/Sources/Repositories/WidgetSettingsRepositoryStorage.swift b/DataLayer/Sources/Repositories/WidgetSettingsRepositoryStorage.swift new file mode 100644 index 00000000..b01e73fe --- /dev/null +++ b/DataLayer/Sources/Repositories/WidgetSettingsRepositoryStorage.swift @@ -0,0 +1,69 @@ +// +// MarketPulseWidgetSettingsRepositoryStorage.swift +// DataLayer +// +// Created by rprokofev on 07.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import DomainLayer +import Extensions +import RxSwift + + +private enum Constants { + static let settingsKey = "widget.settings" + static let userGroupsKey = "group.com.wavesplatform" +} + + +final class WidgetSettingsRepositoryStorage: WidgetSettingsRepositoryProtocol { + + func settings() -> Observable { + + return Observable.create({ [weak self] (subscribe) -> Disposable in + guard let self = self else { return Disposables.create() } + + if let settingsData = self.userDefaults.object(forKey: Constants.settingsKey) as? Data { + if let settings = try? JSONDecoder().decode(DomainLayer.DTO.MarketPulseSettings.self, from: settingsData) { + subscribe.onNext(settings) + } + else { + subscribe.onNext(nil) + } + } + else { + subscribe.onNext(nil) + } + + subscribe.onCompleted() + return Disposables.create() + }) + } + + func saveSettings(_ settings: DomainLayer.DTO.MarketPulseSettings) -> Observable { + + return Observable.create({ [weak self] (subscribe) -> Disposable in + + guard let self = self else { return Disposables.create() } + + do { + let encodedData = try JSONEncoder().encode(settings) + self.userDefaults.set(encodedData, forKey: Constants.settingsKey) + subscribe.onNext(settings) + subscribe.onCompleted() + } + catch _ { + subscribe.onError(RepositoryError.fail) + } + + return Disposables.create() + }) + } + + + private var userDefaults: UserDefaults { + return UserDefaults(suiteName: Constants.userGroupsKey) ?? .standard + } +} diff --git a/WavesWallet-iOS/DataLayer/Service/Coinomat/CoinomatService.swift b/DataLayer/Sources/Service/Coinomat/CoinomatService.swift similarity index 97% rename from WavesWallet-iOS/DataLayer/Service/Coinomat/CoinomatService.swift rename to DataLayer/Sources/Service/Coinomat/CoinomatService.swift index bee648d3..3c8b1867 100644 --- a/WavesWallet-iOS/DataLayer/Service/Coinomat/CoinomatService.swift +++ b/DataLayer/Sources/Service/Coinomat/CoinomatService.swift @@ -8,8 +8,7 @@ import Foundation import Moya -import WavesSDKExtension -import WavesSDKCrypto +import WavesSDK private enum Constants { static let url = "https://coinomat.com/" @@ -97,7 +96,7 @@ extension Coinomat.Service { struct Price: Codable, ApiServicePath { - let crypto: String = WavesSDKCryptoConstants.wavesAssetId + let crypto: String = WavesSDKConstants.wavesAssetId let fiat: String let address: String let amount: Double diff --git a/DataLayer/Sources/Service/Gateway/GatewayService.swift b/DataLayer/Sources/Service/Gateway/GatewayService.swift new file mode 100644 index 00000000..cea41ea1 --- /dev/null +++ b/DataLayer/Sources/Service/Gateway/GatewayService.swift @@ -0,0 +1,119 @@ +// +// GavewayService.swift +// InternalDataLayer +// +// Created by Pavel Gubin on 22.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import Moya +import WavesSDK + +private enum Constants { + + enum Keys { + static let sender = "sender" + } + + enum Path { + static let withdrawProcess = "v1/external/withdraw" + static let depositProcess = "v1/external/deposit" + static let send = "v1/external/send" + } +} + +enum Gateway { + enum Service { + case startWithdrawProcess(baseURL: URL, withdrawProcess: StartProcess) + case startDepositProcess(baseURL: URL, depositProcess: StartProcess) + case send(baseURL: URL, transaction: NodeService.Query.Transaction, accountAddress: String) + } + + enum DTO {} +} + +extension Gateway.DTO { + + struct Deposit: Decodable { + let address: String + let minAmount: Int64 + let maxAmount: Int64 + } + + struct Withdraw: Decodable { + let recipientAddress: String + let minAmount: Int64 + let maxAmount: Int64 + let fee: Int64 + let processId: String + } + +} + +extension Gateway.Service { + + struct StartProcess: Codable { + let userAddress: String + let assetId: String + } +} + +extension Gateway.Service: TargetType { + + var sampleData: Data { + return Data() + } + + var baseURL: URL { + + switch self { + case .startDepositProcess(let initProcess): + return initProcess.baseURL + + case .startWithdrawProcess(let initProcess): + return initProcess.baseURL + + case .send(let send): + return send.baseURL + } + } + + var path: String { + switch self { + case .startWithdrawProcess: + return Constants.Path.withdrawProcess + + case .startDepositProcess: + return Constants.Path.depositProcess + + case .send: + return Constants.Path.send + } + } + + var headers: [String: String]? { + return ContentType.applicationJson.headers + } + + var method: Moya.Method { + return .post + } + + var task: Task { + switch self { + case .startWithdrawProcess(let initProcess): + return .requestParameters(parameters: initProcess.withdrawProcess.dictionary, encoding: JSONEncoding.default) + + case .startDepositProcess(let initProcess): + return .requestParameters(parameters: initProcess.depositProcess.dictionary, encoding: JSONEncoding.default) + + case .send(let send): + + var params = send.transaction.params + params[Constants.Keys.sender] = send.accountAddress + + return .requestParameters(parameters: params, encoding: JSONEncoding.default) + } + } +} diff --git a/WavesWallet-iOS/DataLayer/Service/GitHub/GitHubService.swift b/DataLayer/Sources/Service/GitHub/GitHubService.swift similarity index 60% rename from WavesWallet-iOS/DataLayer/Service/GitHub/GitHubService.swift rename to DataLayer/Sources/Service/GitHub/GitHubService.swift index 3107d147..3dee3aad 100644 --- a/WavesWallet-iOS/DataLayer/Service/GitHub/GitHubService.swift +++ b/DataLayer/Sources/Service/GitHub/GitHubService.swift @@ -18,40 +18,60 @@ extension GitHub { private enum Constants { + //TODO: Refactor - static let urlEnvironmentMainNet: URL = URL(string: "https://raw.githubusercontent.com/wavesplatform/waves-client-config/mobile/v2.3/environment_mainnet.json")! + static let urlEnvironmentStageNetTest: URL = URL(string: "https://raw.githubusercontent.com/wavesplatform/waves-client-config/mobile/v2.6/test_environment_stagenet.json")! + + static let urlEnvironmentMainNetTest: URL = URL(string: "https://raw.githubusercontent.com/wavesplatform/waves-client-config/mobile/v2.6/test_environment_mainnet.json")! + + static let urlEnvironmentTestNetTest: URL = URL(string: + "https://raw.githubusercontent.com/wavesplatform/waves-client-config/mobile/v2.6/test_environment_testnet.json")! + + static let urlEnvironmentStageNet: URL = URL(string: "https://raw.githubusercontent.com/wavesplatform/waves-client-config/mobile/v2.6/environment_stagenet.json")! + + static let urlEnvironmentMainNet: URL = URL(string: "https://raw.githubusercontent.com/wavesplatform/waves-client-config/mobile/v2.6/environment_mainnet.json")! static let urlEnvironmentTestNet: URL = URL(string: - "https://raw.githubusercontent.com/wavesplatform/waves-client-config/mobile/v2.3/environment_testnet.json")! + "https://raw.githubusercontent.com/wavesplatform/waves-client-config/mobile/v2.6/environment_testnet.json")! static let urlTransactionFee: URL = URL(string: "https://raw.githubusercontent.com/wavesplatform/waves-client-config/master/fee.json")! - static let urlApplicationNews: URL = URL(string: "https://raw.githubusercontent.com/wavesplatform/waves-client-config/mobile/v2.3/notifications_ios.json")! + static let urlApplicationNews: URL = URL(string: "https://raw.githubusercontent.com/wavesplatform/waves-client-config/master/notifications_ios.json")! static let urlVersionIos: URL = URL(string: "https://raw.githubusercontent.com/wavesplatform/waves-client-config/master/version_ios.json")! - - static let urlEnvironmentMainNetProxy: URL = URL(string: "https://github-proxy.wvservices.com/wavesplatform/waves-client-config/mobile/v2.3/environment_mainnet.json")! + + static let urlVersionIosTest: URL = URL(string: "https://raw.githubusercontent.com/wavesplatform/waves-client-config/master/test_version_ios.json")! + + static let urlEnvironmentStageNetProxy: URL = URL(string: "https://github-proxy.wvservices.com/wavesplatform/waves-client-config/mobile/v2.6/environment_stagenet.json")! + + static let urlEnvironmentMainNetProxy: URL = URL(string: "https://github-proxy.wvservices.com/wavesplatform/waves-client-config/mobile/v2.6/environment_mainnet.json")! static let urlEnvironmentTestNetProxy: URL = URL(string: - "https://github-proxy.wvservices.com/wavesplatform/waves-client-config/mobile/v2.3/environment_testnet.json")! + "https://github-proxy.wvservices.com/wavesplatform/waves-client-config/mobile/v2.6/environment_testnet.json")! static let urlTransactionFeeProxy: URL = URL(string: "https://github-proxy.wvservices.com/wavesplatform/waves-client-config/master/fee.json")! - static let urlApplicationNewsProxy: URL = URL(string: "https://github-proxy.wvservices.com/wavesplatform/waves-client-config/mobile/v2.3/notifications_ios.json")! + static let urlApplicationNewsProxy: URL = URL(string: "https://github-proxy.wvservices.com/wavesplatform/waves-client-config/master/notifications_ios.json")! static let urlVersionIosProxy: URL = URL(string: "https://github-proxy.wvservices.com/wavesplatform/waves-client-config/master/version_ios.json")! - static let urlApplicationNewsDebug: URL = URL(string: "https://raw.githubusercontent.com/wavesplatform/waves-client-config/mobile/v2.3/notifications_test_ios.json")! + static let urlApplicationNewsDebug: URL = URL(string: "https://raw.githubusercontent.com/wavesplatform/waves-client-config/master/notifications_test_ios.json")! } extension GitHub.Service { enum Environment { + + enum Kind { + case mainnet + case testnet + case stagenet + } /** Response: - Environment */ - case get(isTestNet: Bool, hasProxy: Bool) + case get(kind: Kind, hasProxy: Bool, isDebug: Bool) } enum TransactionRules { @@ -75,7 +95,7 @@ extension GitHub.Service { Response: - ? */ - case get(hasProxy: Bool) + case get(isDebug: Bool, hasProxy: Bool) } } @@ -86,18 +106,39 @@ extension GitHub.Service.Environment: TargetType { var baseURL: URL { switch self { - case .get(let isTestNet, let hasProxy): - if isTestNet { - if hasProxy { - return Constants.urlEnvironmentTestNetProxy + case .get(let kind, let hasProxy, let isDebug): + + switch kind { + case .mainnet: + if isDebug { + return Constants.urlEnvironmentMainNetTest } else { - return Constants.urlEnvironmentTestNet + if hasProxy { + return Constants.urlEnvironmentMainNetProxy + } else { + return Constants.urlEnvironmentMainNet + } } - } else { - if hasProxy { - return Constants.urlEnvironmentMainNetProxy + case .testnet: + if isDebug { + return Constants.urlEnvironmentTestNetTest } else { - return Constants.urlEnvironmentMainNet + if hasProxy { + return Constants.urlEnvironmentTestNetProxy + } else { + return Constants.urlEnvironmentTestNet + } + } + + case .stagenet: + if isDebug { + return Constants.urlEnvironmentStageNetTest + } else { + if hasProxy { + return Constants.urlEnvironmentStageNetProxy + } else { + return Constants.urlEnvironmentStageNet + } } } } @@ -108,7 +149,7 @@ extension GitHub.Service.Environment: TargetType { } var headers: [String: String]? { - return ContentType.applicationJson.headers + return ["Content-type": "application/json"] } var method: Moya.Method { @@ -147,7 +188,7 @@ extension GitHub.Service.TransactionRules: TargetType { } var headers: [String: String]? { - return ContentType.applicationJson.headers + return ["Content-type": "application/json"] } var method: Moya.Method { @@ -192,7 +233,7 @@ extension GitHub.Service.ApplicationNews: TargetType { } var headers: [String: String]? { - return ContentType.applicationJson.headers + return ["Content-type": "application/json"] } var method: Moya.Method { @@ -218,8 +259,12 @@ extension GitHub.Service.ApplicationVersion: TargetType { var baseURL: URL { switch self { - case .get: - return Constants.urlVersionIos + case .get(let isDebug, _): + if isDebug { + return Constants.urlVersionIosTest + } else { + return Constants.urlVersionIos + } } } @@ -228,7 +273,7 @@ extension GitHub.Service.ApplicationVersion: TargetType { } var headers: [String: String]? { - return ContentType.applicationJson.headers + return ["Content-type": "application/json"] } var method: Moya.Method { diff --git a/WavesWallet-iOS/DataLayer/Service/GitHub/TransactionFeeRulesGitHub.swift b/DataLayer/Sources/Service/GitHub/TransactionFeeRulesGitHub.swift similarity index 100% rename from WavesWallet-iOS/DataLayer/Service/GitHub/TransactionFeeRulesGitHub.swift rename to DataLayer/Sources/Service/GitHub/TransactionFeeRulesGitHub.swift diff --git a/WavesWallet-iOS/DataLayer/Service/Spam/AssetsSpamService.swift b/DataLayer/Sources/Service/Spam/AssetsSpamService.swift similarity index 51% rename from WavesWallet-iOS/DataLayer/Service/Spam/AssetsSpamService.swift rename to DataLayer/Sources/Service/Spam/AssetsSpamService.swift index 0116e1b4..73b3d8e8 100644 --- a/WavesWallet-iOS/DataLayer/Service/Spam/AssetsSpamService.swift +++ b/DataLayer/Sources/Service/Spam/AssetsSpamService.swift @@ -9,23 +9,12 @@ import Foundation import Moya -private enum Constants { - - static let urlSpam: URL = URL(string: - "https://raw.githubusercontent.com/wavesplatform/waves-community/master/Scam%20tokens%20according%20to%20the%20opinion%20of%20Waves%20Community.csv")! - - static let urlSpamProxy: URL = URL(string: - "https://github-proxy.wvservices.com/wavesplatform/waves-community/master/Scam%20tokens%20according%20to%20the%20opinion%20of%20Waves%20Community.csv")! -} - - extension Spam.Service { enum Assets { /** Response: - CSV */ - case getSpamList(hasProxy: Bool) case getSpamListByUrl(url: URL) } } @@ -35,19 +24,13 @@ extension Spam.Service.Assets: TargetType { var baseURL: URL { switch self { - case .getSpamList(let hasProxy): - if hasProxy { - return Constants.urlSpamProxy - } else { - return Constants.urlSpam - } case .getSpamListByUrl(let url): return url } } var headers: [String: String]? { - return ContentType.applicationCsv.headers + return ["Content-type": "application/csv"] } var sampleData: Data { diff --git a/DataLayer/Sources/Service/Spam/SpamService.swift b/DataLayer/Sources/Service/Spam/SpamService.swift new file mode 100644 index 00000000..ac42c6d1 --- /dev/null +++ b/DataLayer/Sources/Service/Spam/SpamService.swift @@ -0,0 +1,36 @@ +// +// SpamService.swift +// WavesWallet-iOS +// +// Created by mefilt on 16.07.2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import Moya +import RxSwift + +enum Spam {} + +extension Spam { + enum Service {} +} + +final class SpamAssetsService { + + private let spamProvider: MoyaProvider = .anyMoyaProvider() + + func spamAssets(by url: URL) -> Observable<[String]> { + + return self + .spamProvider + .rx + .request(.getSpamListByUrl(url: url), + callbackQueue: DispatchQueue.global(qos: .userInteractive)) + .filterSuccessfulStatusAndRedirectCodes() + .map({ (response) -> [String] in + return (try? SpamCVC.addresses(from: response.data)) ?? [] + }) + .asObservable() + } +} diff --git a/DataLayerTests/DataLayerTests.swift b/DataLayerTests/DataLayerTests.swift new file mode 100644 index 00000000..2ec2dec9 --- /dev/null +++ b/DataLayerTests/DataLayerTests.swift @@ -0,0 +1,37 @@ +// +// DataLayerTests.swift +// DataLayerTests +// +// Created by rprokofev on 21.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import XCTest +import DataLayer +//import DomainLayer + +class DataLayerTests: XCTestCase { + + override func setUp() { + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() { + + XCTAssert(true) + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + func testPerformanceExample() { + // This is an example of a performance test case. + self.measure { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/DataLayerTests/Info.plist b/DataLayerTests/Info.plist new file mode 100644 index 00000000..a776b05a --- /dev/null +++ b/DataLayerTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 3901 + + diff --git a/DomainLayer.podspec b/DomainLayer.podspec new file mode 100644 index 00000000..a1c263c8 --- /dev/null +++ b/DomainLayer.podspec @@ -0,0 +1,38 @@ +Pod::Spec.new do |spec| + + spec.name = 'DomainLayer' + spec.version = '0.1' + spec.ios.deployment_target = '11.0' + spec.requires_arc = true + spec.license = { :type => 'MIT' } + spec.homepage = 'https://wavesplatform.com' + spec.authors = { 'Mefilt' => 'Mefilt@gmail.com' } + spec.summary = 'DomainLayer' + + spec.source_files = 'DomainLayer/**/**/*.{swift}' + spec.source = { :git => ''} + + spec.ios.framework = 'Foundation' + + spec.static_framework = true + + # DB + spec.dependency 'RealmSwift' + spec.dependency 'RxRealm' + + # Assisstant + spec.dependency 'RxSwift' + spec.dependency 'RxSwiftExt' + spec.dependency 'RxOptional' + spec.dependency 'RxReachability' + + spec.dependency 'KeychainAccess' + + spec.dependency 'CryptoSwift' + + # Waves + spec.dependency 'WavesSDKExtensions' + spec.dependency 'WavesSDK' + spec.dependency 'WavesSDKCrypto' + spec.dependency 'Extensions' +end \ No newline at end of file diff --git a/DomainLayer/DomainLayer.h b/DomainLayer/DomainLayer.h new file mode 100644 index 00000000..078a6f90 --- /dev/null +++ b/DomainLayer/DomainLayer.h @@ -0,0 +1,19 @@ +// +// DomainLayer.h +// DomainLayer +// +// Created by rprokofev on 14.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +#import + +//! Project version number for DomainLayer. +FOUNDATION_EXPORT double DomainLayerVersionNumber; + +//! Project version string for DomainLayer. +FOUNDATION_EXPORT const unsigned char DomainLayerVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/DomainLayer/Info.plist b/DomainLayer/Info.plist new file mode 100644 index 00000000..cc02ce1c --- /dev/null +++ b/DomainLayer/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + 3901 + + diff --git a/WavesWallet-iOS/DomainLayer/Assisstants/AnalyticManager/AnalyticAssetManager.swift b/DomainLayer/Sources/AnalyticManager/AnalyticAssetManager.swift similarity index 93% rename from WavesWallet-iOS/DomainLayer/Assisstants/AnalyticManager/AnalyticAssetManager.swift rename to DomainLayer/Sources/AnalyticManager/AnalyticAssetManager.swift index 442db83f..a101b335 100644 --- a/WavesWallet-iOS/DomainLayer/Assisstants/AnalyticManager/AnalyticAssetManager.swift +++ b/DomainLayer/Sources/AnalyticManager/AnalyticAssetManager.swift @@ -7,7 +7,8 @@ // import Foundation -import WavesSDKExtension +import WavesSDKExtensions +import Extensions struct AnalyticAssetManager: TSUD, Codable, Mutating { @@ -51,7 +52,7 @@ struct AnalyticAssetManager: TSUD, Codable, Mutating { setting.assetsIds.insert(assetId) hasChanges = true - AnalyticManager.trackEvent(.walletStart(.balanceFromZero(assetName: asset.asset.displayName))) + UseCasesFactory.instance.analyticManager.trackEvent(.walletHome(.startBalanceFromZero(assetName: asset.asset.displayName))) } } diff --git a/WavesWallet-iOS/DomainLayer/Assisstants/AnalyticManager/AnalyticManager+Dex.swift b/DomainLayer/Sources/AnalyticManager/AnalyticManager+Dex.swift similarity index 92% rename from WavesWallet-iOS/DomainLayer/Assisstants/AnalyticManager/AnalyticManager+Dex.swift rename to DomainLayer/Sources/AnalyticManager/AnalyticManager+Dex.swift index a2c3ce1e..b4996232 100644 --- a/WavesWallet-iOS/DomainLayer/Assisstants/AnalyticManager/AnalyticManager+Dex.swift +++ b/DomainLayer/Sources/AnalyticManager/AnalyticManager+Dex.swift @@ -8,9 +8,9 @@ import Foundation -extension AnalyticManager.Event { +public extension AnalyticManagerEvent { - enum Dex { + enum Dex: AnalyticManagerEventInfo { private static let key = "Pair" @@ -26,7 +26,7 @@ extension AnalyticManager.Event { /* Нажата кнопка «Okay» на экране созданного ордера. */ case sellOrderSuccess(amountAsset: String, priceAsset: String) - var name: String { + public var name: String { switch self { case .buyTap: return "DEX Buy Tap" @@ -42,7 +42,7 @@ extension AnalyticManager.Event { } } - var params: [String : String] { + public var params: [String : String] { switch self { case .buyTap(let amountAsset, let priceAsset): return [Dex.key: amountAsset + "/" + priceAsset] diff --git a/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+AddressBook.swift b/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+AddressBook.swift new file mode 100644 index 00000000..808ad56a --- /dev/null +++ b/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+AddressBook.swift @@ -0,0 +1,56 @@ +// +// Addressbook.swift +// WavesWallet-iOS +// +// Created by rprokofev on 26.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation + +public extension AnalyticManagerEvent { + enum AddressBook: AnalyticManagerEventInfo { + + case transactionAddressSave + + case transactionAddressEdit + + case profileAddressBookPage + + case profileAddressBookAdd + + case profileAddressBookEdit + + case profileAddressBookDelete + + public var name: String { + switch self { + case .transactionAddressSave: + return "Transaction Address Save" + + case .transactionAddressEdit: + return "Transaction Address Edit" + + case .profileAddressBookPage: + return "Profile Address Book Page" + + case .profileAddressBookAdd: + return "Profile Address Book Add" + + case .profileAddressBookEdit: + return "Profile Address Book Edit" + + case .profileAddressBookDelete: + return "Profile Address Book Delete" + } + } + + public var params: [String : String] { + switch self { + + default: + return [:] + } + } + } +} diff --git a/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+Alias.swift b/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+Alias.swift new file mode 100644 index 00000000..6d9c6c75 --- /dev/null +++ b/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+Alias.swift @@ -0,0 +1,21 @@ +// +// Alias.swift +// WavesWallet-iOS +// +// Created by rprokofev on 26.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation + +//MARK: - Alias +public extension AnalyticManagerEvent { + enum Alias: String { + + /* Нажата кнопка «Create a new alias» на экране профайла. */ + case createProfile = "Alias Create Profile" + + /* Нажата кнопка «Create a new alias» на экране визитки. */ + case aliasCreateVcard = "Alias Create Vcard" + } +} diff --git a/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+CreateANewAccount.swift b/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+CreateANewAccount.swift new file mode 100644 index 00000000..d20cad86 --- /dev/null +++ b/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+CreateANewAccount.swift @@ -0,0 +1,36 @@ +// +// AnalyticManagerEvent+CreateANewAccount.swift +// WavesWallet-iOS +// +// Created by rprokofev on 26.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation + +public extension AnalyticManagerEvent { + + enum CreateANewAccount: AnalyticManagerEventInfo { + + /* Проставлены 3 чекбокса с условиями использования и нажата кнопка "Begin". */ + case newUserConfirm + + // При появлении у пользователя сообщения "Нужно забэкапить SEED", отправляем событие + case newUserWithoutBackup(count: UInt) + + public var name: String { + + switch self { + case .newUserConfirm: + return "New User Confirm" + + case .newUserWithoutBackup: + return "New User Without Backup" + } + } + + public var params: [String : String] { + return [:] + } + } +} diff --git a/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+ImportAccount.swift b/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+ImportAccount.swift new file mode 100644 index 00000000..cb028b0b --- /dev/null +++ b/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+ImportAccount.swift @@ -0,0 +1,34 @@ +// +// AnalyticManagerEvent+ImportAccount.swift +// WavesWallet-iOS +// +// Created by rprokofev on 26.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation + +public extension AnalyticManagerEvent { + + enum ImportAccount { + + case startImportScan + case startImportManually + + public var name: String { + + switch self { + case .startImportScan: + return "Start Import Scan" + + case .startImportManually: + return "Start Import Manually" + } + } + + public var params: [String : String] { + return [:] + } + } +} + diff --git a/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+Menu.swift b/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+Menu.swift new file mode 100644 index 00000000..a38f3dbc --- /dev/null +++ b/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+Menu.swift @@ -0,0 +1,77 @@ +// +// Menu.swift +// WavesWallet-iOS +// +// Created by rprokofev on 26.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation + +public extension AnalyticManagerEvent { + enum Menu: AnalyticManagerEventInfo { + + case wavesMenuPage + + case wavesMenuWhitepaper + + case wavesMenuTermsAndConditions + + case wavesMenuSupport + + case wavesMenuGithub + + case wavesMenuTelegram + + case wavesMenuDiscord + + case wavesMenuTwitter + + case wavesMenuReddit + + case wavesMenuForum + + public var name: String { + + switch self { + case .wavesMenuPage: + return "Waves Menu Page" + + case .wavesMenuWhitepaper: + return "Waves Menu Whitepaper" + + case .wavesMenuTermsAndConditions: + return "Waves Menu Terms and Conditions" + + case .wavesMenuSupport: + return "Waves Menu Support" + + case .wavesMenuGithub: + return "Waves Menu Github" + + case .wavesMenuTelegram: + return "Waves Menu Telegram" + + case .wavesMenuDiscord: + return "Waves Menu Discord" + + case .wavesMenuTwitter: + return "Waves Menu Twitter" + + case .wavesMenuReddit: + return "Waves Menu Reddit" + + case .wavesMenuForum: + return "Waves Menu Forum" + } + } + + public var params: [String : String] { + switch self { + + default: + return [:] + } + } + } +} diff --git a/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+Profile.swift b/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+Profile.swift new file mode 100644 index 00000000..bb68b553 --- /dev/null +++ b/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+Profile.swift @@ -0,0 +1,84 @@ +// +// Profile.swift +// WavesWallet-iOS +// +// Created by rprokofev on 26.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation + +public extension AnalyticManagerEvent { + enum Profile: AnalyticManagerEventInfo { + + private static let key = "Currency" + + case profileAddressAndKeys + + case profileLanguage + + case profileBackupPhrase + + case profileChangePassword + + case profileChangePasscode + + case profileNetwork + + case profileRateApp + + case profileFeedback + + case profileSupport + + case profileDeleteAccount + + case profileLogoutUp + + case profileLogoutDown + + public var name: String { + switch self { + case .profileAddressAndKeys: + return "Profile Address and Keys" + + case .profileLanguage: + return "Profile Language" + + case .profileBackupPhrase: + return "Profile Backup Phrase" + + case .profileChangePassword: + return "Profile Change Password" + + case .profileChangePasscode: + return "profileChangePasscode" + + case .profileNetwork: + return "Profile Network" + + case .profileRateApp: + return "Profile Rate App" + + case .profileFeedback: + return "Profile Feedback" + + case .profileSupport: + return "Profile Support" + + case .profileDeleteAccount: + return "Profile Delete Account" + + case .profileLogoutUp: + return "Profile Logout Up" + + case .profileLogoutDown: + return "Profile Logout Down" + } + } + + public var params: [String : String] { + return [:] + } + } +} diff --git a/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+Receive.swift b/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+Receive.swift new file mode 100644 index 00000000..6b5a4450 --- /dev/null +++ b/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+Receive.swift @@ -0,0 +1,46 @@ +// +// Receive.swift +// WavesWallet-iOS +// +// Created by rprokofev on 26.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation + +public extension AnalyticManagerEvent { + + enum Receive: AnalyticManagerEventInfo { + + private static let key = "Currency" + + /* Нажата кнопка «Continue» у любой криптовалюты или токена. */ + case receiveTap(assetName: String) + + /* Нажата кнопка «Continue» на экране с заполненными полями карты. */ + case cardReceiveTap + + + public var name: String { + switch self { + + case .receiveTap: + return "Wallet Assets Receive Tap" + + case .cardReceiveTap: + return "Wallet Assets Card Receive Tap" + } + } + + public var params: [String : String] { + switch self { + + case .receiveTap(let assetName): + return [Receive.key: assetName] + + default: + return [:] + } + } + } +} diff --git a/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+Send.swift b/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+Send.swift new file mode 100644 index 00000000..b10db8bc --- /dev/null +++ b/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+Send.swift @@ -0,0 +1,43 @@ +// +// Send.swift +// WavesWallet-iOS +// +// Created by rprokofev on 26.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation + +public extension AnalyticManagerEvent { + + enum Send: AnalyticManagerEventInfo { + + private static let key = "Currency" + + /* Нажата кнопка «Continue» у любой криптовалюты или токена. */ + case sendTap(assetName: String) + + /* Нажата кнопка «Confirm» у любой криптовалюты или токена. */ + case sendConfirm(assetName: String) + + public var name: String { + switch self { + case .sendTap: + return "Wallet Assets Send Tap" + + case .sendConfirm: + return "Wallet Assets Send Confirm" + } + } + + public var params: [String : String] { + switch self { + case .sendTap(let assetName): + return [Send.key: assetName] + + case .sendConfirm(let assetName): + return [Send.key: assetName] + } + } + } +} diff --git a/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+SingIn.swift b/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+SingIn.swift new file mode 100644 index 00000000..ba084da9 --- /dev/null +++ b/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+SingIn.swift @@ -0,0 +1,44 @@ +// +// SingIn.swift +// WavesWallet-iOS +// +// Created by rprokofev on 26.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation + +public extension AnalyticManagerEvent { + + enum SingIn { + + case startAccountEdit + case startAccountDelete + case startAccountCounter(Int) + + public var name: String { + + switch self { + case .startAccountEdit: + return "Start Account Edit" + + case .startAccountDelete: + return "Start Account Delete" + + case .startAccountCounter: + return "Start Account Counter" + } + } + + public var params: [String : String] { + switch self { + case .startAccountCounter(let count): + return ["Count" : "\(count)"] + + default: + return [:] + } + } + } +} + diff --git a/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+TokenBurn.swift b/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+TokenBurn.swift new file mode 100644 index 00000000..f16ef1f9 --- /dev/null +++ b/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+TokenBurn.swift @@ -0,0 +1,24 @@ +// +// TokenBurn.swift +// WavesWallet-iOS +// +// Created by rprokofev on 26.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation + +//MARK: - TokenBurn +public extension AnalyticManagerEvent { + enum TokenBurn: String { + + /* Нажата кнопка «Token Burn» на экране ассета. */ + case tap = "Burn Token Tap" + + /* Нажата кнопка «Burn» на экране с заполненными полями. */ + case continueTap = "Burn Token Continue Tap" + + /* Нажата кнопка «Burn» на экране подтверждения. */ + case confirmTap = "Burn Token Confirm Tap" + } +} diff --git a/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+WalletHome.swift b/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+WalletHome.swift new file mode 100644 index 00000000..ff63173c --- /dev/null +++ b/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+WalletHome.swift @@ -0,0 +1,61 @@ +// +// WalletHome.swift +// WavesWallet-iOS +// +// Created by rprokofev on 26.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation + +public extension AnalyticManagerEvent { + enum WalletHome: AnalyticManagerEventInfo { + + private enum Constants { + static let currency = "Currency" + } + + case updateBanner + case tokenSearch + case tokenSortingPage + case tokenSortingPosition + case tokenSortingVisability + case qrCard + case startBalanceFromZero(assetName: String) + + public var name: String { + switch self { + case .updateBanner: + return "Wallet Update Banner" + + case .tokenSearch: + return "Wallet Token Search" + + case .tokenSortingPage: + return "Wallet Token Sorting Page" + + case .tokenSortingPosition: + return "Wallet Token Sorting Position" + + case .tokenSortingVisability: + return "Wallet Token Sorting Visability" + + case .qrCard: + return "Wallet QRCard" + + case .startBalanceFromZero: + return "Wallet Start Balance from Zero" + } + } + + public var params: [String : String] { + switch self { + case .startBalanceFromZero(let assetName): + return [Constants.currency: assetName] + + default: + return [:] + } + } + } +} diff --git a/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+WalletLeasing.swift b/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+WalletLeasing.swift new file mode 100644 index 00000000..0c1cbd75 --- /dev/null +++ b/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+WalletLeasing.swift @@ -0,0 +1,24 @@ +// +// WalletLeasing.swift +// WavesWallet-iOS +// +// Created by rprokofev on 26.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation + +//MARK: - Leasing +public extension AnalyticManagerEvent { + enum WalletLeasing: String { + + /* Нажата кнопка «Start Lease» на экране Wallet. */ + case leasingStartTap = "Leasing Start Tap" + + /* Нажата кнопка «Start Lease» на экране с заполненными полями. */ + case leasingSendTap = "Leasing Send Tap" + + /* Нажата кнопка «Confirm» на экране подтверждения лизинга. */ + case leasingConfirmTap = "Leasing Confirm Tap" + } +} diff --git a/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+WavesQuickAction.swift b/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+WavesQuickAction.swift new file mode 100644 index 00000000..fbc7a8fe --- /dev/null +++ b/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+WavesQuickAction.swift @@ -0,0 +1,40 @@ +// +// WavesQuickAction.swift +// WavesWallet-iOS +// +// Created by rprokofev on 26.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation + +public extension AnalyticManagerEvent { + + enum WavesQuickAction: AnalyticManagerEventInfo { + + private static let key = "Currency" + + case wavesActionPanel + + case wavesActionSend + + case wavesActionReceive + + public var name: String { + switch self { + case .wavesActionPanel: + return "Waves Action Panel" + + case .wavesActionSend: + return "Waves Action Send" + + case .wavesActionReceive: + return "Waves Action Receive" + } + } + + public var params: [String : String] { + return [:] + } + } +} diff --git a/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+Widgets.swift b/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+Widgets.swift new file mode 100644 index 00000000..98871839 --- /dev/null +++ b/DomainLayer/Sources/AnalyticManager/AnalyticManagerEvent+Widgets.swift @@ -0,0 +1,80 @@ +// +// Widgets.swift +// WavesWallet-iOS +// +// Created by rprokofev on 26.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation + +public extension AnalyticManagerEvent { + enum Widgets: AnalyticManagerEventInfo { + + public enum Style { + case dark + case classic + } + + public enum Interval { + case m1 + case m5 + case m10 + case manually + + public var title: String { + switch self { + case .m1: + return "1m" + + case .m5: + return "5m" + + case .m10: + return "10m" + + case .manually: + return "manually" + } + } + } + + public typealias AssetsIds = [String] + + + case marketPulseActive + case marketPulseAdded + case marketPulseRemoved + case marketPulseChanged(Style, Interval, AssetsIds) + + public var name: String { + + switch self { + case .marketPulseActive: + return "Market Pulse Active" + + case .marketPulseAdded: + return "Market Pulse Added" + + case .marketPulseRemoved: + return "Market Pulse Removed" + + case .marketPulseChanged: + return "Market Pulse Settings Changed" + } + } + + public var params: [String : String] { + switch self { + + case .marketPulseChanged(let style, let interval, let assetsIds): + return ["Style": style == .classic ? "Classic" : "Dark", + "Interval": interval.title, + "Assets": assetsIds.joined(separator: ",")] + + default: + return [:] + } + } + } +} diff --git a/DomainLayer/Sources/AnalyticManager/AnalyticManagerProtocol.swift b/DomainLayer/Sources/AnalyticManager/AnalyticManagerProtocol.swift new file mode 100644 index 00000000..100c460c --- /dev/null +++ b/DomainLayer/Sources/AnalyticManager/AnalyticManagerProtocol.swift @@ -0,0 +1,142 @@ +// +// AnalyticManagerProtocol.swift +// WavesWallet-iOS +// +// Created by rprokofev on 20.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation + +public enum AnalyticManagerEvent { + + case createANewAccount(CreateANewAccount) + case importAccount(ImportAccount) + case singIn(SingIn) + case walletHome(WalletHome) + case walletLeasing(WalletLeasing) + case tokenBurn(TokenBurn) + case alias(Alias) + case dex(Dex) + case send(Send) + case receive(Receive) + case wavesQuickAction(WavesQuickAction) + case profile(Profile) + case addressBook(AddressBook) + case menu(Menu) + case widgets(Widgets) +} + +public protocol AnalyticManagerEventInfo { + var name: String { get } + var params: [String : String] { get } +} + +public protocol AnalyticManagerProtocol { + + func setAUUID(_ AUUID: String) + + func trackEvent(_ event: AnalyticManagerEvent) +} + +//MARK - Event params +extension AnalyticManagerEvent: AnalyticManagerEventInfo { + + public var name: String { + switch self { + case .createANewAccount(let model): + return model.name + + case .importAccount(let model): + return model.name + + case .singIn(let model): + return model.name + + case .walletHome(let model): + return model.name + + case .walletLeasing(let model): + return model.rawValue + + case .tokenBurn(let model): + return model.rawValue + + case .alias(let model): + return model.rawValue + + case .dex(let model): + return model.name + + case .send(let model): + return model.name + + case .receive(let model): + return model.name + + case .wavesQuickAction(let model): + return model.name + + case .profile(let model): + return model.name + + case .addressBook(let model): + return model.name + + case .menu(let model): + return model.name + + case .widgets(let model): + return model.name + } + } + + public var params: [String : String] { + switch self { + case .createANewAccount(let model): + return model.params + + case .importAccount(let model): + return model.params + + case .singIn(let model): + return model.params + + case .walletHome(let model): + return model.params + + case .walletLeasing( _): + return [:] + + case .tokenBurn( _): + return [:] + + case .alias( _): + return [:] + + case .dex(let model): + return model.params + + case .send(let model): + return model.params + + case .receive(let model): + return model.params + + case .wavesQuickAction(let model): + return model.params + + case .profile(let model): + return model.params + + case .addressBook(let model): + return model.params + + case .menu(let model): + return model.params + + case .widgets(let model): + return model.params + } + } +} diff --git a/DomainLayer/Sources/Assisstants/ApplicationDebugSettings.swift b/DomainLayer/Sources/Assisstants/ApplicationDebugSettings.swift new file mode 100644 index 00000000..d13c7d74 --- /dev/null +++ b/DomainLayer/Sources/Assisstants/ApplicationDebugSettings.swift @@ -0,0 +1,103 @@ +// +// ApplicationDebugSettings.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 3/28/19. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import Extensions +import WavesSDKExtensions + + +public struct ApplicationDebugSettings: TSUD, Codable, Mutating { + + private static let key: String = "com.waves.debug.settings" + + private var isEnableStage: Bool = false + private var isEnableNotificationsSettingTest: Bool = false + private var isEnableEnviromentTest: Bool = false + private var isEnableVersionUpdateTest: Bool = false + private var debugButtonPosition: CGPoint? = nil + + public static var defaultValue: ApplicationDebugSettings { + return ApplicationDebugSettings(isEnableStage: false, + isEnableNotificationsSettingTest: false, + debugButtonPosition: nil, + isEnableEnviromentTest: false, + isEnableVersionUpdateTest: false) + } + + public static var stringKey: String { + return key + } + + public static var isEnableStage: Bool { + return ApplicationDebugSettings.get().isEnableStage + } + + public static var debugButtonPosition: CGPoint? { + + get { + return ApplicationDebugSettings.get().debugButtonPosition + } + + set { + var settings = ApplicationDebugSettings.get() + settings.debugButtonPosition = newValue + ApplicationDebugSettings.set(settings) + } + } + + public init() {} + + public init(isEnableStage: Bool, + isEnableNotificationsSettingTest: Bool, + debugButtonPosition: CGPoint?, + isEnableEnviromentTest: Bool, + isEnableVersionUpdateTest: Bool) { + self.isEnableStage = isEnableStage + self.isEnableEnviromentTest = isEnableEnviromentTest + self.isEnableVersionUpdateTest = isEnableVersionUpdateTest + self.isEnableNotificationsSettingTest = isEnableNotificationsSettingTest + self.debugButtonPosition = debugButtonPosition + } + + + public static func setupIsEnableStage(isEnable: Bool) { + var settings = ApplicationDebugSettings.get() + settings.isEnableStage = isEnable + ApplicationDebugSettings.set(settings) + } + + public static var isEnableNotificationsSettingTest: Bool { + return ApplicationDebugSettings.get().isEnableNotificationsSettingTest + } + + public static func setEnableNotificationsSettingTest(isEnable: Bool) { + var settings = ApplicationDebugSettings.get() + settings.isEnableNotificationsSettingTest = isEnable + ApplicationDebugSettings.set(settings) + } + + public static var isEnableEnviromentTest: Bool { + return ApplicationDebugSettings.get().isEnableEnviromentTest + } + + public static func setEnableEnviromentTest(isEnable: Bool) { + var settings = ApplicationDebugSettings.get() + settings.isEnableEnviromentTest = isEnable + ApplicationDebugSettings.set(settings) + } + + public static var isEnableVersionUpdateTest: Bool { + return ApplicationDebugSettings.get().isEnableVersionUpdateTest + } + + public static func setEnableVersionUpdateTest(isEnable: Bool) { + var settings = ApplicationDebugSettings.get() + settings.isEnableVersionUpdateTest = isEnable + ApplicationDebugSettings.set(settings) + } +} diff --git a/WavesWallet-iOS/DomainLayer/Assisstants/BiometricManager.swift b/DomainLayer/Sources/Assisstants/BiometricManager.swift similarity index 82% rename from WavesWallet-iOS/DomainLayer/Assisstants/BiometricManager.swift rename to DomainLayer/Sources/Assisstants/BiometricManager.swift index d53f9ef6..bc4f34e9 100644 --- a/WavesWallet-iOS/DomainLayer/Assisstants/BiometricManager.swift +++ b/DomainLayer/Sources/Assisstants/BiometricManager.swift @@ -8,14 +8,15 @@ import Foundation import LocalAuthentication +import Extensions -enum BiometricType { +public enum BiometricType { case none case touchID case faceID } -extension BiometricType { +public extension BiometricType { static var biometricByDevice: BiometricType { get { @@ -48,6 +49,8 @@ extension BiometricType { return .touchID case .faceID: return .faceID + @unknown default: + return .none } } else { return result ? .touchID : .none @@ -56,13 +59,9 @@ extension BiometricType { } } -final class BiometricManager { +public final class BiometricManager { - static var touchIDTypeText: String { - return type == .faceID ? Localizable.Waves.General.Biometric.Faceid.title : Localizable.Waves.General.Biometric.Touchid.title - } - - static var type: BiometricType { + public static var type: BiometricType { get { return BiometricType.enabledBiometric } diff --git a/WavesWallet-iOS/DomainLayer/Assisstants/CleanerWalletManager.swift b/DomainLayer/Sources/Assisstants/CleanerWalletManager.swift similarity index 76% rename from WavesWallet-iOS/DomainLayer/Assisstants/CleanerWalletManager.swift rename to DomainLayer/Sources/Assisstants/CleanerWalletManager.swift index e7efb7b2..14bd5ce0 100644 --- a/WavesWallet-iOS/DomainLayer/Assisstants/CleanerWalletManager.swift +++ b/DomainLayer/Sources/Assisstants/CleanerWalletManager.swift @@ -7,31 +7,32 @@ // import Foundation -import WavesSDKExtension import RxSwift +import WavesSDKExtensions +import Extensions extension CleanerWalletManager: ReactiveCompatible {} -struct CleanerWalletManager: TSUD, Codable, Mutating { +public struct CleanerWalletManager: TSUD, Codable, Mutating { private static let key = "com.waves.cleanwallet.settings" fileprivate var cleanAccounts: Set = Set() - init() { + public init() { self.cleanAccounts = .init() } - static var defaultValue: CleanerWalletManager { + public static var defaultValue: CleanerWalletManager { return CleanerWalletManager() } - static var stringKey: String { + public static var stringKey: String { return key } - static func setCleanWallet(accountAddress: String, isClean: Bool) { + public static func setCleanWallet(accountAddress: String, isClean: Bool) { var settings = CleanerWalletManager.get() if isClean { @@ -45,14 +46,14 @@ struct CleanerWalletManager: TSUD, Codable, Mutating { CleanerWalletManager.set(settings) } - static func isCleanWallet(by accountAddress: String) -> Bool { + public static func isCleanWallet(by accountAddress: String) -> Bool { return CleanerWalletManager.get().cleanAccounts.contains(accountAddress) } } extension Reactive where Base == CleanerWalletManager { - static func setCleanWallet(accountAddress: String, isClean: Bool) -> Observable { + public static func setCleanWallet(accountAddress: String, isClean: Bool) -> Observable { return CleanerWalletManager.rx.get() .flatMap({ (settings) -> Observable in @@ -69,7 +70,7 @@ extension Reactive where Base == CleanerWalletManager { }) } - static func isCleanWallet(by accountAddress: String) -> Observable { + public static func isCleanWallet(by accountAddress: String) -> Observable { return Observable.create({ (subscribe) -> Disposable in subscribe.onNext(CleanerWalletManager.get().cleanAccounts.contains(accountAddress)) diff --git a/DomainLayer/Sources/Assisstants/CleanerWalletManagerBanner.swift b/DomainLayer/Sources/Assisstants/CleanerWalletManagerBanner.swift new file mode 100644 index 00000000..ca2c1769 --- /dev/null +++ b/DomainLayer/Sources/Assisstants/CleanerWalletManagerBanner.swift @@ -0,0 +1,62 @@ +// +// CleanerWalletManager.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 4/17/19. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import WavesSDKExtensions +import Extensions + +extension CleanerWalletManagerBanner: ReactiveCompatible {} + +public struct CleanerWalletManagerBanner: TSUD, Codable, Mutating { + + private static let key = "com.waves.cleanwalletbanner.settings" + + fileprivate var cleanAccounts: Set = Set() + + public init() { + self.cleanAccounts = .init() + } + + public static var defaultValue: CleanerWalletManagerBanner { + return CleanerWalletManagerBanner() + } + + public static var stringKey: String { + return key + } +} + +public extension Reactive where Base == CleanerWalletManagerBanner { + + static func setCleanWalletBanner(accountAddress: String, isClean: Bool) -> Observable { + return CleanerWalletManagerBanner.rx.get() + .flatMap({ (settings) -> Observable in + + var newSettings = settings + if isClean { + if newSettings.cleanAccounts.contains(accountAddress) == false { + newSettings.cleanAccounts.insert(accountAddress) + } + } + else { + newSettings.cleanAccounts.remove(accountAddress) + } + return CleanerWalletManagerBanner.rx.set(newSettings) + }) + } + + static func isCleanWalletBanner(by accountAddress: String) -> Observable { + return Observable.create({ (subscribe) -> Disposable in + + subscribe.onNext(CleanerWalletManagerBanner.get().cleanAccounts.contains(accountAddress)) + subscribe.onCompleted() + return Disposables.create() + }) + } +} diff --git a/DomainLayer/Sources/Assisstants/ClientCrypto/Address.swift b/DomainLayer/Sources/Assisstants/ClientCrypto/Address.swift new file mode 100644 index 00000000..8c42f12f --- /dev/null +++ b/DomainLayer/Sources/Assisstants/ClientCrypto/Address.swift @@ -0,0 +1,76 @@ +// +// Address.swift +// Base58 +// +// Created by rprokofev on 11/04/2019. +// + +import Foundation +import WavesSDK +import WavesSDKCrypto + +public class Address { + static let AddressVersion: UInt8 = 1 + static let ChecksumLength = 4 + static let HashLength = 20 + static let AddressLength = 1 + 1 + HashLength + ChecksumLength + + //TODO: Refactor + public static var walletEnvironment: WalletEnvironment! + + private class func getSchemeByte() -> UInt8 { + return walletEnvironment.scheme.utf8.first! + } + + public class func addressFromPublicKey(publicKey: [UInt8]) -> String { + let publicKeyHash = Hash.secureHash(publicKey)[0.. [UInt8] { + return Array(Hash.secureHash(withoutChecksum)[0.. Bool { + guard let alias = alias else { return false } + + return RegEx.alias(alias) && + alias.count >= WavesSDKConstants.aliasNameMinLimitSymbols && + alias.count <= WavesSDKConstants.aliasNameMaxLimitSymbols + } + private class func isValidAddress(address: String?, schemeBytes: UInt8) -> Bool { + guard let address = address else { return false } + + let bytes = Base58Encoder.decode(address) + if bytes.count == AddressLength + && bytes[0] == AddressVersion + && bytes[1] == schemeBytes { + let checkSum = Array(bytes[bytes.count - ChecksumLength.. Bool { + return isValidAddress(address: address, schemeBytes: getSchemeByte()) + } + + public class func isValidVostokAddress(address: String?) -> Bool { + return isValidAddress(address: address, schemeBytes: walletEnvironment.vostokScheme.utf8.first!) + } + + public class func scheme(from publicKey: String) -> String? { + + let address = Address.addressFromPublicKey(publicKey: publicKey.bytes) + let bytes = Base58Encoder.decode(address) + guard bytes.count == AddressLength else { return nil } + guard bytes[0] == AddressVersion else { return nil } + let schemeBytes = bytes[1] + let data = Data(bytes: [schemeBytes]) + guard let scheme = String(data: data, encoding: .utf8) else { return nil } + + return scheme + } +} diff --git a/DomainLayer/Sources/Assisstants/ClientCrypto/Data+AES.swift b/DomainLayer/Sources/Assisstants/ClientCrypto/Data+AES.swift new file mode 100644 index 00000000..fdcb01e2 --- /dev/null +++ b/DomainLayer/Sources/Assisstants/ClientCrypto/Data+AES.swift @@ -0,0 +1,86 @@ +// +// Data+AES.swift +// WavesWallet-iOS +// +// Created by Prokofev Ruslan on 23/09/2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import WavesSDKCrypto +import Foundation +import CryptoSwift + +fileprivate enum Constants { + static let iterations: Int = 5000 + static let keyLength: Int = 32 +} + +public extension Data { + + func aesEncrypt(withKey key: String) -> Data? { + + let iv: Array = AES.randomIV(AES.blockSize) + let keyBytes = try! PKCS5.PBKDF2(password: key.bytes, + salt: iv, + iterations: Constants.iterations, + keyLength: Constants.keyLength, + variant: .sha256).calculate() + + do { + let aes = try AES(key: keyBytes, blockMode: CBC(iv: iv)) + let encrypt = try aes.encrypt(self.bytes) + + var combine = [UInt8]() + combine.append(contentsOf: iv) + combine.append(contentsOf: encrypt) + return Base58Encoder.encode(combine).data(using: .utf8) + } catch _ { + return nil + } + } + + func aesDecrypt(withKey key: String) -> Data? { + + guard let stringFromData = String(data: self, encoding: .utf8) else { return nil } + + let dataBase58 = Base58Encoder.decode(stringFromData) + + let iv: Array = Array(dataBase58[0.. String? { + guard let data = self.data(using: .utf8) else { return nil } + guard let encrypt = data.aesEncrypt(withKey: key) else { return nil } + + return String(data: encrypt, encoding: .utf8) + } + + func aesDecrypt(withKey key: String) -> String? { + guard let data = self.data(using: .utf8) else { return nil } + guard let decrypt = data.aesDecrypt(withKey: key) else { return nil } + + return String(data: decrypt, encoding: .utf8) + } +} diff --git a/DomainLayer/Sources/Assisstants/ClientCrypto/Hash.swift b/DomainLayer/Sources/Assisstants/ClientCrypto/Hash.swift new file mode 100644 index 00000000..11e7be2f --- /dev/null +++ b/DomainLayer/Sources/Assisstants/ClientCrypto/Hash.swift @@ -0,0 +1,59 @@ +// +// Hash.swift +// WavesWallet-iOS +// +// Created by Alexey Koloskov on 11/04/2017. +// Copyright © 2017 Waves Platform. All rights reserved. +// + +import Foundation +import WavesSDKCrypto +import CommonCrypto + +public class Hash { + + public static func secureHash(_ input: [UInt8]) -> [UInt8] { + var data = Data(count: 32) + var key: UInt8 = 0 + data.withUnsafeMutableBytes {(bytes: UnsafeMutablePointer)->Void in + crypto_generichash_blake2b(bytes, 32, input, UInt64(input.count), &key, 0) + } + var res = Data(count: 32) + res.withUnsafeMutableBytes {(bytes: UnsafeMutablePointer)->Void in + keccak(Array(data), Int32(data.count), bytes, 32) + } + return Array(res) + } + + public static func fastHash(_ input: [UInt8]) -> [UInt8] { + var res = Data(count: 32) + var key: UInt8 = 0 + res.withUnsafeMutableBytes {(bytes: UnsafeMutablePointer)->Void in + crypto_generichash_blake2b(bytes, 32, input, UInt64(input.count), &key, 0) + } + return Array(res) + } + + public static func sign(_ input: [UInt8], _ key: [UInt8]) -> [UInt8] { + return Array(Curve25519.sign(Data(input), withPrivateKey: Data(key))) + } + + public static func sha256(_ data: [UInt8]) -> [UInt8] { + + let len = Int(CC_SHA256_DIGEST_LENGTH) + var digest = [UInt8](repeating: 0, count: len) + + CC_SHA256(data, CC_LONG(data.count), &digest) + + return Array(digest[0.. [UInt8] { + let len = Int(CC_SHA512_DIGEST_LENGTH) + var digest = [UInt8](repeating: 0, count: len) + + CC_SHA512(data, CC_LONG(data.count), &digest) + + return Array(digest[0.. String { + return Base58Encoder.encode(publicKey) + } + + public var hashValue: Int { + return address.hashValue + } + + public static func == (lhs: PublicKeyAccount, rhs: PublicKeyAccount) -> Bool { + return lhs.address == rhs.address + } +} diff --git a/DomainLayer/Sources/Assisstants/ClientCrypto/RXCrypto+SHA.swift b/DomainLayer/Sources/Assisstants/ClientCrypto/RXCrypto+SHA.swift new file mode 100644 index 00000000..b105d520 --- /dev/null +++ b/DomainLayer/Sources/Assisstants/ClientCrypto/RXCrypto+SHA.swift @@ -0,0 +1,39 @@ +// +// String+SHA.swift +// WavesWallet-iOS +// +// Created by mefilt on 26/09/2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import WavesSDKCrypto +import RxSwift +import WavesSDKExtensions + +public enum Crypto {} +extension Crypto: ReactiveCompatible {} + +public extension Reactive where Base == Crypto { + + static func sha256(_ string: String) -> Observable { + return Observable.create({ observer -> Disposable in + + observer.onNext(string.sha256()) + observer.onCompleted() + + return Disposables.create() + }) + } + + static func sha512(_ string: String) -> Observable { + return Observable.create({ observer -> Disposable in + + observer.onNext(string.sha512()) + observer.onCompleted() + + return Disposables.create() + }) + } +} + diff --git a/DomainLayer/Sources/Assisstants/ClientCrypto/WordList.swift b/DomainLayer/Sources/Assisstants/ClientCrypto/WordList.swift new file mode 100644 index 00000000..59d8b107 --- /dev/null +++ b/DomainLayer/Sources/Assisstants/ClientCrypto/WordList.swift @@ -0,0 +1,242 @@ +// +// WordList.swift +// WavesWallet-iOS +// +// Created by Alexey Koloskov on 20/04/2017. +// Copyright © 2017 Waves Platform. All rights reserved. +// + +import Foundation +import Security + +public final class WordList { + static private let wordList = ["abandon", "ability", "able", "about", "above", "absent", "absorb", "abstract", "absurd", "abuse", "access", + "accident", "account", "accuse", "achieve", "acid", "acoustic", "acquire", "across", "act", "action", + "actor", "actress", "actual", "adapt", "add", "addict", "address", "adjust", "admit", "adult", "advance", + "advice", "aerobic", "affair", "afford", "afraid", "again", "age", "agent", "agree", "ahead", "aim", "air", + "airport", "aisle", "alarm", "album", "alcohol", "alert", "alien", "all", "alley", "allow", "almost", + "alone", "alpha", "already", "also", "alter", "always", "amateur", "amazing", "among", "amount", "amused", + "analyst", "anchor", "ancient", "anger", "angle", "angry", "animal", "ankle", "announce", "annual", + "another", "answer", "antenna", "antique", "anxiety", "any", "apart", "apology", "appear", "apple", + "approve", "april", "arch", "arctic", "area", "arena", "argue", "arm", "armed", "armor", "army", "around", + "arrange", "arrest", "arrive", "arrow", "art", "artefact", "artist", "artwork", "ask", "aspect", "assault", + "asset", "assist", "assume", "asthma", "athlete", "atom", "attack", "attend", "attitude", "attract", + "auction", "audit", "august", "aunt", "author", "auto", "autumn", "average", "avocado", "avoid", "awake", + "aware", "away", "awesome", "awful", "awkward", "axis", "baby", "bachelor", "bacon", "badge", "bag", + "balance", "balcony", "ball", "bamboo", "banana", "banner", "bar", "barely", "bargain", "barrel", "base", + "basic", "basket", "battle", "beach", "bean", "beauty", "because", "become", "beef", "before", "begin", + "behave", "behind", "believe", "below", "belt", "bench", "benefit", "best", "betray", "better", "between", + "beyond", "bicycle", "bid", "bike", "bind", "biology", "bird", "birth", "bitter", "black", "blade", "blame", + "blanket", "blast", "bleak", "bless", "blind", "blood", "blossom", "blouse", "blue", "blur", "blush", + "board", "boat", "body", "boil", "bomb", "bone", "bonus", "book", "boost", "border", "boring", "borrow", + "boss", "bottom", "bounce", "box", "boy", "bracket", "brain", "brand", "brass", "brave", "bread", "breeze", + "brick", "bridge", "brief", "bright", "bring", "brisk", "broccoli", "broken", "bronze", "broom", "brother", + "brown", "brush", "bubble", "buddy", "budget", "buffalo", "build", "bulb", "bulk", "bullet", "bundle", + "bunker", "burden", "burger", "burst", "bus", "business", "busy", "butter", "buyer", "buzz", "cabbage", + "cabin", "cable", "cactus", "cage", "cake", "call", "calm", "camera", "camp", "can", "canal", "cancel", + "candy", "cannon", "canoe", "canvas", "canyon", "capable", "capital", "captain", "car", "carbon", "card", + "cargo", "carpet", "carry", "cart", "case", "cash", "casino", "castle", "casual", "cat", "catalog", "catch", + "category", "cattle", "caught", "cause", "caution", "cave", "ceiling", "celery", "cement", "census", + "century", "cereal", "certain", "chair", "chalk", "champion", "change", "chaos", "chapter", "charge", + "chase", "chat", "cheap", "check", "cheese", "chef", "cherry", "chest", "chicken", "chief", "child", + "chimney", "choice", "choose", "chronic", "chuckle", "chunk", "churn", "cigar", "cinnamon", "circle", + "citizen", "city", "civil", "claim", "clap", "clarify", "claw", "clay", "clean", "clerk", "clever", "click", + "client", "cliff", "climb", "clinic", "clip", "clock", "clog", "close", "cloth", "cloud", "clown", "club", + "clump", "cluster", "clutch", "coach", "coast", "coconut", "code", "coffee", "coil", "coin", "collect", + "color", "column", "combine", "come", "comfort", "comic", "common", "company", "concert", "conduct", + "confirm", "congress", "connect", "consider", "control", "convince", "cook", "cool", "copper", "copy", + "coral", "core", "corn", "correct", "cost", "cotton", "couch", "country", "couple", "course", "cousin", + "cover", "coyote", "crack", "cradle", "craft", "cram", "crane", "crash", "crater", "crawl", "crazy", + "cream", "credit", "creek", "crew", "cricket", "crime", "crisp", "critic", "crop", "cross", "crouch", + "crowd", "crucial", "cruel", "cruise", "crumble", "crunch", "crush", "cry", "crystal", "cube", "culture", + "cup", "cupboard", "curious", "current", "curtain", "curve", "cushion", "custom", "cute", "cycle", "dad", + "damage", "damp", "dance", "danger", "daring", "dash", "daughter", "dawn", "day", "deal", "debate", + "debris", "decade", "december", "decide", "decline", "decorate", "decrease", "deer", "defense", "define", + "defy", "degree", "delay", "deliver", "demand", "demise", "denial", "dentist", "deny", "depart", "depend", + "deposit", "depth", "deputy", "derive", "describe", "desert", "design", "desk", "despair", "destroy", + "detail", "detect", "develop", "device", "devote", "diagram", "dial", "diamond", "diary", "dice", "diesel", + "diet", "differ", "digital", "dignity", "dilemma", "dinner", "dinosaur", "direct", "dirt", "disagree", + "discover", "disease", "dish", "dismiss", "disorder", "display", "distance", "divert", "divide", "divorce", + "dizzy", "doctor", "document", "dog", "doll", "dolphin", "domain", "donate", "donkey", "donor", "door", + "dose", "double", "dove", "draft", "dragon", "drama", "drastic", "draw", "dream", "dress", "drift", "drill", + "drink", "drip", "drive", "drop", "drum", "dry", "duck", "dumb", "dune", "during", "dust", "dutch", "duty", + "dwarf", "dynamic", "eager", "eagle", "early", "earn", "earth", "easily", "east", "easy", "echo", "ecology", + "economy", "edge", "edit", "educate", "effort", "egg", "eight", "either", "elbow", "elder", "electric", + "elegant", "element", "elephant", "elevator", "elite", "else", "embark", "embody", "embrace", "emerge", + "emotion", "employ", "empower", "empty", "enable", "enact", "end", "endless", "endorse", "enemy", "energy", + "enforce", "engage", "engine", "enhance", "enjoy", "enlist", "enough", "enrich", "enroll", "ensure", + "enter", "entire", "entry", "envelope", "episode", "equal", "equip", "era", "erase", "erode", "erosion", + "error", "erupt", "escape", "essay", "essence", "estate", "eternal", "ethics", "evidence", "evil", "evoke", + "evolve", "exact", "example", "excess", "exchange", "excite", "exclude", "excuse", "execute", "exercise", + "exhaust", "exhibit", "exile", "exist", "exit", "exotic", "expand", "expect", "expire", "explain", "expose", + "express", "extend", "extra", "eye", "eyebrow", "fabric", "face", "faculty", "fade", "faint", "faith", + "fall", "false", "fame", "family", "famous", "fan", "fancy", "fantasy", "farm", "fashion", "fat", "fatal", + "father", "fatigue", "fault", "favorite", "feature", "february", "federal", "fee", "feed", "feel", "female", + "fence", "festival", "fetch", "fever", "few", "fiber", "fiction", "field", "figure", "file", "film", + "filter", "final", "find", "fine", "finger", "finish", "fire", "firm", "first", "fiscal", "fish", "fit", + "fitness", "fix", "flag", "flame", "flash", "flat", "flavor", "flee", "flight", "flip", "float", "flock", + "floor", "flower", "fluid", "flush", "fly", "foam", "focus", "fog", "foil", "fold", "follow", "food", + "foot", "force", "forest", "forget", "fork", "fortune", "forum", "forward", "fossil", "foster", "found", + "fox", "fragile", "frame", "frequent", "fresh", "friend", "fringe", "frog", "front", "frost", "frown", + "frozen", "fruit", "fuel", "fun", "funny", "furnace", "fury", "future", "gadget", "gain", "galaxy", + "gallery", "game", "gap", "garage", "garbage", "garden", "garlic", "garment", "gas", "gasp", "gate", + "gather", "gauge", "gaze", "general", "genius", "genre", "gentle", "genuine", "gesture", "ghost", "giant", + "gift", "giggle", "ginger", "giraffe", "girl", "give", "glad", "glance", "glare", "glass", "glide", + "glimpse", "globe", "gloom", "glory", "glove", "glow", "glue", "goat", "goddess", "gold", "good", "goose", + "gorilla", "gospel", "gossip", "govern", "gown", "grab", "grace", "grain", "grant", "grape", "grass", + "gravity", "great", "green", "grid", "grief", "grit", "grocery", "group", "grow", "grunt", "guard", "guess", + "guide", "guilt", "guitar", "gun", "gym", "habit", "hair", "half", "hammer", "hamster", "hand", "happy", + "harbor", "hard", "harsh", "harvest", "hat", "have", "hawk", "hazard", "head", "health", "heart", "heavy", + "hedgehog", "height", "hello", "helmet", "help", "hen", "hero", "hidden", "high", "hill", "hint", "hip", + "hire", "history", "hobby", "hockey", "hold", "hole", "holiday", "hollow", "home", "honey", "hood", "hope", + "horn", "horror", "horse", "hospital", "host", "hotel", "hour", "hover", "hub", "huge", "human", "humble", + "humor", "hundred", "hungry", "hunt", "hurdle", "hurry", "hurt", "husband", "hybrid", "ice", "icon", "idea", + "identify", "idle", "ignore", "ill", "illegal", "illness", "image", "imitate", "immense", "immune", + "impact", "impose", "improve", "impulse", "inch", "include", "income", "increase", "index", "indicate", + "indoor", "industry", "infant", "inflict", "inform", "inhale", "inherit", "initial", "inject", "injury", + "inmate", "inner", "innocent", "input", "inquiry", "insane", "insect", "inside", "inspire", "install", + "intact", "interest", "into", "invest", "invite", "involve", "iron", "island", "isolate", "issue", "item", + "ivory", "jacket", "jaguar", "jar", "jazz", "jealous", "jeans", "jelly", "jewel", "job", "join", "joke", + "journey", "joy", "judge", "juice", "jump", "jungle", "junior", "junk", "just", "kangaroo", "keen", "keep", + "ketchup", "key", "kick", "kid", "kidney", "kind", "kingdom", "kiss", "kit", "kitchen", "kite", "kitten", + "kiwi", "knee", "knife", "knock", "know", "lab", "label", "labor", "ladder", "lady", "lake", "lamp", + "language", "laptop", "large", "later", "latin", "laugh", "laundry", "lava", "law", "lawn", "lawsuit", + "layer", "lazy", "leader", "leaf", "learn", "leave", "lecture", "left", "leg", "legal", "legend", "leisure", + "lemon", "lend", "length", "lens", "leopard", "lesson", "letter", "level", "liar", "liberty", "library", + "license", "life", "lift", "light", "like", "limb", "limit", "link", "lion", "liquid", "list", "little", + "live", "lizard", "load", "loan", "lobster", "local", "lock", "logic", "lonely", "long", "loop", "lottery", + "loud", "lounge", "love", "loyal", "lucky", "luggage", "lumber", "lunar", "lunch", "luxury", "lyrics", + "machine", "mad", "magic", "magnet", "maid", "mail", "main", "major", "make", "mammal", "man", "manage", + "mandate", "mango", "mansion", "manual", "maple", "marble", "march", "margin", "marine", "market", + "marriage", "mask", "mass", "master", "match", "material", "math", "matrix", "matter", "maximum", "maze", + "meadow", "mean", "measure", "meat", "mechanic", "medal", "media", "melody", "melt", "member", "memory", + "mention", "menu", "mercy", "merge", "merit", "merry", "mesh", "message", "metal", "method", "middle", + "midnight", "milk", "million", "mimic", "mind", "minimum", "minor", "minute", "miracle", "mirror", "misery", + "miss", "mistake", "mix", "mixed", "mixture", "mobile", "model", "modify", "mom", "moment", "monitor", + "monkey", "monster", "month", "moon", "moral", "more", "morning", "mosquito", "mother", "motion", "motor", + "mountain", "mouse", "move", "movie", "much", "muffin", "mule", "multiply", "muscle", "museum", "mushroom", + "music", "must", "mutual", "myself", "mystery", "myth", "naive", "name", "napkin", "narrow", "nasty", + "nation", "nature", "near", "neck", "need", "negative", "neglect", "neither", "nephew", "nerve", "nest", + "net", "network", "neutral", "never", "news", "next", "nice", "night", "noble", "noise", "nominee", + "noodle", "normal", "north", "nose", "notable", "note", "nothing", "notice", "novel", "now", "nuclear", + "number", "nurse", "nut", "oak", "obey", "object", "oblige", "obscure", "observe", "obtain", "obvious", + "occur", "ocean", "october", "odor", "off", "offer", "office", "often", "oil", "okay", "old", "olive", + "olympic", "omit", "once", "one", "onion", "online", "only", "open", "opera", "opinion", "oppose", + "option", "orange", "orbit", "orchard", "order", "ordinary", "organ", "orient", "original", "orphan", + "ostrich", "other", "outdoor", "outer", "output", "outside", "oval", "oven", "over", "own", "owner", + "oxygen", "oyster", "ozone", "pact", "paddle", "page", "pair", "palace", "palm", "panda", "panel", "panic", + "panther", "paper", "parade", "parent", "park", "parrot", "party", "pass", "patch", "path", "patient", + "patrol", "pattern", "pause", "pave", "payment", "peace", "peanut", "pear", "peasant", "pelican", "pen", + "penalty", "pencil", "people", "pepper", "perfect", "permit", "person", "pet", "phone", "photo", "phrase", + "physical", "piano", "picnic", "picture", "piece", "pig", "pigeon", "pill", "pilot", "pink", "pioneer", + "pipe", "pistol", "pitch", "pizza", "place", "planet", "plastic", "plate", "play", "please", "pledge", + "pluck", "plug", "plunge", "poem", "poet", "point", "polar", "pole", "police", "pond", "pony", "pool", + "popular", "portion", "position", "possible", "post", "potato", "pottery", "poverty", "powder", "power", + "practice", "praise", "predict", "prefer", "prepare", "present", "pretty", "prevent", "price", "pride", + "primary", "print", "priority", "prison", "private", "prize", "problem", "process", "produce", "profit", + "program", "project", "promote", "proof", "property", "prosper", "protect", "proud", "provide", "public", + "pudding", "pull", "pulp", "pulse", "pumpkin", "punch", "pupil", "puppy", "purchase", "purity", "purpose", + "purse", "push", "put", "puzzle", "pyramid", "quality", "quantum", "quarter", "question", "quick", "quit", + "quiz", "quote", "rabbit", "raccoon", "race", "rack", "radar", "radio", "rail", "rain", "raise", "rally", + "ramp", "ranch", "random", "range", "rapid", "rare", "rate", "rather", "raven", "raw", "razor", "ready", + "real", "reason", "rebel", "rebuild", "recall", "receive", "recipe", "record", "recycle", "reduce", + "reflect", "reform", "refuse", "region", "regret", "regular", "reject", "relax", "release", "relief", + "rely", "remain", "remember", "remind", "remove", "render", "renew", "rent", "reopen", "repair", "repeat", + "replace", "report", "require", "rescue", "resemble", "resist", "resource", "response", "result", "retire", + "retreat", "return", "reunion", "reveal", "review", "reward", "rhythm", "rib", "ribbon", "rice", "rich", + "ride", "ridge", "rifle", "right", "rigid", "ring", "riot", "ripple", "risk", "ritual", "rival", "river", + "road", "roast", "robot", "robust", "rocket", "romance", "roof", "rookie", "room", "rose", "rotate", + "rough", "round", "route", "royal", "rubber", "rude", "rug", "rule", "run", "runway", "rural", "sad", + "saddle", "sadness", "safe", "sail", "salad", "salmon", "salon", "salt", "salute", "same", "sample", "sand", + "satisfy", "satoshi", "sauce", "sausage", "save", "say", "scale", "scan", "scare", "scatter", "scene", + "scheme", "school", "science", "scissors", "scorpion", "scout", "scrap", "screen", "script", "scrub", "sea", + "search", "season", "seat", "second", "secret", "section", "security", "seed", "seek", "segment", "select", + "sell", "seminar", "senior", "sense", "sentence", "series", "service", "session", "settle", "setup", + "seven", "shadow", "shaft", "shallow", "share", "shed", "shell", "sheriff", "shield", "shift", "shine", + "ship", "shiver", "shock", "shoe", "shoot", "shop", "short", "shoulder", "shove", "shrimp", "shrug", + "shuffle", "shy", "sibling", "sick", "side", "siege", "sight", "sign", "silent", "silk", "silly", "silver", + "similar", "simple", "since", "sing", "siren", "sister", "situate", "six", "size", "skate", "sketch", "ski", + "skill", "skin", "skirt", "skull", "slab", "slam", "sleep", "slender", "slice", "slide", "slight", "slim", + "slogan", "slot", "slow", "slush", "small", "smart", "smile", "smoke", "smooth", "snack", "snake", "snap", + "sniff", "snow", "soap", "soccer", "social", "sock", "soda", "soft", "solar", "soldier", "solid", + "solution", "solve", "someone", "song", "soon", "sorry", "sort", "soul", "sound", "soup", "source", "south", + "space", "spare", "spatial", "spawn", "speak", "special", "speed", "spell", "spend", "sphere", "spice", + "spider", "spike", "spin", "spirit", "split", "spoil", "sponsor", "spoon", "sport", "spot", "spray", + "spread", "spring", "spy", "square", "squeeze", "squirrel", "stable", "stadium", "staff", "stage", "stairs", + "stamp", "stand", "start", "state", "stay", "steak", "steel", "stem", "step", "stereo", "stick", "still", + "sting", "stock", "stomach", "stone", "stool", "story", "stove", "strategy", "street", "strike", "strong", + "struggle", "student", "stuff", "stumble", "style", "subject", "submit", "subway", "success", "such", + "sudden", "suffer", "sugar", "suggest", "suit", "summer", "sun", "sunny", "sunset", "super", "supply", + "supreme", "sure", "surface", "surge", "surprise", "surround", "survey", "suspect", "sustain", "swallow", + "swamp", "swap", "swarm", "swear", "sweet", "swift", "swim", "swing", "switch", "sword", "symbol", + "symptom", "syrup", "system", "table", "tackle", "tag", "tail", "talent", "talk", "tank", "tape", "target", + "task", "taste", "tattoo", "taxi", "teach", "team", "tell", "ten", "tenant", "tennis", "tent", "term", + "test", "text", "thank", "that", "theme", "then", "theory", "there", "they", "thing", "this", "thought", + "three", "thrive", "throw", "thumb", "thunder", "ticket", "tide", "tiger", "tilt", "timber", "time", "tiny", + "tip", "tired", "tissue", "title", "toast", "tobacco", "today", "toddler", "toe", "together", "toilet", + "token", "tomato", "tomorrow", "tone", "tongue", "tonight", "tool", "tooth", "top", "topic", "topple", + "torch", "tornado", "tortoise", "toss", "total", "tourist", "toward", "tower", "town", "toy", "track", + "trade", "traffic", "tragic", "train", "transfer", "trap", "trash", "travel", "tray", "treat", "tree", + "trend", "trial", "tribe", "trick", "trigger", "trim", "trip", "trophy", "trouble", "truck", "true", + "truly", "trumpet", "trust", "truth", "try", "tube", "tuition", "tumble", "tuna", "tunnel", "turkey", + "turn", "turtle", "twelve", "twenty", "twice", "twin", "twist", "two", "type", "typical", "ugly", + "umbrella", "unable", "unaware", "uncle", "uncover", "under", "undo", "unfair", "unfold", "unhappy", + "uniform", "unique", "unit", "universe", "unknown", "unlock", "until", "unusual", "unveil", "update", + "upgrade", "uphold", "upon", "upper", "upset", "urban", "urge", "usage", "use", "used", "useful", "useless", + "usual", "utility", "vacant", "vacuum", "vague", "valid", "valley", "valve", "van", "vanish", "vapor", + "various", "vast", "vault", "vehicle", "velvet", "vendor", "venture", "venue", "verb", "verify", "version", + "very", "vessel", "veteran", "viable", "vibrant", "vicious", "victory", "video", "view", "village", + "vintage", "violin", "virtual", "virus", "visa", "visit", "visual", "vital", "vivid", "vocal", "voice", + "void", "volcano", "volume", "vote", "voyage", "wage", "wagon", "wait", "walk", "wall", "walnut", "want", + "warfare", "warm", "warrior", "wash", "wasp", "waste", "water", "wave", "way", "wealth", "weapon", "wear", + "weasel", "weather", "web", "wedding", "weekend", "weird", "welcome", "west", "wet", "whale", "what", + "wheat", "wheel", "when", "where", "whip", "whisper", "wide", "width", "wife", "wild", "will", "win", + "window", "wine", "wing", "wink", "winner", "winter", "wire", "wisdom", "wise", "wish", "witness", "wolf", + "woman", "wonder", "wood", "wool", "word", "work", "world", "worry", "worth", "wrap", "wreck", "wrestle", + "wrist", "write", "wrong", "yard", "year", "yellow", "you", "young", "youth", "zebra", "zero", "zone", "zoo"] + + static func randomBytes(_ length: Int) -> [UInt8] { + var res = Data(count: length) + res.withUnsafeMutableBytes {(bytes: UnsafeMutablePointer)->Void in + let _ = SecRandomCopyBytes(kSecRandomDefault, length, bytes) + } + return Array(res) + } + + static private func bytesToBits(_ data: [UInt8]) -> [Bool] { + var bits: [Bool] = [] + for i in 0.. String { + let nbWords = 15; + let len = nbWords / 3 * 4; + let entropy = randomBytes(len) + + let hash = Hash.sha256(entropy) + let hashBits = bytesToBits(hash) + + let entropyBits = bytesToBits(entropy) + let checksumLengthBits = entropyBits.count / 32 + + let concatBits = entropyBits + hashBits[0.. [UInt8] } diff --git a/WavesWallet-iOS/DomainLayer/Assisstants/SmartTransactionDomain+Assistants.swift b/DomainLayer/Sources/Assisstants/SmartTransactionDomain+Assistants.swift similarity index 93% rename from WavesWallet-iOS/DomainLayer/Assisstants/SmartTransactionDomain+Assistants.swift rename to DomainLayer/Sources/Assisstants/SmartTransactionDomain+Assistants.swift index d2b76bf0..98f31eda 100644 --- a/WavesWallet-iOS/DomainLayer/Assisstants/SmartTransactionDomain+Assistants.swift +++ b/DomainLayer/Sources/Assisstants/SmartTransactionDomain+Assistants.swift @@ -8,7 +8,7 @@ import Foundation -extension DomainLayer.DTO.SmartTransaction.Exchange { +public extension DomainLayer.DTO.SmartTransaction.Exchange { var myOrder: Order { if order1.sender.isMyAccount && order2.sender.isMyAccount { return order1.timestamp > order2.timestamp ? order1 : order2 diff --git a/WavesWallet-iOS/DomainLayer/DomainLayerTypes.swift b/DomainLayer/Sources/DomainLayerTypes.swift similarity index 69% rename from WavesWallet-iOS/DomainLayer/DomainLayerTypes.swift rename to DomainLayer/Sources/DomainLayerTypes.swift index 6fd9b962..db14005d 100644 --- a/WavesWallet-iOS/DomainLayer/DomainLayerTypes.swift +++ b/DomainLayer/Sources/DomainLayerTypes.swift @@ -8,7 +8,7 @@ import Foundation -enum DomainLayer { - enum DTO { } - enum Query {} +public enum DomainLayer { + public enum DTO { } + public enum Query {} } diff --git a/DomainLayer/Sources/Generated/Localizable.swift b/DomainLayer/Sources/Generated/Localizable.swift new file mode 100644 index 00000000..4114837e --- /dev/null +++ b/DomainLayer/Sources/Generated/Localizable.swift @@ -0,0 +1,53 @@ +// Generated using SwiftGen, by O.Halligon — https://github.com/SwiftGen/SwiftGen + +import Foundation + +// swiftlint:disable superfluous_disable_command +// swiftlint:disable file_length + +// swiftlint:disable explicit_type_interface identifier_name line_length nesting type_body_length type_name +internal enum Localizable { + + internal enum Biometric { + /// Cancel + internal static var localizedCancelTitle: String { return Localizable.tr("WavesDomainLayer", "biometric.localizedCancelTitle") } + internal static var localizedCancelTitleKey: String { return "biometric.localizedCancelTitle" } + /// Enter Passcode + internal static var localizedFallbackTitle: String { return Localizable.tr("WavesDomainLayer", "biometric.localizedFallbackTitle") } + internal static var localizedFallbackTitleKey: String { return "biometric.localizedFallbackTitle" } + /// Access to your wallet + internal static var readfromkeychain: String { return Localizable.tr("WavesDomainLayer", "biometric.readfromkeychain") } + internal static var readfromkeychainKey: String { return "biometric.readfromkeychain" } + /// Access to your wallet + internal static var saveinkeychain: String { return Localizable.tr("WavesDomainLayer", "biometric.saveinkeychain") } + internal static var saveinkeychainKey: String { return "biometric.saveinkeychain" } + } +} +// swiftlint:enable explicit_type_interface identifier_name line_length nesting type_body_length type_name + +extension Localizable { + + struct Current { + var locale: Locale + var bundle: Bundle + } + + private static let english: Localizable.Current = Localizable.Current(locale: Locale(identifier: "en"), bundle: Bundle(for: BundleToken.self)) + + static var current: Localizable.Current = Localizable.Current(locale: Locale.current, bundle: Bundle(for: BundleToken.self)) + + private static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String { + let format = NSLocalizedString(key, tableName: table, bundle: current.bundle, comment: "") + + let value = String(format: format, locale: current.locale, arguments: args) + + if value.localizedLowercase == key.localizedLowercase { + let format = NSLocalizedString(key, tableName: table, bundle: english.bundle, comment: "") + return String(format: format, locale: english.locale, arguments: args) + } else { + return value + } + } +} + +private final class BundleToken {} diff --git a/WavesWallet-iOS/DomainLayer/Mapper/Asset+Assistants.swift b/DomainLayer/Sources/Mapper/Asset+Assistants.swift similarity index 98% rename from WavesWallet-iOS/DomainLayer/Mapper/Asset+Assistants.swift rename to DomainLayer/Sources/Mapper/Asset+Assistants.swift index 95a885bc..b03dee0b 100644 --- a/WavesWallet-iOS/DomainLayer/Mapper/Asset+Assistants.swift +++ b/DomainLayer/Sources/Mapper/Asset+Assistants.swift @@ -7,6 +7,7 @@ // import Foundation +import Extensions extension DomainLayer.DTO.Asset { diff --git a/WavesWallet-iOS/DomainLayer/Mapper/TransactionDomainDTO+Mapper.swift b/DomainLayer/Sources/Mapper/TransactionDomainDTO+Mapper.swift similarity index 92% rename from WavesWallet-iOS/DomainLayer/Mapper/TransactionDomainDTO+Mapper.swift rename to DomainLayer/Sources/Mapper/TransactionDomainDTO+Mapper.swift index 1b4bb073..abf02ba3 100644 --- a/WavesWallet-iOS/DomainLayer/Mapper/TransactionDomainDTO+Mapper.swift +++ b/DomainLayer/Sources/Mapper/TransactionDomainDTO+Mapper.swift @@ -7,9 +7,10 @@ // import Foundation -import Base58 -import WavesSDKExtension import WavesSDKCrypto +import WavesSDK +import WavesSDKExtensions +import Extensions fileprivate enum TransactionDirection { case sent @@ -58,7 +59,7 @@ struct SmartTransactionMetaData { private func decodedString(_ string: String?) -> String? { if let string = string { - return Base58.decodeToStr(string) + return Base58Encoder.decodeToStr(string) } return nil } @@ -71,7 +72,7 @@ extension DomainLayer.DTO.UnrecognisedTransaction { let accounts: [String: DomainLayer.DTO.Address] = metaData.accounts let totalHeight: Int64 = metaData.totalHeight - guard let wavesAsset = assets[WavesSDKCryptoConstants.wavesAssetId] else { + guard let wavesAsset = assets[WavesSDKConstants.wavesAssetId] else { return nil } guard let sender = accounts[self.sender] else { @@ -103,7 +104,7 @@ extension DomainLayer.DTO.IssueTransaction { let accounts: [String: DomainLayer.DTO.Address] = metaData.accounts let totalHeight: Int64 = metaData.totalHeight - guard let wavesAsset = assets[WavesSDKCryptoConstants.wavesAssetId] else { + guard let wavesAsset = assets[WavesSDKConstants.wavesAssetId] else { return nil } guard let sender = accounts[self.sender] else { @@ -200,7 +201,7 @@ extension DomainLayer.DTO.TransferTransaction { } } - guard let wavesAsset = assets[WavesSDKCryptoConstants.wavesAssetId] else { + guard assets[WavesSDKConstants.wavesAssetId] != nil else { SweetLogger.error("TransferTransaction Not found Waves ID") return nil } @@ -236,7 +237,7 @@ extension DomainLayer.DTO.ReissueTransaction { guard let sender = accounts[self.sender] else { return nil } - guard let wavesAsset = assets[WavesSDKCryptoConstants.wavesAssetId] else { + guard let wavesAsset = assets[WavesSDKConstants.wavesAssetId] else { return nil } @@ -276,7 +277,7 @@ extension DomainLayer.DTO.BurnTransaction { SweetLogger.error("MassTransferTransaction Not found Sender ID") return nil } - guard let wavesAsset = assets[WavesSDKCryptoConstants.wavesAssetId] else { + guard let wavesAsset = assets[WavesSDKConstants.wavesAssetId] else { SweetLogger.error("MassTransferTransaction Not found Waves ID") return nil } @@ -310,7 +311,7 @@ extension DomainLayer.DTO.ExchangeTransaction { let amountAssetId = order1.assetPair.amountAsset let priceAssetId = order1.assetPair.priceAsset - guard let wavesAsset = assets[WavesSDKCryptoConstants.wavesAssetId] else { + guard let wavesAsset = assets[WavesSDKConstants.wavesAssetId] else { return nil } guard let amountAsset = assets[amountAssetId] else { @@ -327,8 +328,38 @@ extension DomainLayer.DTO.ExchangeTransaction { let total = assetPair.totalBalance(priceAmount: self.price, assetAmount: self.amount) - let buyMatcherFee = wavesAsset.balance(self.buyMatcherFee) - let sellMatcherFee = wavesAsset.balance(self.sellMatcherFee) + var buyMatcherFee: Balance! + var sellMatcherFee: Balance! + + if let matcherFeeAssetId = order1.matcherFeeAssetId { + guard let matcherFeeAsset = assets[matcherFeeAssetId] else { return nil } + + if order1.orderType == .sell { + sellMatcherFee = matcherFeeAsset.balance(self.sellMatcherFee) + } + else { + buyMatcherFee = matcherFeeAsset.balance(self.buyMatcherFee) + } + } + + if let matcherFeeAssetId = order2.matcherFeeAssetId { + guard let matcherFeeAsset = assets[matcherFeeAssetId] else { return nil } + + if order2.orderType == .sell { + sellMatcherFee = matcherFeeAsset.balance(self.sellMatcherFee) + } + else { + buyMatcherFee = matcherFeeAsset.balance(self.buyMatcherFee) + } + } + + if buyMatcherFee == nil { + buyMatcherFee = wavesAsset.balance(self.buyMatcherFee) + } + + if sellMatcherFee == nil { + sellMatcherFee = wavesAsset.balance(self.sellMatcherFee) + } guard let order1 = order1.exchangeOrder(assetPair: assetPair, accounts: accounts) @@ -380,7 +411,7 @@ extension DomainLayer.DTO.LeaseTransaction { let accounts: [String: DomainLayer.DTO.Address] = metaData.accounts let totalHeight: Int64 = metaData.totalHeight - guard let wavesAsset = assets[WavesSDKCryptoConstants.wavesAssetId] else { return nil } + guard let wavesAsset = assets[WavesSDKConstants.wavesAssetId] else { return nil } let balance = wavesAsset.balance(self.amount) let isSenderAccount = sender.isMyAccount(accountAddress) @@ -433,7 +464,7 @@ extension DomainLayer.DTO.LeaseCancelTransaction { return nil } - guard let wavesAsset = assets[WavesSDKCryptoConstants.wavesAssetId] else { + guard let wavesAsset = assets[WavesSDKConstants.wavesAssetId] else { return nil } @@ -478,7 +509,7 @@ extension DomainLayer.DTO.AliasTransaction { let accounts: [String: DomainLayer.DTO.Address] = metaData.accounts let totalHeight: Int64 = metaData.totalHeight - guard let wavesAsset = assets[WavesSDKCryptoConstants.wavesAssetId] else { return nil } + guard let wavesAsset = assets[WavesSDKConstants.wavesAssetId] else { return nil } guard let sender = accounts[self.sender] else { return nil } let kind: DomainLayer.DTO.SmartTransaction.Kind = .createdAlias(alias) @@ -507,7 +538,7 @@ extension DomainLayer.DTO.ScriptTransaction { let accounts: [String: DomainLayer.DTO.Address] = metaData.accounts let totalHeight: Int64 = metaData.totalHeight - guard let wavesAsset = assets[WavesSDKCryptoConstants.wavesAssetId] else { return nil } + guard let wavesAsset = assets[WavesSDKConstants.wavesAssetId] else { return nil } guard let sender = accounts[self.sender] else { return nil } let kind: DomainLayer.DTO.SmartTransaction.Kind = .script(isHasScript: script != nil) @@ -536,7 +567,7 @@ extension DomainLayer.DTO.AssetScriptTransaction { let accounts: [String: DomainLayer.DTO.Address] = metaData.accounts let totalHeight: Int64 = metaData.totalHeight - guard let wavesAsset = assets[WavesSDKCryptoConstants.wavesAssetId] else { return nil } + guard let wavesAsset = assets[WavesSDKConstants.wavesAssetId] else { return nil } guard let assetId = assets[assetId] else { return nil } guard let sender = accounts[self.sender] else { return nil } @@ -566,7 +597,7 @@ extension DomainLayer.DTO.SponsorshipTransaction { let accounts: [String: DomainLayer.DTO.Address] = metaData.accounts let totalHeight: Int64 = metaData.totalHeight - guard let wavesAsset = assets[WavesSDKCryptoConstants.wavesAssetId] else { return nil } + guard let wavesAsset = assets[WavesSDKConstants.wavesAssetId] else { return nil } guard let assetAccount = assets[assetId] else { return nil } guard let sender = accounts[self.sender] else { return nil } @@ -664,7 +695,7 @@ extension DomainLayer.DTO.MassTransferTransaction { } } - guard let wavesAsset = assets[WavesSDKCryptoConstants.wavesAssetId] else { + guard let wavesAsset = assets[WavesSDKConstants.wavesAssetId] else { SweetLogger.error("MassTransferTransaction Not found Waves ID") return nil } @@ -704,7 +735,7 @@ extension DomainLayer.DTO.DataTransaction { let prettyJSON = list.prettyJSON ?? "" let kind: DomainLayer.DTO.SmartTransaction.Kind = .data(.init(prettyJSON: prettyJSON)) - guard let wavesAsset = assets[WavesSDKCryptoConstants.wavesAssetId] else { return nil } + guard let wavesAsset = assets[WavesSDKConstants.wavesAssetId] else { return nil } guard let sender = accounts[self.sender] else { return nil } let feeBalance = wavesAsset.balance(fee) @@ -731,7 +762,7 @@ extension DomainLayer.DTO.InvokeScriptTransaction { let accounts: [String: DomainLayer.DTO.Address] = metaData.accounts let totalHeight: Int64 = metaData.totalHeight - guard let wavesAsset = assets[WavesSDKCryptoConstants.wavesAssetId] else { return nil } + guard let wavesAsset = assets[WavesSDKConstants.wavesAssetId] else { return nil } var payment: DomainLayer.DTO.SmartTransaction.InvokeScript.Payment? @@ -876,7 +907,7 @@ extension DomainLayer.DTO.ExchangeTransaction.Order { let kind: DomainLayer.DTO.SmartTransaction.Exchange.Order.Kind = orderType == .sell ? .sell : .buy let amount = assetPair.amountBalance(self.amount) let price = assetPair.priceBalance(self.price) - //TODO: Is Correct?не + let total = assetPair.totalBalance(priceAmount: self.amount, assetAmount: self.price) diff --git a/DomainLayer/Sources/Models/DTO/AccountEnvironmentDomainDTO.swift b/DomainLayer/Sources/Models/DTO/AccountEnvironmentDomainDTO.swift new file mode 100644 index 00000000..8a21966a --- /dev/null +++ b/DomainLayer/Sources/Models/DTO/AccountEnvironmentDomainDTO.swift @@ -0,0 +1,27 @@ +// +// AccountEnvironmentDomainDTO.swift +// WavesWallet-iOS +// +// Created by mefilt on 24/10/2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import Extensions + +public extension DomainLayer.DTO { + + struct AccountEnvironment: Equatable, Mutating { + public var nodeUrl: String? + public var dataUrl: String? + public var spamUrl: String? + public var matcherUrl: String? + + public init(nodeUrl: String?, dataUrl: String?, spamUrl: String?, matcherUrl: String?) { + self.nodeUrl = nodeUrl + self.dataUrl = dataUrl + self.spamUrl = spamUrl + self.matcherUrl = matcherUrl + } + } +} diff --git a/WavesWallet-iOS/DomainLayer/Models/DTO/AccountSettingsDomainDTO.swift b/DomainLayer/Sources/Models/DTO/AccountSettingsDomainDTO.swift similarity index 56% rename from WavesWallet-iOS/DomainLayer/Models/DTO/AccountSettingsDomainDTO.swift rename to DomainLayer/Sources/Models/DTO/AccountSettingsDomainDTO.swift index c03f21a4..647afcf9 100644 --- a/WavesWallet-iOS/DomainLayer/Models/DTO/AccountSettingsDomainDTO.swift +++ b/DomainLayer/Sources/Models/DTO/AccountSettingsDomainDTO.swift @@ -7,9 +7,14 @@ // import Foundation +import Extensions -extension DomainLayer.DTO { +public extension DomainLayer.DTO { struct AccountSettings: Equatable, Mutating { - var isEnabledSpam: Bool + public var isEnabledSpam: Bool + + public init(isEnabledSpam: Bool) { + self.isEnabledSpam = isEnabledSpam + } } } diff --git a/WavesWallet-iOS/DomainLayer/Models/DTO/AliasDomainDTO.swift b/DomainLayer/Sources/Models/DTO/AliasDomainDTO.swift similarity index 52% rename from WavesWallet-iOS/DomainLayer/Models/DTO/AliasDomainDTO.swift rename to DomainLayer/Sources/Models/DTO/AliasDomainDTO.swift index 068b5437..cf8b3d2f 100644 --- a/WavesWallet-iOS/DomainLayer/Models/DTO/AliasDomainDTO.swift +++ b/DomainLayer/Sources/Models/DTO/AliasDomainDTO.swift @@ -8,12 +8,17 @@ import Foundation -extension DomainLayer.DTO { +public extension DomainLayer.DTO { //TODO: need update to correct model from API struct Alias: Hashable { - let name: String - let originalName: String + public let name: String + public let originalName: String + + public init(name: String, originalName: String) { + self.name = name + self.originalName = originalName + } } } diff --git a/DomainLayer/Sources/Models/DTO/AssetBalanceDomainDTO.swift b/DomainLayer/Sources/Models/DTO/AssetBalanceDomainDTO.swift new file mode 100644 index 00000000..115a554e --- /dev/null +++ b/DomainLayer/Sources/Models/DTO/AssetBalanceDomainDTO.swift @@ -0,0 +1,78 @@ +// +// AssetBalanceDomainDTO.swift +// WavesWallet-iOS +// +// Created by Prokofev Ruslan on 05/08/2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import WavesSDKExtensions +import Extensions + +public extension DomainLayer.DTO { + + struct SmartAssetBalance: Mutating { + public let assetId: String + public var totalBalance: Int64 + public var leasedBalance: Int64 + public var inOrderBalance: Int64 + public var settings: DomainLayer.DTO.AssetBalanceSettings + public var asset: DomainLayer.DTO.Asset + public var modified: Date + public let sponsorBalance: Int64 + + public init(assetId: String, totalBalance: Int64, leasedBalance: Int64, inOrderBalance: Int64, settings: DomainLayer.DTO.AssetBalanceSettings, asset: DomainLayer.DTO.Asset, modified: Date, sponsorBalance: Int64) { + self.assetId = assetId + self.totalBalance = totalBalance + self.leasedBalance = leasedBalance + self.inOrderBalance = inOrderBalance + self.settings = settings + self.asset = asset + self.modified = modified + self.sponsorBalance = sponsorBalance + } + } + + struct AssetBalance: Mutating { + + public let assetId: String + public var totalBalance: Int64 + public var leasedBalance: Int64 + public var inOrderBalance: Int64 + public var modified: Date + public let sponsorBalance: Int64 + public let minSponsoredAssetFee: Int64 + + public init(assetId: String, totalBalance: Int64, leasedBalance: Int64, inOrderBalance: Int64, modified: Date, sponsorBalance: Int64, minSponsoredAssetFee: Int64) { + self.assetId = assetId + self.totalBalance = totalBalance + self.leasedBalance = leasedBalance + self.inOrderBalance = inOrderBalance + self.modified = modified + self.sponsorBalance = sponsorBalance + self.minSponsoredAssetFee = minSponsoredAssetFee + } + } + + struct AssetBalanceSettings: Mutating { + public let assetId: String + public var sortLevel: Float + public var isHidden: Bool + public var isFavorite: Bool + + public init(assetId: String, sortLevel: Float, isHidden: Bool, isFavorite: Bool) { + self.assetId = assetId + self.sortLevel = sortLevel + self.isHidden = isHidden + self.isFavorite = isFavorite + } + } +} + +public extension DomainLayer.DTO.SmartAssetBalance { + + var availableBalance: Int64 { + return max(totalBalance - leasedBalance - inOrderBalance, 0) + } +} diff --git a/DomainLayer/Sources/Models/DTO/AssetDomainDTO.swift b/DomainLayer/Sources/Models/DTO/AssetDomainDTO.swift new file mode 100644 index 00000000..50c7cf0b --- /dev/null +++ b/DomainLayer/Sources/Models/DTO/AssetDomainDTO.swift @@ -0,0 +1,119 @@ +// +// File.swift +// WavesWallet-iOS +// +// Created by Prokofev Ruslan on 04/08/2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import Extensions + +public extension DomainLayer.DTO { + + struct Asset: Mutating, Equatable { + + public struct Icon: Equatable { + public let assetId: String + public let name: String + public let url: String? + + public init(assetId: String, name: String, url: String?) { + self.assetId = assetId + self.name = name + self.url = url + } + } + + public let id: String + public let gatewayId: String? + public let wavesId: String? + public let displayName: String + public let precision: Int + public let description: String + public let height: Int64 + public let timestamp: Date + public let sender: String + public let quantity: Int64 + public let ticker: String? + public let isReusable: Bool + public var isSpam: Bool + public let isFiat: Bool + public let isGeneral: Bool + public let isMyWavesToken: Bool + public let isWavesToken: Bool + public let isGateway: Bool + public let isWaves: Bool + public let modified: Date + public let addressRegEx: String + public let iconLogoUrl: String? + public let hasScript: Bool + public var minSponsoredFee: Int64 + public let gatewayType: DomainLayer.DTO.GatewayType? + + public init(id: String, gatewayId: String?, wavesId: String?, displayName: String, precision: Int, description: String, height: Int64, timestamp: Date, sender: String, quantity: Int64, ticker: String?, isReusable: Bool, isSpam: Bool, isFiat: Bool, isGeneral: Bool, isMyWavesToken: Bool, isWavesToken: Bool, isGateway: Bool, isWaves: Bool, modified: Date, addressRegEx: String, iconLogoUrl: String?, hasScript: Bool, minSponsoredFee: Int64, gatewayType: String?) { + + self.id = id + self.gatewayId = gatewayId + self.wavesId = wavesId + self.displayName = displayName + self.precision = precision + self.description = description + self.height = height + self.timestamp = timestamp + self.sender = sender + self.quantity = quantity + self.ticker = ticker + self.isReusable = isReusable + self.isSpam = isSpam + self.isFiat = isFiat + self.isGeneral = isGeneral + self.isMyWavesToken = isMyWavesToken + self.isWavesToken = isWavesToken + self.isGateway = isGateway + self.isWaves = isWaves + self.modified = modified + self.addressRegEx = addressRegEx + self.iconLogoUrl = iconLogoUrl + self.hasScript = hasScript + self.minSponsoredFee = minSponsoredFee + self.gatewayType = DomainLayer.DTO.GatewayType(rawValue: gatewayType ?? "") + } + } +} + +public extension DomainLayer.DTO.Asset { + + var iconLogo: AssetLogo.Icon { + return AssetLogo.Icon(assetId: id, + name: icon, + url: iconLogoUrl, + isSponsored: isSponsored, + hasScript: hasScript) + } + + var icon: String { + + if let gatewayId = gatewayId, gatewayId.count > 0 { + return gatewayId + } + + return displayName + } + + var isMonero: Bool { + return gatewayId == "XMR" + } + + var isEthereum: Bool { + return gatewayId == "ETH" + } + + var isVostok: Bool { + return gatewayId == "Vostok" + } + + var isSponsored: Bool { + return minSponsoredFee > 0 + } +} diff --git a/DomainLayer/Sources/Models/DTO/CandleDomainDTO.swift b/DomainLayer/Sources/Models/DTO/CandleDomainDTO.swift new file mode 100644 index 00000000..0acde8f9 --- /dev/null +++ b/DomainLayer/Sources/Models/DTO/CandleDomainDTO.swift @@ -0,0 +1,52 @@ +// +// CandleDomainDTO.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 12/5/18. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation + +public extension DomainLayer.DTO { + + struct Candle { + public let close: Double + public let high: Double + public let low: Double + public let open: Double + public let timestamp: Double + public let volume: Double + + public init(close: Double, high: Double, low: Double, open: Double, timestamp: Double, volume: Double) { + self.close = close + self.high = high + self.low = low + self.open = open + self.timestamp = timestamp + self.volume = volume + } + } +} + +public extension DomainLayer.DTO.Candle { + enum TimeFrameType: Int { + case m5 = 5 + case m15 = 15 + case m30 = 30 + case h1 = 60 + case h3 = 180 + case h24 = 1440 + } +} + +extension DomainLayer.DTO.Candle: Equatable { + public static func == (lhs: DomainLayer.DTO.Candle, rhs: DomainLayer.DTO.Candle) -> Bool { + return lhs.close == rhs.close && + lhs.high == rhs.high && + lhs.low == rhs.low && + lhs.open == rhs.open && + lhs.timestamp == rhs.timestamp && + lhs.volume == rhs.volume + } +} diff --git a/DomainLayer/Sources/Models/DTO/CoinomatDomainDTO.swift b/DomainLayer/Sources/Models/DTO/CoinomatDomainDTO.swift new file mode 100644 index 00000000..e42f556c --- /dev/null +++ b/DomainLayer/Sources/Models/DTO/CoinomatDomainDTO.swift @@ -0,0 +1,49 @@ +// +// CoinomatDomainDTO.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 12/14/18. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import Extensions + +public extension DomainLayer.DTO { + enum Coinomat { + + public struct TunnelInfo { + public let address: String + public let attachment: String + public let min: Money + + public init(address: String, attachment: String, min: Money) { + self.address = address + self.attachment = attachment + self.min = min + } + } + + public struct Rate { + public let fee: Money + public let min: Money + public let max: Money + + public init(fee: Money, min: Money, max: Money) { + self.fee = fee + self.min = min + self.max = max + } + } + + public struct CardLimit { + public let min: Money + public let max: Money + + public init(min: Money, max: Money) { + self.min = min + self.max = max + } + } + } +} diff --git a/DomainLayer/Sources/Models/DTO/ContactDomainDTO.swift b/DomainLayer/Sources/Models/DTO/ContactDomainDTO.swift new file mode 100644 index 00000000..43971044 --- /dev/null +++ b/DomainLayer/Sources/Models/DTO/ContactDomainDTO.swift @@ -0,0 +1,21 @@ +// +// AddressBookDomainDTO.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 9/25/18. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation + +public extension DomainLayer.DTO { + struct Contact: Hashable { + public let name: String + public let address: String + + public init(name: String, address: String) { + self.name = name + self.address = address + } + } +} diff --git a/DomainLayer/Sources/Models/DTO/DexDomainDTO.swift b/DomainLayer/Sources/Models/DTO/DexDomainDTO.swift new file mode 100644 index 00000000..2ff40e34 --- /dev/null +++ b/DomainLayer/Sources/Models/DTO/DexDomainDTO.swift @@ -0,0 +1,279 @@ +// +// DexTypes.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 9/12/18. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import Extensions + +public extension DomainLayer.DTO { + enum Dex {} +} + +//MARK: Asset +public extension DomainLayer.DTO.Dex { + + struct Asset { + public let id: String + public let name: String + public let shortName: String + public let decimals: Int + + public init(id: String, name: String, shortName: String, decimals: Int) { + self.id = id + self.name = name + self.shortName = shortName + self.decimals = decimals + } + } + + enum OrderType: String { + case sell + case buy + } +} + +//MARK: LastTrade +public extension DomainLayer.DTO.Dex { + + struct LastTrade { + public let time: Date + public let price: Money + public let amount: Money + public let sum: Money + public let type: OrderType + + public init(time: Date, price: Money, amount: Money, sum: Money, type: OrderType) { + self.time = time + self.price = price + self.amount = amount + self.sum = sum + self.type = type + } + } +} + +//MARK: - SmartPair +public extension DomainLayer.DTO.Dex { + + struct SmartPair: Mutating { + public let id: String + public let amountAsset: Asset + public let priceAsset: Asset + public var isChecked: Bool + public let isGeneral: Bool + public var sortLevel: Int + + public init(id: String, amountAsset: Asset, priceAsset: Asset, isChecked: Bool, isGeneral: Bool, sortLevel: Int) { + self.id = id + self.amountAsset = amountAsset + self.priceAsset = priceAsset + self.isChecked = isChecked + self.isGeneral = isGeneral + self.sortLevel = sortLevel + } + } +} + +//MARK: - SimplePair +public extension DomainLayer.DTO.Dex { + + struct SimplePair { + public let amountAsset: String + public let priceAsset: String + + public init(amountAsset: String, priceAsset: String) { + self.amountAsset = amountAsset + self.priceAsset = priceAsset + } + } +} + + +//MARK: - Pair +public extension DomainLayer.DTO.Dex { + + struct Pair { + public let amountAsset: Asset + public let priceAsset: Asset + + public init(amountAsset: Asset, priceAsset: Asset) { + self.amountAsset = amountAsset + self.priceAsset = priceAsset + } + } + + //TODO: Refactor (Очень много разлчных моделей для пар) + /* + + Когда идет запрос в DataService на получение пар по + pairs=_amountAsset/priceAsset + searchByAsset(searchKey) + searchByAssets(amountAsset/priceAsset) + + то DataService выдает разную структуру ответа + */ + + + struct PairsSearch { + + public struct Pair { + public let firstPrice: Double + public let lastPrice: Double + public let volume: Double + public let volumeWaves: Double? + public let quoteVolume: Double? + + public init(firstPrice: Double, lastPrice: Double, volume: Double, volumeWaves: Double?, quoteVolume: Double?) { + self.firstPrice = firstPrice + self.lastPrice = lastPrice + self.volume = volume + self.volumeWaves = volumeWaves + self.quoteVolume = quoteVolume + } + } + + public let pairs: [Pair?] + + public init(pairs: [Pair?]) { + self.pairs = pairs + } + } + +} + +//MARK: - PairPrice +public extension DomainLayer.DTO.Dex { + struct PairPrice { + public let firstPrice: Money + public let lastPrice: Money + public let amountAsset: Asset + public let priceAsset: Asset + + public init(firstPrice: Money, lastPrice: Money, amountAsset: Asset, priceAsset: Asset) { + self.firstPrice = firstPrice + self.lastPrice = lastPrice + self.amountAsset = amountAsset + self.priceAsset = priceAsset + } + } +} + +//MARK: - MyOrder + +public extension DomainLayer.DTO.Dex { + + struct MyOrder { + + public enum Status { + case accepted + case partiallyFilled + case cancelled + case filled + } + + public let id: String + public let time: Date + public var status: Status + public let price: Money + public let amount: Money + public let filled: Money + public let type: OrderType + public let amountAsset: Asset + public let priceAsset: Asset + public let percentFilled: Int + public let fee: Int64? + public let feeAsset: String? + + public init(id: String, time: Date, status: Status, price: Money, amount: Money, filled: Money, type: OrderType, amountAsset: Asset, priceAsset: Asset, percentFilled: Int, fee: Int64?, feeAsset: String?) { + self.fee = fee + self.feeAsset = feeAsset + self.id = id + self.time = time + self.status = status + self.price = price + self.amount = amount + self.filled = filled + self.type = type + self.amountAsset = amountAsset + self.priceAsset = priceAsset + self.percentFilled = percentFilled + } + } +} + +//MARK: - OrderBook +public extension DomainLayer.DTO.Dex { + + struct OrderBook { + + public struct Value { + public let amount: Int64 + public let price: Int64 + + public init(amount: Int64, price: Int64) { + self.amount = amount + self.price = price + } + } + + public let bids: [Value] + public let asks: [Value] + + public init(bids: [Value], asks: [Value]) { + self.bids = bids + self.asks = asks + } + } +} + + +//MARK: - SettingsOrderFee + +public extension DomainLayer.DTO.Dex { + + struct SettingsOrderFee { + + public struct Asset { + public let assetId: String + public let rate: Double + + public init(assetId: String, rate: Double) { + self.assetId = assetId + self.rate = rate + } + } + + public let baseFee: Int64 + public let feeAssets: [Asset] + + public init(baseFee: Int64, feeAssets: [Asset]) { + self.baseFee = baseFee + self.feeAssets = feeAssets + } + } +} + +//MARK: - SmartSettingsOrderFee + +public extension DomainLayer.DTO.Dex { + + struct SmartSettingsOrderFee { + + public struct Asset { + public let rate: Double + public let asset: DomainLayer.DTO.Dex.Asset + + public init(rate: Double, asset: DomainLayer.DTO.Dex.Asset) { + self.rate = rate + self.asset = asset + } + } + + public let baseFee: Int64 + public let feeAssets: [Asset] + } +} diff --git a/DomainLayer/Sources/Models/DTO/GatewayDomainDTO.swift b/DomainLayer/Sources/Models/DTO/GatewayDomainDTO.swift new file mode 100644 index 00000000..ccb65432 --- /dev/null +++ b/DomainLayer/Sources/Models/DTO/GatewayDomainDTO.swift @@ -0,0 +1,48 @@ +// +// GatewayDomainDTO.swift +// InternalDomainLayer +// +// Created by Pavel Gubin on 22.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import Extensions + +public extension DomainLayer.DTO { + + enum GatewayType: String { + case coinomat + case gateway + } + + enum Gateway { + public struct StartWithdrawProcess { + public let recipientAddress: String + public let minAmount: Money + public let maxAmount: Money + public let fee: Money + public let processId: String + + public init(recipientAddress: String, minAmount: Money, maxAmount: Money, fee: Money, processId: String) { + self.recipientAddress = recipientAddress + self.minAmount = minAmount + self.maxAmount = maxAmount + self.fee = fee + self.processId = processId + } + } + + public struct StartDepositProcess { + public let address: String + public let minAmount: Money + public let maxAmount: Money + + public init(address: String, minAmount: Money, maxAmount: Money) { + self.address = address + self.minAmount = minAmount + self.maxAmount = maxAmount + } + } + } +} diff --git a/DomainLayer/Sources/Models/DTO/MarketPulseSettingsDomainDTO.swift b/DomainLayer/Sources/Models/DTO/MarketPulseSettingsDomainDTO.swift new file mode 100644 index 00000000..ef69829e --- /dev/null +++ b/DomainLayer/Sources/Models/DTO/MarketPulseSettingsDomainDTO.swift @@ -0,0 +1,51 @@ +// +// MarketPulseSettings.swift +// DomainLayer +// +// Created by Pavel Gubin on 29.07.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import Extensions + +public extension DomainLayer.DTO { + + struct MarketPulseSettings: Codable { + + public enum Interval: Int, Codable { + case m1 = 60 + case m5 = 300 + case m10 = 600 + case manually = 0 + } + + public struct Asset: Codable { + + public let id: String + public let name: String + public let icon: AssetLogo.Icon + public let amountAsset: String + public let priceAsset: String + + + public init(id: String, name: String, icon: AssetLogo.Icon, amountAsset: String, priceAsset: String) { + self.id = id + self.name = name + self.icon = icon + self.amountAsset = amountAsset + self.priceAsset = priceAsset + } + } + + public let isDarkStyle: Bool + public let interval: Interval + public let assets: [Asset] + + public init(isDarkStyle: Bool, interval: Interval, assets: [Asset]) { + self.isDarkStyle = isDarkStyle + self.interval = interval + self.assets = assets + } + } +} diff --git a/DomainLayer/Sources/Models/DTO/NotificationNewsDomainDTO.swift b/DomainLayer/Sources/Models/DTO/NotificationNewsDomainDTO.swift new file mode 100644 index 00000000..06b3ffe1 --- /dev/null +++ b/DomainLayer/Sources/Models/DTO/NotificationNewsDomainDTO.swift @@ -0,0 +1,30 @@ +// +// NotificationNewsDomainDTO.swift +// WavesWallet-iOS +// +// Created by mefilt on 15/02/2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation + +public extension DomainLayer.DTO { + struct NotificationNews { + public let startDate: Date + public let endDate: Date + public let logoUrl: String + public let id: String + public let title: [String: String] + public let subTitle: [String: String] + + public init(startDate: Date, endDate: Date, logoUrl: String, id: String, title: [String: String], subTitle: [String: String]) { + self.startDate = startDate + self.endDate = endDate + self.logoUrl = logoUrl + self.id = id + self.title = title + self.subTitle = subTitle + } + } +} + diff --git a/DomainLayer/Sources/Models/DTO/Transactions/AddressDomainDTO.swift b/DomainLayer/Sources/Models/DTO/Transactions/AddressDomainDTO.swift new file mode 100644 index 00000000..4e97f2d9 --- /dev/null +++ b/DomainLayer/Sources/Models/DTO/Transactions/AddressDomainDTO.swift @@ -0,0 +1,26 @@ +// +// AccountDomainDTO.swift +// WavesWallet-iOS +// +// Created by mefilt on 10.09.2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation + +public extension DomainLayer.DTO { + struct Address: Hashable { + + public let address: String + public let contact: DomainLayer.DTO.Contact? + public let isMyAccount: Bool + public let aliases: [DomainLayer.DTO.Alias] + + public init(address: String, contact: DomainLayer.DTO.Contact?, isMyAccount: Bool, aliases: [DomainLayer.DTO.Alias]) { + self.address = address + self.contact = contact + self.isMyAccount = isMyAccount + self.aliases = aliases + } + } +} diff --git a/DomainLayer/Sources/Models/DTO/Transactions/AliasTransactionDomainDTO.swift b/DomainLayer/Sources/Models/DTO/Transactions/AliasTransactionDomainDTO.swift new file mode 100644 index 00000000..448f1d18 --- /dev/null +++ b/DomainLayer/Sources/Models/DTO/Transactions/AliasTransactionDomainDTO.swift @@ -0,0 +1,43 @@ +// +// TransactionAliasNode.swift +// WavesWallet-iOS +// +// Created by Prokofev Ruslan on 07/08/2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation + +public extension DomainLayer.DTO { + struct AliasTransaction: Decodable { + public let type: Int + public let id: String + public let sender: String + public let senderPublicKey: String + public let fee: Int64 + public let timestamp: Date + public let version: Int + public let height: Int64? + public let signature: String? + public let proofs: [String]? + public let alias: String + public var modified: Date + public var status: TransactionStatus + + public init(type: Int, id: String, sender: String, senderPublicKey: String, fee: Int64, timestamp: Date, version: Int, height: Int64?, signature: String?, proofs: [String]?, alias: String, modified: Date, status: TransactionStatus) { + self.type = type + self.id = id + self.sender = sender + self.senderPublicKey = senderPublicKey + self.fee = fee + self.timestamp = timestamp + self.version = version + self.height = height + self.signature = signature + self.proofs = proofs + self.alias = alias + self.modified = modified + self.status = status + } + } +} diff --git a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/AnyTransactionDomainDTO.swift b/DomainLayer/Sources/Models/DTO/Transactions/AnyTransactionDomainDTO.swift similarity index 98% rename from WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/AnyTransactionDomainDTO.swift rename to DomainLayer/Sources/Models/DTO/Transactions/AnyTransactionDomainDTO.swift index bd112ea7..1429a57f 100644 --- a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/AnyTransactionDomainDTO.swift +++ b/DomainLayer/Sources/Models/DTO/Transactions/AnyTransactionDomainDTO.swift @@ -8,7 +8,7 @@ import Foundation -extension DomainLayer.DTO { +public extension DomainLayer.DTO { enum TransactionStatus: Int, Decodable { case activeNow @@ -35,8 +35,8 @@ extension DomainLayer.DTO { } } -// TODO: Protocol -extension DomainLayer.DTO.AnyTransaction { +//TODO: Protocol +public extension DomainLayer.DTO.AnyTransaction { var status: DomainLayer.DTO.TransactionStatus { switch self { diff --git a/DomainLayer/Sources/Models/DTO/Transactions/AssetScriptTransactionDomainDTO.swift b/DomainLayer/Sources/Models/DTO/Transactions/AssetScriptTransactionDomainDTO.swift new file mode 100644 index 00000000..49b8498e --- /dev/null +++ b/DomainLayer/Sources/Models/DTO/Transactions/AssetScriptTransactionDomainDTO.swift @@ -0,0 +1,50 @@ +// +// AssetScriptTransactionDomainDTO.swift +// WavesWallet-iOS +// +// Created by mefilt on 22/01/2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation + +public extension DomainLayer.DTO { + + struct AssetScriptTransaction { + + public let type: Int + public let id: String + public let sender: String + public let senderPublicKey: String + public let fee: Int64 + public let timestamp: Date + public let height: Int64 + public let signature: String? + public let proofs: [String]? + public let chainId: Int? + public let version: Int + public let script: String? + public let assetId: String + + public let modified: Date + public var status: TransactionStatus + + public init(type: Int, id: String, sender: String, senderPublicKey: String, fee: Int64, timestamp: Date, height: Int64, signature: String?, proofs: [String]?, chainId: Int?, version: Int, script: String?, assetId: String, modified: Date, status: TransactionStatus) { + self.type = type + self.id = id + self.sender = sender + self.senderPublicKey = senderPublicKey + self.fee = fee + self.timestamp = timestamp + self.height = height + self.signature = signature + self.proofs = proofs + self.chainId = chainId + self.version = version + self.script = script + self.assetId = assetId + self.modified = modified + self.status = status + } + } +} diff --git a/DomainLayer/Sources/Models/DTO/Transactions/BurnTransactionDomainDTO.swift b/DomainLayer/Sources/Models/DTO/Transactions/BurnTransactionDomainDTO.swift new file mode 100644 index 00000000..f7f5537a --- /dev/null +++ b/DomainLayer/Sources/Models/DTO/Transactions/BurnTransactionDomainDTO.swift @@ -0,0 +1,48 @@ +// +// TransactionBurnNode.swift +// WavesWallet-iOS +// +// Created by Prokofev Ruslan on 07/08/2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation + +public extension DomainLayer.DTO { + struct BurnTransaction: Decodable { + public let type: Int + public let id: String + public let sender: String + public let senderPublicKey: String + public let fee: Int64 + public let timestamp: Date + public let version: Int + public let height: Int64 + + public let signature: String? + public let proofs: [String]? + public let chainId: Int? + public let assetId: String + public let amount: Int64 + public var modified: Date + public var status: TransactionStatus + + public init(type: Int, id: String, sender: String, senderPublicKey: String, fee: Int64, timestamp: Date, version: Int, height: Int64, signature: String?, proofs: [String]?, chainId: Int?, assetId: String, amount: Int64, modified: Date, status: TransactionStatus) { + self.type = type + self.id = id + self.sender = sender + self.senderPublicKey = senderPublicKey + self.fee = fee + self.timestamp = timestamp + self.version = version + self.height = height + self.signature = signature + self.proofs = proofs + self.chainId = chainId + self.assetId = assetId + self.amount = amount + self.modified = modified + self.status = status + } + } +} diff --git a/DomainLayer/Sources/Models/DTO/Transactions/DataTransactionDomainDTO.swift b/DomainLayer/Sources/Models/DTO/Transactions/DataTransactionDomainDTO.swift new file mode 100644 index 00000000..ee8cdb5e --- /dev/null +++ b/DomainLayer/Sources/Models/DTO/Transactions/DataTransactionDomainDTO.swift @@ -0,0 +1,63 @@ +// +// TransactionDataNode.swift +// WavesWallet-iOS +// +// Created by Prokofev Ruslan on 07/08/2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation + +public extension DomainLayer.DTO { + + struct DataTransaction { + public struct Data { + public enum Value { + case bool(Bool) + case integer(Int64) + case string(String) + case binary(String) + } + public let key: String + public let value: Value + public let type: String + + public init(key: String, value: Value, type: String) { + self.key = key + self.value = value + self.type = type + } + } + + public let type: Int + public let id: String + public let sender: String + public let senderPublicKey: String + public let fee: Int64 + public let timestamp: Date + public let height: Int64? + public let version: Int + + public let proofs: [String]? + public let data: [Data] + public var modified: Date + public var status: TransactionStatus + public var chainId: String? + + public init(type: Int, id: String, sender: String, senderPublicKey: String, fee: Int64, timestamp: Date, height: Int64?, version: Int, proofs: [String]?, data: [Data], modified: Date, status: TransactionStatus, chainId: String?) { + self.type = type + self.id = id + self.sender = sender + self.chainId = chainId + self.senderPublicKey = senderPublicKey + self.fee = fee + self.timestamp = timestamp + self.height = height + self.version = version + self.proofs = proofs + self.data = data + self.modified = modified + self.status = status + } + } +} diff --git a/DomainLayer/Sources/Models/DTO/Transactions/ExchangeTransactionDomainDTO.swift b/DomainLayer/Sources/Models/DTO/Transactions/ExchangeTransactionDomainDTO.swift new file mode 100644 index 00000000..a200384c --- /dev/null +++ b/DomainLayer/Sources/Models/DTO/Transactions/ExchangeTransactionDomainDTO.swift @@ -0,0 +1,105 @@ +// +// TransactionExchangeNode.swift +// WavesWallet-iOS +// +// Created by Prokofev Ruslan on 07/08/2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import Extensions + +public extension DomainLayer.DTO { + + struct ExchangeTransaction: Mutating { + + public struct Order: Mutating { + + public enum Kind { + case sell + case buy + } + + public let id: String + public let sender: String + public let senderPublicKey: String + public let matcherPublicKey: String + public var assetPair: AssetPair + public let orderType: Kind + public let price: Int64 + public let amount: Int64 + public let timestamp: Date + public let expiration: Int64 + public let matcherFee: Int64 + public let signature: String? + public let matcherFeeAssetId: String? + + public init(id: String, sender: String, senderPublicKey: String, matcherPublicKey: String, assetPair: AssetPair, orderType: Kind, price: Int64, amount: Int64, timestamp: Date, expiration: Int64, matcherFee: Int64, signature: String?, matcherFeeAssetId: String?) { + self.id = id + self.sender = sender + self.senderPublicKey = senderPublicKey + self.matcherPublicKey = matcherPublicKey + self.assetPair = assetPair + self.orderType = orderType + self.price = price + self.amount = amount + self.timestamp = timestamp + self.expiration = expiration + self.matcherFee = matcherFee + self.signature = signature + self.matcherFeeAssetId = matcherFeeAssetId + } + } + + public struct AssetPair: Decodable, Mutating { + public var amountAsset: String + public var priceAsset: String + + public init(amountAsset: String, priceAsset: String) { + self.amountAsset = amountAsset + self.priceAsset = priceAsset + } + } + + public let type: Int + public let id: String + public let sender: String + public let senderPublicKey: String + public let fee: Int64 + public let timestamp: Date + public let height: Int64 + + public let signature: String? + public let proofs: [String]? + public var order1: Order + public var order2: Order + public let price: Int64 + public let amount: Int64 + public let buyMatcherFee: Int64 + public let sellMatcherFee: Int64 + public var modified: Date + public var status: TransactionStatus + public let version: Int + + public init(type: Int, id: String, sender: String, senderPublicKey: String, fee: Int64, timestamp: Date, height: Int64, signature: String?, proofs: [String]?, order1: Order, order2: Order, price: Int64, amount: Int64, buyMatcherFee: Int64, sellMatcherFee: Int64, modified: Date, status: TransactionStatus, version: Int) { + self.type = type + self.id = id + self.sender = sender + self.senderPublicKey = senderPublicKey + self.fee = fee + self.timestamp = timestamp + self.height = height + self.signature = signature + self.proofs = proofs + self.order1 = order1 + self.order2 = order2 + self.price = price + self.amount = amount + self.buyMatcherFee = buyMatcherFee + self.sellMatcherFee = sellMatcherFee + self.modified = modified + self.status = status + self.version = version + } + } +} diff --git a/DomainLayer/Sources/Models/DTO/Transactions/InvokeScriptTransactionDomainDTO.swift b/DomainLayer/Sources/Models/DTO/Transactions/InvokeScriptTransactionDomainDTO.swift new file mode 100644 index 00000000..955191d4 --- /dev/null +++ b/DomainLayer/Sources/Models/DTO/Transactions/InvokeScriptTransactionDomainDTO.swift @@ -0,0 +1,92 @@ +// +// InvokeScriptTransactionDomainDTO.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 4/9/19. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation + +public extension DomainLayer.DTO { + + struct InvokeScriptTransaction { + + public struct Call { + + public struct Args { + public enum Value { + + case bool(Bool) + case integer(Int64) + case string(String) + case binary(String) + } + + public let type: String + public let value: Value + + public init(type: String, value: Value) { + self.type = type + self.value = value + } + } + + + public let function: String + public let args: [Args] + + public init(function: String, args: [Args]) { + self.function = function + self.args = args + } + } + + public struct Payment { + public let amount: Int64 + public let assetId: String? + + public init(amount: Int64, assetId: String?) { + self.amount = amount + self.assetId = assetId + } + } + + public let type: Int + public let id: String + public let sender: String + public let senderPublicKey: String + public let fee: Int64 + public let feeAssetId: String? + public let timestamp: Date + public let proofs: [String]? + public let version: Int + public let dappAddress: String + public let payment: Payment? + public let height: Int64 + + public var modified: Date + public var status: TransactionStatus + public let chainId: String? + public let call: DomainLayer.DTO.InvokeScriptTransaction.Call? + + public init(type: Int, id: String, sender: String, senderPublicKey: String, fee: Int64, feeAssetId: String?, timestamp: Date, proofs: [String]?, version: Int, dappAddress: String, payment: Payment?, height: Int64, modified: Date, status: TransactionStatus, chainId: String?, call: DomainLayer.DTO.InvokeScriptTransaction.Call?) { + self.chainId = chainId + self.type = type + self.id = id + self.sender = sender + self.senderPublicKey = senderPublicKey + self.fee = fee + self.feeAssetId = feeAssetId + self.timestamp = timestamp + self.proofs = proofs + self.version = version + self.dappAddress = dappAddress + self.payment = payment + self.height = height + self.modified = modified + self.call = call + self.status = status + } + } +} diff --git a/DomainLayer/Sources/Models/DTO/Transactions/IssueTransactionDomainDTO.swift b/DomainLayer/Sources/Models/DTO/Transactions/IssueTransactionDomainDTO.swift new file mode 100644 index 00000000..2316387a --- /dev/null +++ b/DomainLayer/Sources/Models/DTO/Transactions/IssueTransactionDomainDTO.swift @@ -0,0 +1,58 @@ +// +// TransactionIssueNode.swift +// WavesWallet-iOS +// +// Created by Prokofev Ruslan on 07/08/2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation + +public extension DomainLayer.DTO { + struct IssueTransaction { + public let type: Int + public let id: String + public let sender: String + public let senderPublicKey: String + public let fee: Int64 + public let timestamp: Date + public let version: Int + public let height: Int64 + + public let chainId: Int? + public let signature: String? + public let proofs: [String]? + public let assetId: String + public let name: String + public let quantity: Int64 + public let reissuable: Bool + public let decimals: Int + public let description: String + public let script: String? + public var modified: Date + public var status: TransactionStatus + + public init(type: Int, id: String, sender: String, senderPublicKey: String, fee: Int64, timestamp: Date, version: Int, height: Int64, chainId: Int?, signature: String?, proofs: [String]?, assetId: String, name: String, quantity: Int64, reissuable: Bool, decimals: Int, description: String, script: String?, modified: Date, status: TransactionStatus) { + self.type = type + self.id = id + self.sender = sender + self.senderPublicKey = senderPublicKey + self.fee = fee + self.timestamp = timestamp + self.version = version + self.height = height + self.chainId = chainId + self.signature = signature + self.proofs = proofs + self.assetId = assetId + self.name = name + self.quantity = quantity + self.reissuable = reissuable + self.decimals = decimals + self.description = description + self.script = script + self.modified = modified + self.status = status + } + } +} diff --git a/DomainLayer/Sources/Models/DTO/Transactions/LeaseCancelTransactionDomainDTO.swift b/DomainLayer/Sources/Models/DTO/Transactions/LeaseCancelTransactionDomainDTO.swift new file mode 100644 index 00000000..6460f968 --- /dev/null +++ b/DomainLayer/Sources/Models/DTO/Transactions/LeaseCancelTransactionDomainDTO.swift @@ -0,0 +1,48 @@ +// +// TransactionLeaseCancelNode.swift +// WavesWallet-iOS +// +// Created by Prokofev Ruslan on 07/08/2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation + +public extension DomainLayer.DTO { + struct LeaseCancelTransaction { + public let type: Int + public let id: String + public let sender: String + public let senderPublicKey: String + public let fee: Int64 + public let timestamp: Date + public let version: Int + public let height: Int64 + + public let signature: String? + public let proofs: [String]? + public let chainId: Int? + public let leaseId: String + public var lease: DomainLayer.DTO.LeaseTransaction? + public var modified: Date + public var status: TransactionStatus + + public init(type: Int, id: String, sender: String, senderPublicKey: String, fee: Int64, timestamp: Date, version: Int, height: Int64, signature: String?, proofs: [String]?, chainId: Int?, leaseId: String, lease: DomainLayer.DTO.LeaseTransaction?, modified: Date, status: TransactionStatus) { + self.type = type + self.id = id + self.sender = sender + self.senderPublicKey = senderPublicKey + self.fee = fee + self.timestamp = timestamp + self.version = version + self.height = height + self.signature = signature + self.proofs = proofs + self.chainId = chainId + self.leaseId = leaseId + self.lease = lease + self.modified = modified + self.status = status + } + } +} diff --git a/DomainLayer/Sources/Models/DTO/Transactions/LeaseTransactionDomainDTO.swift b/DomainLayer/Sources/Models/DTO/Transactions/LeaseTransactionDomainDTO.swift new file mode 100644 index 00000000..42b103de --- /dev/null +++ b/DomainLayer/Sources/Models/DTO/Transactions/LeaseTransactionDomainDTO.swift @@ -0,0 +1,48 @@ +// +// TransactionLeaseNode.swift +// WavesWallet-iOS +// +// Created by mefilt on 18.07.2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation + +public extension DomainLayer.DTO { + struct LeaseTransaction { + public let type: Int + public let id: String + public let sender: String + public let senderPublicKey: String + public let fee: Int64 + public let timestamp: Date + public let version: Int + public let height: Int64 + + public let chainId: Int? + public let signature: String? + public let proofs: [String]? + public let amount: Int64 + public let recipient: String + public var modified: Date + public var status: TransactionStatus + + public init(type: Int, id: String, sender: String, senderPublicKey: String, fee: Int64, timestamp: Date, version: Int, height: Int64, chainId: Int?, signature: String?, proofs: [String]?, amount: Int64, recipient: String, modified: Date, status: TransactionStatus) { + self.type = type + self.id = id + self.sender = sender + self.senderPublicKey = senderPublicKey + self.fee = fee + self.timestamp = timestamp + self.version = version + self.height = height + self.chainId = chainId + self.signature = signature + self.proofs = proofs + self.amount = amount + self.recipient = recipient + self.modified = modified + self.status = status + } + } +} diff --git a/DomainLayer/Sources/Models/DTO/Transactions/MassTransferTransactionDomainDTO.swift b/DomainLayer/Sources/Models/DTO/Transactions/MassTransferTransactionDomainDTO.swift new file mode 100644 index 00000000..4743b577 --- /dev/null +++ b/DomainLayer/Sources/Models/DTO/Transactions/MassTransferTransactionDomainDTO.swift @@ -0,0 +1,62 @@ +// +// TransactionMassTransferNode.swift +// WavesWallet-iOS +// +// Created by Prokofev Ruslan on 07/08/2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import Extensions + +public extension DomainLayer.DTO { + struct MassTransferTransaction: Mutating { + + public struct Transfer { + public let recipient: String + public let amount: Int64 + + public init(recipient: String, amount: Int64) { + self.recipient = recipient + self.amount = amount + } + } + + public let type: Int + public let id: String + public let sender: String + public let senderPublicKey: String + public let fee: Int64 + public let timestamp: Date + public let version: Int + public let height: Int64 + + public let proofs: [String]? + public var assetId: String + public let attachment: String + public let transferCount: Int + public let totalAmount: Int64 + public let transfers: [Transfer] + public var modified: Date + public var status: TransactionStatus + + public init(type: Int, id: String, sender: String, senderPublicKey: String, fee: Int64, timestamp: Date, version: Int, height: Int64, proofs: [String]?, assetId: String, attachment: String, transferCount: Int, totalAmount: Int64, transfers: [Transfer], modified: Date, status: TransactionStatus) { + self.type = type + self.id = id + self.sender = sender + self.senderPublicKey = senderPublicKey + self.fee = fee + self.timestamp = timestamp + self.version = version + self.height = height + self.proofs = proofs + self.assetId = assetId + self.attachment = attachment + self.transferCount = transferCount + self.totalAmount = totalAmount + self.transfers = transfers + self.modified = modified + self.status = status + } + } +} diff --git a/DomainLayer/Sources/Models/DTO/Transactions/ReissueTransactionDomainDTO.swift b/DomainLayer/Sources/Models/DTO/Transactions/ReissueTransactionDomainDTO.swift new file mode 100644 index 00000000..8eee4240 --- /dev/null +++ b/DomainLayer/Sources/Models/DTO/Transactions/ReissueTransactionDomainDTO.swift @@ -0,0 +1,50 @@ +// +// TransactionReissueNode.swift +// WavesWallet-iOS +// +// Created by Prokofev Ruslan on 07/08/2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation + +public extension DomainLayer.DTO { + struct ReissueTransaction { + public let type: Int + public let id: String + public let sender: String + public let senderPublicKey: String + public let fee: Int64 + public let timestamp: Date + public let version: Int + public let height: Int64 + + public let signature: String? + public let proofs: [String]? + public let chainId: Int? + public let assetId: String + public let quantity: Int64 + public let reissuable: Bool + public var modified: Date + public var status: TransactionStatus + + public init(type: Int, id: String, sender: String, senderPublicKey: String, fee: Int64, timestamp: Date, version: Int, height: Int64, signature: String?, proofs: [String]?, chainId: Int?, assetId: String, quantity: Int64, reissuable: Bool, modified: Date, status: TransactionStatus) { + self.type = type + self.id = id + self.sender = sender + self.senderPublicKey = senderPublicKey + self.fee = fee + self.timestamp = timestamp + self.version = version + self.height = height + self.signature = signature + self.proofs = proofs + self.chainId = chainId + self.assetId = assetId + self.quantity = quantity + self.reissuable = reissuable + self.modified = modified + self.status = status + } + } +} diff --git a/DomainLayer/Sources/Models/DTO/Transactions/ScriptTransactionDomainDTO.swift b/DomainLayer/Sources/Models/DTO/Transactions/ScriptTransactionDomainDTO.swift new file mode 100644 index 00000000..aed0394d --- /dev/null +++ b/DomainLayer/Sources/Models/DTO/Transactions/ScriptTransactionDomainDTO.swift @@ -0,0 +1,47 @@ +// +// SetScriptTransactionDomainDTO.swift +// WavesWallet-iOS +// +// Created by mefilt on 22/01/2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation + +public extension DomainLayer.DTO { + struct ScriptTransaction { + + public let type: Int + public let id: String + public let sender: String + public let senderPublicKey: String + public let fee: Int64 + public let timestamp: Date + public let version: Int + public let height: Int64? + public let chainId: Int? + + public let signature: String? + public let proofs: [String]? + public var script: String? + public var modified: Date + public var status: TransactionStatus + + public init(type: Int, id: String, sender: String, senderPublicKey: String, fee: Int64, timestamp: Date, version: Int, height: Int64?, chainId: Int?, signature: String?, proofs: [String]?, script: String?, modified: Date, status: TransactionStatus) { + self.type = type + self.id = id + self.sender = sender + self.senderPublicKey = senderPublicKey + self.fee = fee + self.timestamp = timestamp + self.version = version + self.height = height + self.chainId = chainId + self.signature = signature + self.proofs = proofs + self.script = script + self.modified = modified + self.status = status + } + } +} diff --git a/DomainLayer/Sources/Models/DTO/Transactions/SmartTransactionDomainDTO.swift b/DomainLayer/Sources/Models/DTO/Transactions/SmartTransactionDomainDTO.swift new file mode 100644 index 00000000..b9efae3b --- /dev/null +++ b/DomainLayer/Sources/Models/DTO/Transactions/SmartTransactionDomainDTO.swift @@ -0,0 +1,264 @@ +// +// TransactionDomainDTO.swift +// WavesWallet-iOS +// +// Created by Prokofev Ruslan on 07/09/2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import Extensions + +public extension DomainLayer.DTO { + + struct AssetPair: Equatable { + public var amountAsset: Asset + public var priceAsset: Asset + + public init(amountAsset: Asset, priceAsset: Asset) { + self.amountAsset = amountAsset + self.priceAsset = priceAsset + } + } + + struct SmartTransaction: Equatable { + + public typealias Asset = DomainLayer.DTO.Asset + public typealias Account = DomainLayer.DTO.Address + + public enum Status: Equatable { + case activeNow + case completed + case unconfirmed + } + + public struct Transfer: Equatable { + public let balance: Balance + public let asset: Asset + + //It is for sent too (sender) + public let recipient: Account + public let attachment: String? + public let hasSponsorship: Bool + + public let myAccount: Account + + public init(balance: Balance, asset: Asset, recipient: Account, attachment: String?, hasSponsorship: Bool, myAccount: Account) { + self.balance = balance + self.asset = asset + self.recipient = recipient + self.attachment = attachment + self.hasSponsorship = hasSponsorship + self.myAccount = myAccount + } + } + + public struct Exchange: Equatable { + + public struct Order: Equatable { + public enum Kind: Equatable { + case buy + case sell + } + + public let timestamp: Date + public let expiration: Date + public let sender: Account + public let kind: Kind + public let pair: AssetPair + public let price: Balance + public let amount: Balance + public let total: Balance + + public init(timestamp: Date, expiration: Date, sender: Account, kind: Kind, pair: AssetPair, price: Balance, amount: Balance, total: Balance) { + self.timestamp = timestamp + self.expiration = expiration + self.sender = sender + self.kind = kind + self.pair = pair + self.price = price + self.amount = amount + self.total = total + } + } + + public let price: Balance + public let amount: Balance + public let total: Balance + public let buyMatcherFee: Balance + public let sellMatcherFee: Balance + public let order1: Order + public let order2: Order + + public init(price: Balance, amount: Balance, total: Balance, buyMatcherFee: Balance, sellMatcherFee: Balance, order1: Order, order2: Order) { + self.price = price + self.amount = amount + self.total = total + self.buyMatcherFee = buyMatcherFee + self.sellMatcherFee = sellMatcherFee + self.order1 = order1 + self.order2 = order2 + } + } + + public struct Leasing: Equatable { + public let asset: Asset + public let balance: Balance + public let account: Account + public let myAccount: Account + + public init(asset: Asset, balance: Balance, account: Account, myAccount: Account) { + self.asset = asset + self.balance = balance + self.account = account + self.myAccount = myAccount + } + } + + public struct Issue: Equatable { + public let asset: Asset + public let balance: Balance + public let description: String? + + public init(asset: Asset, balance: Balance, description: String?) { + self.asset = asset + self.balance = balance + self.description = description + } + } + + public struct MassTransfer: Equatable { + public struct Transfer: Equatable { + public let amount: Money + public let recipient: Account + + public init(amount: Money, recipient: Account) { + self.amount = amount + self.recipient = recipient + } + } + + public let total: Balance + public let asset: Asset + public let attachment: String? + public let transfers: [Transfer] + + public init(total: Balance, asset: Asset, attachment: String?, transfers: [Transfer]) { + self.total = total + self.asset = asset + self.attachment = attachment + self.transfers = transfers + } + } + + public struct MassReceive: Equatable { + public struct Transfer: Equatable { + public let amount: Money + public let recipient: Account + + public init(amount: Money, recipient: Account) { + self.amount = amount + self.recipient = recipient + } + } + + public let total: Balance + public let myTotal: Balance + public let asset: Asset + public let attachment: String? + public let transfers: [Transfer] + + public init(total: Balance, myTotal: Balance, asset: Asset, attachment: String?, transfers: [Transfer]) { + self.total = total + self.myTotal = myTotal + self.asset = asset + self.attachment = attachment + self.transfers = transfers + } + } + + public struct Data: Equatable { + public let prettyJSON: String + + public init(prettyJSON: String) { + self.prettyJSON = prettyJSON + } + } + + public struct InvokeScript: Equatable { + public struct Payment: Equatable { + public let amount: Money + public let asset: Asset? + + public init(amount: Money, asset: Asset?) { + self.amount = amount + self.asset = asset + } + } + public let payment: Payment? + public let scriptAddress: String + + public init(payment: Payment?, scriptAddress: String) { + self.payment = payment + self.scriptAddress = scriptAddress + } + } + + public enum Kind: Equatable { + case receive(Transfer) + case sent(Transfer) + case spamReceive(Transfer) + case selfTransfer(Transfer) + case massSent(MassTransfer) + case massReceived(MassReceive) + case spamMassReceived(MassReceive) + + case startedLeasing(Leasing) + case canceledLeasing(Leasing) + case incomingLeasing(Leasing) + + case exchange(Exchange) + + case tokenGeneration(Issue) + case tokenBurn(Issue) + case tokenReissue(Issue) + + case createdAlias(String) + + case unrecognisedTransaction + + case data(Data) + + case script(isHasScript: Bool) + case assetScript(Asset) + case sponsorship(isEnabled: Bool, asset: Asset) + case invokeScript(InvokeScript) + } + + public let id: String + public let type: Int + public let kind: Kind + public let timestamp: Date + public let totalFee: Balance + public let feeAsset: Asset + public let height: Int64? + public let confirmationHeight: Int64 + public let sender: Account + public let status: Status + + public init(id: String, type: Int, kind: Kind, timestamp: Date, totalFee: Balance, feeAsset: Asset, height: Int64?, confirmationHeight: Int64, sender: Account, status: Status) { + self.id = id + self.type = type + self.kind = kind + self.timestamp = timestamp + self.totalFee = totalFee + self.feeAsset = feeAsset + self.height = height + self.confirmationHeight = confirmationHeight + self.sender = sender + self.status = status + } + } +} + + diff --git a/DomainLayer/Sources/Models/DTO/Transactions/SponsorshipTransactionDomainDTO.swift b/DomainLayer/Sources/Models/DTO/Transactions/SponsorshipTransactionDomainDTO.swift new file mode 100644 index 00000000..145abbd2 --- /dev/null +++ b/DomainLayer/Sources/Models/DTO/Transactions/SponsorshipTransactionDomainDTO.swift @@ -0,0 +1,49 @@ +// +// SponsorshipTransaction.swift +// WavesWallet-iOS +// +// Created by Prokofev Ruslan on 05/02/2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation + +public extension DomainLayer.DTO { + public struct SponsorshipTransaction { + + public let type: Int + public let id: String + public let sender: String + public let senderPublicKey: String + public let fee: Int64 + public let timestamp: Date + public let version: Int + public let height: Int64? + + public let signature: String? + public let proofs: [String]? + + public var assetId: String + public let minSponsoredAssetFee: Int64? + + public var modified: Date + public var status: TransactionStatus + + public init(type: Int, id: String, sender: String, senderPublicKey: String, fee: Int64, timestamp: Date, version: Int, height: Int64?, signature: String?, proofs: [String]?, assetId: String, minSponsoredAssetFee: Int64?, modified: Date, status: TransactionStatus) { + self.type = type + self.id = id + self.sender = sender + self.senderPublicKey = senderPublicKey + self.fee = fee + self.timestamp = timestamp + self.version = version + self.height = height + self.signature = signature + self.proofs = proofs + self.assetId = assetId + self.minSponsoredAssetFee = minSponsoredAssetFee + self.modified = modified + self.status = status + } + } +} diff --git a/DomainLayer/Sources/Models/DTO/Transactions/TransferTransactionDomainDTO.swift b/DomainLayer/Sources/Models/DTO/Transactions/TransferTransactionDomainDTO.swift new file mode 100644 index 00000000..2641dcbc --- /dev/null +++ b/DomainLayer/Sources/Models/DTO/Transactions/TransferTransactionDomainDTO.swift @@ -0,0 +1,55 @@ +// +// TransactionTransferNode.swift +// WavesWallet-iOS +// +// Created by Prokofev Ruslan on 07/08/2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import Extensions + +public extension DomainLayer.DTO { + struct TransferTransaction: Decodable, Mutating { + public let type: Int + public let id: String + public let sender: String + public let senderPublicKey: String + public let fee: Int64 + public let timestamp: Date + public let version: Int + public let height: Int64 + + public let signature: String? + public let proofs: [String]? + public let recipient: String + public var assetId: String + public let feeAssetId: String + public let feeAsset: String? + public let amount: Int64 + public let attachment: String? + public var modified: Date + public var status: TransactionStatus + + public init(type: Int, id: String, sender: String, senderPublicKey: String, fee: Int64, timestamp: Date, version: Int, height: Int64, signature: String?, proofs: [String]?, recipient: String, assetId: String, feeAssetId: String, feeAsset: String?, amount: Int64, attachment: String?, modified: Date, status: TransactionStatus) { + self.type = type + self.id = id + self.sender = sender + self.senderPublicKey = senderPublicKey + self.fee = fee + self.timestamp = timestamp + self.version = version + self.height = height + self.signature = signature + self.proofs = proofs + self.recipient = recipient + self.assetId = assetId + self.feeAssetId = feeAssetId + self.feeAsset = feeAsset + self.amount = amount + self.attachment = attachment + self.modified = modified + self.status = status + } + } +} diff --git a/DomainLayer/Sources/Models/DTO/Transactions/UnrecognisedTransactionDomainDTO.swift b/DomainLayer/Sources/Models/DTO/Transactions/UnrecognisedTransactionDomainDTO.swift new file mode 100644 index 00000000..0d5dd035 --- /dev/null +++ b/DomainLayer/Sources/Models/DTO/Transactions/UnrecognisedTransactionDomainDTO.swift @@ -0,0 +1,35 @@ +// +// UnrecognisedTransactionDomainDTO.swift +// WavesWallet-iOS +// +// Created by mefilt on 31.08.2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation + +public extension DomainLayer.DTO { + struct UnrecognisedTransaction { + public let type: Int + public let id: String + public let sender: String + public let senderPublicKey: String + public let fee: Int64 + public let timestamp: Date + public let height: Int64 + public let modified: Date + public var status: TransactionStatus + + public init(type: Int, id: String, sender: String, senderPublicKey: String, fee: Int64, timestamp: Date, height: Int64, modified: Date, status: TransactionStatus) { + self.type = type + self.id = id + self.sender = sender + self.senderPublicKey = senderPublicKey + self.fee = fee + self.timestamp = timestamp + self.height = height + self.modified = modified + self.status = status + } + } +} diff --git a/DomainLayer/Sources/Models/DTO/WalletDomainDTO.swift b/DomainLayer/Sources/Models/DTO/WalletDomainDTO.swift new file mode 100644 index 00000000..744e9e90 --- /dev/null +++ b/DomainLayer/Sources/Models/DTO/WalletDomainDTO.swift @@ -0,0 +1,130 @@ +// +// WalletDomainDTO.swift +// WavesWallet-iOS +// +// Created by mefilt on 21.09.2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import WavesSDKExtensions +import Extensions + +public extension DomainLayer.DTO { + + struct Wallet: Mutating, Hashable { + public var name: String + public let address: String + public let publicKey: String + public var isLoggedIn: Bool + public var isBackedUp: Bool + public var hasBiometricEntrance: Bool + public let id: String + public var isNeedShowWalletCleanBanner: Bool + + public init(name: String, address: String, publicKey: String, isLoggedIn: Bool, isBackedUp: Bool, hasBiometricEntrance: Bool, id: String, isNeedShowWalletCleanBanner: Bool) { + self.name = name + self.address = address + self.publicKey = publicKey + self.isLoggedIn = isLoggedIn + self.isBackedUp = isBackedUp + self.hasBiometricEntrance = hasBiometricEntrance + self.id = id + self.isNeedShowWalletCleanBanner = isNeedShowWalletCleanBanner + } + } + + struct WalletEncryption: Mutating { + + public enum Kind { + case passcode(secret: String) + case none + + public var secret: String? { + switch self { + case .passcode(let secret): + return secret + default: + return nil + } + } + } + + public let publicKey: String + public var kind: Kind + public var seedId: String + + public init(publicKey: String, kind: Kind, seedId: String) { + self.publicKey = publicKey + self.kind = kind + self.seedId = seedId + } + } + + struct WalletSeed: Equatable { + public let publicKey: String + public let seed: String + public let address: String + + public init(publicKey: String, seed: String, address: String) { + self.publicKey = publicKey + self.seed = seed + self.address = address + } + } + + struct WalletRegistation { + public let name: String + public let address: String + public let privateKey: PrivateKeyAccount + public let isBackedUp: Bool + public let password: String + public let passcode: String + + public init(name: String, address: String, privateKey: PrivateKeyAccount, isBackedUp: Bool, password: String, passcode: String) { + self.name = name + self.address = address + self.privateKey = privateKey + self.isBackedUp = isBackedUp + self.password = password + self.passcode = passcode + } + } + + final class SignedWallet { + + public let wallet: DomainLayer.DTO.Wallet + public let publicKey: PublicKeyAccount + public let privateKey: PrivateKeyAccount + public let seed: WalletSeed + + public init(wallet: DomainLayer.DTO.Wallet, publicKey: PublicKeyAccount, privateKey: PrivateKeyAccount, seed: WalletSeed) { + self.wallet = wallet + self.publicKey = publicKey + self.privateKey = privateKey + self.seed = seed + } + + public var address: String { + return wallet.address + } + + public init(wallet: Wallet, + seed: WalletSeed) { + + self.seed = seed + self.wallet = wallet + self.publicKey = PublicKeyAccount(publicKey: seed.publicKey) + self.privateKey = PrivateKeyAccount(seedStr: seed.seed) + } + + public func sign(input: [UInt8], kind: [SigningKind]) throws -> [UInt8] { + let privateKey = PrivateKeyAccount(seedStr: seed.seed) + return Hash.sign(input, privateKey.privateKey) + } + + public var seedWords: [String] { + return seed.seed.split(separator: " ").map { "\($0)" } + } + } +} diff --git a/WavesWallet-iOS/DomainLayer/Models/ResponseType.swift b/DomainLayer/Sources/Models/ResponseType.swift similarity index 62% rename from WavesWallet-iOS/DomainLayer/Models/ResponseType.swift rename to DomainLayer/Sources/Models/ResponseType.swift index 9681e682..7063409e 100644 --- a/WavesWallet-iOS/DomainLayer/Models/ResponseType.swift +++ b/DomainLayer/Sources/Models/ResponseType.swift @@ -7,18 +7,24 @@ // import Foundation +import WavesSDK -struct ResponseType { +public struct ResponseType { - let output: T? - let error: NetworkError? + public let output: T? + public let error: NetworkError? + + public init(output: T?, error: NetworkError?) { + self.output = output + self.error = error + } - enum Result { + public enum Result { case success(T) case error(NetworkError) } - var result: Result { + public var result: Result { if let output = self.output { return Result.success(output) } diff --git a/DomainLayer/Sources/Models/WalletEnvironment.swift b/DomainLayer/Sources/Models/WalletEnvironment.swift new file mode 100644 index 00000000..072e4a66 --- /dev/null +++ b/DomainLayer/Sources/Models/WalletEnvironment.swift @@ -0,0 +1,117 @@ +// +// Environment.swift +// WavesWallet-iOS +// +// Created by Alexey Koloskov on 28/04/2017. +// Copyright © 2017 Waves Platform. All rights reserved. +// + +import Foundation +import WavesSDKExtensions + +private enum Constants { + static let alias = "alias" + fileprivate static let main = "environment_mainnet" + fileprivate static let test = "environment_testnet" + fileprivate static let stage = "environment_stagenet" + + static let vostokMainNetScheme = "V" + static let vostokTestNetScheme = "F" +} + +//TODO: Rename ? +public struct WalletEnvironment: Decodable { + + public enum Kind: String { + case mainnet = "W" + case testnet = "T" + case stagenet = "S" + + public var chainId: String { + return rawValue + } + + } + + public struct AssetInfo: Decodable { + + public struct Icon: Decodable { + public let `default`: String? + } + + public let assetId: String + public let displayName: String + public let isFiat: Bool + public let isGateway: Bool + public let wavesId: String + public let gatewayId: String + public let addressRegEx: String + public let iconUrls: Icon? + public let gatewayType: String? + } + + public struct Servers: Decodable { + public let nodeUrl: URL + public let dataUrl: URL + public let spamUrl: URL + public let matcherUrl: URL + public let gatewayUrl: URL + + public init(nodeUrl: URL, + dataUrl: URL, + spamUrl: URL, + matcherUrl: URL, + gatewayUrl: URL) { + + self.nodeUrl = nodeUrl + self.dataUrl = dataUrl + self.spamUrl = spamUrl + self.matcherUrl = matcherUrl + self.gatewayUrl = gatewayUrl + } + } + + public let name: String + public let servers: Servers + public let scheme: String + public let generalAssets: [AssetInfo] + public let assets: [AssetInfo]? + + public var kind: Kind { + return Kind.init(rawValue: scheme) ?? .mainnet + } + + public static let Testnet: WalletEnvironment = parseJSON(json: Constants.test)! + public static let Mainnet: WalletEnvironment = parseJSON(json: Constants.main)! + public static let Stagenet: WalletEnvironment = parseJSON(json: Constants.stage)! + + public init(name: String, + servers: Servers, + scheme: String, + generalAssets: [AssetInfo], + assets: [AssetInfo]?) { + + self.name = name + self.servers = servers + self.scheme = scheme + self.generalAssets = generalAssets + self.assets = assets + } + + private static func parseJSON(json fileName: String) -> WalletEnvironment? { + return JSONDecoder.decode(json: fileName) + } + +} + +public extension WalletEnvironment { + + var aliasScheme: String { + return Constants.alias + ":" + scheme + ":" + } + + var vostokScheme: String { + return self.kind == .testnet ? Constants.vostokTestNetScheme : Constants.vostokMainNetScheme + } +} + diff --git a/DomainLayer/Sources/Queries/DomainDexQueries.swift b/DomainLayer/Sources/Queries/DomainDexQueries.swift new file mode 100644 index 00000000..4ed9e139 --- /dev/null +++ b/DomainLayer/Sources/Queries/DomainDexQueries.swift @@ -0,0 +1,85 @@ +// +// OrderMatcherQueries.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 12/26/18. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import WavesSDKExtensions +import Extensions + +public extension DomainLayer.Query { + + enum Dex { + + public struct CreateOrder { + public let wallet: DomainLayer.DTO.SignedWallet + public let matcherPublicKey: PublicKeyAccount + public let amountAsset: String + public let priceAsset: String + public let amount: Int64 + public let price: Int64 + public let orderType: DomainLayer.DTO.Dex.OrderType + public let matcherFee: Int64 + public let timestamp: Int64 + public let expiration: Int64 + public let matcherFeeAsset: String + + public init(wallet: DomainLayer.DTO.SignedWallet, matcherPublicKey: PublicKeyAccount, amountAsset: String, priceAsset: String, amount: Int64, price: Int64, orderType: DomainLayer.DTO.Dex.OrderType, matcherFee: Int64, timestamp: Int64, expiration: Int64, matcherFeeAsset: String) { + self.wallet = wallet + self.matcherPublicKey = matcherPublicKey + self.amountAsset = amountAsset + self.priceAsset = priceAsset + self.amount = amount + self.price = price + self.orderType = orderType + self.matcherFee = matcherFee + self.timestamp = timestamp + self.expiration = expiration + self.matcherFeeAsset = matcherFeeAsset + } + } + + public struct CancelOrder { + public let wallet: DomainLayer.DTO.SignedWallet + public let orderId: String + public let amountAsset: String + public let priceAsset: String + + public init(wallet: DomainLayer.DTO.SignedWallet, orderId: String, amountAsset: String, priceAsset: String) { + self.wallet = wallet + self.orderId = orderId + self.amountAsset = amountAsset + self.priceAsset = priceAsset + } + } + + public struct SearchPairs { + + public struct Pair { + public let amountAsset: String + public let priceAsset: String + + public init(amountAsset: String, + priceAsset: String) { + self.amountAsset = amountAsset + self.priceAsset = priceAsset + } + } + + public enum Kind { + case pairs([Pair]) + case searchByAsset(String) + case searchByAssets(String) + } + + public let kind: Kind + + public init(kind: Kind) { + self.kind = kind + } + } + } +} diff --git a/WavesWallet-iOS/DomainLayer/Repositories/AccountBalance/AccountBalanceRepositoryProtocol.swift b/DomainLayer/Sources/Repositories/AccountBalanceRepositoryProtocol.swift similarity index 89% rename from WavesWallet-iOS/DomainLayer/Repositories/AccountBalance/AccountBalanceRepositoryProtocol.swift rename to DomainLayer/Sources/Repositories/AccountBalanceRepositoryProtocol.swift index 47b72e94..d8d9407f 100644 --- a/WavesWallet-iOS/DomainLayer/Repositories/AccountBalance/AccountBalanceRepositoryProtocol.swift +++ b/DomainLayer/Sources/Repositories/AccountBalanceRepositoryProtocol.swift @@ -9,11 +9,11 @@ import Foundation import RxSwift -enum AccountBalanceRepositoryError: Error { +public enum AccountBalanceRepositoryError: Error { case fail } -protocol AccountBalanceRepositoryProtocol { +public protocol AccountBalanceRepositoryProtocol { func balances(by wallet: DomainLayer.DTO.SignedWallet) -> Observable<[DomainLayer.DTO.AssetBalance]> func balance(by assetId: String, wallet: DomainLayer.DTO.SignedWallet) -> Observable diff --git a/WavesWallet-iOS/DomainLayer/Repositories/AccountSettingsRepositoryProtocol.swift b/DomainLayer/Sources/Repositories/AccountSettingsRepositoryProtocol.swift similarity index 50% rename from WavesWallet-iOS/DomainLayer/Repositories/AccountSettingsRepositoryProtocol.swift rename to DomainLayer/Sources/Repositories/AccountSettingsRepositoryProtocol.swift index 9fc621ed..633e1dea 100644 --- a/WavesWallet-iOS/DomainLayer/Repositories/AccountSettingsRepositoryProtocol.swift +++ b/DomainLayer/Sources/Repositories/AccountSettingsRepositoryProtocol.swift @@ -9,11 +9,17 @@ import Foundation import RxSwift -enum AccountSettingsRepositoryError: Error { +public enum AccountSettingsRepositoryError: Error { case invalid } -protocol AccountSettingsRepositoryProtocol { +public protocol AccountSettingsRepositoryProtocol { + + func saveAccountEnvironment(_ accountEnvironment: DomainLayer.DTO.AccountEnvironment, + accountAddress: String) -> Observable + func accountEnvironment(accountAddress: String) -> Observable + func accountSettings(accountAddress: String) -> Observable func saveAccountSettings(accountAddress: String, settings: DomainLayer.DTO.AccountSettings) -> Observable + func setSpamURL(_ url: String, by accountAddress: String) -> Observable } diff --git a/WavesWallet-iOS/DomainLayer/Repositories/AddressBook/AddressBookRepositoryProtocol.swift b/DomainLayer/Sources/Repositories/AddressBookRepositoryProtocol.swift similarity index 93% rename from WavesWallet-iOS/DomainLayer/Repositories/AddressBook/AddressBookRepositoryProtocol.swift rename to DomainLayer/Sources/Repositories/AddressBookRepositoryProtocol.swift index 26449de8..78dc7b76 100644 --- a/WavesWallet-iOS/DomainLayer/Repositories/AddressBook/AddressBookRepositoryProtocol.swift +++ b/DomainLayer/Sources/Repositories/AddressBookRepositoryProtocol.swift @@ -9,7 +9,7 @@ import Foundation import RxSwift -protocol AddressBookRepositoryProtocol { +public protocol AddressBookRepositoryProtocol { func contact(by address: String, accountAddress: String) -> Observable func save(contact: DomainLayer.DTO.Contact, accountAddress: String) -> Observable diff --git a/WavesWallet-iOS/DomainLayer/Repositories/AddressRepositoryProtocol.swift b/DomainLayer/Sources/Repositories/AddressRepositoryProtocol.swift similarity index 86% rename from WavesWallet-iOS/DomainLayer/Repositories/AddressRepositoryProtocol.swift rename to DomainLayer/Sources/Repositories/AddressRepositoryProtocol.swift index b86e8292..03f90f9e 100644 --- a/WavesWallet-iOS/DomainLayer/Repositories/AddressRepositoryProtocol.swift +++ b/DomainLayer/Sources/Repositories/AddressRepositoryProtocol.swift @@ -9,7 +9,7 @@ import Foundation import RxSwift -protocol AddressRepositoryProtocol { +public protocol AddressRepositoryProtocol { func isSmartAddress(accountAddress: String) -> Observable } diff --git a/WavesWallet-iOS/DomainLayer/Repositories/AliasesRepositoryProtocol.swift b/DomainLayer/Sources/Repositories/AliasesRepositoryProtocol.swift similarity index 85% rename from WavesWallet-iOS/DomainLayer/Repositories/AliasesRepositoryProtocol.swift rename to DomainLayer/Sources/Repositories/AliasesRepositoryProtocol.swift index 01ba795f..33b4af02 100644 --- a/WavesWallet-iOS/DomainLayer/Repositories/AliasesRepositoryProtocol.swift +++ b/DomainLayer/Sources/Repositories/AliasesRepositoryProtocol.swift @@ -9,12 +9,12 @@ import Foundation import RxSwift -enum AliasesRepositoryError: Error { +public enum AliasesRepositoryError: Error { case invalid case dontExist } -protocol AliasesRepositoryProtocol { +public protocol AliasesRepositoryProtocol { func aliases(accountAddress: String) -> Observable<[DomainLayer.DTO.Alias]> func alias(by name: String, accountAddress: String) -> Observable func saveAliases(by accountAddress: String, aliases: [DomainLayer.DTO.Alias]) -> Observable diff --git a/WavesWallet-iOS/DomainLayer/Repositories/ApplicationVersionRepositoryProtocol.swift b/DomainLayer/Sources/Repositories/ApplicationVersionRepositoryProtocol.swift similarity index 70% rename from WavesWallet-iOS/DomainLayer/Repositories/ApplicationVersionRepositoryProtocol.swift rename to DomainLayer/Sources/Repositories/ApplicationVersionRepositoryProtocol.swift index bb38e91b..10237ac4 100644 --- a/WavesWallet-iOS/DomainLayer/Repositories/ApplicationVersionRepositoryProtocol.swift +++ b/DomainLayer/Sources/Repositories/ApplicationVersionRepositoryProtocol.swift @@ -9,6 +9,7 @@ import Foundation import RxSwift -protocol ApplicationVersionRepositoryProtocol { +public protocol ApplicationVersionRepositoryProtocol { func version() -> Observable + func forceUpdateVersion() -> Observable } diff --git a/WavesWallet-iOS/DomainLayer/Repositories/AssetsBalanceSettingsRepositoryProtocol.swift b/DomainLayer/Sources/Repositories/AssetsBalanceSettingsRepositoryProtocol.swift similarity index 86% rename from WavesWallet-iOS/DomainLayer/Repositories/AssetsBalanceSettingsRepositoryProtocol.swift rename to DomainLayer/Sources/Repositories/AssetsBalanceSettingsRepositoryProtocol.swift index 5ae7ec73..4ef83cab 100644 --- a/WavesWallet-iOS/DomainLayer/Repositories/AssetsBalanceSettingsRepositoryProtocol.swift +++ b/DomainLayer/Sources/Repositories/AssetsBalanceSettingsRepositoryProtocol.swift @@ -8,21 +8,19 @@ import Foundation import RxSwift -import RealmSwift -import RxRealm -enum RepositoryError: Error { +public enum RepositoryError: Error { case fail case notFound } -extension Float { +public extension Float { var notFound: Float { return -1 } } -protocol AssetsBalanceSettingsRepositoryProtocol { +public protocol AssetsBalanceSettingsRepositoryProtocol { func settings(by accountAddress: String, ids: [String]) -> Observable<[String: DomainLayer.DTO.AssetBalanceSettings]> func settings(by accountAddress: String) -> Observable<[DomainLayer.DTO.AssetBalanceSettings]> func listenerSettings(by accountAddress: String, ids: [String]) -> Observable<[DomainLayer.DTO.AssetBalanceSettings]> diff --git a/WavesWallet-iOS/DomainLayer/Repositories/Assets/AssetsRepositoryProtocol.swift b/DomainLayer/Sources/Repositories/AssetsRepositoryProtocol.swift similarity index 78% rename from WavesWallet-iOS/DomainLayer/Repositories/Assets/AssetsRepositoryProtocol.swift rename to DomainLayer/Sources/Repositories/AssetsRepositoryProtocol.swift index 68b300aa..a83bed27 100644 --- a/WavesWallet-iOS/DomainLayer/Repositories/Assets/AssetsRepositoryProtocol.swift +++ b/DomainLayer/Sources/Repositories/AssetsRepositoryProtocol.swift @@ -9,12 +9,12 @@ import Foundation import RxSwift -enum AssetsRepositoryError: Error { +public enum AssetsRepositoryError: Error { case fail case notFound } -protocol AssetsRepositoryProtocol { +public protocol AssetsRepositoryProtocol { func assets(by ids: [String], accountAddress: String) -> Observable<[DomainLayer.DTO.Asset]> @@ -22,4 +22,6 @@ protocol AssetsRepositoryProtocol { func saveAsset(_ asset: DomainLayer.DTO.Asset, by accountAddress: String) -> Observable func isSmartAsset(_ assetId: String, by accountAddress: String) -> Observable + + func searchAssets(search: String) -> Observable<[DomainLayer.DTO.Asset]> } diff --git a/WavesWallet-iOS/DomainLayer/Repositories/AuthenticationRepositoryProtocol.swift b/DomainLayer/Sources/Repositories/AuthenticationRepositoryProtocol.swift similarity index 84% rename from WavesWallet-iOS/DomainLayer/Repositories/AuthenticationRepositoryProtocol.swift rename to DomainLayer/Sources/Repositories/AuthenticationRepositoryProtocol.swift index e1dd7409..d6d9119a 100644 --- a/WavesWallet-iOS/DomainLayer/Repositories/AuthenticationRepositoryProtocol.swift +++ b/DomainLayer/Sources/Repositories/AuthenticationRepositoryProtocol.swift @@ -9,14 +9,14 @@ import Foundation import RxSwift -enum AuthenticationRepositoryError: Error { +public enum AuthenticationRepositoryError: Error { case fail case passcodeIncorrect case permissionDenied case attemptsEnded } -protocol AuthenticationRepositoryProtocol { +public protocol AuthenticationRepositoryProtocol { func registration(with id: String, keyForPassword: String, passcode: String) -> Observable func auth(with id: String, passcode: String) -> Observable func changePasscode(with id: String, oldPasscode: String, passcode: String) -> Observable diff --git a/WavesWallet-iOS/DomainLayer/Repositories/BlockRepositoryProtocol.swift b/DomainLayer/Sources/Repositories/BlockRepositoryProtocol.swift similarity index 76% rename from WavesWallet-iOS/DomainLayer/Repositories/BlockRepositoryProtocol.swift rename to DomainLayer/Sources/Repositories/BlockRepositoryProtocol.swift index bdb264ea..97ae5896 100644 --- a/WavesWallet-iOS/DomainLayer/Repositories/BlockRepositoryProtocol.swift +++ b/DomainLayer/Sources/Repositories/BlockRepositoryProtocol.swift @@ -9,10 +9,10 @@ import Foundation import RxSwift -enum BlockRepositoryError: Error { +public enum BlockRepositoryError: Error { case fail } -protocol BlockRepositoryProtocol { +public protocol BlockRepositoryProtocol { func height(accountAddress: String) -> Observable } diff --git a/DomainLayer/Sources/Repositories/CandlesRepositoryProtocol.swift b/DomainLayer/Sources/Repositories/CandlesRepositoryProtocol.swift new file mode 100644 index 00000000..5982fcc0 --- /dev/null +++ b/DomainLayer/Sources/Repositories/CandlesRepositoryProtocol.swift @@ -0,0 +1,14 @@ +// +// CandlesRepositoryProtocol.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 12/5/18. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift + +public protocol CandlesRepositoryProtocol { + func candles(amountAsset: String, priceAsset: String, timeStart: Date, timeEnd: Date, timeFrame: DomainLayer.DTO.Candle.TimeFrameType) -> Observable<[DomainLayer.DTO.Candle]> +} diff --git a/WavesWallet-iOS/DomainLayer/Repositories/CoinomatRepositoryProtocol.swift b/DomainLayer/Sources/Repositories/CoinomatRepositoryProtocol.swift similarity index 92% rename from WavesWallet-iOS/DomainLayer/Repositories/CoinomatRepositoryProtocol.swift rename to DomainLayer/Sources/Repositories/CoinomatRepositoryProtocol.swift index afa6faa2..b46daeb1 100644 --- a/WavesWallet-iOS/DomainLayer/Repositories/CoinomatRepositoryProtocol.swift +++ b/DomainLayer/Sources/Repositories/CoinomatRepositoryProtocol.swift @@ -8,8 +8,9 @@ import Foundation import RxSwift +import Extensions -protocol CoinomatRepositoryProtocol { +public protocol CoinomatRepositoryProtocol { func tunnelInfo(asset: DomainLayer.DTO.Asset, currencyFrom: String, currencyTo: String, walletTo: String, moneroPaymentID: String?) -> Observable func getRate(asset: DomainLayer.DTO.Asset) -> Observable func cardLimits(address: String, fiat: String) -> Observable diff --git a/WavesWallet-iOS/DomainLayer/Repositories/Dex/DexOrderBookRepositoryProtocol.swift b/DomainLayer/Sources/Repositories/DexOrderBookRepositoryProtocol.swift similarity index 63% rename from WavesWallet-iOS/DomainLayer/Repositories/Dex/DexOrderBookRepositoryProtocol.swift rename to DomainLayer/Sources/Repositories/DexOrderBookRepositoryProtocol.swift index 5b5d4e54..5349a898 100644 --- a/WavesWallet-iOS/DomainLayer/Repositories/Dex/DexOrderBookRepositoryProtocol.swift +++ b/DomainLayer/Sources/Repositories/DexOrderBookRepositoryProtocol.swift @@ -9,15 +9,17 @@ import Foundation import RxSwift -protocol DexOrderBookRepositoryProtocol { +public protocol DexOrderBookRepositoryProtocol { - func orderBook(wallet: DomainLayer.DTO.SignedWallet, amountAsset: String, priceAsset: String) -> Observable + func orderBook(amountAsset: String, priceAsset: String) -> Observable - func markets(wallet: DomainLayer.DTO.SignedWallet) -> Observable<[DomainLayer.DTO.Dex.SmartPair]> + func markets(wallet: DomainLayer.DTO.SignedWallet, pairs: [DomainLayer.DTO.Dex.Pair]) -> Observable<[DomainLayer.DTO.Dex.SmartPair]> func myOrders(wallet: DomainLayer.DTO.SignedWallet, amountAsset: DomainLayer.DTO.Dex.Asset, priceAsset: DomainLayer.DTO.Dex.Asset) -> Observable<[DomainLayer.DTO.Dex.MyOrder]> func cancelOrder(wallet: DomainLayer.DTO.SignedWallet, orderId: String, amountAsset: String, priceAsset: String) -> Observable func createOrder(wallet: DomainLayer.DTO.SignedWallet, order: DomainLayer.Query.Dex.CreateOrder) -> Observable + + func orderSettingsFee() -> Observable } diff --git a/DomainLayer/Sources/Repositories/DexPairsPriceRepositoryProtocol.swift b/DomainLayer/Sources/Repositories/DexPairsPriceRepositoryProtocol.swift new file mode 100644 index 00000000..2df7e058 --- /dev/null +++ b/DomainLayer/Sources/Repositories/DexPairsPriceRepositoryProtocol.swift @@ -0,0 +1,20 @@ +// +// DexListRepositoryRemote.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 12/17/18. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift + +public protocol DexPairsPriceRepositoryProtocol { + + func list(pairs: [DomainLayer.DTO.Dex.Pair]) -> Observable<[DomainLayer.DTO.Dex.PairPrice]> + + //TODO: Refactor searchPairs and search + func searchPairs(_ query: DomainLayer.Query.Dex.SearchPairs) -> Observable + + func search(by accountAddress: String, searchText: String) -> Observable<[DomainLayer.DTO.Dex.SimplePair]> +} diff --git a/WavesWallet-iOS/DomainLayer/Repositories/Dex/DexRealmRepositoryProtocol.swift b/DomainLayer/Sources/Repositories/DexRealmRepositoryProtocol.swift similarity index 94% rename from WavesWallet-iOS/DomainLayer/Repositories/Dex/DexRealmRepositoryProtocol.swift rename to DomainLayer/Sources/Repositories/DexRealmRepositoryProtocol.swift index 4af437df..af63ab29 100644 --- a/WavesWallet-iOS/DomainLayer/Repositories/Dex/DexRealmRepositoryProtocol.swift +++ b/DomainLayer/Sources/Repositories/DexRealmRepositoryProtocol.swift @@ -9,7 +9,7 @@ import Foundation import RxSwift -protocol DexRealmRepositoryProtocol { +public protocol DexRealmRepositoryProtocol { func save(pair: DomainLayer.DTO.Dex.SmartPair, accountAddress: String) -> Observable func delete(by id: String, accountAddress: String) -> Observable diff --git a/DomainLayer/Sources/Repositories/EnvironmentRepositoryProtocol.swift b/DomainLayer/Sources/Repositories/EnvironmentRepositoryProtocol.swift new file mode 100644 index 00000000..694d2133 --- /dev/null +++ b/DomainLayer/Sources/Repositories/EnvironmentRepositoryProtocol.swift @@ -0,0 +1,33 @@ +// +// EnvironmentsInteractor.swift +// WavesWallet-iOS +// +// Created by mefilt on 18/10/2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import WavesSDKExtensions +import Extensions + +public enum EnvironmentRepositoryError: Error { + case invalidURL + case invalidResponse +} + +public protocol ApplicationEnvironmentProtocol { + var walletEnvironment: WalletEnvironment { get } + var timestampServerDiff: Int64 { get } +} + + +public protocol EnvironmentRepositoryProtocol { + + func applicationEnvironment() -> Observable + + func walletEnvironment() -> Observable + func deffaultEnvironment() -> Observable + + var environmentKind: WalletEnvironment.Kind { get set } +} diff --git a/DomainLayer/Sources/Repositories/GatewayRepositoryProtocol.swift b/DomainLayer/Sources/Repositories/GatewayRepositoryProtocol.swift new file mode 100644 index 00000000..ad996211 --- /dev/null +++ b/DomainLayer/Sources/Repositories/GatewayRepositoryProtocol.swift @@ -0,0 +1,18 @@ +// +// GatewayRepositoryProtocol.swift +// InternalDomainLayer +// +// Created by Pavel Gubin on 22.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift + +public protocol GatewayRepositoryProtocol { + + func startWithdrawProcess(address: String, asset: DomainLayer.DTO.Asset) -> Observable + func startDepositProcess(address: String, asset: DomainLayer.DTO.Asset) -> Observable + func send(by specifications: TransactionSenderSpecifications, wallet: DomainLayer.DTO.SignedWallet) -> Observable + +} diff --git a/DomainLayer/Sources/Repositories/LastTradesRepositoryProtocol.swift b/DomainLayer/Sources/Repositories/LastTradesRepositoryProtocol.swift new file mode 100644 index 00000000..6e56ef9e --- /dev/null +++ b/DomainLayer/Sources/Repositories/LastTradesRepositoryProtocol.swift @@ -0,0 +1,14 @@ +// +// LastTradesRepositoryProtocol.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 12/5/18. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift + +public protocol LastTradesRepositoryProtocol { + func lastTrades(amountAsset: DomainLayer.DTO.Dex.Asset, priceAsset: DomainLayer.DTO.Dex.Asset, limit: Int) -> Observable<[DomainLayer.DTO.Dex.LastTrade]> +} diff --git a/DomainLayer/Sources/Repositories/MarketPulseWidgetSettingsRepositoryProtocol.swift b/DomainLayer/Sources/Repositories/MarketPulseWidgetSettingsRepositoryProtocol.swift new file mode 100644 index 00000000..87d4327c --- /dev/null +++ b/DomainLayer/Sources/Repositories/MarketPulseWidgetSettingsRepositoryProtocol.swift @@ -0,0 +1,14 @@ +// +// MarketPulseWidgetSettingsRepositoryProtocol.swift +// DomainLayer +// +// Created by Pavel Gubin on 29.07.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift + +public protocol MarketPulseWidgetSettingsRepositoryProtocol { + func settings() -> Observable +} diff --git a/WavesWallet-iOS/DomainLayer/Repositories/Dex/MatcherRepositoryProtocol.swift b/DomainLayer/Sources/Repositories/MatcherRepositoryProtocol.swift similarity index 50% rename from WavesWallet-iOS/DomainLayer/Repositories/Dex/MatcherRepositoryProtocol.swift rename to DomainLayer/Sources/Repositories/MatcherRepositoryProtocol.swift index 7f35c1aa..fd7e1db4 100644 --- a/WavesWallet-iOS/DomainLayer/Repositories/Dex/MatcherRepositoryProtocol.swift +++ b/DomainLayer/Sources/Repositories/MatcherRepositoryProtocol.swift @@ -8,10 +8,12 @@ import Foundation import RxSwift -import WavesSDKExtension -import WavesSDKCrypto +import WavesSDKExtensions +import Extensions -protocol MatcherRepositoryProtocol { +public protocol MatcherRepositoryProtocol { - func matcherPublicKey(accountAddress: String) -> Observable + func matcherPublicKey() -> Observable + + func settingsIdsPairs() -> Observable<[String]> } diff --git a/DomainLayer/Sources/Repositories/MobileKeeperRepositoryProtocol.swift b/DomainLayer/Sources/Repositories/MobileKeeperRepositoryProtocol.swift new file mode 100644 index 00000000..d59c0b6b --- /dev/null +++ b/DomainLayer/Sources/Repositories/MobileKeeperRepositoryProtocol.swift @@ -0,0 +1,139 @@ +// +// MobileKeeperRepositoryProtocol.swift +// DomainLayer +// +// Created by rprokofev on 30.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import WavesSDKCrypto + +public extension DomainLayer.DTO { + enum MobileKeeper {} +} + +public extension DomainLayer.DTO.MobileKeeper { + + struct Application { + public let name: String + public let iconUrl: String + public let scheme: String + + public init(name: String, iconUrl: String, scheme: String) { + self.name = name + self.iconUrl = iconUrl + self.scheme = scheme + } + } + + enum Action { + case sign + case send + } + + struct Request { + public let dApp: Application + public let action: Action + public let transaction: TransactionSenderSpecifications + public let id: String + + public init(dApp: Application, + action: Action, + transaction: TransactionSenderSpecifications, + id: String) { + self.dApp = dApp + self.action = action + self.transaction = transaction + self.id = id + } + } + + enum Success { + case sign(TransactionSenderSpecifications) + case send(DomainLayer.DTO.AnyTransaction) + } + + enum Error { + case reject + case message(String, Int) + case invalidRequest + case transactionDontSupport + } + + struct Response { + public enum Kind { + case error(Error) + case success(Success) + } + + public let requestId: String + public let kind: Kind + + public init(requestId: String, kind: Kind) { + self.requestId = requestId + self.kind = kind + } + } + + + struct CompletedRequest { + public let request: Request + public let timestamp: Date + public let proof: Bytes + public let txId: String + public let publicKey: String + public let response: Response + + public init(request: Request, timestamp: Date, proof: Bytes, txId: String, publicKey: String, response: Response) { + self.request = request + self.timestamp = timestamp + self.proof = proof + self.txId = txId + self.response = response + self.publicKey = publicKey + } + } + + struct PrepareRequest { + public let request: Request + public let timestamp: Date + public let proof: Bytes + public let txId: String + public let signedWallet: DomainLayer.DTO.SignedWallet + + public init(request: Request, timestamp: Date, proof: Bytes, txId: String, signedWallet: DomainLayer.DTO.SignedWallet) { + self.request = request + self.timestamp = timestamp + self.proof = proof + self.txId = txId + self.signedWallet = signedWallet + } + } +} + +public enum MobileKeeperUseCaseError: Error { + case none + case dAppDontOpen + case transactionDontSupport + case dataIncorrect +} + +public protocol MobileKeeperRepositoryProtocol { + + + func prepareRequest(_ request: DomainLayer.DTO.MobileKeeper.Request, + signedWallet: DomainLayer.DTO.SignedWallet, + timestamp: Date) -> Observable + + func completeRequest(_ prepareRequest: DomainLayer.DTO.MobileKeeper.PrepareRequest) -> Observable + + func decodableRequest(_ url: URL) -> Observable + + func approveRequest(_ completedRequest: DomainLayer.DTO.MobileKeeper.CompletedRequest) -> Observable + + func rejectRequest(_ request: DomainLayer.DTO.MobileKeeper.Request) -> Observable + + func errorRequest(_ request: DomainLayer.DTO.MobileKeeper.Request, error: DomainLayer.DTO.MobileKeeper.Error) -> Observable +} diff --git a/WavesWallet-iOS/DomainLayer/Repositories/NotificationNewsRepositoryProtocol.swift b/DomainLayer/Sources/Repositories/NotificationNewsRepositoryProtocol.swift similarity index 84% rename from WavesWallet-iOS/DomainLayer/Repositories/NotificationNewsRepositoryProtocol.swift rename to DomainLayer/Sources/Repositories/NotificationNewsRepositoryProtocol.swift index c538a91f..dbe497ff 100644 --- a/WavesWallet-iOS/DomainLayer/Repositories/NotificationNewsRepositoryProtocol.swift +++ b/DomainLayer/Sources/Repositories/NotificationNewsRepositoryProtocol.swift @@ -9,7 +9,7 @@ import Foundation import RxSwift -protocol NotificationNewsRepositoryProtocol { +public protocol NotificationNewsRepositoryProtocol { func notificationNews() -> Observable<[DomainLayer.DTO.NotificationNews]> } diff --git a/DomainLayer/Sources/Repositories/SpamAssetsRepositoryProtocol.swift b/DomainLayer/Sources/Repositories/SpamAssetsRepositoryProtocol.swift new file mode 100644 index 00000000..de782bbb --- /dev/null +++ b/DomainLayer/Sources/Repositories/SpamAssetsRepositoryProtocol.swift @@ -0,0 +1,18 @@ +// +// SpamAssetsRepositoryProtocol.swift +// WavesWallet-iOS +// +// Created by rprokofev on 25.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import Moya +import RxSwift + +public typealias SpamAssetId = String + +public protocol SpamAssetsRepositoryProtocol { + + func spamAssets(accountAddress: String) -> Observable<[SpamAssetId]> +} diff --git a/DomainLayer/Sources/Repositories/TransactionsRepositoryProtocol.swift b/DomainLayer/Sources/Repositories/TransactionsRepositoryProtocol.swift new file mode 100644 index 00000000..6ea210af --- /dev/null +++ b/DomainLayer/Sources/Repositories/TransactionsRepositoryProtocol.swift @@ -0,0 +1,336 @@ +// +// Transactions.swift +// WavesWallet-iOS +// +// Created by mefilt on 29.08.2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import WavesSDK + +public enum TransactionsRepositoryError: Error { + case fail +} + +public enum TransactionStatus: Int, Decodable { + case activeNow + case completed + case unconfirmed +} + +public extension TransactionType { + + static var all: [TransactionType] { + return [.issue, + .transfer, + .reissue, + .burn, + .exchange, + .createLease, + .cancelLease, + .createAlias, + .massTransfer, + .data, + .script, + .sponsorship, + .assetScript, + .invokeScript] + } +} + +public struct TransactionsSpecifications { + + public struct Page { + public let offset: Int + public let limit: Int + + public init(offset: Int, limit: Int) { + self.offset = offset + self.limit = limit + } + } + + public let page: Page? + public let assets: [String] + public let senders: [String] + public let types: [TransactionType] + + public init(page: Page?, assets: [String], senders: [String], types: [TransactionType]) { + self.page = page + self.assets = assets + self.senders = senders + self.types = types + } +} + + +public struct AliasTransactionSender { + public let alias: String + public let fee: Int64 + + public init(alias: String, fee: Int64) { + self.alias = alias + self.fee = fee + } +} + +public struct LeaseTransactionSender { + public let recipient: String + public let amount: Int64 + public let fee: Int64 + + public init(recipient: String, amount: Int64, fee: Int64) { + self.recipient = recipient + self.amount = amount + self.fee = fee + } +} + +public struct BurnTransactionSender { + public let assetID: String + public let quantity: Int64 + public let fee: Int64 + + public init(assetID: String, quantity: Int64, fee: Int64) { + self.assetID = assetID + self.quantity = quantity + self.fee = fee + } +} + +public struct CancelLeaseTransactionSender { + public let leaseId: String + public let fee: Int64 + + public init(leaseId: String, fee: Int64) { + self.leaseId = leaseId + self.fee = fee + } +} + +public struct SendTransactionSender { + public let recipient: String + public let assetId: String + public let amount: Int64 + public let fee: Int64 + public let attachment: String + public let feeAssetID: String + public let chainId: String? + public let timestamp: Date? + + public init(recipient: String, + assetId: String, + amount: Int64, + fee: Int64, + attachment: String, + feeAssetID: String, + chainId: String? = nil, + timestamp: Date? = nil) { + self.recipient = recipient + self.assetId = assetId + self.chainId = chainId + self.amount = amount + self.timestamp = timestamp + self.fee = fee + self.attachment = attachment + self.feeAssetID = feeAssetID + } +} + +public struct DataTransactionSender { + public struct Value { + public enum Kind { + case integer(Int64) + case boolean(Bool) + case string(String) + case binary(String) + } + + public let key: String + public let value: Kind + + public init(key: String, value: Kind) { + self.key = key + self.value = value + } + } + + public let fee: Int64 + public let data: [Value] + public let chainId: String? + public let timestamp: Date? + + public init(fee: Int64, data: [Value], chainId: String? = nil, timestamp: Date? = nil) { + self.fee = fee + self.data = data + self.timestamp = timestamp + self.chainId = chainId + } +} + +public struct InvokeScriptTransactionSender { + + public struct Arg { + public enum Value { + case bool(Bool) //boolean + case integer(Int64) // integer + case string(String) // string + case binary(String) // binary + } + + public let value: Value + + public init(value: Value) { + self.value = value + } + } + + public struct Call { + public let function: String + public let args: [Arg] + + public init(function: String, args: [Arg]) { + self.function = function + self.args = args + } + } + + public struct Payment { + public let amount: Int64 + public let assetId: String + + public init(amount: Int64, assetId: String) { + self.amount = amount + self.assetId = assetId + } + } + + public let fee: Int64 + public let feeAssetId: String + public let dApp: String + public let call: Call? + public let payment: [Payment] + public let chainId: String? + public let timestamp: Date? + + public init(fee: Int64, + feeAssetId: String, + dApp: String, + call: Call?, + payment: [Payment], + chainId: String?, + timestamp: Date?) { + self.fee = fee + self.feeAssetId = feeAssetId + self.dApp = dApp + self.call = call + self.payment = payment + self.timestamp = timestamp + self.chainId = chainId + } +} + +//TOOD: Rename to Query +public enum TransactionSenderSpecifications { + case createAlias(AliasTransactionSender) + case lease(LeaseTransactionSender) + case burn(BurnTransactionSender) + case cancelLease(CancelLeaseTransactionSender) + case data(DataTransactionSender) + case send(SendTransactionSender) + case invokeScript(InvokeScriptTransactionSender) + + + public var timestamp: Date? { + switch self { + case .data(let model): + return model.timestamp + + case .send(let model): + return model.timestamp + + case .invokeScript(let model): + return model.timestamp + + default: + return nil + } + } + + public var chainId: String? { + switch self { + case .data(let model): + return model.chainId + + case .send(let model): + return model.chainId + + case .invokeScript(let model): + return model.chainId + + default: + return nil + } + } + +} + +public protocol TransactionsRepositoryProtocol { + + func transactions(by address: DomainLayer.DTO.Address, offset: Int, limit: Int) -> Observable<[DomainLayer.DTO.AnyTransaction]> + func transactions(by address: DomainLayer.DTO.Address, specifications: TransactionsSpecifications) -> Observable<[DomainLayer.DTO.AnyTransaction]> + func newTransactions(by address: DomainLayer.DTO.Address, + specifications: TransactionsSpecifications) -> Observable<[DomainLayer.DTO.AnyTransaction]> + + func activeLeasingTransactions(by accountAddress: String) -> Observable<[DomainLayer.DTO.LeaseTransaction]> + + func saveTransactions(_ transactions: [DomainLayer.DTO.AnyTransaction], accountAddress: String) -> Observable + + func isHasTransaction(by id: String, accountAddress: String, ignoreUnconfirmed: Bool) -> Observable + func isHasTransactions(by ids: [String], accountAddress: String, ignoreUnconfirmed: Bool) -> Observable + func isHasTransactions(by accountAddress: String, ignoreUnconfirmed: Bool) -> Observable + + func send(by specifications: TransactionSenderSpecifications, wallet: DomainLayer.DTO.SignedWallet) -> Observable + + func feeRules() -> Observable +} + +extension DomainLayer.DTO { + + public struct TransactionFeeRules { + public struct Rule { + public let addSmartAssetFee: Bool + public let addSmartAccountFee: Bool + public let minPriceStep: Int64 + public let fee: Int64 + public let pricePerTransfer: Int64 + public let pricePerKb: Int64 + + + public init(addSmartAssetFee: Bool, addSmartAccountFee: Bool, minPriceStep: Int64, fee: Int64, pricePerTransfer: Int64, pricePerKb: Int64) { + self.addSmartAssetFee = addSmartAssetFee + self.addSmartAccountFee = addSmartAccountFee + self.minPriceStep = minPriceStep + self.fee = fee + self.pricePerTransfer = pricePerTransfer + self.pricePerKb = pricePerKb + } + } + + public let smartAssetExtraFee: Int64 + public let smartAccountExtraFee: Int64 + + public let defaultRule: TransactionFeeRules.Rule + public let rules: [TransactionType: TransactionFeeRules.Rule] + + public init(smartAssetExtraFee: Int64, smartAccountExtraFee: Int64, defaultRule: TransactionFeeRules.Rule, rules: [TransactionType: TransactionFeeRules.Rule]) { + self.smartAssetExtraFee = smartAssetExtraFee + self.smartAccountExtraFee = smartAccountExtraFee + self.defaultRule = defaultRule + self.rules = rules + } + } +} + diff --git a/WavesWallet-iOS/DomainLayer/Repositories/UtilsRepositoryProtocol.swift b/DomainLayer/Sources/Repositories/UtilsRepositoryProtocol.swift similarity index 86% rename from WavesWallet-iOS/DomainLayer/Repositories/UtilsRepositoryProtocol.swift rename to DomainLayer/Sources/Repositories/UtilsRepositoryProtocol.swift index 08f01ab0..5f355b11 100644 --- a/WavesWallet-iOS/DomainLayer/Repositories/UtilsRepositoryProtocol.swift +++ b/DomainLayer/Sources/Repositories/UtilsRepositoryProtocol.swift @@ -9,6 +9,6 @@ import Foundation import RxSwift -protocol UtilsRepositoryProtocol { +public protocol UtilsRepositoryProtocol { func timestampServerDiff(accountAddress: String) -> Observable } diff --git a/WavesWallet-iOS/DomainLayer/Repositories/WalletSeedRepositoryProtocol.swift b/DomainLayer/Sources/Repositories/WalletSeedRepositoryProtocol.swift similarity index 83% rename from WavesWallet-iOS/DomainLayer/Repositories/WalletSeedRepositoryProtocol.swift rename to DomainLayer/Sources/Repositories/WalletSeedRepositoryProtocol.swift index 9b8e8fdd..3f34cd26 100644 --- a/WavesWallet-iOS/DomainLayer/Repositories/WalletSeedRepositoryProtocol.swift +++ b/DomainLayer/Sources/Repositories/WalletSeedRepositoryProtocol.swift @@ -11,20 +11,20 @@ import RxSwift typealias StringSHA512 = String -enum WalletSeedRepositoryError: Error { +public enum WalletSeedRepositoryError: Error { case fail case permissionDenied case notFound } -struct WalletSeedRepositoryChangePasswordQuery { +public struct WalletSeedRepositoryChangePasswordQuery { let oldSeedId: String let newSeedId: String let oldPassword: String let newPassword: String } -protocol WalletSeedRepositoryProtocol { +public protocol WalletSeedRepositoryProtocol { func seed(for address: String, publicKey: String, seedId: String, password: String) -> Observable func saveSeed(for walletSeed: DomainLayer.DTO.WalletSeed, seedId: String, password: String) -> Observable func deleteSeed(for address: String, seedId: String) -> Observable diff --git a/WavesWallet-iOS/DomainLayer/Repositories/WalletsRepositoryProtocol.swift b/DomainLayer/Sources/Repositories/WalletsRepositoryProtocol.swift similarity index 86% rename from WavesWallet-iOS/DomainLayer/Repositories/WalletsRepositoryProtocol.swift rename to DomainLayer/Sources/Repositories/WalletsRepositoryProtocol.swift index 200310c9..789e0006 100644 --- a/WavesWallet-iOS/DomainLayer/Repositories/WalletsRepositoryProtocol.swift +++ b/DomainLayer/Sources/Repositories/WalletsRepositoryProtocol.swift @@ -9,17 +9,18 @@ import Foundation import RxSwift -enum WalletsRepositoryError: Error { +//TODO: Remove +public enum WalletsRepositoryError: Error { case fail case notFound } -struct WalletsRepositorySpecifications { - let isLoggedIn: Bool +public struct WalletsRepositorySpecifications { + public let isLoggedIn: Bool } -protocol WalletsRepositoryProtocol { +public protocol WalletsRepositoryProtocol { func wallet(by publicKey: String) -> Observable func wallets() -> Observable<[DomainLayer.DTO.Wallet]> diff --git a/DomainLayer/Sources/Repositories/WidgetSettingsRepositoryProtocol.swift b/DomainLayer/Sources/Repositories/WidgetSettingsRepositoryProtocol.swift new file mode 100644 index 00000000..e2fc6c4e --- /dev/null +++ b/DomainLayer/Sources/Repositories/WidgetSettingsRepositoryProtocol.swift @@ -0,0 +1,17 @@ +// +// MarketPulseWidgetSettingsRepositoryProtocol.swift +// DomainLayer +// +// Created by Pavel Gubin on 29.07.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift + +public protocol WidgetSettingsRepositoryProtocol { + + func settings() -> Observable + + func saveSettings(_ settings: DomainLayer.DTO.MarketPulseSettings) -> Observable +} diff --git a/WavesWallet-iOS/DomainLayer/FactoryRepositoriesProtocol.swift b/DomainLayer/Sources/RepositoriesFactoryProtocol.swift similarity index 77% rename from WavesWallet-iOS/DomainLayer/FactoryRepositoriesProtocol.swift rename to DomainLayer/Sources/RepositoriesFactoryProtocol.swift index 2cefd9be..309ecc40 100644 --- a/WavesWallet-iOS/DomainLayer/FactoryRepositoriesProtocol.swift +++ b/DomainLayer/Sources/RepositoriesFactoryProtocol.swift @@ -8,7 +8,7 @@ import Foundation -protocol FactoryRepositoriesProtocol { +public protocol RepositoriesFactoryProtocol { var assetsRepositoryLocal: AssetsRepositoryProtocol { get } var assetsRepositoryRemote: AssetsRepositoryProtocol { get } @@ -56,31 +56,15 @@ protocol FactoryRepositoriesProtocol { var notificationNewsRepository: NotificationNewsRepositoryProtocol { get } var applicationVersionRepository: ApplicationVersionRepositoryProtocol { get } -} - -protocol RepositoryCache { - - func isCache(local: R, remote: R) -> Bool - var isInvalid: Bool { get set } -} + + //TODO: Rename + var analyticManager: AnalyticManagerProtocol { get } + + var spamAssets: SpamAssetsRepositoryProtocol { get } + + var gatewayRepository: GatewayRepositoryProtocol { get } -final class RepositoriesDuplex { - - private let local: R - private let remote: R - let cache: RepositoryCache - - init(local: R, remote: R, cache: RepositoryCache) { - self.local = local - self.remote = remote - self.cache = cache - } - - var repository: R { - if cache.isCache(local: local, remote: remote) { - return local - } else { - return remote - } - } + var widgetSettingsStorage: WidgetSettingsRepositoryProtocol { get } + + var mobileKeeperRepository: MobileKeeperRepositoryProtocol { get } } diff --git a/WavesWallet-iOS/DomainLayer/Interactor/AccountBalanceInteractor.swift b/DomainLayer/Sources/UseCases/AccountBalanceUseCase.swift similarity index 90% rename from WavesWallet-iOS/DomainLayer/Interactor/AccountBalanceInteractor.swift rename to DomainLayer/Sources/UseCases/AccountBalanceUseCase.swift index 3216a49e..dc2cb06b 100644 --- a/WavesWallet-iOS/DomainLayer/Interactor/AccountBalanceInteractor.swift +++ b/DomainLayer/Sources/UseCases/AccountBalanceUseCase.swift @@ -7,48 +7,35 @@ // import Foundation -import Moya -import RealmSwift import RxSwift import RxSwiftExt -import WavesSDKExtension -import WavesSDKCrypto +import WavesSDK +import WavesSDKExtensions +import Extensions fileprivate enum Constants { static let durationInseconds: Double = 0 } -enum AccountBalanceInteractorError: Error { - case fail -} - -protocol AccountBalanceInteractorProtocol { - func balances() -> Observable<[DomainLayer.DTO.SmartAssetBalance]> - func balances(by wallet: DomainLayer.DTO.SignedWallet) -> Observable<[DomainLayer.DTO.SmartAssetBalance]> - func balance(by assetId: String, - wallet: DomainLayer.DTO.SignedWallet) -> Observable - func balance(by assetId: String) -> Observable -} - -final class AccountBalanceInteractor: AccountBalanceInteractorProtocol { +final class AccountBalanceUseCase: AccountBalanceUseCaseProtocol { - private let authorizationInteractor: AuthorizationInteractorProtocol + private let authorizationInteractor: AuthorizationUseCaseProtocol private let balanceRepositoryRemote: AccountBalanceRepositoryProtocol private let environmentRepository: EnvironmentRepositoryProtocol - private let assetsInteractor: AssetsInteractorProtocol - private let assetsBalanceSettings: AssetsBalanceSettingsInteractorProtocol - private let leasingInteractor: TransactionsInteractorProtocol + private let assetsInteractor: AssetsUseCaseProtocol + private let assetsBalanceSettings: AssetsBalanceSettingsUseCaseProtocol + private let leasingInteractor: TransactionsUseCaseProtocol private let assetsBalanceSettingsRepository: AssetsBalanceSettingsRepositoryProtocol private let disposeBag: DisposeBag = DisposeBag() - init(authorizationInteractor: AuthorizationInteractorProtocol, + init(authorizationInteractor: AuthorizationUseCaseProtocol, balanceRepositoryRemote: AccountBalanceRepositoryProtocol, environmentRepository: EnvironmentRepositoryProtocol, - assetsInteractor: AssetsInteractorProtocol, - assetsBalanceSettings: AssetsBalanceSettingsInteractorProtocol, - transactionsInteractor: TransactionsInteractorProtocol, + assetsInteractor: AssetsUseCaseProtocol, + assetsBalanceSettings: AssetsBalanceSettingsUseCaseProtocol, + transactionsInteractor: TransactionsUseCaseProtocol, assetsBalanceSettingsRepository: AssetsBalanceSettingsRepositoryProtocol) { self.authorizationInteractor = authorizationInteractor @@ -72,8 +59,7 @@ final class AccountBalanceInteractor: AccountBalanceInteractorProtocol { func balances(by wallet: DomainLayer.DTO.SignedWallet) -> Observable<[DomainLayer.DTO.SmartAssetBalance]> { return self - .remoteBalances(by: wallet) - .share() + .remoteBalances(by: wallet) .subscribeOn(ConcurrentDispatchQueueScheduler(queue: DispatchQueue.global(qos: .userInteractive))) } @@ -92,20 +78,22 @@ final class AccountBalanceInteractor: AccountBalanceInteractorProtocol { wallet: DomainLayer.DTO.SignedWallet) -> Observable { return self .remoteBalance(by: wallet, - assetId: assetId) - .share() + assetId: assetId) .subscribeOn(ConcurrentDispatchQueueScheduler(queue: DispatchQueue.global(qos: .userInteractive))) } } // MARK: Privet methods -private extension AccountBalanceInteractor { +private extension AccountBalanceUseCase { private func assetBalances(by wallet: DomainLayer.DTO.SignedWallet) -> Observable<[DomainLayer.DTO.AssetBalance]> { - let balances = balanceRepositoryRemote.balances(by: wallet) - let environment = environmentRepository.accountEnvironment(accountAddress: wallet.address) + let balances = balanceRepositoryRemote + .balances(by: wallet) + + let environment = environmentRepository + .walletEnvironment() return Observable.zip(balances, environment) .map { (arg) -> [DomainLayer.DTO.AssetBalance] in @@ -165,7 +153,7 @@ private extension AccountBalanceInteractor { .flatMapLatest { (leasing) -> Observable<[DomainLayer.DTO.AssetBalance]> in let amount = leasing.reduce(into: Int64(0), { $0 = $0 + $1.balance.money.amount }) let newBalances = balances.mutate(transform: { (balance) in - if balance.assetId == WavesSDKCryptoConstants.wavesAssetId { + if balance.assetId == WavesSDKConstants.wavesAssetId { balance.leasedBalance = amount } }) @@ -278,7 +266,7 @@ private extension AccountBalanceInteractor { return remoteBalances(by: wallet, assetBalances: assetBalance) .flatMap({ (balances) -> Observable in guard let first = balances.first else { - return Observable.error(AccountBalanceInteractorError.fail) + return Observable.error(AccountBalanceUseCaseError.fail) } return Observable.just(first) @@ -320,6 +308,7 @@ private extension AccountBalanceInteractor { return Observable.create({ (subscribe) -> Disposable in let generalAssets = assets.filter { $0.asset.isGeneral } + AnalyticAssetManager.trackFromZeroBalances(assets: generalAssets, accountAddress: accountAddress) @@ -413,7 +402,7 @@ private extension AccountBalanceInteractor { private extension DomainLayer.DTO.AssetBalance { - init(info: Environment.AssetInfo) { + init(info: WalletEnvironment.AssetInfo) { self.assetId = info.assetId self.totalBalance = 0 self.leasedBalance = 0 diff --git a/WavesWallet-iOS/DomainLayer/Interactor/AddressInteractor.swift b/DomainLayer/Sources/UseCases/AddressUseCase.swift similarity index 94% rename from WavesWallet-iOS/DomainLayer/Interactor/AddressInteractor.swift rename to DomainLayer/Sources/UseCases/AddressUseCase.swift index 0681ceaf..380dd4b0 100644 --- a/WavesWallet-iOS/DomainLayer/Interactor/AddressInteractor.swift +++ b/DomainLayer/Sources/UseCases/AddressUseCase.swift @@ -9,19 +9,20 @@ import Foundation import RxSwift import RxCocoa +import Extensions -protocol AddressInteractorProtocol { +public protocol AddressInteractorProtocol { func address(by ids: [String], myAddress: String) -> Observable<[DomainLayer.DTO.Address]> func addressSync(by ids: [String], myAddress: String) -> SyncObservable<[DomainLayer.DTO.Address]> } -final class AddressInteractor: AddressInteractorProtocol { +final class AddressUseCase: AddressInteractorProtocol { private let addressBookRepository: AddressBookRepositoryProtocol - private let aliasesInteractor: AliasesInteractorProtocol + private let aliasesInteractor: AliasesUseCaseProtocol init(addressBookRepository: AddressBookRepositoryProtocol, - aliasesInteractor: AliasesInteractorProtocol) { + aliasesInteractor: AliasesUseCaseProtocol) { self.addressBookRepository = addressBookRepository self.aliasesInteractor = aliasesInteractor diff --git a/WavesWallet-iOS/DomainLayer/Interactor/AliasesInteractor.swift b/DomainLayer/Sources/UseCases/AliasesUseCase.swift similarity index 92% rename from WavesWallet-iOS/DomainLayer/Interactor/AliasesInteractor.swift rename to DomainLayer/Sources/UseCases/AliasesUseCase.swift index 5970cdcb..7885b148 100644 --- a/WavesWallet-iOS/DomainLayer/Interactor/AliasesInteractor.swift +++ b/DomainLayer/Sources/UseCases/AliasesUseCase.swift @@ -6,17 +6,12 @@ // Copyright © 2018 Waves Platform. All rights reserved. // -import Foundation - import Foundation import RxSwift import RxCocoa +import Extensions -protocol AliasesInteractorProtocol { - func aliases(by accountAddress: String) -> SyncObservable<[DomainLayer.DTO.Alias]> -} - -final class AliasesInteractor: AliasesInteractorProtocol { +final class AliasesUseCase: AliasesUseCaseProtocol { private let aliasesRepository: AliasesRepositoryProtocol private let aliasesRepositoryLocal: AliasesRepositoryProtocol diff --git a/DomainLayer/Sources/UseCases/ApplicationVersionUseCase.swift b/DomainLayer/Sources/UseCases/ApplicationVersionUseCase.swift new file mode 100644 index 00000000..8839e7da --- /dev/null +++ b/DomainLayer/Sources/UseCases/ApplicationVersionUseCase.swift @@ -0,0 +1,64 @@ +// +// ApplicationVersionUseCase.swift +// WavesWallet-iOS +// +// Created by rprokofev on 30/05/2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift + +public extension DomainLayer.DTO { + struct VersionUpdateData { + public let isNeedForceUpdate: Bool + public let forceUpdateVersion: String + } +} + +public protocol ApplicationVersionUseCaseProtocol { + func isHasNewVersion() -> Observable + func isNeedForceUpdate() -> Observable +} + +public final class ApplicationVersionUseCase: ApplicationVersionUseCaseProtocol { + + private let applicationVersionRepository: ApplicationVersionRepositoryProtocol + + public init(applicationVersionRepository: ApplicationVersionRepositoryProtocol) { + self.applicationVersionRepository = applicationVersionRepository + } + + public func isHasNewVersion() -> Observable { + + return applicationVersionRepository + .version() + .flatMap { (version) -> Observable in + let currentVersion = Bundle.main.version.versionToInt() + return Observable.just(currentVersion.lexicographicallyPrecedes(version.versionToInt())) + } + } + + public func isNeedForceUpdate() -> Observable { + return applicationVersionRepository + .forceUpdateVersion() + .flatMap { (version) -> Observable in + let currentVersion = Bundle.main.version.versionToInt() + + let isNeedForceUpdate: Bool = currentVersion.lexicographicallyPrecedes(version.versionToInt()) + return Observable.just(DomainLayer.DTO.VersionUpdateData.init(isNeedForceUpdate: isNeedForceUpdate, + forceUpdateVersion: version)) + } + .catchError { (_) -> Observable in + return Observable.just(DomainLayer.DTO.VersionUpdateData.init(isNeedForceUpdate: false, + forceUpdateVersion: "")) + } + } +} + +private extension String { + func versionToInt() -> [Int] { + return self.components(separatedBy: ".") + .map { Int.init($0) ?? 0 } + } +} diff --git a/WavesWallet-iOS/DomainLayer/Interactor/AssetsBalanceSettingsInteractor.swift b/DomainLayer/Sources/UseCases/AssetsBalanceSettingsUseCase.swift similarity index 90% rename from WavesWallet-iOS/DomainLayer/Interactor/AssetsBalanceSettingsInteractor.swift rename to DomainLayer/Sources/UseCases/AssetsBalanceSettingsUseCase.swift index 50129000..6a17d2a2 100644 --- a/WavesWallet-iOS/DomainLayer/Interactor/AssetsBalanceSettingsInteractor.swift +++ b/DomainLayer/Sources/UseCases/AssetsBalanceSettingsUseCase.swift @@ -8,30 +8,22 @@ import Foundation import RxSwift -import WavesSDKExtension -import WavesSDKCrypto +import WavesSDKExtensions private enum Constants { static let sortLevelNotFound: Float = -1 } -protocol AssetsBalanceSettingsInteractorProtocol { - - func settings(by accountAddress: String, assets: [DomainLayer.DTO.Asset]) -> Observable<[DomainLayer.DTO.AssetBalanceSettings]> - func setFavorite(by accountAddress: String, assetId: String, isFavorite: Bool) -> Observable - func updateAssetsSettings(by accountAddress: String, settings: [DomainLayer.DTO.AssetBalanceSettings]) -> Observable -} - -final class AssetsBalanceSettingsInteractor: AssetsBalanceSettingsInteractorProtocol { +final class AssetsBalanceSettingsUseCase: AssetsBalanceSettingsUseCaseProtocol { private let assetsBalanceSettingsRepository: AssetsBalanceSettingsRepositoryProtocol private let environmentRepository: EnvironmentRepositoryProtocol - private let authorizationInteractor: AuthorizationInteractorProtocol + private let authorizationInteractor: AuthorizationUseCaseProtocol init(assetsBalanceSettingsRepositoryLocal: AssetsBalanceSettingsRepositoryProtocol, environmentRepository: EnvironmentRepositoryProtocol, - authorizationInteractor: AuthorizationInteractorProtocol) { + authorizationInteractor: AuthorizationUseCaseProtocol) { self.assetsBalanceSettingsRepository = assetsBalanceSettingsRepositoryLocal self.environmentRepository = environmentRepository @@ -45,7 +37,7 @@ final class AssetsBalanceSettingsInteractor: AssetsBalanceSettingsInteractorProt guard let self = self else { return Observable.empty() } - return self.environmentRepository.accountEnvironment(accountAddress: wallet.address) + return self.environmentRepository.walletEnvironment() .flatMap({ [weak self] (environment) -> Observable<[DomainLayer.DTO.AssetBalanceSettings]> in guard let self = self else { return Observable.empty() } @@ -117,10 +109,10 @@ final class AssetsBalanceSettingsInteractor: AssetsBalanceSettingsInteractorProt } - -private extension AssetsBalanceSettingsInteractor { +private extension AssetsBalanceSettingsUseCase { - func assetSettings(assets: [DomainLayer.DTO.Asset], ids: [String], accountAddress: String, environment: Environment) -> Observable<[DomainLayer.DTO.AssetBalanceSettings]> { + //TODO: Refactor method + func assetSettings(assets: [DomainLayer.DTO.Asset], ids: [String], accountAddress: String, environment: WalletEnvironment) -> Observable<[DomainLayer.DTO.AssetBalanceSettings]> { let spamIds = assets.reduce(into: [String: Bool](), {$0[$1.id] = $1.isSpam }) @@ -176,7 +168,7 @@ private extension AssetsBalanceSettingsInteractor { }) } - func sortAssets(assets: [DomainLayer.DTO.Asset], enviroment: Environment) -> [DomainLayer.DTO.Asset] { + func sortAssets(assets: [DomainLayer.DTO.Asset], enviroment: WalletEnvironment) -> [DomainLayer.DTO.Asset] { let favoriteAssets = assets.filter { $0.isInitialFavorite }.sorted(by: { $0.isWaves && !$1.isWaves }) let secondsAssets = assets.filter { !$0.isInitialFavorite } diff --git a/WavesWallet-iOS/DomainLayer/Interactor/AssetsInteractor.swift b/DomainLayer/Sources/UseCases/AssetsUseCase.swift similarity index 87% rename from WavesWallet-iOS/DomainLayer/Interactor/AssetsInteractor.swift rename to DomainLayer/Sources/UseCases/AssetsUseCase.swift index 79c5abf9..ccadcca6 100644 --- a/WavesWallet-iOS/DomainLayer/Interactor/AssetsInteractor.swift +++ b/DomainLayer/Sources/UseCases/AssetsUseCase.swift @@ -6,23 +6,11 @@ // Copyright © 2018 Waves Platform. All rights reserved. // -import CSV import Foundation -import Moya -import RealmSwift -import RxRealm import RxSwift +import Extensions -protocol AssetsInteractorProtocol { - func assets(by ids: [String], accountAddress: String) -> Observable<[DomainLayer.DTO.Asset]> - func assetsSync(by ids: [String], accountAddress: String) -> SyncObservable<[DomainLayer.DTO.Asset]> -} - -fileprivate enum Constants { - static let durationInseconds: Double = 0 -} - -final class AssetsInteractor: AssetsInteractorProtocol { +final class AssetsUseCase: AssetsUseCaseProtocol { private let repositoryLocal: AssetsRepositoryProtocol private let repositoryRemote: AssetsRepositoryProtocol @@ -58,7 +46,6 @@ final class AssetsInteractor: AssetsInteractorProtocol { }) } .take(1) - .share() .subscribeOn(ConcurrentDispatchQueueScheduler(queue: DispatchQueue.global(qos: .userInteractive))) } @@ -100,8 +87,7 @@ final class AssetsInteractor: AssetsInteractorProtocol { case .error(let error): return Observable.error(error) } - }) - .share() + }) .subscribeOn(ConcurrentDispatchQueueScheduler(queue: DispatchQueue.global(qos: .userInteractive))) } } diff --git a/WavesWallet-iOS/DomainLayer/Interactor/AuthorizationInteractor.swift b/DomainLayer/Sources/UseCases/AuthorizationUseCase.swift similarity index 89% rename from WavesWallet-iOS/DomainLayer/Interactor/AuthorizationInteractor.swift rename to DomainLayer/Sources/UseCases/AuthorizationUseCase.swift index a7e9d213..26046263 100644 --- a/WavesWallet-iOS/DomainLayer/Interactor/AuthorizationInteractor.swift +++ b/DomainLayer/Sources/UseCases/AuthorizationUseCase.swift @@ -10,8 +10,9 @@ import Foundation import RxSwift import KeychainAccess import LocalAuthentication -import RealmSwift -import WavesSDKExtension +import WavesSDKExtensions +import WavesSDKCrypto +import Extensions private enum Constants { static let service = "com.wavesplatform.wallets" @@ -32,7 +33,7 @@ private extension DomainLayer.DTO.Wallet { } } -private extension AuthorizationInteractor { +private extension AuthorizationUseCase { func registerData(_ wallet: DomainLayer.DTO.WalletRegistation) -> Observable { @@ -43,7 +44,7 @@ private extension AuthorizationInteractor { let keyForPassword = UUID().uuidString.sha512() let password = wallet.password guard let secret: String = password.aesEncrypt(withKey: keyForPassword) else { - observer.onError(AuthorizationInteractorError.fail) + observer.onError(AuthorizationUseCaseError.fail) return Disposables.create() } @@ -63,7 +64,7 @@ private extension AuthorizationInteractor { let keyForPassword = UUID().uuidString.sha512() guard let secret: String = password.aesEncrypt(withKey: keyForPassword) else { - observer.onError(AuthorizationInteractorError.fail) + observer.onError(AuthorizationUseCaseError.fail) return Disposables.create() } @@ -85,7 +86,7 @@ private extension AuthorizationInteractor { let keyForPassword = UUID().uuidString.sha512() let password = password guard let secret: String = password.aesEncrypt(withKey: keyForPassword) else { - observer.onError(AuthorizationInteractorError.fail) + observer.onError(AuthorizationUseCaseError.fail) return Disposables.create() } @@ -165,33 +166,29 @@ private final class SeedRepositoryMemory { } } -protocol AuthorizationInteractorLocalizable { - var fallbackTitle: String { get } - var cancelTitle: String { get } - var readFromkeychain: String { get } - var saveInkeychain: String { get } -} - -final class AuthorizationInteractor: AuthorizationInteractorProtocol { +final class AuthorizationUseCase: AuthorizationUseCaseProtocol { private let localWalletRepository: WalletsRepositoryProtocol private let localWalletSeedRepository: WalletSeedRepositoryProtocol private let remoteAuthenticationRepository: AuthenticationRepositoryProtocol private let accountSettingsRepository: AccountSettingsRepositoryProtocol - private let localizable: AuthorizationInteractorLocalizable + private let analyticManager: AnalyticManagerProtocol + private let localizable: AuthorizationInteractorLocalizableProtocol init(localWalletRepository: WalletsRepositoryProtocol, localWalletSeedRepository: WalletSeedRepositoryProtocol, remoteAuthenticationRepository: AuthenticationRepositoryProtocol, accountSettingsRepository: AccountSettingsRepositoryProtocol, - localizable: AuthorizationInteractorLocalizable) { + localizable: AuthorizationInteractorLocalizableProtocol, + analyticManager: AnalyticManagerProtocol) { self.localWalletRepository = localWalletRepository self.localWalletSeedRepository = localWalletSeedRepository self.remoteAuthenticationRepository = remoteAuthenticationRepository self.accountSettingsRepository = accountSettingsRepository self.localizable = localizable + self.analyticManager = analyticManager } //TODO: Mutex @@ -201,13 +198,18 @@ final class AuthorizationInteractor: AuthorizationInteractorProtocol { return verifyAccessWallet(type: type, wallet: wallet) .flatMap({ [weak self] status -> Observable in - guard let self = self else { return Observable.error(AuthorizationInteractorError.fail) } + guard let self = self else { return Observable.error(AuthorizationUseCaseError.fail) } guard case .completed(let signedWallet) = status else { return Observable.just(status) } let wallet = signedWallet.wallet let seed = signedWallet.seed self.seedRepositoryMemory.append(seed) - + + let auuidBytes = WavesCrypto.shared.blake2b256(input: wallet.address.toBytes) + let auuid = WavesCrypto.shared.base64encode(input: auuidBytes) + + self.analyticManager.setAUUID(auuid) + return self .setIsLoggedIn(wallet: wallet) .flatMap { wallet -> Observable in @@ -245,7 +247,7 @@ final class AuthorizationInteractor: AuthorizationInteractorProtocol { return localWalletRepository .wallets(specifications: .init(isLoggedIn: true)) .catchError({ [weak self] error -> Observable<[DomainLayer.DTO.Wallet]> in - guard let self = self else { return Observable.error(AuthorizationInteractorError.fail) } + guard let self = self else { return Observable.error(AuthorizationUseCaseError.fail) } return Observable.error(self.handlerError(error)) }) } @@ -254,13 +256,13 @@ final class AuthorizationInteractor: AuthorizationInteractorProtocol { return self.localWalletRepository.walletEncryption(by: wallet.publicKey) .flatMap { walletEncrypted -> Observable in if walletEncrypted.kind.secret == nil { - return Observable.error(AuthorizationInteractorError.passcodeNotCreated) + return Observable.error(AuthorizationUseCaseError.passcodeNotCreated) } return Observable.just(true) } .catchError({ [weak self] error -> Observable in - guard let self = self else { return Observable.error(AuthorizationInteractorError.fail) } + guard let self = self else { return Observable.error(AuthorizationUseCaseError.fail) } return Observable.error(self.handlerError(error)) }) } @@ -274,8 +276,8 @@ final class AuthorizationInteractor: AuthorizationInteractorProtocol { .flatMap({ [weak self] wallet -> Observable in guard let self = self else { return Observable.never() } - guard let wallet = wallet else { return Observable.error(AuthorizationInteractorError.permissionDenied) } - guard let seed = self.seedRepositoryMemory.seed(wallet.publicKey) else { return Observable.error(AuthorizationInteractorError.permissionDenied) } + guard let wallet = wallet else { return Observable.error(AuthorizationUseCaseError.permissionDenied) } + guard let seed = self.seedRepositoryMemory.seed(wallet.publicKey) else { return Observable.error(AuthorizationUseCaseError.permissionDenied) } return self.signedWallet(wallet: wallet, seed: seed) }) } @@ -289,7 +291,7 @@ final class AuthorizationInteractor: AuthorizationInteractorProtocol { return self.reRegisterBiometric(wallet: wallet, passcode: passcode) }) .catchError({ [weak self] error -> Observable in - guard let self = self else { return Observable.error(AuthorizationInteractorError.fail) } + guard let self = self else { return Observable.error(AuthorizationUseCaseError.fail) } return Observable.error(self.handlerError(error)) }) } @@ -326,7 +328,7 @@ final class AuthorizationInteractor: AuthorizationInteractorProtocol { return self.reRegisterBiometric(wallet: wallet, passcode: passcode) }) .catchError({ [weak self] error -> Observable in - guard let self = self else { return Observable.error(AuthorizationInteractorError.fail) } + guard let self = self else { return Observable.error(AuthorizationUseCaseError.fail) } return Observable.error(self.handlerError(error)) }) } @@ -340,12 +342,12 @@ final class AuthorizationInteractor: AuthorizationInteractorProtocol { .sweetDebug("Verify acccess") .flatMap({ [weak self] _ -> Observable in - guard let self = self else { return Observable.error(AuthorizationInteractorError.fail) } + guard let self = self else { return Observable.error(AuthorizationUseCaseError.fail) } return self.localWalletRepository.walletEncryption(by: wallet.publicKey) }) .flatMap({ [weak self] walletEncryption -> Observable<(DomainLayer.DTO.WalletSeed, ChangePasswordData)> in - guard let self = self else { return Observable.error(AuthorizationInteractorError.fail) } + guard let self = self else { return Observable.error(AuthorizationUseCaseError.fail) } let currentSeed = self.localWalletSeedRepository.seed(for: wallet.address, publicKey: wallet.publicKey, seedId: walletEncryption.seedId, @@ -425,7 +427,7 @@ final class AuthorizationInteractor: AuthorizationInteractorProtocol { // MARK: - Wallets methods -extension AuthorizationInteractor { +extension AuthorizationUseCase { func existWallet(by publicKey: String) -> Observable { return self.localWalletRepository @@ -435,13 +437,13 @@ extension AuthorizationInteractor { case let walletError as WalletsRepositoryError: switch walletError { case .notFound: - return Observable.error(AuthorizationInteractorError.walletNotFound) + return Observable.error(AuthorizationUseCaseError.walletNotFound) default: - return Observable.error(AuthorizationInteractorError.fail) + return Observable.error(AuthorizationUseCaseError.fail) } default: - return Observable.error(AuthorizationInteractorError.fail) + return Observable.error(AuthorizationUseCaseError.fail) } }) } @@ -451,7 +453,7 @@ extension AuthorizationInteractor { .localWalletRepository .wallets() .catchError({ [weak self] error -> Observable<[DomainLayer.DTO.Wallet]> in - guard let self = self else { return Observable.error(AuthorizationInteractorError.fail) } + guard let self = self else { return Observable.error(AuthorizationUseCaseError.fail) } return Observable.error(self.handlerError(error)) }) } @@ -460,12 +462,12 @@ extension AuthorizationInteractor { return existWallet(by: registration.privateKey.getPublicKeyStr()) .flatMap({ (wallet) -> Observable in - return Observable.error(AuthorizationInteractorError.walletAlreadyExist) + return Observable.error(AuthorizationUseCaseError.walletAlreadyExist) }) .catchError({ [weak self] error -> Observable in - guard let self = self else { return Observable.error(AuthorizationInteractorError.fail) } + guard let self = self else { return Observable.error(AuthorizationUseCaseError.fail) } - if let authError = error as? AuthorizationInteractorError, case AuthorizationInteractorError.walletAlreadyExist = authError { + if let authError = error as? AuthorizationUseCaseError, case AuthorizationUseCaseError.walletAlreadyExist = authError { return Observable.error(error) } @@ -533,7 +535,7 @@ extension AuthorizationInteractor { return self.localWalletRepository.saveWallet(wallet) }) .catchError({ [weak self] error -> Observable in - guard let self = self else { return Observable.error(AuthorizationInteractorError.fail) } + guard let self = self else { return Observable.error(AuthorizationUseCaseError.fail) } return Observable.error(self.handlerError(error)) }) .share() @@ -545,7 +547,7 @@ extension AuthorizationInteractor { let deleleteWalletSeed = localWalletRepository .walletEncryption(by: wallet.publicKey) .flatMap { [weak self] walletEncryption -> Observable in - guard let self = self else { return Observable.error(AuthorizationInteractorError.fail) } + guard let self = self else { return Observable.error(AuthorizationUseCaseError.fail) } return self.localWalletSeedRepository.deleteSeed(for: wallet.address, seedId: walletEncryption.seedId) } @@ -554,16 +556,9 @@ extension AuthorizationInteractor { deleleteWalletSeed, CleanerWalletManager.rx.setCleanWallet(accountAddress: wallet.address, isClean: false), localWalletRepository.removeWalletEncryption(by: wallet.publicKey)]) - .flatMap({ _ -> Observable in - let realm = try? WalletRealmFactory.realm(accountAddress: wallet.address) - try? realm?.write { - realm?.deleteAll() - } - return Observable.just(true) - }) .map { _ in true } .catchError({ [weak self] error -> Observable in - guard let self = self else { return Observable.error(AuthorizationInteractorError.fail) } + guard let self = self else { return Observable.error(AuthorizationUseCaseError.fail) } return Observable.error(self.handlerError(error)) }) } @@ -573,7 +568,7 @@ extension AuthorizationInteractor { .localWalletRepository .saveWallet(wallet) .catchError({ [weak self] error -> Observable in - guard let self = self else { return Observable.error(AuthorizationInteractorError.fail) } + guard let self = self else { return Observable.error(AuthorizationUseCaseError.fail) } return Observable.error(self.handlerError(error)) }) } @@ -581,7 +576,7 @@ extension AuthorizationInteractor { // MARK: - Logout methods -extension AuthorizationInteractor { +extension AuthorizationUseCase { func logout() -> Observable { return walletsLoggedIn().flatMap(weak: self, selector: { $0.logout }) @@ -592,7 +587,7 @@ extension AuthorizationInteractor { return Observable.create({ [weak self] observer -> Disposable in guard let self = self else { - observer.onError(AuthorizationInteractorError.fail) + observer.onError(AuthorizationUseCaseError.fail) return Disposables.create() } @@ -612,18 +607,18 @@ extension AuthorizationInteractor { .localWalletRepository .wallet(by: publicKey) .flatMap({ [weak self] wallet -> Observable in - guard let self = self else { return Observable.error(AuthorizationInteractorError.fail) } + guard let self = self else { return Observable.error(AuthorizationUseCaseError.fail) } let newWallet = wallet.mutate(transform: { $0.isLoggedIn = false }) return self .localWalletRepository .saveWallet(newWallet) }) .flatMap({ [weak self] (wallet) -> Observable in - guard let self = self else { return Observable.error(AuthorizationInteractorError.fail) } + guard let self = self else { return Observable.error(AuthorizationUseCaseError.fail) } return self.revokeAuth().map { _ in wallet } }) .catchError({ [weak self] error -> Observable in - guard let self = self else { return Observable.error(AuthorizationInteractorError.fail) } + guard let self = self else { return Observable.error(AuthorizationUseCaseError.fail) } return Observable.error(self.handlerError(error)) }) .subscribe(onNext: { completed in @@ -638,7 +633,7 @@ extension AuthorizationInteractor { // MARK: - Biometric methods -extension AuthorizationInteractor { +extension AuthorizationUseCase { func registerBiometric(wallet: DomainLayer.DTO.Wallet, passcode: String) -> Observable { @@ -727,7 +722,7 @@ extension AuthorizationInteractor { // MARK: - Keychain methods -private extension AuthorizationInteractor { +private extension AuthorizationUseCase { private func removePasscodeInKeychain(wallet: DomainLayer.DTO.Wallet) -> Observable { return biometricAccess() @@ -751,7 +746,7 @@ private extension AuthorizationInteractor { observer.onNext(true) observer.onCompleted() } catch _ { - observer.onError(AuthorizationInteractorError.biometricDisable) + observer.onError(AuthorizationUseCaseError.biometricDisable) } @@ -772,7 +767,7 @@ private extension AuthorizationInteractor { observer.onNext(true) observer.onCompleted() } catch _ { - observer.onError(AuthorizationInteractorError.biometricDisable) + observer.onError(AuthorizationUseCaseError.biometricDisable) } return Disposables.create {} @@ -784,7 +779,7 @@ private extension AuthorizationInteractor { return Observable.create { [weak self] observer -> Disposable in guard let self = self else { - observer.onError(AuthorizationInteractorError.fail) + observer.onError(AuthorizationUseCaseError.fail) return Disposables.create() } @@ -798,7 +793,7 @@ private extension AuthorizationInteractor { if context.canEvaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, error: &error) { context.evaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, - localizedReason: self.localizable.readFromkeychain ?? "", + localizedReason: self.localizable.readFromkeychain, reply: { (result, error) in @@ -806,10 +801,10 @@ private extension AuthorizationInteractor { context.invalidate() if let error = error as? LAError { SweetLogger.error("biometricDisable \(error.code) \(error.localizedDescription)") - observer.onError(error.authorizationInteractorError) + observer.onError(error.authorizationUseCaseError) } else { SweetLogger.error("biometricDisable Not Found \(error)") - observer.onError(AuthorizationInteractorError.biometricDisable) + observer.onError(AuthorizationUseCaseError.biometricDisable) } } else { @@ -822,9 +817,9 @@ private extension AuthorizationInteractor { } else { context.invalidate() if let error = error as? LAError { - observer.onError(error.authorizationInteractorError) + observer.onError(error.authorizationUseCaseError) } else { - observer.onError(AuthorizationInteractorError.biometricDisable) + observer.onError(AuthorizationUseCaseError.biometricDisable) } } @@ -846,7 +841,7 @@ private extension AuthorizationInteractor { return Observable.create { [weak self] observer -> Disposable in guard let self = self else { - observer.onError(AuthorizationInteractorError.fail) + observer.onError(AuthorizationUseCaseError.fail) return Disposables.create() } @@ -861,10 +856,10 @@ private extension AuthorizationInteractor { } catch let error { - if error is AuthorizationInteractorError { + if error is AuthorizationUseCaseError { observer.onError(error) } else { - observer.onError(AuthorizationInteractorError.biometricDisable) + observer.onError(AuthorizationUseCaseError.biometricDisable) } } @@ -886,7 +881,7 @@ private extension AuthorizationInteractor { return Observable.create { [weak self] observer -> Disposable in guard let self = self else { - observer.onError(AuthorizationInteractorError.fail) + observer.onError(AuthorizationUseCaseError.fail) return Disposables.create() } @@ -898,16 +893,16 @@ private extension AuthorizationInteractor { do { guard let passcode = try keychain.get(wallet.publicKey) else { - throw AuthorizationInteractorError.biometricDisable + throw AuthorizationUseCaseError.biometricDisable } observer.onNext(passcode) observer.onCompleted() } catch let error { - if error is AuthorizationInteractorError { + if error is AuthorizationUseCaseError { observer.onError(error) } else { - observer.onError(AuthorizationInteractorError.permissionDenied) + observer.onError(AuthorizationUseCaseError.permissionDenied) } } @@ -919,7 +914,7 @@ private extension AuthorizationInteractor { // MARK: - Auth methods -private extension AuthorizationInteractor { +private extension AuthorizationUseCase { private func verifyAccessWallet(type: AuthorizationType, wallet: DomainLayer.DTO.Wallet) -> Observable { @@ -955,10 +950,10 @@ private extension AuthorizationInteractor { return Observable.merge(Observable.just(AuthorizationVerifyAccessStatus.waiting), verify) }) .catchError({ [weak self] error -> Observable in - guard let self = self else { return Observable.error(AuthorizationInteractorError.fail) } + guard let self = self else { return Observable.error(AuthorizationUseCaseError.fail) } - if let authError = error as? AuthorizationInteractorError, - authError == AuthorizationInteractorError.biometricDisable + if let authError = error as? AuthorizationUseCaseError, + authError == AuthorizationUseCaseError.biometricDisable { var newWallet = wallet newWallet.hasBiometricEntrance = false @@ -966,7 +961,7 @@ private extension AuthorizationInteractor { .localWalletRepository .saveWallet(newWallet) .flatMap({ [weak self] _ -> Observable in - guard let self = self else { return Observable.error(AuthorizationInteractorError.fail) } + guard let self = self else { return Observable.error(AuthorizationUseCaseError.fail) } return Observable.error(self.handlerError(error)) }) } @@ -984,19 +979,19 @@ private extension AuthorizationInteractor { return self.verifyAccessWalletUsingPassword(password, wallet: wallet) } .catchError({ [weak self] error -> Observable in - guard let self = self else { return Observable.error(AuthorizationInteractorError.fail) } + guard let self = self else { return Observable.error(AuthorizationUseCaseError.fail) } return Observable.error(self.handlerError(error)) }) .catchError({ [weak self] (error) -> Observable in - guard let self = self else { return Observable.error(AuthorizationInteractorError.fail) } + guard let self = self else { return Observable.error(AuthorizationUseCaseError.fail) } - if let authError = error as? AuthorizationInteractorError, authError == .attemptsEnded { + if let authError = error as? AuthorizationUseCaseError, authError == .attemptsEnded { return self .localWalletRepository .walletEncryption(by: wallet.publicKey) .flatMap({ [weak self] (walletEnc) -> Observable in - guard let self = self else { return Observable.error(AuthorizationInteractorError.fail) } + guard let self = self else { return Observable.error(AuthorizationUseCaseError.fail) } var newWalletEnc = walletEnc newWalletEnc.kind = .none @@ -1030,14 +1025,14 @@ private extension AuthorizationInteractor { return self.signedWallet(wallet: wallet, seed: seed) }) .catchError({ [weak self] error -> Observable in - guard let self = self else { return Observable.error(AuthorizationInteractorError.fail) } + guard let self = self else { return Observable.error(AuthorizationUseCaseError.fail) } return Observable.error(self.handlerError(error)) }) } } // MARK: - Assistants methods -fileprivate extension AuthorizationInteractor { +fileprivate extension AuthorizationUseCase { func signedWallet(wallet: DomainLayer.DTO.Wallet, seed: DomainLayer.DTO.WalletSeed) -> Observable { @@ -1055,7 +1050,7 @@ fileprivate extension AuthorizationInteractor { return remoteAuthenticationRepository .auth(with: wallet.id, passcode: passcode) .flatMap({ [weak self] keyForPassword -> Observable<(String, DomainLayer.DTO.WalletEncryption)> in - guard let self = self else { return Observable.error(AuthorizationInteractorError.fail) } + guard let self = self else { return Observable.error(AuthorizationUseCaseError.fail) } return self.localWalletRepository.walletEncryption(by: wallet.publicKey).map { (keyForPassword, $0) } }) .flatMap { data -> Observable in @@ -1063,13 +1058,13 @@ fileprivate extension AuthorizationInteractor { let keyForPassword = data.0 let walletEncryption = data.1 - guard let secret = walletEncryption.kind.secret else { return Observable.error(AuthorizationInteractorError.passcodeNotCreated)} + guard let secret = walletEncryption.kind.secret else { return Observable.error(AuthorizationUseCaseError.passcodeNotCreated)} - guard let password: String = secret.aesDecrypt(withKey: keyForPassword) else { return Observable.error(AuthorizationInteractorError.fail) } + guard let password: String = secret.aesDecrypt(withKey: keyForPassword) else { return Observable.error(AuthorizationUseCaseError.fail) } return Observable.just(password) } .catchError({ [weak self] error -> Observable in - guard let self = self else { return Observable.error(AuthorizationInteractorError.fail) } + guard let self = self else { return Observable.error(AuthorizationUseCaseError.fail) } return Observable.error(self.handlerError(error)) }) } @@ -1096,7 +1091,7 @@ fileprivate extension AuthorizationInteractor { .map { _ in currentWallet } }) .catchError({ [weak self] error -> Observable in - guard let self = self else { return Observable.error(AuthorizationInteractorError.fail) } + guard let self = self else { return Observable.error(AuthorizationUseCaseError.fail) } return Observable.error(self.handlerError(error)) }) } @@ -1121,28 +1116,28 @@ fileprivate extension AuthorizationInteractor { case let error as AuthenticationRepositoryError: switch error { case .attemptsEnded: - return AuthorizationInteractorError.attemptsEnded + return AuthorizationUseCaseError.attemptsEnded case .fail: - return AuthorizationInteractorError.fail + return AuthorizationUseCaseError.fail case .passcodeIncorrect: - return AuthorizationInteractorError.passcodeIncorrect + return AuthorizationUseCaseError.passcodeIncorrect case .permissionDenied: - return AuthorizationInteractorError.permissionDenied + return AuthorizationUseCaseError.permissionDenied } case let error as WalletSeedRepositoryError: switch error { case .permissionDenied: - return AuthorizationInteractorError.passwordIncorrect + return AuthorizationUseCaseError.passwordIncorrect default: - return AuthorizationInteractorError.fail + return AuthorizationUseCaseError.fail } - case let error as AuthorizationInteractorError: + case let error as AuthorizationUseCaseError: return error default: @@ -1155,26 +1150,26 @@ fileprivate extension AuthorizationInteractor { extension LAError { - var authorizationInteractorError: AuthorizationInteractorError { + var authorizationUseCaseError: AuthorizationUseCaseError { switch self { case LAError.userCancel, LAError.systemCancel, LAError.appCancel, LAError.authenticationFailed: - return AuthorizationInteractorError.biometricUserCancel + return AuthorizationUseCaseError.biometricUserCancel case LAError.biometryLockout: - return AuthorizationInteractorError.biometricLockout + return AuthorizationUseCaseError.biometricLockout case LAError.userFallback: - return AuthorizationInteractorError.biometricUserFallback + return AuthorizationUseCaseError.biometricUserFallback case LAError.passcodeNotSet: - return AuthorizationInteractorError.biometricDisable + return AuthorizationUseCaseError.biometricDisable default: - return AuthorizationInteractorError.biometricDisable + return AuthorizationUseCaseError.biometricDisable } } } diff --git a/DomainLayer/Sources/UseCases/CorrectionPairsUseCase.swift b/DomainLayer/Sources/UseCases/CorrectionPairsUseCase.swift new file mode 100644 index 00000000..58e6da9b --- /dev/null +++ b/DomainLayer/Sources/UseCases/CorrectionPairsUseCase.swift @@ -0,0 +1,96 @@ +// +// CorrectionPairsUseCase.swift +// DomainLayer +// +// Created by rprokofev on 12.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import WavesSDKCrypto + +public protocol CorrectionPairsUseCaseLogicProtocol { + static func mapCorrectPairs(settingsIdsPairs: [String], pairs: [DomainLayer.DTO.CorrectionPairs.Pair]) -> [DomainLayer.DTO.CorrectionPairs.Pair] +} + +public final class CorrectionPairsUseCaseLogic: CorrectionPairsUseCaseLogicProtocol { + + public static func mapCorrectPairs(settingsIdsPairs: [String], pairs: [DomainLayer.DTO.CorrectionPairs.Pair]) -> [DomainLayer.DTO.CorrectionPairs.Pair] { + + let result = pairs.map({ (pair) -> DomainLayer.DTO.CorrectionPairs.Pair in + + let amounIndex = settingsIdsPairs.firstIndex(of: pair.amountAsset) + let priceIndex = settingsIdsPairs.firstIndex(of: pair.priceAsset) + + var amount: String! = nil + var price: String! = nil + + if let amounIndex = amounIndex, let priceIndex = priceIndex { + if amounIndex > priceIndex { + amount = pair.amountAsset + price = pair.priceAsset + } else { + amount = pair.priceAsset + price = pair.amountAsset + } + } else if amounIndex != nil && priceIndex == nil { + amount = pair.priceAsset + price = pair.amountAsset + } else if priceIndex != nil && amounIndex == nil { + amount = pair.amountAsset + price = pair.priceAsset + } else { + let amountBytes = WavesCrypto.shared.base58decode(input: pair.amountAsset).data?.hexDescription ?? "" + let priceBytes = WavesCrypto.shared.base58decode(input: pair.priceAsset).data?.hexDescription ?? "" + + if amountBytes > priceBytes { + + amount = pair.amountAsset + price = pair.priceAsset + + } else { + amount = pair.priceAsset + price = pair.amountAsset + } + } + + return DomainLayer.DTO.CorrectionPairs.Pair.init(amountAsset: amount, + priceAsset: price) + }) + + return result + } +} + +//TODO: Testing! +final class CorrectionPairsUseCase: CorrectionPairsUseCaseProtocol { + + private let repositories: RepositoriesFactoryProtocol + private let useCases: UseCasesFactoryProtocol + + init(repositories: RepositoriesFactoryProtocol, useCases: UseCasesFactoryProtocol) { + self.repositories = repositories + self.useCases = useCases + } + + func correction(pairs: [DomainLayer.DTO.CorrectionPairs.Pair]) -> Observable<[DomainLayer.DTO.CorrectionPairs.Pair]> { + + let pairs = repositories + .matcherRepository + .settingsIdsPairs() + .flatMap { (pricePairs) -> Observable<[DomainLayer.DTO.CorrectionPairs.Pair]> in + + let result = CorrectionPairsUseCaseLogic.mapCorrectPairs(settingsIdsPairs: pricePairs, pairs: pairs) + return Observable.just(result) + } + + return pairs + } +} + +fileprivate extension Data { + var hexDescription: String { + return reduce("") {$0 + String(format: "%02x", $1)} + } +} diff --git a/WavesWallet-iOS/DomainLayer/Interactor/MigrationInteractor.swift b/DomainLayer/Sources/UseCases/MigrationUseCase.swift similarity index 95% rename from WavesWallet-iOS/DomainLayer/Interactor/MigrationInteractor.swift rename to DomainLayer/Sources/UseCases/MigrationUseCase.swift index 1cba5c20..1aa6c49a 100644 --- a/WavesWallet-iOS/DomainLayer/Interactor/MigrationInteractor.swift +++ b/DomainLayer/Sources/UseCases/MigrationUseCase.swift @@ -10,9 +10,9 @@ import Foundation import RxSwift import Realm import RealmSwift -import Base58 -import WavesSDKExtension import WavesSDKCrypto +import WavesSDKExtensions +import Extensions fileprivate struct ApplicationVersion: Codable, TSUD { @@ -64,17 +64,17 @@ final class SweetMigration { } } -final class MigrationInteractor { +public final class MigrationUseCase: MigrationUseCaseProtocol { private var walletsRepository: WalletsRepositoryProtocol private var sweetMigration: SweetMigration = SweetMigration() - init(walletsRepository: WalletsRepositoryProtocol) { + public init(walletsRepository: WalletsRepositoryProtocol) { self.walletsRepository = walletsRepository } - func migration() -> Observable { + public func migration() -> Observable { sweetMigration.register(targetVersion: "2.0") { [weak self] () -> Observable in guard let self = self else { return Observable.never() } @@ -94,7 +94,7 @@ final class MigrationInteractor { let newWallets = wallets.map({ wallet -> DomainLayer.DTO.Wallet in let id = UUID().uuidString - let address = PublicKeyAccount(publicKey: Base58.decode(wallet.publicKey)).address + let address = PublicKeyAccount(publicKey: Base58Encoder.decode(wallet.publicKey)).address return DomainLayer.DTO.Wallet(name: wallet.name, address: address, publicKey: wallet.publicKey, diff --git a/DomainLayer/Sources/UseCases/OrderBookUseCase.swift b/DomainLayer/Sources/UseCases/OrderBookUseCase.swift new file mode 100644 index 00000000..84fd8c13 --- /dev/null +++ b/DomainLayer/Sources/UseCases/OrderBookUseCase.swift @@ -0,0 +1,76 @@ +// +// OrderBookUseCase.swift +// InternalDomainLayer +// +// Created by Pavel Gubin on 08.07.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import WavesSDK + +final class OrderBookUseCase: OrderBookUseCaseProtocol { + + private let orderBookRepository: DexOrderBookRepositoryProtocol + private let assetsInteractor: AssetsUseCaseProtocol + private let authorizationInteractor: AuthorizationUseCaseProtocol + + init(orderBookRepository: DexOrderBookRepositoryProtocol, + assetsInteractor: AssetsUseCaseProtocol, + authorizationInteractor: AuthorizationUseCaseProtocol) { + self.orderBookRepository = orderBookRepository + self.assetsInteractor = assetsInteractor + self.authorizationInteractor = authorizationInteractor + } + + func orderSettingsFee() -> Observable { + + return authorizationInteractor.authorizedWallet() + .flatMap({ [weak self] (wallet) -> Observable in + guard let self = self else { return Observable.empty() } + + return self.orderBookRepository.orderSettingsFee() + .flatMap({ [weak self] (baseSettings) -> Observable in + guard let self = self else { return Observable.empty() } + + return self.assetsInteractor.assets(by: baseSettings.feeAssets.map{$0.assetId}, + accountAddress: wallet.address) + .map({ [weak self] (assets) -> DomainLayer.DTO.Dex.SmartSettingsOrderFee in + + guard let self = self else { + return DomainLayer.DTO.Dex.SmartSettingsOrderFee(baseFee: 0, feeAssets: []) + } + return self.mapAssetsToSmartSettings(assets: assets, baseSettings: baseSettings) + }) + }) + }) + } + + private func mapAssetsToSmartSettings(assets: [DomainLayer.DTO.Asset], + baseSettings: DomainLayer.DTO.Dex.SettingsOrderFee) -> DomainLayer.DTO.Dex.SmartSettingsOrderFee { + + var sortedAssets = assets.sorted(by: {$0.displayName < $1.displayName}) + + if let index = sortedAssets.firstIndex(where: {$0.id == WavesSDKConstants.wavesAssetId}) { + + let wavesAsset = sortedAssets[index] + sortedAssets.remove(at: index) + sortedAssets.insert(wavesAsset, at: 0) + } + + let feeAssets = sortedAssets.map({ (asset) -> DomainLayer.DTO.Dex.SmartSettingsOrderFee.Asset in + + let dexAsset = DomainLayer.DTO.Dex.Asset.init(id: asset.id, + name: asset.displayName, + shortName: asset.ticker ?? asset.displayName, + decimals: asset.precision) + + let rate = baseSettings.feeAssets.first(where: {$0.assetId == asset.id})?.rate ?? 0 + return DomainLayer.DTO.Dex.SmartSettingsOrderFee.Asset(rate: rate, asset: dexAsset) + }) + + + return DomainLayer.DTO.Dex.SmartSettingsOrderFee(baseFee: baseSettings.baseFee, feeAssets: feeAssets) + } +} diff --git a/DomainLayer/Sources/UseCases/Protocol/AccountBalanceUseCaseProtocol.swift b/DomainLayer/Sources/UseCases/Protocol/AccountBalanceUseCaseProtocol.swift new file mode 100644 index 00000000..cff7f0d6 --- /dev/null +++ b/DomainLayer/Sources/UseCases/Protocol/AccountBalanceUseCaseProtocol.swift @@ -0,0 +1,22 @@ +// +// AccountBalanceUseCaseProtocol.swift +// WavesWallet-iOS +// +// Created by rprokofev on 21.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift + +public enum AccountBalanceUseCaseError: Error { + case fail +} + +public protocol AccountBalanceUseCaseProtocol { + func balances() -> Observable<[DomainLayer.DTO.SmartAssetBalance]> + func balances(by wallet: DomainLayer.DTO.SignedWallet) -> Observable<[DomainLayer.DTO.SmartAssetBalance]> + func balance(by assetId: String, + wallet: DomainLayer.DTO.SignedWallet) -> Observable + func balance(by assetId: String) -> Observable +} diff --git a/DomainLayer/Sources/UseCases/Protocol/AddressUseCaseProtocol.swift b/DomainLayer/Sources/UseCases/Protocol/AddressUseCaseProtocol.swift new file mode 100644 index 00000000..380d33c7 --- /dev/null +++ b/DomainLayer/Sources/UseCases/Protocol/AddressUseCaseProtocol.swift @@ -0,0 +1,18 @@ +// +// AddressUseCaseProtocol.swift +// WavesWallet-iOS +// +// Created by rprokofev on 21.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import Extensions + +public protocol AddressUseCaseProtocol { + func address(by ids: [String], myAddress: String) -> Observable<[DomainLayer.DTO.Address]> + func addressSync(by ids: [String], myAddress: String) -> SyncObservable<[DomainLayer.DTO.Address]> +} + + diff --git a/DomainLayer/Sources/UseCases/Protocol/AliasesUseCaseProtocol.swift b/DomainLayer/Sources/UseCases/Protocol/AliasesUseCaseProtocol.swift new file mode 100644 index 00000000..a7fab2a3 --- /dev/null +++ b/DomainLayer/Sources/UseCases/Protocol/AliasesUseCaseProtocol.swift @@ -0,0 +1,14 @@ +// +// AliasesUseCaseProtocol.swift +// WavesWallet-iOS +// +// Created by rprokofev on 21.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import Extensions + +public protocol AliasesUseCaseProtocol { + func aliases(by accountAddress: String) -> SyncObservable<[DomainLayer.DTO.Alias]> +} diff --git a/DomainLayer/Sources/UseCases/Protocol/AssetsBalanceSettingsUseCaseProtocol.swift b/DomainLayer/Sources/UseCases/Protocol/AssetsBalanceSettingsUseCaseProtocol.swift new file mode 100644 index 00000000..89b072bc --- /dev/null +++ b/DomainLayer/Sources/UseCases/Protocol/AssetsBalanceSettingsUseCaseProtocol.swift @@ -0,0 +1,18 @@ +// +// AssetsBalanceSettingsUseCaseProtocol.swift +// WavesWallet-iOS +// +// Created by rprokofev on 21.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import WavesSDKExtensions + +public protocol AssetsBalanceSettingsUseCaseProtocol { + + func settings(by accountAddress: String, assets: [DomainLayer.DTO.Asset]) -> Observable<[DomainLayer.DTO.AssetBalanceSettings]> + func setFavorite(by accountAddress: String, assetId: String, isFavorite: Bool) -> Observable + func updateAssetsSettings(by accountAddress: String, settings: [DomainLayer.DTO.AssetBalanceSettings]) -> Observable +} diff --git a/DomainLayer/Sources/UseCases/Protocol/AssetsUseCaseProtocol.swift b/DomainLayer/Sources/UseCases/Protocol/AssetsUseCaseProtocol.swift new file mode 100644 index 00000000..1a3e265f --- /dev/null +++ b/DomainLayer/Sources/UseCases/Protocol/AssetsUseCaseProtocol.swift @@ -0,0 +1,16 @@ +// +// AssetsUseCaseProtocol.swift +// WavesWallet-iOS +// +// Created by rprokofev on 21.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import Extensions + +public protocol AssetsUseCaseProtocol { + func assets(by ids: [String], accountAddress: String) -> Observable<[DomainLayer.DTO.Asset]> + func assetsSync(by ids: [String], accountAddress: String) -> SyncObservable<[DomainLayer.DTO.Asset]> +} diff --git a/WavesWallet-iOS/DomainLayer/Interactor/AuthorizationInteractorProtocol.swift b/DomainLayer/Sources/UseCases/Protocol/AuthorizationUseCaseProtocol.swift similarity index 83% rename from WavesWallet-iOS/DomainLayer/Interactor/AuthorizationInteractorProtocol.swift rename to DomainLayer/Sources/UseCases/Protocol/AuthorizationUseCaseProtocol.swift index 39a97ad1..897271f3 100644 --- a/WavesWallet-iOS/DomainLayer/Interactor/AuthorizationInteractorProtocol.swift +++ b/DomainLayer/Sources/UseCases/Protocol/AuthorizationUseCaseProtocol.swift @@ -1,5 +1,5 @@ // -// AuthorizationInteractorProtocol.swift +// AuthorizationUseCaseProtocol.swift // WavesWallet-iOS // // Created by Prokofev Ruslan on 09/10/2018. @@ -9,14 +9,14 @@ import Foundation import RxSwift -enum AuthorizationType { +public enum AuthorizationType { case passcode(String) // The password by format sha512 case password(String) case biometric } -enum AuthorizationInteractorError: Error { +public enum AuthorizationUseCaseError: Error { case fail case walletAlreadyExist case walletNotFound @@ -31,19 +31,26 @@ enum AuthorizationInteractorError: Error { case biometricUserFallback } -enum AuthorizationAuthStatus { +public enum AuthorizationAuthStatus { case detectBiometric case waiting case completed(DomainLayer.DTO.Wallet) } -enum AuthorizationVerifyAccessStatus { +public enum AuthorizationVerifyAccessStatus { case detectBiometric case waiting case completed(DomainLayer.DTO.SignedWallet) } -protocol AuthorizationInteractorProtocol { +public protocol AuthorizationInteractorLocalizableProtocol { + var fallbackTitle: String { get } + var cancelTitle: String { get } + var readFromkeychain: String { get } + var saveInkeychain: String { get } +} + +public protocol AuthorizationUseCaseProtocol { func existWallet(by publicKey: String) -> Observable func wallets() -> Observable<[DomainLayer.DTO.Wallet]> @@ -57,11 +64,11 @@ protocol AuthorizationInteractorProtocol { //passcodeNotCreated or permissionDenied func hasPermissionToLoggedIn(_ wallet: DomainLayer.DTO.Wallet) -> Observable - // Return AuthorizationInteractorError permissionDenied + // Return AuthorizationUseCaseError permissionDenied func authorizedWallet() -> Observable func isAuthorizedWallet(_ wallet: DomainLayer.DTO.Wallet) -> Observable - // Return AuthorizationInteractorError + // Return AuthorizationUseCaseError func auth(type: AuthorizationType, wallet: DomainLayer.DTO.Wallet) -> Observable func verifyAccess(type: AuthorizationType, wallet: DomainLayer.DTO.Wallet) -> Observable diff --git a/DomainLayer/Sources/UseCases/Protocol/MigrationUseCaseProtocol.swift b/DomainLayer/Sources/UseCases/Protocol/MigrationUseCaseProtocol.swift new file mode 100644 index 00000000..74f80580 --- /dev/null +++ b/DomainLayer/Sources/UseCases/Protocol/MigrationUseCaseProtocol.swift @@ -0,0 +1,14 @@ +// +// MigrationUseCaseProtocol.swift +// WavesWallet-iOS +// +// Created by rprokofev on 21.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift + +public protocol MigrationUseCaseProtocol { + func migration() -> Observable +} diff --git a/DomainLayer/Sources/UseCases/Protocol/OrderBookUseCaseProtocol.swift b/DomainLayer/Sources/UseCases/Protocol/OrderBookUseCaseProtocol.swift new file mode 100644 index 00000000..d681e63a --- /dev/null +++ b/DomainLayer/Sources/UseCases/Protocol/OrderBookUseCaseProtocol.swift @@ -0,0 +1,14 @@ +// +// OrderBookUseCaseProtocol.swift +// InternalDomainLayer +// +// Created by Pavel Gubin on 08.07.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift + +public protocol OrderBookUseCaseProtocol { + func orderSettingsFee() -> Observable +} diff --git a/DomainLayer/Sources/UseCases/Protocol/PairsPathUseCaseProtocol.swift b/DomainLayer/Sources/UseCases/Protocol/PairsPathUseCaseProtocol.swift new file mode 100644 index 00000000..53c091bf --- /dev/null +++ b/DomainLayer/Sources/UseCases/Protocol/PairsPathUseCaseProtocol.swift @@ -0,0 +1,29 @@ +// +// PairsPathUseCaseProtocol.swift +// DomainLayer +// +// Created by rprokofev on 12.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift + +public extension DomainLayer.DTO { + enum CorrectionPairs { + + public struct Pair { + public let amountAsset: String + public let priceAsset: String + + public init(amountAsset: String, priceAsset: String) { + self.amountAsset = amountAsset + self.priceAsset = priceAsset + } + } + } +} + +public protocol CorrectionPairsUseCaseProtocol { + func correction(pairs: [DomainLayer.DTO.CorrectionPairs.Pair]) -> Observable<[DomainLayer.DTO.CorrectionPairs.Pair]> +} diff --git a/DomainLayer/Sources/UseCases/Protocol/TransactionsUseCaseProtocol.swift b/DomainLayer/Sources/UseCases/Protocol/TransactionsUseCaseProtocol.swift new file mode 100644 index 00000000..19a4d24e --- /dev/null +++ b/DomainLayer/Sources/UseCases/Protocol/TransactionsUseCaseProtocol.swift @@ -0,0 +1,37 @@ +// +// TransactionsUseCaseProtocol.swift +// InternalDomainLayer +// +// Created by rprokofev on 21.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import Extensions + +public enum TransactionsUseCaseError: Error { + case invalid + case commissionReceiving +} + +public extension DomainLayer.Query { + enum TransactionSpecificationType { + case createAlias + case lease + case burn(assetID: String) + case cancelLease + case sendTransaction(assetID: String) + case createOrder(amountAsset: String, priceAsset: String, settingsOrderFee: DomainLayer.DTO.Dex.SmartSettingsOrderFee, feeAssetId: String) + } +} + +public let TransactionFeeDefaultRule: String = "default" + +public protocol TransactionsUseCaseProtocol { + + func send(by specifications: TransactionSenderSpecifications, wallet: DomainLayer.DTO.SignedWallet) -> Observable + func transactionsSync(by accountAddress: String, specifications: TransactionsSpecifications) -> SyncObservable<[DomainLayer.DTO.SmartTransaction]> + func activeLeasingTransactionsSync(by accountAddress: String) -> SyncObservable<[DomainLayer.DTO.SmartTransaction]> + func calculateFee(by transactionSpecs: DomainLayer.Query.TransactionSpecificationType, accountAddress: String) -> Observable +} diff --git a/DomainLayer/Sources/UseCases/Protocol/WidgetSettingsInizializationUseCaseProtocol.swift b/DomainLayer/Sources/UseCases/Protocol/WidgetSettingsInizializationUseCaseProtocol.swift new file mode 100644 index 00000000..a20a4a7f --- /dev/null +++ b/DomainLayer/Sources/UseCases/Protocol/WidgetSettingsInizializationUseCaseProtocol.swift @@ -0,0 +1,14 @@ +// +// MarketPulseWidgetUseCaseProtocol.swift +// DomainLayer +// +// Created by rprokofev on 12.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift + +public protocol WidgetSettingsInizializationUseCaseProtocol { + func settings() -> Observable +} diff --git a/DomainLayer/Sources/UseCases/Protocol/WidgetSettingsUseCaseProtocol.swift b/DomainLayer/Sources/UseCases/Protocol/WidgetSettingsUseCaseProtocol.swift new file mode 100644 index 00000000..b9e04d70 --- /dev/null +++ b/DomainLayer/Sources/UseCases/Protocol/WidgetSettingsUseCaseProtocol.swift @@ -0,0 +1,61 @@ +// +// WidgetSettingsUseCaseProtocol.swift +// DomainLayer +// +// Created by rprokofev on 12.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift + +public extension DomainLayer.DTO { + enum Widget {} +} + +public extension DomainLayer.DTO.Widget { + + static let defaultCountAssets: Int = 4 + static let minCountAssets: Int = 2 + static let maxCountAssets: Int = 9 + + enum Interval { + case m1 + case m5 + case m10 + case manually + } + + enum Style { + case classic + case dark + } + + struct Settings { + public let assets: [DomainLayer.DTO.Asset] + public let style: Style + public let interval: Interval + + public init(assets: [DomainLayer.DTO.Asset], style: Style, interval: Interval) { + self.assets = assets + self.style = style + self.interval = interval + } + } +} + + +public protocol WidgetSettingsUseCaseProtocol { + + func settings() -> Observable + + func saveSettings(_ settings: DomainLayer.DTO.Widget.Settings) -> Observable + + func changeInterval(_ interval: DomainLayer.DTO.Widget.Interval) -> Observable + + func changeStyle(_ style: DomainLayer.DTO.Widget.Style) -> Observable + + func removeAsset(_ asset: DomainLayer.DTO.Asset) -> Observable + + func sortAssets(_ sortMap: [String: Int]) -> Observable +} diff --git a/WavesWallet-iOS/DomainLayer/Interactor/TransactionsInteractor.swift b/DomainLayer/Sources/UseCases/TransactionsUseCase.swift similarity index 91% rename from WavesWallet-iOS/DomainLayer/Interactor/TransactionsInteractor.swift rename to DomainLayer/Sources/UseCases/TransactionsUseCase.swift index edd9561e..e4cd3d02 100644 --- a/WavesWallet-iOS/DomainLayer/Interactor/TransactionsInteractor.swift +++ b/DomainLayer/Sources/UseCases/TransactionsUseCase.swift @@ -1,5 +1,5 @@ // -// TransactionsInteractor.swift +// TransactionsUseCase.swift // WavesWallet-iOS // // Created by mefilt on 04.09.2018. @@ -7,41 +7,16 @@ // import Foundation -import Moya import RxSwift -import WavesSDKExtension -import WavesSDKCrypto - -enum TransactionsInteractorError: Error { - case invalid - case commissionReceiving -} - -extension DomainLayer.Query { - enum TransactionSpecificationType { - case createAlias - case lease - case burn(assetID: String) - case cancelLease - case sendTransaction(assetID: String) - case createOrder(amountAsset: String, priceAsset: String) - } -} - -let TransactionFeeDefaultRule: String = "default" - -protocol TransactionsInteractorProtocol { - - func send(by specifications: TransactionSenderSpecifications, wallet: DomainLayer.DTO.SignedWallet) -> Observable - func transactionsSync(by accountAddress: String, specifications: TransactionsSpecifications) -> SyncObservable<[DomainLayer.DTO.SmartTransaction]> - func activeLeasingTransactionsSync(by accountAddress: String) -> SyncObservable<[DomainLayer.DTO.SmartTransaction]> - func calculateFee(by transactionSpecs: DomainLayer.Query.TransactionSpecificationType, accountAddress: String) -> Observable -} +import WavesSDKExtensions +import WavesSDK +import Extensions fileprivate enum Constants { static let durationInseconds: Double = 15 static let maxLimit: Int = 1000 static let offset: Int = 50 + static let rateSmart: Int64 = 400000 } fileprivate typealias IfNeededLoadNextTransactionsQuery = @@ -100,14 +75,14 @@ private typealias RemoteActiveLeasingResult = (txs: [DomainLayer.DTO.LeaseTransa private typealias AnyTransactionsObservable = Observable<[DomainLayer.DTO.AnyTransaction]> fileprivate typealias AnyTransactionsSyncQuery = (address: DomainLayer.DTO.Address, specifications: TransactionsSpecifications, remoteError: Error?) -final class TransactionsInteractor: TransactionsInteractorProtocol { +final class TransactionsUseCase: TransactionsUseCaseProtocol { typealias SmartTransactionsSyncObservable = SyncObservable<[DomainLayer.DTO.SmartTransaction]> private var transactionsRepositoryLocal: TransactionsRepositoryProtocol private var transactionsRepositoryRemote: TransactionsRepositoryProtocol - private var assetsInteractors: AssetsInteractorProtocol + private var assetsInteractors: AssetsUseCaseProtocol private var addressInteractors: AddressInteractorProtocol private var addressRepository: AddressRepositoryProtocol @@ -117,14 +92,17 @@ final class TransactionsInteractor: TransactionsInteractorProtocol { private var accountSettingsRepository: AccountSettingsRepositoryProtocol + private var orderBookRepository: DexOrderBookRepositoryProtocol + init(transactionsRepositoryLocal: TransactionsRepositoryProtocol, transactionsRepositoryRemote: TransactionsRepositoryProtocol, - assetsInteractors: AssetsInteractorProtocol, + assetsInteractors: AssetsUseCaseProtocol, addressInteractors: AddressInteractorProtocol, addressRepository: AddressRepositoryProtocol, assetsRepositoryRemote: AssetsRepositoryProtocol, blockRepositoryRemote: BlockRepositoryProtocol, - accountSettingsRepository: AccountSettingsRepositoryProtocol) { + accountSettingsRepository: AccountSettingsRepositoryProtocol, + orderBookRepository: DexOrderBookRepositoryProtocol) { self.transactionsRepositoryLocal = transactionsRepositoryLocal self.transactionsRepositoryRemote = transactionsRepositoryRemote @@ -134,12 +112,13 @@ final class TransactionsInteractor: TransactionsInteractorProtocol { self.assetsRepository = assetsRepositoryRemote self.blockRepositoryRemote = blockRepositoryRemote self.accountSettingsRepository = accountSettingsRepository + self.orderBookRepository = orderBookRepository } func calculateFee(by transactionSpecs: DomainLayer.Query.TransactionSpecificationType, accountAddress: String) -> Observable { - let isSmartAccount = addressRepository.isSmartAddress(accountAddress: accountAddress).sweetDebug("isSmartAddress") - let wavesAsset = assetsInteractors.assetsSync(by: [WavesSDKCryptoConstants.wavesAssetId], accountAddress: accountAddress) + let isSmartAccount = addressRepository.isSmartAddress(accountAddress: accountAddress) + let wavesAsset = assetsInteractors.assetsSync(by: [WavesSDKConstants.wavesAssetId], accountAddress: accountAddress) .flatMap { (asset) -> Observable in if let result = asset.remote?.first { @@ -151,9 +130,9 @@ final class TransactionsInteractor: TransactionsInteractorProtocol { } else if let error = asset.error { return Observable.error(error) } else { - return Observable.error(TransactionsInteractorError.invalid) + return Observable.error(TransactionsUseCaseError.invalid) } - }.sweetDebug("assetsSync") + } let isSmartAssets = transactionSpecs.assetIds.reduce(into: [Observable<(String,Bool)>]()) { (result, assetId) in @@ -168,9 +147,10 @@ final class TransactionsInteractor: TransactionsInteractorProtocol { let isSmartAssetsObservable = Observable.combineLatest(isSmartAssets).ifEmpty(default: []) - let rules = transactionsRepositoryRemote.feeRules().sweetDebug("feeRules") + let rules = transactionsRepositoryRemote.feeRules() - return Observable.zip(isSmartAccount, wavesAsset, rules, isSmartAssetsObservable.sweetDebug("isSmartAssets")) + + return Observable.zip(isSmartAccount, wavesAsset, rules, isSmartAssetsObservable) .flatMap { [weak self] (isSmartAccount, wavesAsset, rules, isSmartAssets) -> Observable in guard let self = self else { return Observable.never() } @@ -193,12 +173,12 @@ final class TransactionsInteractor: TransactionsInteractorProtocol { case let error as NetworkError: switch error { case .notFound: - return Observable.error(TransactionsInteractorError.commissionReceiving) + return Observable.error(TransactionsUseCaseError.commissionReceiving) default: return Observable.error(error) } default: - return Observable.error(TransactionsInteractorError.commissionReceiving) + return Observable.error(TransactionsUseCaseError.commissionReceiving) } }) } @@ -225,7 +205,7 @@ final class TransactionsInteractor: TransactionsInteractorProtocol { return ts.resultIngoreError ?? [] }) .flatMap({ txs -> Observable in - guard let tx = txs.first else { return Observable.error(TransactionsInteractorError.invalid) } + guard let tx = txs.first else { return Observable.error(TransactionsUseCaseError.invalid) } return Observable.just(tx) }) }) @@ -288,7 +268,7 @@ final class TransactionsInteractor: TransactionsInteractorProtocol { if let error = sync.error { return Observable.error(error) } else { - return Observable.error(TransactionsInteractorError.invalid) + return Observable.error(TransactionsUseCaseError.invalid) } } @@ -321,7 +301,7 @@ final class TransactionsInteractor: TransactionsInteractorProtocol { // MARK: - - Main Logic sync download/save transactions -fileprivate extension TransactionsInteractor { +fileprivate extension TransactionsUseCase { private func initialLoadingTransactionSync(query: InitialTransactionsQuery) -> SmartTransactionsSyncObservable { @@ -510,7 +490,7 @@ fileprivate extension TransactionsInteractor { .transactions(by: query.address, specifications: TransactionsSpecifications(page: nil, assets: [], senders: [], - types: [TransactionType.lease])) + types: [TransactionType.createLease])) .flatMap { (txs) -> Observable<[String: DomainLayer.DTO.AnyTransaction]> in let map = txs.reduce(into: [String: DomainLayer.DTO.AnyTransaction].init(), { (result, tx) in result[tx.id] = tx @@ -608,7 +588,7 @@ fileprivate extension TransactionsInteractor { } } - return SmartTransactionsSyncObservable.just(.error(TransactionsInteractorError.invalid)) + return SmartTransactionsSyncObservable.just(.error(TransactionsUseCaseError.invalid)) } guard let accounts = data.accounts.resultIngoreError else { @@ -620,7 +600,7 @@ fileprivate extension TransactionsInteractor { } } - return SmartTransactionsSyncObservable.just(.error(TransactionsInteractorError.invalid)) + return SmartTransactionsSyncObservable.just(.error(TransactionsUseCaseError.invalid)) } let assetsMap = assets.reduce(into: [String: DomainLayer.DTO.Asset](), { $0[$1.id] = $1 }) @@ -667,7 +647,7 @@ fileprivate extension TransactionsInteractor { // MARK: - - Assistants method -fileprivate extension TransactionsInteractor { +fileprivate extension TransactionsUseCase { private func isHasTransactionsSync(_ query: IsHasTransactionsSyncQuery) -> Observable { @@ -724,7 +704,7 @@ fileprivate extension TransactionsInteractor { } var fee: Int64 = rule.fee - + if rule.addSmartAccountFee && isSmartAddress { fee += rules.smartAccountExtraFee } @@ -743,14 +723,33 @@ fileprivate extension TransactionsInteractor { fee += rules.smartAssetExtraFee } - case .createOrder(let amountAssetId, let priceAssetId): - if rule.addSmartAssetFee && isSmartAssets[amountAssetId] == true { - fee += rules.smartAssetExtraFee + case .createOrder(let amountAssetId, let priceAssetId, let settingsOrderFee, let feeAssetId): + + var n: Int64 = 0 + + if isSmartAssets[amountAssetId] == true { + n += 1 } - if rule.addSmartAssetFee && isSmartAssets[priceAssetId] == true { - fee += rules.smartAssetExtraFee + if isSmartAssets[priceAssetId] == true { + n += 1 + } + + if isSmartAssets[feeAssetId] == true && + feeAssetId != amountAssetId && + feeAssetId != priceAssetId { + n += 1 + } + + if isSmartAddress { + n += 1 } + + let assetRate = settingsOrderFee.feeAssets.first(where: {$0.asset.id == feeAssetId})?.rate ?? 0 + let assetDecimal = settingsOrderFee.feeAssets.first(where: {$0.asset.id == feeAssetId})?.asset.decimals ?? 0 + let assetFee = assetRate * Double(settingsOrderFee.baseFee + Constants.rateSmart * n) + + return Money(Int64(ceil(assetFee)), assetDecimal) } return Money(fee, wavesAsset.precision) @@ -793,42 +792,50 @@ private extension DomainLayer.DTO.AnyTransaction { switch self { case .unrecognised: - return [WavesSDKCryptoConstants.wavesAssetId] + return [WavesSDKConstants.wavesAssetId] case .issue(let tx): return [tx.assetId] case .transfer(let tx): let assetId = tx.assetId - return [assetId, WavesSDKCryptoConstants.wavesAssetId, tx.feeAssetId] + return [assetId, WavesSDKConstants.wavesAssetId, tx.feeAssetId] case .reissue(let tx): return [tx.assetId] case .burn(let tx): - return [tx.assetId, WavesSDKCryptoConstants.wavesAssetId] + return [tx.assetId, WavesSDKConstants.wavesAssetId] case .exchange(let tx): - return [tx.order1.assetPair.amountAsset, tx.order1.assetPair.priceAsset] - + + var ids = [tx.order1.assetPair.amountAsset, tx.order1.assetPair.priceAsset] + if let matcherFeeAssetId = tx.order1.matcherFeeAssetId { + ids.append(matcherFeeAssetId) + } + if let matcherFeeAssetId = tx.order2.matcherFeeAssetId { + ids.append(matcherFeeAssetId) + } + return ids + case .lease: - return [WavesSDKCryptoConstants.wavesAssetId] + return [WavesSDKConstants.wavesAssetId] case .leaseCancel: - return [WavesSDKCryptoConstants.wavesAssetId] + return [WavesSDKConstants.wavesAssetId] case .alias: - return [WavesSDKCryptoConstants.wavesAssetId] + return [WavesSDKConstants.wavesAssetId] case .massTransfer(let tx): - return [tx.assetId, WavesSDKCryptoConstants.wavesAssetId] + return [tx.assetId, WavesSDKConstants.wavesAssetId] case .data: - return [WavesSDKCryptoConstants.wavesAssetId] + return [WavesSDKConstants.wavesAssetId] case .script: - return [WavesSDKCryptoConstants.wavesAssetId] + return [WavesSDKConstants.wavesAssetId] case .assetScript(let tx): return [tx.assetId] @@ -839,9 +846,9 @@ private extension DomainLayer.DTO.AnyTransaction { case .invokeScript(let tx): if let payment = tx.payment, let assetId = payment.assetId { - return [WavesSDKCryptoConstants.wavesAssetId, assetId] + return [WavesSDKConstants.wavesAssetId, assetId] } - return [WavesSDKCryptoConstants.wavesAssetId] + return [WavesSDKConstants.wavesAssetId] } } @@ -931,21 +938,21 @@ private extension DomainLayer.Query.TransactionSpecificationType { case .sendTransaction(let assetId): return [assetId] - case .createOrder(let amountAssetId, let priceAssetId): - return [amountAssetId, priceAssetId] + case .createOrder(let amountAssetId, let priceAssetId, _, let feeAssetId): + return [amountAssetId, priceAssetId, feeAssetId] } } var transactionType: TransactionType? { switch self { case .createAlias: - return TransactionType.alias + return TransactionType.createAlias case .lease: - return TransactionType.lease + return TransactionType.createLease case .cancelLease: - return TransactionType.leaseCancel + return TransactionType.cancelLease case .burn: return TransactionType.burn diff --git a/DomainLayer/Sources/UseCases/WidgetSettingsInizializationUseCase.swift b/DomainLayer/Sources/UseCases/WidgetSettingsInizializationUseCase.swift new file mode 100644 index 00000000..2ae33593 --- /dev/null +++ b/DomainLayer/Sources/UseCases/WidgetSettingsInizializationUseCase.swift @@ -0,0 +1,95 @@ +// +// WidgetSettingsInizializationUseCase.swift +// DomainLayer +// +// Created by rprokofev on 12.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import WavesSDK + +public class WidgetSettingsInizializationUseCase: WidgetSettingsInizializationUseCaseProtocol { + + private let repositories: RepositoriesFactoryProtocol + private let useCases: UseCasesFactoryProtocol + + init(repositories: RepositoriesFactoryProtocol, useCases: UseCasesFactoryProtocol) { + self.repositories = repositories + self.useCases = useCases + } + + public func settings() -> Observable { + + return repositories + .widgetSettingsStorage + .settings() + .flatMap({ [weak self] settings -> Observable in + + guard let self = self else { return Observable.never() } + + if let settings = settings { + return Observable.just(settings) + } + + return self.initial() + }) + } + + private func initial() -> Observable { + + return repositories + .environmentRepository + .walletEnvironment() + .flatMap { [weak self] (walletEnviroment) -> Observable<[DomainLayer.DTO.Asset]> in + + guard let self = self else { return Observable.never() } + let assets = walletEnviroment.generalAssets.prefix(DomainLayer.DTO.Widget.defaultCountAssets) + return self.useCases.assets.assets(by: assets.map { $0.assetId }, accountAddress: "") + } + .flatMap { [weak self] (assets) -> Observable in + + guard let self = self else { return Observable.never() } + + return self + .useCases + .correctionPairsUseCase + .correction(pairs: assets.map { DomainLayer.DTO.CorrectionPairs.Pair.init(amountAsset: $0.id, + priceAsset: WavesSDKConstants.wavesAssetId) }) + .flatMap({ (pairsAfterCorrection) -> Observable<[DomainLayer.DTO.CorrectionPairs.Pair]> in + + + //TODO: Remove + return self.repositories + .dexPairsPriceRepository + .searchPairs(.init(kind: .pairs(pairsAfterCorrection.map { .init(amountAsset: $0.amountAsset, + priceAsset: $0.priceAsset) }))) + .map({ (pairs) -> [DomainLayer.DTO.CorrectionPairs.Pair] in + + return pairsAfterCorrection + }) + + }) + .map({ (pairs) -> DomainLayer.DTO.MarketPulseSettings in + + let marketPulseAssets: [DomainLayer.DTO.MarketPulseSettings.Asset] = assets.enumerated() + .map({ (element) -> DomainLayer.DTO.MarketPulseSettings.Asset in + + let asset = element.element + let pair = pairs[element.offset] + + return .init(id: asset.id, + name: asset.displayName, + icon: asset.iconLogo, + amountAsset: pair.amountAsset, + priceAsset: pair.priceAsset) + + }) + return DomainLayer.DTO.MarketPulseSettings(isDarkStyle: false, + interval: .m10, + assets: marketPulseAssets) + }) + } + } +} diff --git a/DomainLayer/Sources/UseCases/WidgetSettingsUseCase.swift b/DomainLayer/Sources/UseCases/WidgetSettingsUseCase.swift new file mode 100644 index 00000000..495ee88f --- /dev/null +++ b/DomainLayer/Sources/UseCases/WidgetSettingsUseCase.swift @@ -0,0 +1,228 @@ +// +// WidgetSettingsUseCase.swift +// DomainLayer +// +// Created by rprokofev on 12.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import WavesSDK + +public class WidgetSettingsUseCase: WidgetSettingsUseCaseProtocol { + + private let repositories: RepositoriesFactoryProtocol + private let useCases: UseCasesFactoryProtocol + + init(repositories: RepositoriesFactoryProtocol, useCases: UseCasesFactoryProtocol) { + self.repositories = repositories + self.useCases = useCases + } + + //TODO: Remove Loading Assets + public func settings() -> Observable { + + return useCases + .widgetSettingsInizialization + .settings() + .flatMap({ [weak self] (settings) -> Observable in + + guard let self = self else { return Observable.never() } + + return self + .useCases + .assets + .assets(by: settings.assets.map { $0.id }, accountAddress: "") + .map { DomainLayer.DTO.Widget.Settings.init(assets: $0, + style: settings.styleWidget, + interval: settings.intervalWidget) } + }) + } + + public func changeInterval(_ interval: DomainLayer.DTO.Widget.Interval) -> Observable { + + return useCases + .widgetSettingsInizialization + .settings() + .flatMap({ [weak self] (settings) -> Observable in + + guard let self = self else { return Observable.never() } + + let newSettings = DomainLayer.DTO.MarketPulseSettings(isDarkStyle: settings.isDarkStyle, + interval: interval.marketPulseInterval, + assets: settings.assets) + return self + .repositories + .widgetSettingsStorage + .saveSettings(newSettings) + .map { _ in return true } + }) + } + + public func changeStyle(_ style: DomainLayer.DTO.Widget.Style) -> Observable { + + return useCases + .widgetSettingsInizialization + .settings() + .flatMap({ [weak self] (settings) -> Observable in + + guard let self = self else { return Observable.never() } + + let newSettings = DomainLayer.DTO.MarketPulseSettings(isDarkStyle: style == .dark, + interval: settings.interval, + assets: settings.assets) + return self + .repositories + .widgetSettingsStorage + .saveSettings(newSettings) + .map { _ in return true } + }) + } + + public func removeAsset(_ asset: DomainLayer.DTO.Asset) -> Observable { + + return useCases + .widgetSettingsInizialization + .settings() + .flatMap({ [weak self] (settings) -> Observable in + + guard let self = self else { return Observable.never() } + + let newAssets = settings.assets.filter { $0.id != asset.id } + + let newSettings = DomainLayer.DTO.MarketPulseSettings(isDarkStyle: settings.isDarkStyle, + interval: settings.interval, + assets: newAssets) + return self + .repositories + .widgetSettingsStorage + .saveSettings(newSettings) + .map { _ in return true } + }) + } + + public func saveSettings(_ settings: DomainLayer.DTO.Widget.Settings) -> Observable { + + return self + .useCases + .correctionPairsUseCase + .correction(pairs: settings + .assets + .map { .init(amountAsset: $0.id, priceAsset: WavesSDKConstants.wavesAssetId) }) + .map({ (pairs) -> DomainLayer.DTO.MarketPulseSettings in + + let assets: [DomainLayer.DTO.MarketPulseSettings.Asset] = settings + .assets + .enumerated() + .map({ (element) -> DomainLayer.DTO.MarketPulseSettings.Asset in + let asset = element.element + let pair = pairs[element.offset] + + return .init(id: asset.id, + name: asset.displayName, + icon: asset.iconLogo, + amountAsset: pair.amountAsset, + priceAsset: pair.priceAsset) + }) + + return DomainLayer.DTO.MarketPulseSettings.init(isDarkStyle: settings.isDarkStyle, + interval: settings.interval.marketPulseInterval, + assets: assets) + }) + .flatMap({ [weak self] (marketPulseSettings) -> Observable in + guard let self = self else { return Observable.never() } + + return self + .repositories + .widgetSettingsStorage + .saveSettings(marketPulseSettings) + .map { _ in settings } + }) + } + + public func sortAssets(_ sortMap: [String: Int]) -> Observable { + + return useCases + .widgetSettingsInizialization + .settings() + .flatMap({ [weak self] (settings) -> Observable in + + guard let self = self else { return Observable.never() } + + let newAssets = settings.assets.sorted(by: { (sortMap[$0.id] ?? 0) < (sortMap[$1.id] ?? 0) }) + + let newSettings = DomainLayer.DTO.MarketPulseSettings(isDarkStyle: settings.isDarkStyle, + interval: settings.interval, + assets: newAssets) + return self + .repositories + .widgetSettingsStorage + .saveSettings(newSettings) + .map { _ in return true } + }) + } +} + + +fileprivate extension DomainLayer.DTO.Widget.Interval { + + var marketPulseInterval: DomainLayer.DTO.MarketPulseSettings.Interval { + + switch self { + case .m1: + return .m1 + + case .m5: + return .m5 + + case .m10: + return .m10 + + case .manually: + return .manually + } + } + +} + +fileprivate extension DomainLayer.DTO.Widget.Settings { + + var isDarkStyle: Bool { + return self.style == .dark + } + + var marketPulseSettings: DomainLayer.DTO.MarketPulseSettings { + + return .init(isDarkStyle: isDarkStyle, + interval: interval.marketPulseInterval, + assets: []) + } +} + +fileprivate extension DomainLayer.DTO.MarketPulseSettings { + + var styleWidget: DomainLayer.DTO.Widget.Style { + if isDarkStyle { + return .dark + } else { + return .classic + } + } + + var intervalWidget: DomainLayer.DTO.Widget.Interval { + switch self.interval { + case .m1: + return .m1 + + case .m5: + return .m5 + + case .m10: + return .m10 + + case .manually: + return .manually + } + } +} diff --git a/DomainLayer/Sources/UseCasesFactory.swift b/DomainLayer/Sources/UseCasesFactory.swift new file mode 100644 index 00000000..75637da4 --- /dev/null +++ b/DomainLayer/Sources/UseCasesFactory.swift @@ -0,0 +1,134 @@ +// +// UseCasesFactory.swift +// WavesWallet-iOS +// +// Created by mefilt on 06.08.2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation + +public final class UseCasesFactory: UseCasesFactoryProtocol { + + public let repositories: RepositoriesFactoryProtocol + + public let authorizationInteractorLocalizable: AuthorizationInteractorLocalizableProtocol + + public static var instance: UseCasesFactory! + + init(repositories: RepositoriesFactoryProtocol, authorizationInteractorLocalizable: AuthorizationInteractorLocalizableProtocol) { + self.repositories = repositories + self.authorizationInteractorLocalizable = authorizationInteractorLocalizable + } + + public class func initialization(repositories: RepositoriesFactoryProtocol, authorizationInteractorLocalizable: AuthorizationInteractorLocalizableProtocol) { + self.instance = UseCasesFactory(repositories: repositories, authorizationInteractorLocalizable: authorizationInteractorLocalizable) + } + + public private(set) lazy var analyticManager: AnalyticManagerProtocol = { + return repositories.analyticManager + }() + + public private(set) lazy var accountBalance: AccountBalanceUseCaseProtocol = { + + let interactor = AccountBalanceUseCase(authorizationInteractor: self.authorization, + balanceRepositoryRemote: repositories.accountBalanceRepositoryRemote, + environmentRepository: repositories.environmentRepository, + assetsInteractor: self.assets, + assetsBalanceSettings: self.assetsBalanceSettings, + transactionsInteractor: self.transactions, + assetsBalanceSettingsRepository: repositories.assetsBalanceSettingsRepositoryLocal) + return interactor + }() + + public private(set) lazy var transactions: TransactionsUseCaseProtocol = { + + let interactor = TransactionsUseCase(transactionsRepositoryLocal: repositories.transactionsRepositoryLocal, + transactionsRepositoryRemote: repositories.transactionsRepositoryRemote, + assetsInteractors: self.assets, + addressInteractors: self.address, + addressRepository: repositories.addressRepository, + assetsRepositoryRemote: repositories.assetsRepositoryRemote, + blockRepositoryRemote: repositories.blockRemote, + accountSettingsRepository: repositories.accountSettingsRepository, + orderBookRepository: repositories.dexOrderBookRepository) + return interactor + }() + + public private(set) lazy var address: AddressInteractorProtocol = { + + let interactor = AddressUseCase(addressBookRepository: repositories.addressBookRepository, + aliasesInteractor: self.aliases) + return interactor + }() + + public private(set) lazy var authorization: AuthorizationUseCaseProtocol = { + + let interactor = AuthorizationUseCase(localWalletRepository: repositories.walletsRepositoryLocal, + localWalletSeedRepository: repositories.walletSeedRepositoryLocal, + remoteAuthenticationRepository: repositories.authenticationRepositoryRemote, + accountSettingsRepository: repositories.accountSettingsRepository, + localizable: self.authorizationInteractorLocalizable, + analyticManager: self.analyticManager) + + return interactor + }() + + public private(set) lazy var aliases: AliasesUseCaseProtocol = { + + let interactor = AliasesUseCase(aliasesRepositoryRemote: repositories.aliasesRepositoryRemote, + aliasesRepositoryLocal: repositories.aliasesRepositoryLocal) + + return interactor + }() + + public private(set) lazy var assetsBalanceSettings: AssetsBalanceSettingsUseCaseProtocol = { + + let interactor = AssetsBalanceSettingsUseCase(assetsBalanceSettingsRepositoryLocal: repositories.assetsBalanceSettingsRepositoryLocal, + environmentRepository: repositories.environmentRepository, + authorizationInteractor: authorization) + + return interactor + }() + + public private(set) lazy var migration: MigrationUseCaseProtocol = { + + return MigrationUseCase(walletsRepository: repositories.walletsRepositoryLocal) + }() + + public private(set) lazy var applicationVersionUseCase: ApplicationVersionUseCase = ApplicationVersionUseCase(applicationVersionRepository: repositories.applicationVersionRepository) + + public private(set) lazy var assets: AssetsUseCaseProtocol = { + + let interactor = AssetsUseCase(assetsRepositoryLocal: repositories.assetsRepositoryLocal, + assetsRepositoryRemote: repositories.assetsRepositoryRemote) + + return interactor + }() + + public private(set) lazy var oderbook: OrderBookUseCaseProtocol = { + + let interactor = OrderBookUseCase(orderBookRepository: repositories.dexOrderBookRepository, + assetsInteractor: assets, + authorizationInteractor: authorization) + return interactor + }() + + public private(set) lazy var widgetSettings: WidgetSettingsUseCaseProtocol = { + + let useCase = WidgetSettingsUseCase(repositories: repositories, useCases: self) + return useCase + }() + + public private(set) lazy var widgetSettingsInizialization: WidgetSettingsInizializationUseCaseProtocol = { + + let useCase = WidgetSettingsInizializationUseCase(repositories: repositories, useCases: self) + return useCase + }() + + public private(set) lazy var correctionPairsUseCase: CorrectionPairsUseCaseProtocol = { + + let useCase = CorrectionPairsUseCase(repositories: repositories, useCases: self) + return useCase + }() +} diff --git a/DomainLayer/Sources/UseCasesFactoryProtocol.swift b/DomainLayer/Sources/UseCasesFactoryProtocol.swift new file mode 100644 index 00000000..18bf1cd8 --- /dev/null +++ b/DomainLayer/Sources/UseCasesFactoryProtocol.swift @@ -0,0 +1,30 @@ +// +// FactoryInteractor.swift +// WavesWallet-iOS +// +// Created by mefilt on 06.08.2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation + +public protocol UseCasesFactoryProtocol { + var assets: AssetsUseCaseProtocol { get } + var accountBalance: AccountBalanceUseCaseProtocol { get } + var transactions: TransactionsUseCaseProtocol { get } + var address: AddressInteractorProtocol { get } + var authorization: AuthorizationUseCaseProtocol { get } + var aliases: AliasesUseCaseProtocol { get } + var assetsBalanceSettings: AssetsBalanceSettingsUseCaseProtocol { get } + var migration: MigrationUseCaseProtocol { get } + + var applicationVersionUseCase: ApplicationVersionUseCase { get } + var analyticManager: AnalyticManagerProtocol { get } + + var oderbook: OrderBookUseCaseProtocol { get } + + var widgetSettings: WidgetSettingsUseCaseProtocol { get } + var widgetSettingsInizialization: WidgetSettingsInizializationUseCaseProtocol { get } + + var correctionPairsUseCase: CorrectionPairsUseCaseProtocol { get } +} diff --git a/DomainLayerTests/DomainLayerTests.swift b/DomainLayerTests/DomainLayerTests.swift new file mode 100644 index 00000000..2286b127 --- /dev/null +++ b/DomainLayerTests/DomainLayerTests.swift @@ -0,0 +1,33 @@ +// +// DomainLayerTests.swift +// DomainLayerTests +// +// Created by rprokofev on 21.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import XCTest + +class DomainLayerTests: XCTestCase { + + override func setUp() { + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + func testPerformanceExample() { + // This is an example of a performance test case. + self.measure { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/DomainLayerTests/Info.plist b/DomainLayerTests/Info.plist new file mode 100644 index 00000000..a776b05a --- /dev/null +++ b/DomainLayerTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 3901 + + diff --git a/DummyForTest/AppDelegate.swift b/DummyForTest/AppDelegate.swift new file mode 100644 index 00000000..f63abcc4 --- /dev/null +++ b/DummyForTest/AppDelegate.swift @@ -0,0 +1,46 @@ +// +// AppDelegate.swift +// DummyForTest +// +// Created by rprokofev on 12.07.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + 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. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/DummyForTest/Assets.xcassets/AppIcon.appiconset/Contents.json b/DummyForTest/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d8db8d65 --- /dev/null +++ b/DummyForTest/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/DummyForTest/Assets.xcassets/Contents.json b/DummyForTest/Assets.xcassets/Contents.json new file mode 100644 index 00000000..da4a164c --- /dev/null +++ b/DummyForTest/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/DummyForTest/Base.lproj/LaunchScreen.storyboard b/DummyForTest/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..bfa36129 --- /dev/null +++ b/DummyForTest/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DummyForTest/Base.lproj/Main.storyboard b/DummyForTest/Base.lproj/Main.storyboard new file mode 100644 index 00000000..f1bcf384 --- /dev/null +++ b/DummyForTest/Base.lproj/Main.storyboard @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DummyForTest/Info.plist b/DummyForTest/Info.plist new file mode 100644 index 00000000..2a936b0a --- /dev/null +++ b/DummyForTest/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 3901 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/DummyForTest/ViewController.swift b/DummyForTest/ViewController.swift new file mode 100644 index 00000000..abbf2b92 --- /dev/null +++ b/DummyForTest/ViewController.swift @@ -0,0 +1,20 @@ +// +// ViewController.swift +// DummyForTest +// +// Created by rprokofev on 12.07.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import UIKit + +class ViewController: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view. + } + + +} + diff --git a/Extensions.podspec b/Extensions.podspec new file mode 100644 index 00000000..284714f8 --- /dev/null +++ b/Extensions.podspec @@ -0,0 +1,30 @@ +Pod::Spec.new do |spec| + + spec.name = 'Extensions' + spec.version = '0.1' + spec.ios.deployment_target = '11.0' + spec.requires_arc = true + spec.license = { :type => 'MIT' } + spec.homepage = 'https://wavesplatform.com' + spec.authors = { 'Mefilt' => 'Mefilt@gmail.com' } + spec.summary = 'Extensions' + + spec.source_files = 'Extensions/**/**/*.{swift}' + spec.source = { :git => ''} + + spec.ios.framework = 'Foundation' + spec.ios.framework = 'UIKit' + + spec.static_framework = true + + # Assisstant + spec.dependency 'RxSwift' + spec.dependency 'RxSwiftExt' + spec.dependency 'RxOptional' + spec.dependency 'DeviceKit' + + # Waves + spec.dependency 'WavesSDKExtensions' + spec.dependency 'WavesSDK' + spec.dependency 'WavesSDKCrypto' +end diff --git a/WavesWallet-iOS/Extensions/Balance.swift b/Extensions/Balance.swift similarity index 67% rename from WavesWallet-iOS/Extensions/Balance.swift rename to Extensions/Balance.swift index c8b156a5..2e235979 100644 --- a/WavesWallet-iOS/Extensions/Balance.swift +++ b/Extensions/Balance.swift @@ -12,21 +12,31 @@ public struct Balance: Equatable { public struct Currency: Equatable { public let title: String public let ticker: String? + + public init(title: String, ticker: String?) { + self.title = title + self.ticker = ticker + } } public let currency: Currency public let money: Money + + public init(currency: Currency, money: Money) { + self.currency = currency + self.money = money + } } public extension Balance { - public enum Sign: String, Equatable { + enum Sign: String, Equatable { case none = "" case plus = "+" case minus = "-" } - public func displayShortText(sign: Sign, withoutCurrency: Bool) -> String { + func displayShortText(sign: Sign, withoutCurrency: Bool) -> String { var text = "" if withoutCurrency { @@ -38,7 +48,7 @@ public extension Balance { return sign.rawValue + text } - public func displayText(sign: Sign, withoutCurrency: Bool) -> String { + func displayText(sign: Sign, withoutCurrency: Bool) -> String { var text = "" if withoutCurrency { @@ -50,11 +60,11 @@ public extension Balance { return sign.rawValue + text } - public var displayText: String { + var displayText: String { return money.displayText + " " + currency.title } - public var displayTextWithoutCurrencyName: String { + var displayTextWithoutCurrencyName: String { return money.displayText } diff --git a/Extensions/Extensions.h b/Extensions/Extensions.h new file mode 100644 index 00000000..45a78721 --- /dev/null +++ b/Extensions/Extensions.h @@ -0,0 +1,19 @@ +// +// Extensions.h +// Extensions +// +// Created by rprokofev on 17.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +#import + +//! Project version number for Extensions. +FOUNDATION_EXPORT double ExtensionsVersionNumber; + +//! Project version string for Extensions. +FOUNDATION_EXPORT const unsigned char ExtensionsVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/Extensions/Info.plist b/Extensions/Info.plist new file mode 100644 index 00000000..cc02ce1c --- /dev/null +++ b/Extensions/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + 3901 + + diff --git a/Extensions/Sources/Balance.swift b/Extensions/Sources/Balance.swift new file mode 100644 index 00000000..2e235979 --- /dev/null +++ b/Extensions/Sources/Balance.swift @@ -0,0 +1,71 @@ +// +// Balance.swift +// WavesWallet-iOS +// +// Created by Prokofev Ruslan on 07/09/2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation + +public struct Balance: Equatable { + public struct Currency: Equatable { + public let title: String + public let ticker: String? + + public init(title: String, ticker: String?) { + self.title = title + self.ticker = ticker + } + } + + public let currency: Currency + public let money: Money + + public init(currency: Currency, money: Money) { + self.currency = currency + self.money = money + } +} + +public extension Balance { + + enum Sign: String, Equatable { + case none = "" + case plus = "+" + case minus = "-" + } + + func displayShortText(sign: Sign, withoutCurrency: Bool) -> String { + var text = "" + + if withoutCurrency { + text = money.displayShortText + } else { + text = money.displayShortText + " " + currency.title + } + + return sign.rawValue + text + } + + func displayText(sign: Sign, withoutCurrency: Bool) -> String { + var text = "" + + if withoutCurrency { + text = money.displayText + } else { + text = money.displayText + " " + currency.title + } + + return sign.rawValue + text + } + + var displayText: String { + return money.displayText + " " + currency.title + } + + var displayTextWithoutCurrencyName: String { + return money.displayText + } + +} diff --git a/Extensions/Sources/Common/Decimal+Assisstants.swift b/Extensions/Sources/Common/Decimal+Assisstants.swift new file mode 100644 index 00000000..759bbbe1 --- /dev/null +++ b/Extensions/Sources/Common/Decimal+Assisstants.swift @@ -0,0 +1,37 @@ +// +// Decimal+Assisstants.swift +// WavesWallet-iOS +// +// Created by Prokofev Ruslan on 29/08/2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation + +public extension Decimal { + + func rounded() -> Decimal { + + let behavior = NSDecimalNumberHandler(roundingMode: .down, + scale: 0, + raiseOnExactness: false, + raiseOnOverflow: false, + raiseOnUnderflow: false, + raiseOnDivideByZero: false) + + let number = NSDecimalNumber(decimal: self) + return number.rounding(accordingToBehavior: behavior).decimalValue + } + + var doubleValue:Double { + return NSDecimalNumber(decimal:self).doubleValue + } + + var floatValue: Float { + return NSDecimalNumber(decimal: self).floatValue + } + + var int64Value: Int64 { + return NSDecimalNumber(decimal: self).int64Value + } +} diff --git a/Extensions/Sources/Common/DeepLink.swift b/Extensions/Sources/Common/DeepLink.swift new file mode 100644 index 00000000..48d4fd24 --- /dev/null +++ b/Extensions/Sources/Common/DeepLink.swift @@ -0,0 +1,77 @@ +// +// DeepLink\.swift +// Extensions +// +// Created by rprokofev on 15.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation + +public struct DeepLink { + public let url: URL + + public init(url: URL) { + self.url = DeepLinkParser.parseHttpsURLToScheme(url) + } +} + +public extension DeepLink { + + #if DEBUG + static let scheme: String = "waves-dev" + #elseif TEST + static let scheme: String = "waves-test" + #else + static let scheme: String = "waves" + #endif + + static let widgetSettings: String = "\(DeepLink.scheme)://widgetsettings" + static let mobileKeeper: String = "\(DeepLink.scheme)://keeper" + static let send: String = "\(DeepLink.scheme)://send" + static let dex: String = "\(DeepLink.scheme)://dex" +} + +public extension DeepLink { + + var isClientSendLink: Bool { + return url.absoluteString.range(of: DeepLink.send) != nil + } + + + var isClientDexLink: Bool { + return url.absoluteString.range(of: DeepLink.dex) != nil && + url.absoluteString.range(of: "assetId1") != nil && + url.absoluteString.range(of: "assetId2") != nil + } + + var isMobileKeeper: Bool { + return url.absoluteString.range(of: DeepLink.mobileKeeper) != nil + } +} + + +private final class DeepLinkParser { + + private static let fragmentSymbol = "#" + + static func parseHttpsURLToScheme(_ url: URL) -> URL { + + guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false) else { + return url + } + + guard components.scheme != DeepLink.scheme else { return url } + guard let host = components.host else { return url } + + let urlString = url.absoluteString.replacingOccurrences(of: fragmentSymbol, with: "") + let range = (urlString as NSString).range(of: host) + if range.location != NSNotFound { + let newUrlString = (urlString as NSString).substring(from: range.location + range.length) + if let newUrl = URL(string: DeepLink.scheme + ":/" + newUrlString) { + return newUrl + } + } + return url + } +} diff --git a/WavesWallet-iOS/Extensions/UIKit/Kingfisher+Rx.swift b/Extensions/Sources/Common/Kingfisher+Rx.swift similarity index 82% rename from WavesWallet-iOS/Extensions/UIKit/Kingfisher+Rx.swift rename to Extensions/Sources/Common/Kingfisher+Rx.swift index e331fcc9..942cb642 100644 --- a/WavesWallet-iOS/Extensions/UIKit/Kingfisher+Rx.swift +++ b/Extensions/Sources/Common/Kingfisher+Rx.swift @@ -10,7 +10,7 @@ import Foundation import Kingfisher import RxSwift -func retrieveOrDonwloadImage(key: String, url: String) -> Observable { +public func retrieveOrDonwloadImage(key: String, url: String) -> Observable { return retrieveImage(key: key) .flatMap({ (image) -> Observable in @@ -29,28 +29,28 @@ func retrieveOrDonwloadImage(key: String, url: String) -> Observable { }) } -func saveImage(key: String, image: UIImage) -> Observable { +public func saveImage(key: String, image: UIImage) -> Observable { return ImageCache.default.rx.saveImage(key: key, image: image) } -func retrieveImage(key: String) -> Observable { +public func retrieveImage(key: String) -> Observable { return ImageCache.default.rx.retrieveImage(key: key) } -func clearImageCache() { +public func clearImageCache() { ImageCache.default.clearDiskCache() ImageCache.default.clearMemoryCache() ImageCache.default.cleanExpiredDiskCache() ImageCache.default.cleanExpiredMemoryCache() } -func downloadImage(path: String) -> Observable { +public func downloadImage(path: String) -> Observable { return ImageDownloader.default.rx.downloadImage(path: path) } -extension Reactive where Base == ImageDownloader { +public extension Reactive where Base == ImageDownloader { - func downloadImage(path: String) -> Observable { + public func downloadImage(path: String) -> Observable { return Observable.create({ [base] (observer) -> Disposable in @@ -69,7 +69,8 @@ extension Reactive where Base == ImageDownloader { completionHandler: { (result) in isFinish = true - if let pic = result.value?.image { + + if let pic = try? result.get().image { observer.onNext(pic) observer.onCompleted() } else { @@ -95,9 +96,9 @@ extension ImageDownloader: ReactiveCompatible { } } -extension Reactive where Base == ImageCache { +public extension Reactive where Base == ImageCache { - func saveImage(key: String, image: UIImage) -> Observable { + public func saveImage(key: String, image: UIImage) -> Observable { return Observable.create({ [base] (observer) -> Disposable in @@ -110,7 +111,7 @@ extension Reactive where Base == ImageCache { }) } - func retrieveImage(key: String) -> Observable { + public func retrieveImage(key: String) -> Observable { return Observable.create({ [base] (observer) -> Disposable in diff --git a/Extensions/Sources/Common/Language.swift b/Extensions/Sources/Common/Language.swift new file mode 100644 index 00000000..c4b8f1e8 --- /dev/null +++ b/Extensions/Sources/Common/Language.swift @@ -0,0 +1,122 @@ +// +// Language.swift +// WavesWallet-iOS +// +// Created by mefilt on 13.09.2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// +import Foundation +import WavesSDKExtensions + +public extension Notification.Name { + static let changedLanguage: Notification.Name = Notification.Name.init("com.waves.language.notification.changedLanguage") +} + +public struct Language: Codable { + public let title: String + public let icon: String + public let code: String + public let titleCode: String? + + public init(title: String, icon: String, code: String, titleCode: String?) { + self.title = title + self.icon = icon + self.code = code + self.titleCode = titleCode + } +} + +public protocol Localization { + func setupLocalization() +} + +public protocol LocalizableProtocol { + static var locale: Locale { set get } + static var bundle: Bundle { set get } +} + +private struct LanguageCode: TSUD { + + private static let key: String = "com.waves.language.code" + private static let deffaultLanguageCode: String = "en" + + static var defaultValue: Language { + return Language.languages.first(where: { $0.code == LanguageCode.deffaultLanguageCode })! + } + + static var stringKey: String { + return LanguageCode.key + } + + static var userDefaults: UserDefaults { + return UserDefaults.init(suiteName: "group.com.wavesplatform") ?? .standard + } +} + +public extension Language { + + private static var localizable: LocalizableProtocol.Type! + private static var jsonLanguages: String! + fileprivate static var languages: [Language]! + + static func load(localizable: L.Type, languages: [Language]) where L: LocalizableProtocol { + + self.languages = languages + self.localizable = localizable + //Migration to group + if LanguageCode.get().code != LanguageCode.defaultValue.code && LanguageCode.get(.standard).code != LanguageCode.defaultValue.code { + LanguageCode.set(LanguageCode.get(.standard)) + } + + let langauge = LanguageCode.get() + if isValidLanguage(langauge) { + change(langauge, withoutNotification: true) + } + else { + change(Language.defaultLanguage, withoutNotification: true) + } + } + + static var currentLanguage: Language { + return LanguageCode.get() + } + + static var defaultLanguage: Language { + return LanguageCode.defaultValue + } + + static var currentLocale: Locale { + return Locale(identifier: currentLanguage.code) + } + + static func change(_ language: Language, withoutNotification: Bool = false) { + guard let path = Bundle.main.path(forResource: language.code, ofType: "lproj"), let bundle = Bundle(path: path) else { + return + } + + LanguageCode.set(language) + Language.localizable.locale = Locale(identifier: language.code) + Language.localizable.bundle = bundle + + if withoutNotification == false { + NotificationCenter.default.post(name: .changedLanguage, object: language) + } + } + + private static func isValidLanguage(_ language: Language) -> Bool { + if let path = Bundle.main.path(forResource: language.code, ofType: "lproj"), let _ = Bundle(path: path) { + return true + } + return false + } + + func localizedString(key: String) -> String { + + if let path = Bundle.main.path(forResource: code, ofType: "lproj"), + let bundle = Bundle(path: path) { + return bundle.localizedString(forKey: key, value: nil, table: "Waves") + } + return key + } +} + diff --git a/WavesWallet-iOS/Extensions/Money.swift b/Extensions/Sources/Common/Money.swift similarity index 79% rename from WavesWallet-iOS/Extensions/Money.swift rename to Extensions/Sources/Common/Money.swift index 6317bda8..909e5413 100644 --- a/WavesWallet-iOS/Extensions/Money.swift +++ b/Extensions/Sources/Common/Money.swift @@ -23,7 +23,7 @@ public struct Money: Hashable, Codable { public extension Money { - public init(value: Decimal, _ decimals: Int) { + init(value: Decimal, _ decimals: Int) { let decimalValue = (value * pow(10, decimals)).rounded() let isValidDecimal = Decimal(Int64.max) >= decimalValue @@ -36,51 +36,51 @@ public extension Money { public extension Money { - public var displayText: String { + + var displayText: String { return MoneyUtil.getScaledText(amount, decimals: decimals) } - public var displayTextWithoutSpaces: String { + var displayTextWithoutSpaces: String { return displayText.replacingOccurrences(of: " ", with: "") } - public func displayTextFull(isFiat: Bool) -> String { + func displayTextFull(isFiat: Bool) -> String { return MoneyUtil.getScaledFullText(amount, decimals: decimals, isFiat: isFiat) } - public var displayShortText: String { + var displayShortText: String { return MoneyUtil.getScaledShortText(amount, decimals: decimals) } } public extension Money { - public var isZero: Bool { + var isZero: Bool { return amount == 0 } - public var decimalValue: Decimal { + var decimalValue: Decimal { return Decimal(amount) / pow(10, decimals) } - public var doubleValue: Double { + var doubleValue: Double { return decimalValue.doubleValue } - public var floatValue: Float { + var floatValue: Float { return decimalValue.floatValue } } - public extension Money { - public func add(_ value: Double) -> Money { + func add(_ value: Double) -> Money { let additionalValue = Int64(value * pow(10, decimals).doubleValue) return Money(amount + additionalValue, decimals) } - public func minus(_ value: Double) -> Money { + func minus(_ value: Double) -> Money { let additionalValue = Int64(value * pow(10, decimals).doubleValue) var newAmount = amount - additionalValue @@ -95,7 +95,7 @@ public extension Money { //MARK: - Calculation public extension Money { - public static func price(amount: Int64, amountDecimals: Int, priceDecimals: Int) -> Money { + static func price(amount: Int64, amountDecimals: Int, priceDecimals: Int) -> Money { let precisionDiff = priceDecimals - amountDecimals + 8 let decimalValue = Decimal(amount) / pow(10, precisionDiff) diff --git a/WavesWallet-iOS/Extensions/MoneyUtil.swift b/Extensions/Sources/Common/MoneyUtil.swift similarity index 100% rename from WavesWallet-iOS/Extensions/MoneyUtil.swift rename to Extensions/Sources/Common/MoneyUtil.swift diff --git a/WavesWallet-iOS/Extensions/Mutating.swift b/Extensions/Sources/Common/Mutating.swift similarity index 85% rename from WavesWallet-iOS/Extensions/Mutating.swift rename to Extensions/Sources/Common/Mutating.swift index 7e053484..ae889155 100644 --- a/WavesWallet-iOS/Extensions/Mutating.swift +++ b/Extensions/Sources/Common/Mutating.swift @@ -7,11 +7,11 @@ // import Foundation -protocol Mutating { +public protocol Mutating { func mutate(transform: (inout Self) -> ()) -> Self } -extension Mutating { +public extension Mutating { func mutate(transform: (inout Self) -> ()) -> Self { var value = self transform(&value) @@ -19,7 +19,7 @@ extension Mutating { } } -extension Array where Element: Mutating { +public extension Array where Element: Mutating { func mutate(transform: (inout Element) -> ()) -> [Element] { return self.map({ element -> Element in diff --git a/Extensions/Sources/Common/Platform.swift b/Extensions/Sources/Common/Platform.swift new file mode 100644 index 00000000..b12425c2 --- /dev/null +++ b/Extensions/Sources/Common/Platform.swift @@ -0,0 +1,79 @@ +import UIKit +import DeviceKit + +//TODO: Rename +public struct Platform { + + public static let ScreenWidth = UIScreen.main.bounds.width + + private static let device = Device.current + + public static let isIphone5: Bool = { + return device.isOneOf([.iPhone5, .simulator(.iPhone5), + .iPhone5c, .simulator(.iPhone5c), + .iPhone5s, .simulator(.iPhone5s), + .iPhoneSE, .simulator(.iPhoneSE)]) + }() + + public static let isIphone7: Bool = { + + return device.isOneOf([.iPhone6, .simulator(.iPhone6), + .iPhone6s, .simulator(.iPhone6s), + .iPhone7, .simulator(.iPhone7), + .iPhone8, .simulator(.iPhone8)]) + }() + + public static let isIphoneXSeries: Bool = { + return device.isOneOf([.iPhoneX, .simulator(.iPhoneX), + .iPhoneXR, .simulator(.iPhoneXR), + .iPhoneXS, .simulator(.iPhoneXS), + .iPhoneXSMax, .simulator(.iPhoneXSMax), + .iPhone11, .simulator(.iPhone11), + .iPhone11Pro, .simulator(.iPhone11Pro), + .iPhone11ProMax, .simulator(.iPhone11ProMax)]) + }() + + public static let isIphonePlus: Bool = { + + return device.isOneOf([.iPhone6Plus, .simulator(.iPhone6Plus), + .iPhone6sPlus, .simulator(.iPhone6sPlus), + .iPhone7Plus, .simulator(.iPhone7Plus), + .iPhone8Plus, .simulator(.iPhone8Plus)]) + }() + + public static let isIphoneX: Bool = { + + return device.isOneOf([.iPhoneX, .simulator(.iPhoneX), + .iPhoneXS, .simulator(.iPhoneXS), + .iPhone11Pro, .simulator(.iPhone11Pro)]) + }() + + public static let isIphoneXMax: Bool = { + + return device.isOneOf([.iPhoneXSMax, .simulator(.iPhoneXSMax), + .iPhone11ProMax, .simulator(.iPhone11ProMax)]) + }() + + public static let isIphoneXR: Bool = { + + return device.isOneOf([.iPhoneXR, .simulator(.iPhoneXR), + .iPhone11, .simulator(.iPhone11)]) + }() + + public static let isSupportFaceID: Bool = { + + let realDevices = Device.allFaceIDCapableDevices + let simulators: [Device] = realDevices.map {.simulator($0)} + + return device.isOneOf(realDevices + simulators) + }() + + + public static var isIOS13orGreater: Bool { + if #available(iOS 13, *) { + return true + } else { + return false + } + } +} diff --git a/Extensions/Sources/Common/Reachability+Shared.swift b/Extensions/Sources/Common/Reachability+Shared.swift new file mode 100644 index 00000000..ddb965a3 --- /dev/null +++ b/Extensions/Sources/Common/Reachability+Shared.swift @@ -0,0 +1,18 @@ +// +// Reachability+Shared.swift +// WavesWallet-iOS +// +// Created by mefilt on 26/11/2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import Reachability + +public enum ReachabilityService { + public static var instance: Reachability = { + let reachability = Reachability()! + try? reachability.startNotifier() + return reachability + }() +} diff --git a/WavesWallet-iOS/Extensions/RunLoopThreadScheduler.swift b/Extensions/Sources/Common/RunLoopThreadScheduler.swift similarity index 84% rename from WavesWallet-iOS/Extensions/RunLoopThreadScheduler.swift rename to Extensions/Sources/Common/RunLoopThreadScheduler.swift index 1c099ccd..0b328ab8 100644 --- a/WavesWallet-iOS/Extensions/RunLoopThreadScheduler.swift +++ b/Extensions/Sources/Common/RunLoopThreadScheduler.swift @@ -8,11 +8,11 @@ import Foundation import RxSwift -final class RunLoopThreadScheduler: ImmediateSchedulerType { +public final class RunLoopThreadScheduler: ImmediateSchedulerType { private let thread: Thread private let target: ThreadTarget - init(threadName: String) { + public init(threadName: String) { self.target = ThreadTarget() self.thread = Thread(target: target, selector: #selector(ThreadTarget.threadEntryPoint), @@ -21,7 +21,7 @@ final class RunLoopThreadScheduler: ImmediateSchedulerType { self.thread.start() } - func schedule(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable { + public func schedule(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable { let disposable = SingleAssignmentDisposable() var action: Action? = Action { @@ -49,10 +49,10 @@ final class RunLoopThreadScheduler: ImmediateSchedulerType { } } -enum Schedulers { - static var realmThreadScheduler: RunLoopThreadScheduler { +public enum Schedulers { + public static var realmThreadScheduler: RunLoopThreadScheduler = { return RunLoopThreadScheduler(threadName: "Realm") - } + }() } private final class ThreadTarget: NSObject { diff --git a/WavesWallet-iOS/Extensions/Sync.swift b/Extensions/Sources/Common/Sync.swift similarity index 85% rename from WavesWallet-iOS/Extensions/Sync.swift rename to Extensions/Sources/Common/Sync.swift index fb906b74..7680d858 100644 --- a/WavesWallet-iOS/Extensions/Sync.swift +++ b/Extensions/Sources/Common/Sync.swift @@ -14,7 +14,7 @@ public enum Sync { case local(Result, error: Error) case error(Error) - var remote: Result? { + public var remote: Result? { switch self { case .remote(let model): return model @@ -24,7 +24,7 @@ public enum Sync { } } - var local: (result: Result, error: Error)? { + public var local: (result: Result, error: Error)? { switch self { case .local(let model, let error): return (result: model, error: error) @@ -34,7 +34,7 @@ public enum Sync { } } - var resultIngoreError: Result? { + public var resultIngoreError: Result? { switch self { case .remote(let model): return model @@ -46,7 +46,7 @@ public enum Sync { } } - var error: Error? { + public var error: Error? { switch self { case .error(let error): return error @@ -56,7 +56,7 @@ public enum Sync { } } - var anyError: Error? { + public var anyError: Error? { switch self { case .error(let error): return error diff --git a/Extensions/Sources/Common/System.swift b/Extensions/Sources/Common/System.swift new file mode 100644 index 00000000..06e44d95 --- /dev/null +++ b/Extensions/Sources/Common/System.swift @@ -0,0 +1,79 @@ +// +// System.swift +// RemotePlace +// +// Created by Prokofev Ruslan on 10/02/2019. +// Copyright © 2019 RemotePlace. All rights reserved. +// + +import Foundation +import RxSwift +import RxCocoa +import RxFeedback +import WavesSDKExtensions + +open class System { + + public typealias State = S + + public typealias Event = E + + public typealias Feedback = (Driver) -> Signal + + private let inputEvent: PublishSubject = .init() + + public init() {} + + public func start(sideEffects: [Feedback]) -> Driver { + + var newSideEffects = sideEffects + + let feedback: Feedback = react(request: { (state) -> Bool? in + return true + }) { [weak self] _ -> Signal in + guard let self = self else { return Signal.empty() } + return self.inputEvent.observeOn(MainScheduler.instance).asSignal(onErrorSignalWith: Signal.empty()) + } + + newSideEffects.append(feedback) + newSideEffects.append(contentsOf: internalFeedbacks()) + + let system = Driver + .system(initialState: self.initialState(), + reduce: { [weak self] state, event -> State in + + guard let self = self else { return state } + + var newState = state + self.reduce(event: event, state: &newState) + return newState + }, + feedback: newSideEffects) + + return system + } + + public func send(_ event: Event) { + inputEvent.onNext(event) + } + + open func initialState() -> State! { + assertMethodNeedOverriding() + return nil + } + + open func internalFeedbacks() -> [Feedback] { + assertMethodNeedOverriding() + return [] + } + + open func reduce(event: Event, state: inout State) { + assertMethodNeedOverriding() + } +} + +public extension System { + func start() -> Driver { + return start(sideEffects: []) + } +} diff --git a/WavesWallet-iOS/Extensions/TSUD+Rx.swift b/Extensions/Sources/Common/TSUD+Rx.swift similarity index 92% rename from WavesWallet-iOS/Extensions/TSUD+Rx.swift rename to Extensions/Sources/Common/TSUD+Rx.swift index cf5e6ef7..4e00806c 100644 --- a/WavesWallet-iOS/Extensions/TSUD+Rx.swift +++ b/Extensions/Sources/Common/TSUD+Rx.swift @@ -7,9 +7,9 @@ // import RxSwift -import WavesSDKExtension +import WavesSDKExtensions -extension Reactive where Base: TSUD { +public extension Reactive where Base: TSUD { static func get(_ nsud: UserDefaults = .standard) -> Observable { diff --git a/WavesWallet-iOS/Extensions/Decimal+Assisstants.swift b/Extensions/Sources/Decimal+Assisstants.swift similarity index 52% rename from WavesWallet-iOS/Extensions/Decimal+Assisstants.swift rename to Extensions/Sources/Decimal+Assisstants.swift index e63009c7..16e52ffd 100644 --- a/WavesWallet-iOS/Extensions/Decimal+Assisstants.swift +++ b/Extensions/Sources/Decimal+Assisstants.swift @@ -14,38 +14,38 @@ public extension Decimal { // https://github.com/apple/swift/commit/2f4e70bf7f4eee43bfb2f24d6215eb1f63c05d01 //TODO: can be fixed with new xCode 10.2, need to check + //TODO: Exeperement +// public init(_ value: UInt64) { +// self = Decimal() +// if value == 0 { +// return +// } +// +// var compactValue = value +// var exponent: Int32 = 0 +// while compactValue % 10 == 0 { +// compactValue = compactValue / 10 +// exponent = exponent + 1 +// } +// _isCompact = 1 +// _exponent = exponent +// +// let wordCount = ((UInt64.bitWidth - compactValue.leadingZeroBitCount) + (UInt16.bitWidth - 1)) / UInt16.bitWidth +// _length = UInt32(wordCount) +// _mantissa.0 = UInt16(truncatingIfNeeded: compactValue >> 0) +// _mantissa.1 = UInt16(truncatingIfNeeded: compactValue >> 16) +// _mantissa.2 = UInt16(truncatingIfNeeded: compactValue >> 32) +// _mantissa.3 = UInt16(truncatingIfNeeded: compactValue >> 48) +// } +// +// public init(_ value: Int64) { +// self.init(value.magnitude) +// if value < 0 { +// _isNegative = 1 +// } +// } - public init(_ value: UInt64) { - self = Decimal() - if value == 0 { - return - } - - var compactValue = value - var exponent: Int32 = 0 - while compactValue % 10 == 0 { - compactValue = compactValue / 10 - exponent = exponent + 1 - } - _isCompact = 1 - _exponent = exponent - - let wordCount = ((UInt64.bitWidth - compactValue.leadingZeroBitCount) + (UInt16.bitWidth - 1)) / UInt16.bitWidth - _length = UInt32(wordCount) - _mantissa.0 = UInt16(truncatingIfNeeded: compactValue >> 0) - _mantissa.1 = UInt16(truncatingIfNeeded: compactValue >> 16) - _mantissa.2 = UInt16(truncatingIfNeeded: compactValue >> 32) - _mantissa.3 = UInt16(truncatingIfNeeded: compactValue >> 48) - } - - public init(_ value: Int64) { - self.init(value.magnitude) - if value < 0 { - _isNegative = 1 - } - } - - public func rounded() -> Decimal { + func rounded() -> Decimal { let behavior = NSDecimalNumberHandler(roundingMode: .down, scale: 0, @@ -58,15 +58,15 @@ public extension Decimal { return number.rounding(accordingToBehavior: behavior).decimalValue } - public var doubleValue:Double { + var doubleValue:Double { return NSDecimalNumber(decimal:self).doubleValue } - public var floatValue: Float { + var floatValue: Float { return NSDecimalNumber(decimal: self).floatValue } - public var int64Value: Int64 { + var int64Value: Int64 { return NSDecimalNumber(decimal: self).int64Value } } diff --git a/Extensions/Sources/Money.swift b/Extensions/Sources/Money.swift new file mode 100644 index 00000000..909e5413 --- /dev/null +++ b/Extensions/Sources/Money.swift @@ -0,0 +1,105 @@ +// +// Money.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 8/23/18. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation + +public struct Money: Hashable, Codable { + public let amount: Int64 + public let decimals: Int + + public private(set) var isBigAmount = false + public private(set) var isSmallAmount = false + + public init(_ amount: Int64, _ decimals: Int) { + self.amount = amount + self.decimals = decimals + } +} + +public extension Money { + + init(value: Decimal, _ decimals: Int) { + let decimalValue = (value * pow(10, decimals)).rounded() + let isValidDecimal = Decimal(Int64.max) >= decimalValue + + self.amount = isValidDecimal ? Int64(truncating: decimalValue as NSNumber) : 0 + self.decimals = decimals + self.isBigAmount = self.amount == 0 && value > 0 && decimalValue > 0 + self.isSmallAmount = self.amount == 0 && value > 0 && decimalValue == 0 + } +} + + +public extension Money { + + var displayText: String { + return MoneyUtil.getScaledText(amount, decimals: decimals) + } + + var displayTextWithoutSpaces: String { + return displayText.replacingOccurrences(of: " ", with: "") + } + + func displayTextFull(isFiat: Bool) -> String { + return MoneyUtil.getScaledFullText(amount, decimals: decimals, isFiat: isFiat) + } + + var displayShortText: String { + return MoneyUtil.getScaledShortText(amount, decimals: decimals) + } +} + +public extension Money { + + var isZero: Bool { + return amount == 0 + } + + var decimalValue: Decimal { + return Decimal(amount) / pow(10, decimals) + } + + var doubleValue: Double { + return decimalValue.doubleValue + } + + var floatValue: Float { + return decimalValue.floatValue + } +} + +public extension Money { + + func add(_ value: Double) -> Money { + let additionalValue = Int64(value * pow(10, decimals).doubleValue) + return Money(amount + additionalValue, decimals) + } + + func minus(_ value: Double) -> Money { + + let additionalValue = Int64(value * pow(10, decimals).doubleValue) + var newAmount = amount - additionalValue + + if newAmount < 0 { + newAmount = 0 + } + return Money(newAmount, decimals) + } +} + +//MARK: - Calculation +public extension Money { + + static func price(amount: Int64, amountDecimals: Int, priceDecimals: Int) -> Money { + + let precisionDiff = priceDecimals - amountDecimals + 8 + let decimalValue = Decimal(amount) / pow(10, precisionDiff) + + return Money((decimalValue * pow(10, priceDecimals)).int64Value, priceDecimals) + } +} diff --git a/Extensions/Sources/MoneyUtil.swift b/Extensions/Sources/MoneyUtil.swift new file mode 100644 index 00000000..806033f7 --- /dev/null +++ b/Extensions/Sources/MoneyUtil.swift @@ -0,0 +1,54 @@ +import Foundation +import UIKit + +private enum Constants { + static let groupingSeparator = " " + static let decimalSeparator = "." +} + +public class MoneyUtil { + + public class func getScaledFullText(_ amount: Int64, decimals: Int, isFiat: Bool) -> String { + let f = NumberFormatter() + f.decimalSeparator = Constants.decimalSeparator + f.groupingSeparator = Constants.groupingSeparator + f.numberStyle = .decimal + f.maximumFractionDigits = decimals + f.minimumFractionDigits = isFiat ? decimals : 0 + let result = f.string(from: Decimal(amount) / pow(10, decimals) as NSNumber) + return result ?? "" + } + + public class func getScaledText(_ amount: Int64, decimals: Int) -> String { + let f = NumberFormatter() + f.decimalSeparator = Constants.decimalSeparator + f.groupingSeparator = Constants.groupingSeparator + f.numberStyle = .decimal + f.maximumFractionDigits = decimals + f.minimumFractionDigits = 0 + let result = f.string(from: Decimal(amount) / pow(10, decimals) as NSNumber) + return result ?? "" + } + + public class func getScaledShortText(_ amount: Int64, decimals: Int) -> String { + + let decimalValue = Decimal(amount) / pow(10, decimals) + let num = decimalValue.doubleValue; + + if num < 1000 { + return getScaledText(amount, decimals: decimals) + } + + let exp = Int(log10(num) / 3) + + let units = ["K", "M", "B", "T", "P", "E"] + let roundedNum = floor(10 * num / pow(1000, Double(exp))) / 10 + + let floatingValue = modf(roundedNum).1 + if floatingValue == 0 { + return String(Int(roundedNum)) + units[exp-1] + } + + return "\(roundedNum)\(units[exp-1])" + } +} diff --git a/Extensions/Sources/Mutating.swift b/Extensions/Sources/Mutating.swift new file mode 100644 index 00000000..ae889155 --- /dev/null +++ b/Extensions/Sources/Mutating.swift @@ -0,0 +1,31 @@ +// +// Mutating.swift +// WavesWallet-iOS +// +// Created by mefilt on 26.07.2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// +import Foundation + +public protocol Mutating { + func mutate(transform: (inout Self) -> ()) -> Self +} + +public extension Mutating { + func mutate(transform: (inout Self) -> ()) -> Self { + var value = self + transform(&value) + return value + } +} + +public extension Array where Element: Mutating { + + func mutate(transform: (inout Element) -> ()) -> [Element] { + return self.map({ element -> Element in + return element.mutate(transform: { ref in + transform(&ref) + }) + }) + } +} diff --git a/Extensions/Sources/Platform.swift b/Extensions/Sources/Platform.swift new file mode 100644 index 00000000..0ce8fe15 --- /dev/null +++ b/Extensions/Sources/Platform.swift @@ -0,0 +1,64 @@ +import UIKit +import DeviceKit + +//TODO: Rename +public struct Platform { + + public static let ScreenWidth = UIScreen.main.bounds.width + + private static let device = Device.current + + public static let isIphone5: Bool = { + return device.isOneOf([.iPhone5, .simulator(.iPhone5), + .iPhone5c, .simulator(.iPhone5c), + .iPhone5s, .simulator(.iPhone5s), + .iPhoneSE, .simulator(.iPhoneSE)]) + }() + + public static let isIphone7: Bool = { + + return device.isOneOf([.iPhone6, .simulator(.iPhone6), + .iPhone6s, .simulator(.iPhone6s), + .iPhone7, .simulator(.iPhone7), + .iPhone8, .simulator(.iPhone8)]) + }() + + public static let isIphoneXSeries: Bool = { + return device.isOneOf([.iPhoneX, .simulator(.iPhoneX), + .iPhoneXR, .simulator(.iPhoneXR), + .iPhoneXS, .simulator(.iPhoneXS), + .iPhoneXSMax, .simulator(.iPhoneXSMax)]) + }() + + public static let isIphonePlus: Bool = { + + return device.isOneOf([.iPhone6Plus, .simulator(.iPhone6Plus), + .iPhone6sPlus, .simulator(.iPhone6sPlus), + .iPhone7Plus, .simulator(.iPhone7Plus), + .iPhone8Plus, .simulator(.iPhone8Plus)]) + }() + + public static let isIphoneX: Bool = { + + return device.isOneOf([.iPhoneX, .simulator(.iPhoneX), + .iPhoneXS, .simulator(.iPhoneXS)]) + }() + + public static let isIphoneXMax: Bool = { + + return device.isOneOf([.iPhoneXSMax, .simulator(.iPhoneXSMax)]) + }() + + public static let isIphoneXR: Bool = { + + return device.isOneOf([.iPhoneXR, .simulator(.iPhoneXR)]) + }() + + public static let isSupportFaceID: Bool = { + + let realDevices = Device.allFaceIDCapableDevices + let simulators: [Device] = realDevices.map {.simulator($0)} + + return device.isOneOf(realDevices + simulators) + }() +} diff --git a/Extensions/Sources/RunLoopThreadScheduler.swift b/Extensions/Sources/RunLoopThreadScheduler.swift new file mode 100644 index 00000000..0b328ab8 --- /dev/null +++ b/Extensions/Sources/RunLoopThreadScheduler.swift @@ -0,0 +1,76 @@ +// +// RunLoopThreadScheduler.swift +// WavesWallet-iOS +// +// Created by Prokofev Ruslan on 28/09/2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// +import Foundation +import RxSwift + +public final class RunLoopThreadScheduler: ImmediateSchedulerType { + private let thread: Thread + private let target: ThreadTarget + + public init(threadName: String) { + self.target = ThreadTarget() + self.thread = Thread(target: target, + selector: #selector(ThreadTarget.threadEntryPoint), + object: nil) + self.thread.name = threadName + self.thread.start() + } + + public func schedule(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable { + let disposable = SingleAssignmentDisposable() + + var action: Action? = Action { + if disposable.isDisposed { + return + } + disposable.setDisposable(action(state)) + } + + action?.perform(#selector(Action.performAction), + on: thread, + with: nil, + waitUntilDone: false, + modes: [RunLoop.Mode.default.rawValue]) + + let actionDisposable = Disposables.create { + action = nil + } + + return Disposables.create(disposable, actionDisposable) + } + + deinit { + thread.cancel() + } +} + +public enum Schedulers { + public static var realmThreadScheduler: RunLoopThreadScheduler = { + return RunLoopThreadScheduler(threadName: "Realm") + }() +} + +private final class ThreadTarget: NSObject { + @objc fileprivate func threadEntryPoint() { + let runLoop = RunLoop.current + runLoop.add(NSMachPort(), forMode: RunLoop.Mode.default) + runLoop.run() + } +} + +private final class Action: NSObject { + private let action: () -> () + + init(action: @escaping () -> ()) { + self.action = action + } + + @objc func performAction() { + action() + } +} diff --git a/Extensions/Sources/Sync.swift b/Extensions/Sources/Sync.swift new file mode 100644 index 00000000..7680d858 --- /dev/null +++ b/Extensions/Sources/Sync.swift @@ -0,0 +1,72 @@ +// +// Sync.swift +// WavesWallet-iOS +// +// Created by Prokofev Ruslan on 25/11/2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift + +public enum Sync { + case remote(Result) + case local(Result, error: Error) + case error(Error) + + public var remote: Result? { + switch self { + case .remote(let model): + return model + + default: + return nil + } + } + + public var local: (result: Result, error: Error)? { + switch self { + case .local(let model, let error): + return (result: model, error: error) + + default: + return nil + } + } + + public var resultIngoreError: Result? { + switch self { + case .remote(let model): + return model + + case .local(let model, _): + return model + default: + return nil + } + } + + public var error: Error? { + switch self { + case .error(let error): + return error + + default: + return nil + } + } + + public var anyError: Error? { + switch self { + case .error(let error): + return error + + case .local(_, let error): + return error + default: + return nil + } + } +} + +public typealias SyncObservable = Observable> diff --git a/Extensions/Sources/TSUD+Rx.swift b/Extensions/Sources/TSUD+Rx.swift new file mode 100644 index 00000000..4e00806c --- /dev/null +++ b/Extensions/Sources/TSUD+Rx.swift @@ -0,0 +1,34 @@ +// +// TSUD+Rx.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 4/30/19. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import RxSwift +import WavesSDKExtensions + +public extension Reactive where Base: TSUD { + + static func get(_ nsud: UserDefaults = .standard) -> Observable { + + return Observable.create({ (subscribe) -> Disposable in + + subscribe.onNext(Base.init()[nsud]) + subscribe.onCompleted() + return Disposables.create() + }) + } + + static func set(_ value: Base.ValueType, _ nsud: UserDefaults = .standard) -> Observable{ + + return Observable.create({ (subscribe) -> Disposable in + + Base.init()[nsud] = value + subscribe.onNext(true) + subscribe.onCompleted() + return Disposables.create() + }) + } +} diff --git a/WavesWallet-iOS/Extensions/UIKit/Type/AssetLogo.swift b/Extensions/Sources/UI/AssetLogo.swift similarity index 56% rename from WavesWallet-iOS/Extensions/UIKit/Type/AssetLogo.swift rename to Extensions/Sources/UI/AssetLogo.swift index 202683f3..72663f29 100644 --- a/WavesWallet-iOS/Extensions/UIKit/Type/AssetLogo.swift +++ b/Extensions/Sources/UI/AssetLogo.swift @@ -10,108 +10,115 @@ import Foundation import RxSwift import Kingfisher -enum AssetLogo: String { - case waves = "waves" - case usd = "usd" - case monero = "xmr" - case litecoin = "ltc" - case lira = "try" - case eur = "eur" - case eth = "eth" - case dash = "dash" - case bitcoinCash = "bch" - case bitcoin = "btc" - case zcash = "zec" - case wct = "wavescommunity" - case bsv = "bsv" -} - -extension AssetLogo { +public enum AssetLogo { - var image48: UIImage { - switch self { - case .waves: - return Images.logoWaves48.image - case .usd: - return Images.logoUsd48.image - case .monero: - return Images.logoMonero48.image - case .litecoin: - return Images.logoLtc48.image - case .lira: - return Images.logoLira48.image - case .eur: - return Images.logoEuro48.image - case .eth: - return Images.logoEthereum48.image - case .dash: - return Images.logoDash48.image - case .bitcoin: - return Images.logoBitcoin48.image - case .bitcoinCash: - return Images.logoBitcoincash48.image - case .zcash: - return Images.logoZec48.image - case .wct: - return Images.logoWct48.image - case .bsv: - return Images.logoWct48.image + public struct Icon: Equatable, Codable { + public let assetId: String + public let name: String + public let url: String? + public let isSponsored: Bool + public let hasScript: Bool + + public init(assetId: String, + name: String, + url: String?, + isSponsored: Bool, + hasScript: Bool) { + + self.assetId = assetId + self.name = name + self.url = url + self.isSponsored = isSponsored + self.hasScript = hasScript } - } -} - -extension AssetLogo { + + var key: String { - struct Style: Hashable { - struct Border: Hashable { - let width: CGFloat - let color: UIColor + var keys: [String] = .init() + + keys.append(assetId) + keys.append(name) + keys.append("\(isSponsored)") + keys.append("\(hasScript)") + + if let url = url { + keys.append(url) + } + + return keys.reduce(into: "", { $0 = $0 + "." + $1 }) + } + } + + public struct Style: Hashable { + public struct Border: Hashable { + public let width: CGFloat + public let color: UIColor + + public init(width: CGFloat, + color: UIColor) { + self.width = width + self.color = color + } } - struct Specifications: Hashable { - let isSponsored: Bool - let hasScript: Bool - let size: CGSize + public struct Specifications: Hashable { + + public let sponsoredImage: UIImage + public let scriptImage: UIImage + public let size: CGSize + + public init(sponsoredImage: UIImage, + scriptImage: UIImage, + size: CGSize) { + self.sponsoredImage = sponsoredImage + self.scriptImage = scriptImage + self.size = size + } + } + + public let size: CGSize + public let font: UIFont + public let specs: Specifications + + public init(size: CGSize, + font: UIFont, + specs: Specifications) { + self.size = size + self.font = font + self.specs = specs } - - let size: CGSize - let font: UIFont - let specs: Specifications var key: String { - var key = "\(size.width)_\(size.height)" - key += "\(font.familyName)_\(font.lineHeight)" - if specs.isSponsored || specs.hasScript { - key += "\(specs.size.width)_\(specs.size.height)_\(specs.isSponsored)_\(specs.hasScript)" - } + var keys: [String] = .init() + + keys.append("\(size.width)") + keys.append("\(size.height)") + keys.append("\(font.familyName)") + keys.append("\(font.lineHeight)") + keys.append("\(specs.size.width)") + keys.append("\(specs.size.height)") + - return key + return keys.reduce(into: "", { $0 = $0 + "." + $1 }) } } +} - private static func cacheKeyForRemoteLogo(icon: DomainLayer.DTO.Asset.Icon, - style: Style) -> String { - return "com.wavesplatform.asset.logo.v2.\(icon.name).\(icon.assetId).\(style.key)" - } +public extension AssetLogo { - private static func cacheKeyForLocalLogo(icon: DomainLayer.DTO.Asset.Icon, - style: Style) -> String { - return "\(cacheKeyForRemoteLogo(icon: icon, style: style)).local" - } - - static func logo(icon: DomainLayer.DTO.Asset.Icon, + static func logo(icon: AssetLogo.Icon, style: Style) -> Observable { - + let key = cacheKeyForRemoteLogo(icon: icon, style: style) - + return retrieveImage(key: key) .flatMap({ (image) -> Observable in if let image = image { return Observable.just(image) } else { if let url = icon.url { - + return Observable.merge(localLogo(icon: icon, style: style), remoteLogo(icon: icon, @@ -124,8 +131,22 @@ extension AssetLogo { } }) } +} + +public extension AssetLogo { + + private static func cacheKeyForRemoteLogo(icon: AssetLogo.Icon, + style: Style) -> String { + return "com.wavesplatform.asset.logo.v3.\(icon.key).\(style.key)" + } - private static func remoteLogo(icon: DomainLayer.DTO.Asset.Icon, + private static func cacheKeyForLocalLogo(icon: AssetLogo.Icon, + style: Style) -> String { + return "\(cacheKeyForRemoteLogo(icon: icon, style: style)).local" + } + + + private static func remoteLogo(icon: AssetLogo.Icon, style: Style, url: String) -> Observable { @@ -151,9 +172,9 @@ extension AssetLogo { }) } - private static func prepareRemoteLogo(icon: DomainLayer.DTO.Asset.Icon, - style: Style, - image: UIImage) -> Observable { + private static func prepareRemoteLogo(icon: AssetLogo.Icon, + style: Style, + image: UIImage) -> Observable { let image = rxCreateLogo(icon: icon, image: image, @@ -168,7 +189,7 @@ extension AssetLogo { }) } - private static func localLogo(icon: DomainLayer.DTO.Asset.Icon, + private static func localLogo(icon: AssetLogo.Icon, style: Style) -> Observable { let localKey = cacheKeyForLocalLogo(icon: icon, style: style) @@ -177,9 +198,8 @@ extension AssetLogo { if let image = image { return Observable.just(image) } else { - let logo = AssetLogo(rawValue: icon.name.lowercased())?.image48 let image = rxCreateLogo(icon: icon, - image: logo, + image: nil, style: style) return image @@ -190,7 +210,7 @@ extension AssetLogo { }) } - private static func rxCreateLogo(icon: DomainLayer.DTO.Asset.Icon, + private static func rxCreateLogo(icon: AssetLogo.Icon, image: UIImage?, style: Style) -> Observable { @@ -205,7 +225,7 @@ extension AssetLogo { .observeOn(MainScheduler.asyncInstance) } - private static func createLogo(icon: DomainLayer.DTO.Asset.Icon, + private static func createLogo(icon: AssetLogo.Icon, image: UIImage?, style: Style) -> UIImage? { @@ -254,7 +274,7 @@ extension AssetLogo { } } - if style.specs.isSponsored || style.specs.hasScript { + if icon.hasScript || icon.isSponsored { let rect = CGRect(x: size.width - style.specs.size.width, y: size.height - style.specs.size.height, @@ -269,12 +289,58 @@ extension AssetLogo { context.setFillColor(color.cgColor) context.fill(rect) - let image = style.specs.isSponsored ? Images.sponsoritem18White.image : Images.scriptasset18White.image - image.draw(in: rect) + + if icon.hasScript { + style.specs.scriptImage.draw(in: rect) + } + + if icon.isSponsored { + style.specs.sponsoredImage.draw(in: rect) + } } let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return image } + + + static func createLogo(name: String, + logoColor: UIColor, + style: Style) -> UIImage? { + + let size = style.size + let font = style.font + + UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale) + guard let context = UIGraphicsGetCurrentContext() else { return nil } + context.saveGState() + + let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height) + context.addPath(UIBezierPath(roundedRect: rect, cornerRadius: rect.height * 0.5).cgPath) + context.clip() + context.setFillColor(logoColor.cgColor) + context.fill(rect) + if let first = name.first { + let symbol = String(first).uppercased() + let style = NSMutableParagraphStyle() + style.alignment = .center + let attributedString = NSAttributedString(string: symbol, + attributes: [.foregroundColor: UIColor.white, + .font: font, + .paragraphStyle: style]) + let sizeStr = attributedString.size() + + attributedString.draw(with: CGRect(x: (size.width - sizeStr.width) * 0.5, + y: (size.height - sizeStr.height) * 0.5, + width: sizeStr.width, + height: sizeStr.height), + options: [.usesLineFragmentOrigin], + context: nil) + } + + let image = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + return image + } } diff --git a/WavesWallet-iOS/Extensions/UIKit/CALayer+RoundingCorners.swift b/Extensions/Sources/UI/CALayer+RoundingCorners.swift similarity index 80% rename from WavesWallet-iOS/Extensions/UIKit/CALayer+RoundingCorners.swift rename to Extensions/Sources/UI/CALayer+RoundingCorners.swift index 59f454fc..95048835 100644 --- a/WavesWallet-iOS/Extensions/UIKit/CALayer+RoundingCorners.swift +++ b/Extensions/Sources/UI/CALayer+RoundingCorners.swift @@ -13,9 +13,9 @@ fileprivate enum Constants { static let maskName = "calayer.mask.clip.name" } -extension CALayer { +public extension CALayer { - func clip() { + public func clip() { self.mask = { let mask = CAShapeLayer() @@ -26,10 +26,10 @@ extension CALayer { }() } - func clip(roundedRect rect: CGRect? = nil, - byRoundingCorners corners: UIRectCorner = .allCorners, - cornerRadius: CGFloat, - inverse: Bool = false) { + public func clip(roundedRect rect: CGRect? = nil, + byRoundingCorners corners: UIRectCorner = .allCorners, + cornerRadius: CGFloat, + inverse: Bool = false) { self.mask = { @@ -52,15 +52,15 @@ extension CALayer { }() } - func removeClip() { + public func removeClip() { self.mask = nil } - func border(roundedRect rect: CGRect? = nil, - byRoundingCorners corners: UIRectCorner = .allCorners, - cornerRadius: CGFloat, - borderWidth: CGFloat, - borderColor: UIColor) { + public func border(roundedRect rect: CGRect? = nil, + byRoundingCorners corners: UIRectCorner = .allCorners, + cornerRadius: CGFloat, + borderWidth: CGFloat, + borderColor: UIColor) { self.removeBorder() @@ -96,7 +96,7 @@ extension CALayer { addSublayer(border) } - func removeBorder() { + public func removeBorder() { self.sublayers? .filter { $0.name == Constants.maskName } .forEach { $0.removeFromSuperlayer() } diff --git a/WavesWallet-iOS/Extensions/UIKit/CALayer+Shadow.swift b/Extensions/Sources/UI/CALayer+Shadow.swift similarity index 54% rename from WavesWallet-iOS/Extensions/UIKit/CALayer+Shadow.swift rename to Extensions/Sources/UI/CALayer+Shadow.swift index 74cd416c..6dcac7ea 100644 --- a/WavesWallet-iOS/Extensions/UIKit/CALayer+Shadow.swift +++ b/Extensions/Sources/UI/CALayer+Shadow.swift @@ -8,17 +8,25 @@ import UIKit -struct ShadowOptions { - let offset: CGSize - let color: UIColor - let opacity: Float - let shadowRadius: Float - let shouldRasterize: Bool +public struct ShadowOptions { + public let offset: CGSize + public let color: UIColor + public let opacity: Float + public let shadowRadius: Float + public let shouldRasterize: Bool + + public init(offset: CGSize, color: UIColor, opacity: Float, shadowRadius: Float, shouldRasterize: Bool) { + self.offset = offset + self.color = color + self.opacity = opacity + self.shadowRadius = shadowRadius + self.shouldRasterize = shouldRasterize + } } -extension CALayer { +public extension CALayer { - func setupShadow(options: ShadowOptions) { + public func setupShadow(options: ShadowOptions) { shadowColor = options.color.cgColor shadowOffset = options.offset shadowOpacity = options.opacity @@ -29,7 +37,7 @@ extension CALayer { } } - func removeShadow() { + public func removeShadow() { shadowColor = nil shadowOffset = CGSize.zero shadowOpacity = 0 diff --git a/WavesWallet-iOS/Extensions/UIKit/CGFloat+Min.swift b/Extensions/Sources/UI/CGFloat+Min.swift similarity index 83% rename from WavesWallet-iOS/Extensions/UIKit/CGFloat+Min.swift rename to Extensions/Sources/UI/CGFloat+Min.swift index 66b30f80..3b48f253 100644 --- a/WavesWallet-iOS/Extensions/UIKit/CGFloat+Min.swift +++ b/Extensions/Sources/UI/CGFloat+Min.swift @@ -9,8 +9,8 @@ import Foundation import UIKit -extension CGFloat { - static var minValue: CGFloat { +public extension CGFloat { + public static var minValue: CGFloat { if #available(iOS 11.0, *) { return CGFloat.leastNonzeroMagnitude } else { diff --git a/WavesWallet-iOS/Extensions/CGSize+Hashable.swift b/Extensions/Sources/UI/CGSize+Hashable.swift similarity index 100% rename from WavesWallet-iOS/Extensions/CGSize+Hashable.swift rename to Extensions/Sources/UI/CGSize+Hashable.swift diff --git a/WavesWallet-iOS/Extensions/UIKit/ControlEvent+ScrollView.swift b/Extensions/Sources/UI/ControlEvent+ScrollView.swift similarity index 84% rename from WavesWallet-iOS/Extensions/UIKit/ControlEvent+ScrollView.swift rename to Extensions/Sources/UI/ControlEvent+ScrollView.swift index 4951b9d9..21728bc7 100644 --- a/WavesWallet-iOS/Extensions/UIKit/ControlEvent+ScrollView.swift +++ b/Extensions/Sources/UI/ControlEvent+ScrollView.swift @@ -11,9 +11,9 @@ import Foundation import RxCocoa import RxSwift -extension Reactive where Base: UIScrollView { +public extension Reactive where Base: UIScrollView { - var didEndScroll: ControlEvent { + public var didEndScroll: ControlEvent { let events = base.rx .didEndDragging .flatMap(weak: base) { owner, isDecelerate -> Observable in @@ -26,7 +26,7 @@ extension Reactive where Base: UIScrollView { return ControlEvent(events: events) } - func didRefreshing(refreshControl: UIRefreshControl) -> ControlEvent { + public func didRefreshing(refreshControl: UIRefreshControl) -> ControlEvent { let didEndScroll = base .rx diff --git a/WavesWallet-iOS/Extensions/UIKit/Protocols/Module/ModuleBuilder.swift b/Extensions/Sources/UI/Protocols/Module/ModuleBuilder.swift similarity index 79% rename from WavesWallet-iOS/Extensions/UIKit/Protocols/Module/ModuleBuilder.swift rename to Extensions/Sources/UI/Protocols/Module/ModuleBuilder.swift index 6a355f85..96cda9c7 100644 --- a/WavesWallet-iOS/Extensions/UIKit/Protocols/Module/ModuleBuilder.swift +++ b/Extensions/Sources/UI/Protocols/Module/ModuleBuilder.swift @@ -8,12 +8,12 @@ import UIKit -protocol ModuleBuilder { +public protocol ModuleBuilder { associatedtype Input func build(input: Input) -> UIViewController } -extension ModuleBuilder where Input == Void { +public extension ModuleBuilder where Input == Void { func build() -> UIViewController { return build(input: ()) } diff --git a/WavesWallet-iOS/Extensions/UIKit/Protocols/Module/ModuleBuilderOutput.swift b/Extensions/Sources/UI/Protocols/Module/ModuleBuilderOutput.swift similarity index 81% rename from WavesWallet-iOS/Extensions/UIKit/Protocols/Module/ModuleBuilderOutput.swift rename to Extensions/Sources/UI/Protocols/Module/ModuleBuilderOutput.swift index 5b791e04..51c35096 100644 --- a/WavesWallet-iOS/Extensions/UIKit/Protocols/Module/ModuleBuilderOutput.swift +++ b/Extensions/Sources/UI/Protocols/Module/ModuleBuilderOutput.swift @@ -8,7 +8,7 @@ import UIKit -protocol ModuleBuilderOutput: ModuleBuilder { +public protocol ModuleBuilderOutput: ModuleBuilder { associatedtype Output var output: Output { get } } diff --git a/WavesWallet-iOS/Extensions/UIKit/Protocols/Reusable/NibLoadable.swift b/Extensions/Sources/UI/Protocols/Reusable/NibLoadable.swift similarity index 95% rename from WavesWallet-iOS/Extensions/UIKit/Protocols/Reusable/NibLoadable.swift rename to Extensions/Sources/UI/Protocols/Reusable/NibLoadable.swift index 35a663a7..313a36f6 100644 --- a/WavesWallet-iOS/Extensions/UIKit/Protocols/Reusable/NibLoadable.swift +++ b/Extensions/Sources/UI/Protocols/Reusable/NibLoadable.swift @@ -33,7 +33,7 @@ public extension NibLoadable { } public extension NibLoadable where Self: Reusable { - static var nibName: String { + public static var nibName: String { return reuseIdentifier } } diff --git a/WavesWallet-iOS/Extensions/UIKit/Protocols/Reusable/NibOwnerLoadable.swift b/Extensions/Sources/UI/Protocols/Reusable/NibOwnerLoadable.swift similarity index 100% rename from WavesWallet-iOS/Extensions/UIKit/Protocols/Reusable/NibOwnerLoadable.swift rename to Extensions/Sources/UI/Protocols/Reusable/NibOwnerLoadable.swift diff --git a/WavesWallet-iOS/Extensions/UIKit/Protocols/Reusable/Reusable.swift b/Extensions/Sources/UI/Protocols/Reusable/Reusable.swift similarity index 100% rename from WavesWallet-iOS/Extensions/UIKit/Protocols/Reusable/Reusable.swift rename to Extensions/Sources/UI/Protocols/Reusable/Reusable.swift diff --git a/WavesWallet-iOS/Extensions/UIKit/Protocols/Reusable/UICollectionView+Reusable.swift b/Extensions/Sources/UI/Protocols/Reusable/UICollectionView+Reusable.swift similarity index 98% rename from WavesWallet-iOS/Extensions/UIKit/Protocols/Reusable/UICollectionView+Reusable.swift rename to Extensions/Sources/UI/Protocols/Reusable/UICollectionView+Reusable.swift index f653658a..fc580516 100644 --- a/WavesWallet-iOS/Extensions/UIKit/Protocols/Reusable/UICollectionView+Reusable.swift +++ b/Extensions/Sources/UI/Protocols/Reusable/UICollectionView+Reusable.swift @@ -8,7 +8,7 @@ import UIKit -extension UICollectionView { +public extension UICollectionView { enum SupplementaryViewKind { case header diff --git a/WavesWallet-iOS/Extensions/UIKit/Protocols/Reusable/UITableView+Reusable.swift b/Extensions/Sources/UI/Protocols/Reusable/UITableView+Reusable.swift similarity index 80% rename from WavesWallet-iOS/Extensions/UIKit/Protocols/Reusable/UITableView+Reusable.swift rename to Extensions/Sources/UI/Protocols/Reusable/UITableView+Reusable.swift index fd3cbb96..e7a432ba 100644 --- a/WavesWallet-iOS/Extensions/UIKit/Protocols/Reusable/UITableView+Reusable.swift +++ b/Extensions/Sources/UI/Protocols/Reusable/UITableView+Reusable.swift @@ -10,22 +10,22 @@ import Foundation import UIKit public extension UITableView { - func registerHeaderFooter(type: HeaderFooter.Type) + public func registerHeaderFooter(type: HeaderFooter.Type) where HeaderFooter: UITableViewHeaderFooterView & NibReusable { register(HeaderFooter.nib, forHeaderFooterViewReuseIdentifier: HeaderFooter.reuseIdentifier) } - func registerHeaderFooter(type: HeaderFooter.Type) + public func registerHeaderFooter(type: HeaderFooter.Type) where HeaderFooter: UITableViewHeaderFooterView & Reusable { register(type, forHeaderFooterViewReuseIdentifier: HeaderFooter.reuseIdentifier) } - func dequeueHeaderFooter() -> HeaderFooter + public func dequeueHeaderFooter() -> HeaderFooter where HeaderFooter: UITableViewHeaderFooterView & Reusable { return dequeueReusableHeaderFooterView(withIdentifier: HeaderFooter.reuseIdentifier) as! HeaderFooter } - func dequeueAndRegisterHeaderFooter() -> HeaderFooter + public func dequeueAndRegisterHeaderFooter() -> HeaderFooter where HeaderFooter: UITableViewHeaderFooterView & NibReusable { if let headerFooter = dequeueReusableHeaderFooterView(withIdentifier: HeaderFooter.reuseIdentifier) as? HeaderFooter { return headerFooter @@ -35,7 +35,7 @@ public extension UITableView { } } - func dequeueAndRegisterHeaderFooter() -> HeaderFooter + public func dequeueAndRegisterHeaderFooter() -> HeaderFooter where HeaderFooter: UITableViewHeaderFooterView & Reusable { if let headerFooter = dequeueReusableHeaderFooterView(withIdentifier: HeaderFooter.reuseIdentifier) as? HeaderFooter { return headerFooter @@ -49,27 +49,27 @@ public extension UITableView { // MARK: - Register and dequeue cell public extension UITableView { - func registerCell(type: Cell.Type) + public func registerCell(type: Cell.Type) where Cell: UITableViewCell & NibReusable { register(Cell.nib, forCellReuseIdentifier: Cell.reuseIdentifier) } - func registerCell(type: Cell.Type) + public func registerCell(type: Cell.Type) where Cell: UITableViewCell & Reusable { register(type, forCellReuseIdentifier: Cell.reuseIdentifier) } - func dequeueCell() -> Cell + public func dequeueCell() -> Cell where Cell: UITableViewCell & Reusable { return dequeueReusableCell(withIdentifier: Cell.reuseIdentifier) as! Cell } - func dequeueCellForIndexPath(indexPath: IndexPath) -> Cell + public func dequeueCellForIndexPath(indexPath: IndexPath) -> Cell where Cell: UITableViewCell & Reusable { return dequeueReusableCell(withIdentifier: Cell.reuseIdentifier, for: indexPath) as! Cell } - func dequeueAndRegisterCell() -> Cell + public func dequeueAndRegisterCell() -> Cell where Cell: UITableViewCell & NibReusable { if let cell = dequeueReusableCell(withIdentifier: Cell.reuseIdentifier) as? Cell { return cell @@ -79,7 +79,7 @@ public extension UITableView { } } - func dequeueAndRegisterCell() -> Cell + public func dequeueAndRegisterCell() -> Cell where Cell: UITableViewCell & Reusable { if let cell = dequeueReusableCell(withIdentifier: Cell.reuseIdentifier) as? Cell { return cell @@ -89,13 +89,13 @@ public extension UITableView { } } - func dequeueAndRegisterCell(indexPath: IndexPath) -> Cell + public func dequeueAndRegisterCell(indexPath: IndexPath) -> Cell where Cell: UITableViewCell & NibReusable { register(Cell.nib, forCellReuseIdentifier: Cell.reuseIdentifier) return dequeueReusableCell(withIdentifier: Cell.reuseIdentifier, for: indexPath) as! Cell } - func dequeueAndRegisterCell(indexPath: IndexPath) -> Cell + public func dequeueAndRegisterCell(indexPath: IndexPath) -> Cell where Cell: UITableViewCell & Reusable { register(Cell.self, forCellReuseIdentifier: Cell.reuseIdentifier) return dequeueReusableCell(withIdentifier: Cell.reuseIdentifier, for: indexPath) as! Cell diff --git a/Extensions/Sources/UI/Protocols/SectionDisplayCollection.swift b/Extensions/Sources/UI/Protocols/SectionDisplayCollection.swift new file mode 100644 index 00000000..abc14170 --- /dev/null +++ b/Extensions/Sources/UI/Protocols/SectionDisplayCollection.swift @@ -0,0 +1,59 @@ +// +// SectionDisplayCollection.swift +// WavesWallet-iOS +// +// Created by Prokofev Ruslan on 15/08/2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation + +public protocol SectionProtocol { + associatedtype Row + var rows: [Row] { get set } +} + +public protocol DataSourceProtocol { + associatedtype Section: SectionProtocol + var sections: [Section] { get set } +} + +public extension DataSourceProtocol { + subscript(indexPath: IndexPath) -> Section.Row { + get { + return sections[indexPath.section].rows[indexPath.row] + } + + set { + sections[indexPath.section].rows[indexPath.row] = newValue + } + } + + subscript(section: Int) -> Section { + get { + return sections[section] + } + + set { + sections[section] = newValue + } + } +} + +public extension SectionProtocol { + subscript(index: Int) -> Row { + get { + return rows[index] + } + set { + rows[index] = newValue + } + } +} + +public extension Array where Element: SectionProtocol { + + subscript(indexPath: IndexPath) -> Element.Row { + return self[indexPath.section][indexPath.row] + } +} diff --git a/WavesWallet-iOS/Extensions/UIKit/Protocols/ViewCalculate.swift b/Extensions/Sources/UI/Protocols/ViewCalculate.swift similarity index 81% rename from WavesWallet-iOS/Extensions/UIKit/Protocols/ViewCalculate.swift rename to Extensions/Sources/UI/Protocols/ViewCalculate.swift index f0e744b0..5d07a3da 100644 --- a/WavesWallet-iOS/Extensions/UIKit/Protocols/ViewCalculate.swift +++ b/Extensions/Sources/UI/Protocols/ViewCalculate.swift @@ -8,12 +8,12 @@ import UIKit -protocol ViewCalculateHeight { +public protocol ViewCalculateHeight { associatedtype Model static func viewHeight(model: Model, width: CGFloat) -> CGFloat } -protocol ViewHeight { +public protocol ViewHeight { static func viewHeight() -> CGFloat } diff --git a/WavesWallet-iOS/Extensions/UIKit/Protocols/ViewConfiguration.swift b/Extensions/Sources/UI/Protocols/ViewConfiguration.swift similarity index 71% rename from WavesWallet-iOS/Extensions/UIKit/Protocols/ViewConfiguration.swift rename to Extensions/Sources/UI/Protocols/ViewConfiguration.swift index 34066beb..04e2cfe8 100644 --- a/WavesWallet-iOS/Extensions/UIKit/Protocols/ViewConfiguration.swift +++ b/Extensions/Sources/UI/Protocols/ViewConfiguration.swift @@ -8,16 +8,16 @@ import Foundation -protocol ViewConfiguration { +public protocol ViewConfiguration { associatedtype Model func update(with model: Model) } -protocol ViewAnimatableConfiguration: ViewConfiguration { +public protocol ViewAnimatableConfiguration: ViewConfiguration { func update(with model: Model, animated: Bool) } -extension ViewAnimatableConfiguration { +public extension ViewAnimatableConfiguration { func update(with model: Model) { update(with: model, animated: true) } diff --git a/Extensions/Sources/UI/String+Size.swift b/Extensions/Sources/UI/String+Size.swift new file mode 100644 index 00000000..6e1dc54e --- /dev/null +++ b/Extensions/Sources/UI/String+Size.swift @@ -0,0 +1,44 @@ +// +// String+Size.swift +// WavesWallet-iOS +// +// Created by rprokofev on 24/05/2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import UIKit + +public extension String { + + public func maxHeight(font: UIFont, forWidth: CGFloat) -> CGFloat { + let text = self as NSString + return ceil(text.boundingRect(with: CGSize(width: forWidth, height: CGFloat.greatestFiniteMagnitude), options: .usesLineFragmentOrigin, attributes: [.font: font], context: nil).size.height) + } + + public func maxHeightMultiline(font: UIFont, forWidth: CGFloat) -> CGFloat { + let style = NSMutableParagraphStyle() + style.lineBreakMode = .byWordWrapping + + let rect = NSAttributedString(string: self, attributes: [.font: font, + .paragraphStyle: style]) + .boundingRect(with: CGSize(width: forWidth, + height: CGFloat.greatestFiniteMagnitude), + options: [.usesLineFragmentOrigin, .usesFontLeading], + context: nil) + + return ceil(rect.height) + } + + public func maxWidth(font: UIFont) -> CGFloat { + let text = self as NSString + return ceil(text.boundingRect(with: CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude), options: .usesLineFragmentOrigin, attributes: [.font: font], context: nil).size.width) + } +} + +public extension NSAttributedString { + + public func boundingRect(with size: CGSize) -> CGRect { + return boundingRect(with: size, options: [.usesLineFragmentOrigin, .usesFontLeading], context: nil) + } +} diff --git a/WavesWallet-iOS/Extensions/UIKit/TableViewNoShadow.swift b/Extensions/Sources/UI/TableViewNoShadow.swift similarity index 74% rename from WavesWallet-iOS/Extensions/UIKit/TableViewNoShadow.swift rename to Extensions/Sources/UI/TableViewNoShadow.swift index 20ec8cc0..8955a342 100644 --- a/WavesWallet-iOS/Extensions/UIKit/TableViewNoShadow.swift +++ b/Extensions/Sources/UI/TableViewNoShadow.swift @@ -8,9 +8,9 @@ import UIKit -final class TableViewNoShadow: UITableView { +public final class TableViewNoShadow: UITableView { - override func didAddSubview(_ subview: UIView) { + override public func didAddSubview(_ subview: UIView) { super.didAddSubview(subview) if "\(type(of: subview))" == "UIShadowView" { subview.removeFromSuperview() diff --git a/WavesWallet-iOS/Extensions/UIKit/TimingFunction.swift b/Extensions/Sources/UI/TimingFunction.swift similarity index 97% rename from WavesWallet-iOS/Extensions/UIKit/TimingFunction.swift rename to Extensions/Sources/UI/TimingFunction.swift index c7f1097f..45ed8fd4 100644 --- a/WavesWallet-iOS/Extensions/UIKit/TimingFunction.swift +++ b/Extensions/Sources/UI/TimingFunction.swift @@ -8,7 +8,7 @@ import QuartzCore -enum TimingFunction { +public enum TimingFunction { case linear case easeIn case easeOut @@ -39,7 +39,7 @@ enum TimingFunction { case easeOutBack case easeInOutBack - var caMediaTimingFuction: CAMediaTimingFunction { + public var caMediaTimingFuction: CAMediaTimingFunction { switch self { case .linear: return CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) diff --git a/WavesWallet-iOS/Extensions/UIKit/UIApplication+OpenURL.swift b/Extensions/Sources/UI/UIApplication+OpenURL.swift similarity index 95% rename from WavesWallet-iOS/Extensions/UIKit/UIApplication+OpenURL.swift rename to Extensions/Sources/UI/UIApplication+OpenURL.swift index 960068b8..5ab6590d 100644 --- a/WavesWallet-iOS/Extensions/UIKit/UIApplication+OpenURL.swift +++ b/Extensions/Sources/UI/UIApplication+OpenURL.swift @@ -8,7 +8,7 @@ import UIKit -extension UIApplication { +public extension UIApplication { func openURLAsync(_ url: URL) { DispatchQueue.main.async { self.open(url, options: convertToUIApplicationOpenExternalURLOptionsKeyDictionary(.init()), completionHandler: nil) diff --git a/WavesWallet-iOS/Extensions/UIKit/UIButton+WithoutAnimation.swift b/Extensions/Sources/UI/UIButton+WithoutAnimation.swift similarity index 69% rename from WavesWallet-iOS/Extensions/UIKit/UIButton+WithoutAnimation.swift rename to Extensions/Sources/UI/UIButton+WithoutAnimation.swift index 28ba2ee3..489eac38 100644 --- a/WavesWallet-iOS/Extensions/UIKit/UIButton+WithoutAnimation.swift +++ b/Extensions/Sources/UI/UIButton+WithoutAnimation.swift @@ -8,10 +8,8 @@ import UIKit - -// TODO: COME BACK -extension UIButton { - func setTitleWithoutAnimated(_ title: String?, for state: UIControl.State) { +public extension UIButton { + public func setTitleWithoutAnimated(_ title: String?, for state: UIControl.State) { UIView.performWithoutAnimation { setTitle(title, for: state) } diff --git a/WavesWallet-iOS/Extensions/UIKit/UIColor+Asset.swift b/Extensions/Sources/UI/UIColor+Asset.swift similarity index 97% rename from WavesWallet-iOS/Extensions/UIKit/UIColor+Asset.swift rename to Extensions/Sources/UI/UIColor+Asset.swift index 4c40a0f5..e0027bff 100644 --- a/WavesWallet-iOS/Extensions/UIKit/UIColor+Asset.swift +++ b/Extensions/Sources/UI/UIColor+Asset.swift @@ -50,7 +50,7 @@ private enum Constants { ] } -extension UIColor { +public extension UIColor { static func colorAsset(assetId: String) -> UIColor { diff --git a/WavesWallet-iOS/Extensions/UIKit/UIColor+Colors.swift b/Extensions/Sources/UI/UIColor+Colors.swift similarity index 95% rename from WavesWallet-iOS/Extensions/UIKit/UIColor+Colors.swift rename to Extensions/Sources/UI/UIColor+Colors.swift index 003751da..7890a9f9 100644 --- a/WavesWallet-iOS/Extensions/UIKit/UIColor+Colors.swift +++ b/Extensions/Sources/UI/UIColor+Colors.swift @@ -8,19 +8,19 @@ import UIKit -extension UIColor { +public extension UIColor { @nonobjc class var overlayDark: UIColor { return UIColor(red: 0.0, green: 26.0 / 255.0, blue: 57.0 / 255.0, alpha: 0.2) } - @nonobjc class var white: UIColor { - return UIColor(white: 1.0, alpha: 1.0) - } +// @nonobjc class var white: UIColor { +// return UIColor(white: 1.0, alpha: 1.0) +// } - @nonobjc class var black: UIColor { - return UIColor(white: 0.0, alpha: 1.0) - } +// @nonobjc class var black: UIColor { +// return UIColor(white: 0.0, alpha: 1.0) +// } @nonobjc class var disabled666: UIColor { return UIColor(red: 0.0 / 255.0, green: 26.0 / 255.0, blue: 57 / 255.0, alpha: 1.0) @@ -209,4 +209,8 @@ extension UIColor { @nonobjc class var blueGrey: UIColor { return UIColor(red: 155.0 / 255.0, green: 166.0 / 255.0, blue: 178.0 / 255.0, alpha: 1.0) } + + @nonobjc class var clearBlue: UIColor { + return UIColor(red: 51.0 / 255.0, green: 129.0 / 255.0, blue: 237.0 / 255.0, alpha: 1.0) + } } diff --git a/WavesWallet-iOS/Extensions/UIKit/UIColor+Hex.swift b/Extensions/Sources/UI/UIColor+Hex.swift similarity index 85% rename from WavesWallet-iOS/Extensions/UIKit/UIColor+Hex.swift rename to Extensions/Sources/UI/UIColor+Hex.swift index 65f2cd7b..b46c2e8a 100644 --- a/WavesWallet-iOS/Extensions/UIKit/UIColor+Hex.swift +++ b/Extensions/Sources/UI/UIColor+Hex.swift @@ -8,9 +8,9 @@ import UIKit -extension UIColor { +public extension UIColor { - convenience init(red: Int, green: Int, blue: Int) { + public convenience init(red: Int, green: Int, blue: Int) { assert(red >= 0 && red <= 255, "Invalid red component") assert(green >= 0 && green <= 255, "Invalid green component") assert(blue >= 0 && blue <= 255, "Invalid blue component") @@ -18,16 +18,15 @@ extension UIColor { self.init(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: 1.0) } - convenience init(_ red: Int, _ green: Int, _ blue: Int) { + public convenience init(_ red: Int, _ green: Int, _ blue: Int) { self.init(red:red, green:green, blue:blue) } - convenience init(netHex: Int) { + public convenience init(netHex: Int) { self.init(red:(netHex >> 16) & 0xff, green:(netHex >> 8) & 0xff, blue:netHex & 0xff) } - - convenience init(hex: String) { + public convenience init(hex: String) { var cString:String = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased() @@ -48,7 +47,7 @@ extension UIColor { alpha: 1.0) } - func toHexString() -> String { + public func toHexString() -> String { var r:CGFloat = 0 var g:CGFloat = 0 var b:CGFloat = 0 diff --git a/WavesWallet-iOS/Extensions/UIKit/UIFeedbackGenerator.swift b/Extensions/Sources/UI/UIFeedbackGenerator.swift similarity index 81% rename from WavesWallet-iOS/Extensions/UIKit/UIFeedbackGenerator.swift rename to Extensions/Sources/UI/UIFeedbackGenerator.swift index 964bd255..4dd291e4 100644 --- a/WavesWallet-iOS/Extensions/UIKit/UIFeedbackGenerator.swift +++ b/Extensions/Sources/UI/UIFeedbackGenerator.swift @@ -9,16 +9,16 @@ import UIKit import AudioToolbox -enum ImpactFeedbackGenerator { +public enum ImpactFeedbackGenerator { - static func impactOccurred() { + public static func impactOccurred() { if #available(iOS 10.0, *) { UIImpactFeedbackGenerator(style: .medium) .impactOccurred() } } - static func impactOccurredOrVibrate() { + public static func impactOccurredOrVibrate() { if #available(iOS 10.0, *) { UIImpactFeedbackGenerator(style: .medium) .impactOccurred() diff --git a/WavesWallet-iOS/Extensions/UIKit/UIFont+Additions.swift b/Extensions/Sources/UI/UIFont+Additions.swift similarity index 64% rename from WavesWallet-iOS/Extensions/UIKit/UIFont+Additions.swift rename to Extensions/Sources/UI/UIFont+Additions.swift index 923cd132..37e76f00 100644 --- a/WavesWallet-iOS/Extensions/UIKit/UIFont+Additions.swift +++ b/Extensions/Sources/UI/UIFont+Additions.swift @@ -8,57 +8,57 @@ import UIKit -extension UIFont { +public extension UIFont { - class var titleH1: UIFont { + public class var titleH1: UIFont { return UIFont.systemFont(ofSize: 34.0, weight: .bold) } - class var titleH2: UIFont { + public class var titleH2: UIFont { return UIFont.systemFont(ofSize: 22.0, weight: .bold) } - class var headlineRegular: UIFont { + public class var headlineRegular: UIFont { return UIFont.systemFont(ofSize: 22.0, weight: .regular) } - class var headlineSemibold: UIFont { + public class var headlineSemibold: UIFont { return UIFont.systemFont(ofSize: 17.0, weight: .semibold) } - class var bodyRegular: UIFont { + public class var bodyRegular: UIFont { return UIFont.systemFont(ofSize: 17.0, weight: .regular) } - class var bodySemibold: UIFont { + public class var bodySemibold: UIFont { return UIFont.systemFont(ofSize: 17.0, weight: .semibold) } - class var actionSheetRegular: UIFont { + public class var actionSheetRegular: UIFont { return UIFont.systemFont(ofSize: 20.0, weight: .regular) } - class var actionSheetSemibold: UIFont { + public class var actionSheetSemibold: UIFont { return UIFont.systemFont(ofSize: 20.0, weight: .semibold) } - class var passcodeRegular: UIFont { + public class var passcodeRegular: UIFont { return UIFont.systemFont(ofSize: 36, weight: .regular) } - class var captionRegular: UIFont { + public class var captionRegular: UIFont { return UIFont.systemFont(ofSize: 13, weight: .regular) } - class var captionSemibold: UIFont { + public class var captionSemibold: UIFont { return UIFont.systemFont(ofSize: 13, weight: .regular) } - class var tagRegular: UIFont { + public class var tagRegular: UIFont { return UIFont.systemFont(ofSize: 10, weight: .regular) } - class var tabBarRegular: UIFont { + public class var tabBarRegular: UIFont { return UIFont.systemFont(ofSize: 10, weight: .regular) } } diff --git a/WavesWallet-iOS/Extensions/UIKit/UIImage+Color.swift b/Extensions/Sources/UI/UIImage+Color.swift similarity index 100% rename from WavesWallet-iOS/Extensions/UIKit/UIImage+Color.swift rename to Extensions/Sources/UI/UIImage+Color.swift diff --git a/WavesWallet-iOS/Extensions/UIKit/UIImageView+Rx.swift b/Extensions/Sources/UI/UIImageView+Rx.swift similarity index 94% rename from WavesWallet-iOS/Extensions/UIKit/UIImageView+Rx.swift rename to Extensions/Sources/UI/UIImageView+Rx.swift index fa3a7c03..2a1d81d5 100644 --- a/WavesWallet-iOS/Extensions/UIKit/UIImageView+Rx.swift +++ b/Extensions/Sources/UI/UIImageView+Rx.swift @@ -11,7 +11,7 @@ import UIKit import RxSwift import RxCocoa -extension Reactive where Base: UIImageView { +public extension Reactive where Base: UIImageView { /// Bindable sink for `image` property. public var imageAnimationFadeIn: Binder { diff --git a/WavesWallet-iOS/Extensions/UIKit/UINavigationController+Additionals.swift b/Extensions/Sources/UI/UINavigationController+Additionals.swift similarity index 79% rename from WavesWallet-iOS/Extensions/UIKit/UINavigationController+Additionals.swift rename to Extensions/Sources/UI/UINavigationController+Additionals.swift index d0c9e9f5..5bff53c6 100644 --- a/WavesWallet-iOS/Extensions/UIKit/UINavigationController+Additionals.swift +++ b/Extensions/Sources/UI/UINavigationController+Additionals.swift @@ -8,9 +8,9 @@ import UIKit -extension UINavigationController { +public extension UINavigationController { - func pushViewControllerAndSetLast(_ viewController: UIViewController) { + public func pushViewControllerAndSetLast(_ viewController: UIViewController) { CATransaction.begin() CATransaction.setCompletionBlock { @@ -22,9 +22,9 @@ extension UINavigationController { } -extension UIImage { +public extension UIImage { - static func shadowImage(color: UIColor) -> UIImage? { + public static func shadowImage(color: UIColor) -> UIImage? { UIGraphicsBeginImageContext(CGSize(width: 0.5, height: 0.5)) guard let ctx = UIGraphicsGetCurrentContext() else { return nil } color.setFill() diff --git a/WavesWallet-iOS/Extensions/UIKit/UIScrollView+ContentInset.swift b/Extensions/Sources/UI/UIScrollView+ContentInset.swift similarity index 78% rename from WavesWallet-iOS/Extensions/UIKit/UIScrollView+ContentInset.swift rename to Extensions/Sources/UI/UIScrollView+ContentInset.swift index 7336f169..2e6d0ab9 100644 --- a/WavesWallet-iOS/Extensions/UIKit/UIScrollView+ContentInset.swift +++ b/Extensions/Sources/UI/UIScrollView+ContentInset.swift @@ -8,9 +8,9 @@ import UIKit -extension UIScrollView { +public extension UIScrollView { - var adjustedContentInsetAdapter: UIEdgeInsets { + public var adjustedContentInsetAdapter: UIEdgeInsets { if #available(iOS 11.0, *) { return adjustedContentInset } else { diff --git a/WavesWallet-iOS/Extensions/UIKit/UIScrollView+Pagination.swift b/Extensions/Sources/UI/UIScrollView+Pagination.swift similarity index 78% rename from WavesWallet-iOS/Extensions/UIKit/UIScrollView+Pagination.swift rename to Extensions/Sources/UI/UIScrollView+Pagination.swift index c8f6acf7..19c9000a 100644 --- a/WavesWallet-iOS/Extensions/UIKit/UIScrollView+Pagination.swift +++ b/Extensions/Sources/UI/UIScrollView+Pagination.swift @@ -8,9 +8,9 @@ import UIKit -extension UIScrollView { +public extension UIScrollView { - var currentPage: Int { + public var currentPage: Int { return Int(contentOffset.x / bounds.size.width) } } diff --git a/WavesWallet-iOS/Extensions/UIKit/UITableView+Animation.swift b/Extensions/Sources/UI/UITableView+Animation.swift similarity index 80% rename from WavesWallet-iOS/Extensions/UIKit/UITableView+Animation.swift rename to Extensions/Sources/UI/UITableView+Animation.swift index 34c0d7dd..a83a4bd7 100644 --- a/WavesWallet-iOS/Extensions/UIKit/UITableView+Animation.swift +++ b/Extensions/Sources/UI/UITableView+Animation.swift @@ -8,9 +8,9 @@ import UIKit -extension UITableView { +public extension UITableView { - func reloadDataWithAnimationTheCrossDissolve(completion: (() -> Void)? = nil) { + public func reloadDataWithAnimationTheCrossDissolve(completion: (() -> Void)? = nil) { UIView.transition(with: self, duration: 0.24, options: [.transitionCrossDissolve, diff --git a/WavesWallet-iOS/Extensions/UIKit/UITableView+HeaderView.swift b/Extensions/Sources/UI/UITableView+HeaderView.swift similarity index 94% rename from WavesWallet-iOS/Extensions/UIKit/UITableView+HeaderView.swift rename to Extensions/Sources/UI/UITableView+HeaderView.swift index b41d20c3..465582ba 100644 --- a/WavesWallet-iOS/Extensions/UIKit/UITableView+HeaderView.swift +++ b/Extensions/Sources/UI/UITableView+HeaderView.swift @@ -8,7 +8,7 @@ import UIKit -extension UITableView { +public extension UITableView { private enum AssociatedKey { static var headerView = "headerView" @@ -27,7 +27,7 @@ extension UITableView { } } - func bindHeaderView(_ view: UIView) { + public func bindHeaderView(_ view: UIView) { self.containerHeaderView?.removeFromSuperview() self.containerHeaderView = UIView() diff --git a/WavesWallet-iOS/Extensions/UIKit/UIView+Additionals.swift b/Extensions/Sources/UI/UIView+Additionals.swift similarity index 90% rename from WavesWallet-iOS/Extensions/UIKit/UIView+Additionals.swift rename to Extensions/Sources/UI/UIView+Additionals.swift index 55d65b7c..875ca0b2 100644 --- a/WavesWallet-iOS/Extensions/UIKit/UIView+Additionals.swift +++ b/Extensions/Sources/UI/UIView+Additionals.swift @@ -9,11 +9,11 @@ import Foundation import UIKit -extension UIView { +public extension UIView { - func addTableCellShadowStyle() { + func addTableCellShadowStyle(offset: CGSize = CGSize(width: 0, height: 4)) { - setupShadow(options: .init(offset: CGSize(width: 0, height: 4), + setupShadow(options: .init(offset: offset, color: .black, opacity: 0.10, shadowRadius: 2, @@ -21,9 +21,13 @@ extension UIView { self.cornerRadius = 4 } - class func loadView() -> UIView { + func removeTableCellShadowStyle() { + removeShadow() + } + + class func loadView() -> View where View : UIView { let clsName = String(describing: self) - return Bundle.main.loadNibNamed(clsName, owner: nil, options: nil)!.last! as! UIView + return Bundle.main.loadNibNamed(clsName, owner: nil, options: nil)!.last! as! View } func shakeView() { diff --git a/WavesWallet-iOS/Extensions/UIKit/UIView+Animation.swift b/Extensions/Sources/UI/UIView+Animation.swift similarity index 85% rename from WavesWallet-iOS/Extensions/UIKit/UIView+Animation.swift rename to Extensions/Sources/UI/UIView+Animation.swift index 09b3a53f..0e86e1d9 100644 --- a/WavesWallet-iOS/Extensions/UIKit/UIView+Animation.swift +++ b/Extensions/Sources/UI/UIView+Animation.swift @@ -8,9 +8,9 @@ import UIKit -extension UIView { +public extension UIView { - static let fastDurationAnimation: TimeInterval = 0.24 + public static let fastDurationAnimation: TimeInterval = 0.24 func shake() { self.transform = CGAffineTransform(translationX: 20, y: 0) diff --git a/WavesWallet-iOS/Extensions/UIKit/UIView+Passtrough.swift b/Extensions/Sources/UI/UIView+Passtrough.swift similarity index 92% rename from WavesWallet-iOS/Extensions/UIKit/UIView+Passtrough.swift rename to Extensions/Sources/UI/UIView+Passtrough.swift index c23c2631..72869008 100644 --- a/WavesWallet-iOS/Extensions/UIKit/UIView+Passtrough.swift +++ b/Extensions/Sources/UI/UIView+Passtrough.swift @@ -7,9 +7,9 @@ // import UIKit -import WavesSDKExtension +import WavesSDKExtensions -extension UIView { +public extension UIView { private enum AssociatedKeys { static var shouldPassthroughTouch = "shouldPassthroughTouch" @@ -17,13 +17,13 @@ extension UIView { static var isEnabledPassthroughSubviews = "isEnabledPassthroughSubviews" } - static func passtroughInit() { + public static func passtroughInit() { Runtime.swizzle(for: self, original: #selector(hitTest(_:with:)), swizzled: #selector(swizzledHitTest(_:with:))) } - var isEnabledPassthroughSubviews: Bool { + public var isEnabledPassthroughSubviews: Bool { get { return associatedObject(for: &AssociatedKeys.isEnabledPassthroughSubviews) ?? false @@ -40,7 +40,7 @@ extension UIView { } } - var passthroughFrame: CGRect? { + public var passthroughFrame: CGRect? { get { if let value: NSValue = associatedObject(for: &AssociatedKeys.passthroughFrame) { @@ -66,7 +66,7 @@ extension UIView { } } - @IBInspectable var shouldPassthroughTouch: Bool { + @IBInspectable public var shouldPassthroughTouch: Bool { get { return associatedObject(for: &AssociatedKeys.shouldPassthroughTouch) ?? false diff --git a/WavesWallet-iOS/Extensions/UIKit/UIView+SafeArea.swift b/Extensions/Sources/UI/UIView+SafeArea.swift similarity index 95% rename from WavesWallet-iOS/Extensions/UIKit/UIView+SafeArea.swift rename to Extensions/Sources/UI/UIView+SafeArea.swift index 497af78f..b600eb0c 100644 --- a/WavesWallet-iOS/Extensions/UIKit/UIView+SafeArea.swift +++ b/Extensions/Sources/UI/UIView+SafeArea.swift @@ -8,8 +8,7 @@ import UIKit - -extension UIView { +public extension UIView { var layoutInsets: UIEdgeInsets { diff --git a/WavesWallet-iOS/Extensions/UIKit/UIView+Shadow.swift b/Extensions/Sources/UI/UIView+Shadow.swift similarity index 98% rename from WavesWallet-iOS/Extensions/UIKit/UIView+Shadow.swift rename to Extensions/Sources/UI/UIView+Shadow.swift index 31270824..10c79b47 100644 --- a/WavesWallet-iOS/Extensions/UIKit/UIView+Shadow.swift +++ b/Extensions/Sources/UI/UIView+Shadow.swift @@ -7,13 +7,13 @@ // import UIKit -import WavesSDKExtension +import WavesSDKExtensions fileprivate enum Constants { static let deffaultValue: Float = -1 } -extension UIView { +public extension UIView { private enum AssociatedKeys { static var cornerRadius = "cornerRadius" diff --git a/WavesWallet-iOS/Extensions/UIKit/UIView+TouchInset.swift b/Extensions/Sources/UI/UIView+TouchInset.swift similarity index 95% rename from WavesWallet-iOS/Extensions/UIKit/UIView+TouchInset.swift rename to Extensions/Sources/UI/UIView+TouchInset.swift index 75a9bcf7..5e00d4e5 100644 --- a/WavesWallet-iOS/Extensions/UIKit/UIView+TouchInset.swift +++ b/Extensions/Sources/UI/UIView+TouchInset.swift @@ -7,9 +7,9 @@ // import UIKit -import WavesSDKExtension +import WavesSDKExtensions -extension UIView { +public extension UIView { private struct AssociatedKeys { static var touchInsets = "touchInsets" diff --git a/WavesWallet-iOS/Extensions/UIKit/UIViewController+Rx.swift b/Extensions/Sources/UI/UIViewController+Rx.swift similarity index 77% rename from WavesWallet-iOS/Extensions/UIKit/UIViewController+Rx.swift rename to Extensions/Sources/UI/UIViewController+Rx.swift index 3f771ab8..c9fdda4c 100644 --- a/WavesWallet-iOS/Extensions/UIKit/UIViewController+Rx.swift +++ b/Extensions/Sources/UI/UIViewController+Rx.swift @@ -12,61 +12,64 @@ import RxCocoa import RxSwift public extension Reactive where Base: UIViewController { - public var viewDidLoad: ControlEvent { + var viewDidLoad: ControlEvent { let source = self.methodInvoked(#selector(Base.viewDidLoad)).map { _ in } return ControlEvent(events: source) } - public var viewWillAppear: ControlEvent { + var viewWillAppear: ControlEvent { let source = self.methodInvoked(#selector(Base.viewWillAppear)).map { $0.first as? Bool ?? false } return ControlEvent(events: source) } - public var viewDidAppear: ControlEvent { + var viewDidAppear: ControlEvent { let source = self.methodInvoked(#selector(Base.viewDidAppear)).map { $0.first as? Bool ?? false } return ControlEvent(events: source) } - public var viewWillDisappear: ControlEvent { + var viewWillDisappear: ControlEvent { let source = self.methodInvoked(#selector(Base.viewWillDisappear)).map { $0.first as? Bool ?? false } return ControlEvent(events: source) } - public var viewDidDisappear: ControlEvent { + + var viewDidDisappear: ControlEvent { let source = self.methodInvoked(#selector(Base.viewDidDisappear)).map { $0.first as? Bool ?? false } return ControlEvent(events: source) } - public var viewWillLayoutSubviews: ControlEvent { + var viewWillLayoutSubviews: ControlEvent { let source = self.methodInvoked(#selector(Base.viewWillLayoutSubviews)).map { _ in } return ControlEvent(events: source) } - public var viewDidLayoutSubviews: ControlEvent { + + var viewDidLayoutSubviews: ControlEvent { let source = self.methodInvoked(#selector(Base.viewDidLayoutSubviews)).map { _ in } return ControlEvent(events: source) } - public var willMoveToParentViewController: ControlEvent { + var willMoveToParentViewController: ControlEvent { let source = self.methodInvoked(#selector(Base.willMove)).map { $0.first as? UIViewController } return ControlEvent(events: source) } - public var didMoveToParentViewController: ControlEvent { + + var didMoveToParentViewController: ControlEvent { let source = self.methodInvoked(#selector(Base.didMove)).map { $0.first as? UIViewController } return ControlEvent(events: source) } - public var didReceiveMemoryWarning: ControlEvent { + var didReceiveMemoryWarning: ControlEvent { let source = self.methodInvoked(#selector(Base.didReceiveMemoryWarning)).map { _ in } return ControlEvent(events: source) } /// Rx observable, triggered when the ViewController appearance state changes (true if the View is being displayed, false otherwise) - public var isVisible: Observable { + var isVisible: Observable { let viewDidAppearObservable = self.base.rx.viewDidAppear.map { _ in true } let viewWillDisappearObservable = self.base.rx.viewWillDisappear.map { _ in false } return Observable.merge(viewDidAppearObservable, viewWillDisappearObservable) } /// Rx observable, triggered when the ViewController is being dismissed - public var isDismissing: ControlEvent { + var isDismissing: ControlEvent { let source = self.sentMessage(#selector(Base.dismiss)).map { $0.first as? Bool ?? false } return ControlEvent(events: source) } diff --git a/WavesWallet-iOS/Extensions/UIKit/UIViewController+SafeArea.swift b/Extensions/Sources/UI/UIViewController+SafeArea.swift similarity index 89% rename from WavesWallet-iOS/Extensions/UIKit/UIViewController+SafeArea.swift rename to Extensions/Sources/UI/UIViewController+SafeArea.swift index 414a93ee..f4ee58b2 100644 --- a/WavesWallet-iOS/Extensions/UIKit/UIViewController+SafeArea.swift +++ b/Extensions/Sources/UI/UIViewController+SafeArea.swift @@ -9,13 +9,13 @@ import Foundation import UIKit -protocol LayoutInsetsProvider: AnyObject { +public protocol LayoutInsetsProvider: AnyObject { var layoutInsets: UIEdgeInsets { get } } extension UIViewController: LayoutInsetsProvider { - var layoutInsets: UIEdgeInsets { + public var layoutInsets: UIEdgeInsets { if #available(iOS 11.0, *) { return UIEdgeInsets(top: view.safeAreaInsets.top, left: view.safeAreaInsets.left, @@ -29,7 +29,7 @@ extension UIViewController: LayoutInsetsProvider { } } - var layoutInsetsKey: String { + public var layoutInsetsKey: String { if #available(iOS 11.0, *) { return "view.safeAreaInsets" } else { @@ -38,7 +38,7 @@ extension UIViewController: LayoutInsetsProvider { } } -protocol LayoutGuideProvider { +public protocol LayoutGuideProvider { var leadingAnchor: NSLayoutXAxisAnchor { get } var trailingAnchor: NSLayoutXAxisAnchor { get } var leftAnchor: NSLayoutXAxisAnchor { get } @@ -54,7 +54,7 @@ protocol LayoutGuideProvider { extension UIView: LayoutGuideProvider {} extension UILayoutGuide: LayoutGuideProvider {} -extension UIView { +public extension UIView { var compatibleSafeAreaLayoutGuide: LayoutGuideProvider { if #available(iOS 11, *) { return safeAreaLayoutGuide diff --git a/Gemfile b/Gemfile index 65be59b4..caf3ed00 100644 --- a/Gemfile +++ b/Gemfile @@ -8,4 +8,7 @@ gem 'cocoapods-check' gem 'json' gem 'bigdecimal' gem 'pry' -gem 'versionomy' \ No newline at end of file +gem 'versionomy' +gem 'mini_magick', '>= 4.9.4' +gem 'rest-client' +gem 'fastlane-plugin-sentry' diff --git a/Gemfile.lock b/Gemfile.lock index a306be8e..323f69fe 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,29 +1,32 @@ GEM remote: https://rubygems.org/ specs: - CFPropertyList (3.0.0) + CFPropertyList (3.0.1) activesupport (4.2.11.1) i18n (~> 0.7) minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) - addressable (2.6.0) - public_suffix (>= 2.0.2, < 4.0) + addressable (2.7.0) + public_suffix (>= 2.0.2, < 5.0) + algoliasearch (1.27.1) + httpclient (~> 2.8, >= 2.8.3) + json (>= 1.5.1) atomos (0.1.3) - babosa (1.0.2) + babosa (1.0.3) bigdecimal (1.4.4) blockenspiel (0.5.0) - claide (1.0.2) - cocoapods (1.7.2) + claide (1.0.3) + cocoapods (1.8.1) activesupport (>= 4.0.2, < 5) claide (>= 1.0.2, < 2.0) - cocoapods-core (= 1.7.2) + cocoapods-core (= 1.8.1) cocoapods-deintegrate (>= 1.0.3, < 2.0) cocoapods-downloader (>= 1.2.2, < 2.0) cocoapods-plugins (>= 1.0.0, < 2.0) cocoapods-search (>= 1.0.0, < 2.0) cocoapods-stats (>= 1.0.0, < 2.0) - cocoapods-trunk (>= 1.3.1, < 2.0) + cocoapods-trunk (>= 1.4.0, < 2.0) cocoapods-try (>= 1.1.0, < 2.0) colored2 (~> 3.1) escape (~> 0.0.4) @@ -32,11 +35,13 @@ GEM molinillo (~> 0.6.6) nap (~> 1.0) ruby-macho (~> 1.4) - xcodeproj (>= 1.10.0, < 2.0) + xcodeproj (>= 1.11.1, < 2.0) cocoapods-check (1.1.0) cocoapods (~> 1.0) - cocoapods-core (1.7.2) + cocoapods-core (1.8.1) activesupport (>= 4.0.2, < 6) + algoliasearch (~> 1.0) + concurrent-ruby (~> 1.1) fuzzy_match (~> 2.0.4) nap (~> 1.0) cocoapods-deintegrate (1.0.4) @@ -45,7 +50,7 @@ GEM nap cocoapods-search (1.0.0) cocoapods-stats (1.1.0) - cocoapods-trunk (1.3.1) + cocoapods-trunk (1.4.1) nap (>= 0.8, < 2.0) netrc (~> 0.11) cocoapods-try (1.1.0) @@ -58,21 +63,21 @@ GEM declarative (0.0.10) declarative-option (0.1.0) digest-crc (0.4.1) - domain_name (0.5.20180417) + domain_name (0.5.20190701) unf (>= 0.0.5, < 1.0.0) - dotenv (2.7.2) + dotenv (2.7.5) emoji_regex (1.0.1) escape (0.0.4) - excon (0.64.0) - faraday (0.15.4) + excon (0.68.0) + faraday (0.17.0) multipart-post (>= 1.2, < 3) faraday-cookie_jar (0.0.6) faraday (>= 0.7.4) http-cookie (~> 1.0.0) faraday_middleware (0.13.1) faraday (>= 0.7.4, < 1.0) - fastimage (2.1.5) - fastlane (2.125.2) + fastimage (2.1.7) + fastlane (2.135.2) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.3, < 3.0.0) babosa (>= 1.0.2, < 2.0.0) @@ -82,9 +87,9 @@ GEM dotenv (>= 2.1.1, < 3.0.0) emoji_regex (>= 0.1, < 2.0) excon (>= 0.45.0, < 1.0.0) - faraday (~> 0.9) + faraday (~> 0.17) faraday-cookie_jar (~> 0.0.6) - faraday_middleware (~> 0.9) + faraday_middleware (~> 0.13.1) fastimage (>= 2.1.0, < 3.0.0) gh_inspector (>= 1.1.2, < 2.0.0) google-api-client (>= 0.21.2, < 0.24.0) @@ -92,12 +97,12 @@ GEM highline (>= 1.7.2, < 2.0.0) json (< 3.0.0) jwt (~> 2.1.0) - mini_magick (~> 4.5.1) + mini_magick (>= 4.9.4, < 5.0.0) multi_xml (~> 0.5) multipart-post (~> 2.0.0) plist (>= 3.1.0, < 4.0.0) public_suffix (~> 2.0.0) - rubyzip (>= 1.2.2, < 2.0.0) + rubyzip (>= 1.3.0, < 2.0.0) security (= 0.1.3) simctl (~> 1.6.3) slack-notifier (>= 2.0.0, < 3.0.0) @@ -109,7 +114,8 @@ GEM xcodeproj (>= 1.8.1, < 2.0.0) xcpretty (~> 0.3.0) xcpretty-travis-formatter (>= 0.0.3) - fourflusher (2.3.0) + fastlane-plugin-sentry (1.5.0) + fourflusher (2.3.1) fuzzy_match (2.0.4) gh_inspector (1.1.3) google-api-client (0.23.9) @@ -120,9 +126,9 @@ GEM representable (~> 3.0) retriable (>= 2.0, < 4.0) signet (~> 0.9) - google-cloud-core (1.3.0) + google-cloud-core (1.4.1) google-cloud-env (~> 1.0) - google-cloud-env (1.1.0) + google-cloud-env (1.3.0) faraday (~> 0.11) google-cloud-storage (1.16.0) digest-crc (~> 0.4) @@ -137,22 +143,23 @@ GEM os (>= 0.9, < 2.0) signet (~> 0.7) highline (1.7.10) + http-accept (1.7.0) http-cookie (1.0.3) domain_name (~> 0.5) httpclient (2.8.3) i18n (0.9.5) concurrent-ruby (~> 1.0) - json (2.2.0) + json (2.3.0) jwt (2.1.0) - memoist (0.16.0) + memoist (0.16.1) method_source (0.9.2) - mime-types (3.2.2) + mime-types (3.3) mime-types-data (~> 3.2015) - mime-types-data (3.2019.0331) - mini_magick (4.5.1) - minitest (5.11.3) + mime-types-data (3.2019.1009) + mini_magick (4.9.5) + minitest (5.12.2) molinillo (0.6.6) - multi_json (1.13.1) + multi_json (1.14.1) multi_xml (0.6.0) multipart-post (2.0.0) nanaimo (0.2.6) @@ -169,17 +176,22 @@ GEM declarative (< 0.1.0) declarative-option (< 0.2.0) uber (< 0.2.0) + rest-client (2.1.0) + http-accept (>= 1.7.0, < 2.0) + http-cookie (>= 1.0.2, < 2.0) + mime-types (>= 1.16, < 4.0) + netrc (~> 0.8) retriable (3.1.2) rouge (2.0.7) ruby-macho (1.4.0) - rubyzip (1.2.3) + rubyzip (1.3.0) security (0.1.3) - signet (0.11.0) + signet (0.12.0) addressable (~> 2.3) faraday (~> 0.9) jwt (>= 1.5, < 3.0) multi_json (~> 1.10) - simctl (1.6.5) + simctl (1.6.6) CFPropertyList naturally slack-notifier (2.3.2) @@ -201,7 +213,7 @@ GEM versionomy (0.5.0) blockenspiel (~> 0.5) word_wrap (1.0.0) - xcodeproj (1.10.0) + xcodeproj (1.13.0) CFPropertyList (>= 2.3.3, < 4.0) atomos (~> 0.1.3) claide (>= 1.0.2, < 2.0) @@ -221,9 +233,12 @@ DEPENDENCIES cocoapods-check dotenv fastlane + fastlane-plugin-sentry json + mini_magick (>= 4.9.4) pry + rest-client versionomy BUNDLED WITH - 2.0.1 + 2.0.2 diff --git a/MarketPulseWidget/Base.lproj/MainInterface.storyboard b/MarketPulseWidget/Base.lproj/MainInterface.storyboard new file mode 100644 index 00000000..0b1360ef --- /dev/null +++ b/MarketPulseWidget/Base.lproj/MainInterface.storyboard @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MarketPulseWidget/Info.plist b/MarketPulseWidget/Info.plist new file mode 100644 index 00000000..4ee92bf6 --- /dev/null +++ b/MarketPulseWidget/Info.plist @@ -0,0 +1,31 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Market Pulse + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + XPC! + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + NSExtension + + NSExtensionMainStoryboard + MainInterface + NSExtensionPointIdentifier + com.apple.widget-extension + + + diff --git a/MarketPulseWidget/MarketPulseWidget.entitlements b/MarketPulseWidget/MarketPulseWidget.entitlements new file mode 100644 index 00000000..ccdf6270 --- /dev/null +++ b/MarketPulseWidget/MarketPulseWidget.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.security.application-groups + + group.com.wavesplatform + + + diff --git a/MarketPulseWidget/Resources/Localization/de.lproj/WavesMarketPulse.strings b/MarketPulseWidget/Resources/Localization/de.lproj/WavesMarketPulse.strings new file mode 100644 index 00000000..d8a9f9f6 --- /dev/null +++ b/MarketPulseWidget/Resources/Localization/de.lproj/WavesMarketPulse.strings @@ -0,0 +1 @@ +"marketpulsewidget.button.update.title" = "Aktualisieren"; diff --git a/MarketPulseWidget/Resources/Localization/en.lproj/WavesMarketPulse.strings b/MarketPulseWidget/Resources/Localization/en.lproj/WavesMarketPulse.strings new file mode 100644 index 00000000..db34538e --- /dev/null +++ b/MarketPulseWidget/Resources/Localization/en.lproj/WavesMarketPulse.strings @@ -0,0 +1 @@ +"marketpulsewidget.button.update.title" = "Update"; diff --git a/MarketPulseWidget/Resources/Localization/es.lproj/WavesMarketPulse.strings b/MarketPulseWidget/Resources/Localization/es.lproj/WavesMarketPulse.strings new file mode 100644 index 00000000..992acd5c --- /dev/null +++ b/MarketPulseWidget/Resources/Localization/es.lproj/WavesMarketPulse.strings @@ -0,0 +1 @@ +"marketpulsewidget.button.update.title" = "Actualizar"; diff --git a/MarketPulseWidget/Resources/Localization/fr-FR.lproj/WavesMarketPulse.strings b/MarketPulseWidget/Resources/Localization/fr-FR.lproj/WavesMarketPulse.strings new file mode 100644 index 00000000..c86baf01 --- /dev/null +++ b/MarketPulseWidget/Resources/Localization/fr-FR.lproj/WavesMarketPulse.strings @@ -0,0 +1 @@ +"marketpulsewidget.button.update.title" = "Mettre à jour"; diff --git a/MarketPulseWidget/Resources/Localization/hi-IN.lproj/WavesMarketPulse.strings b/MarketPulseWidget/Resources/Localization/hi-IN.lproj/WavesMarketPulse.strings new file mode 100644 index 00000000..a476d68b --- /dev/null +++ b/MarketPulseWidget/Resources/Localization/hi-IN.lproj/WavesMarketPulse.strings @@ -0,0 +1 @@ +"marketpulsewidget.button.update.title" = "अद्यतन करें"; diff --git a/MarketPulseWidget/Resources/Localization/id.lproj/WavesMarketPulse.strings b/MarketPulseWidget/Resources/Localization/id.lproj/WavesMarketPulse.strings new file mode 100644 index 00000000..b41f4c80 --- /dev/null +++ b/MarketPulseWidget/Resources/Localization/id.lproj/WavesMarketPulse.strings @@ -0,0 +1 @@ +"marketpulsewidget.button.update.title" = "Memperbarui"; diff --git a/MarketPulseWidget/Resources/Localization/it.lproj/WavesMarketPulse.strings b/MarketPulseWidget/Resources/Localization/it.lproj/WavesMarketPulse.strings new file mode 100644 index 00000000..436315a7 --- /dev/null +++ b/MarketPulseWidget/Resources/Localization/it.lproj/WavesMarketPulse.strings @@ -0,0 +1 @@ +"marketpulsewidget.button.update.title" = "Aggiorna"; diff --git a/MarketPulseWidget/Resources/Localization/ja.lproj/WavesMarketPulse.strings b/MarketPulseWidget/Resources/Localization/ja.lproj/WavesMarketPulse.strings new file mode 100644 index 00000000..39adf158 --- /dev/null +++ b/MarketPulseWidget/Resources/Localization/ja.lproj/WavesMarketPulse.strings @@ -0,0 +1 @@ +"marketpulsewidget.button.update.title" = "更新"; diff --git a/MarketPulseWidget/Resources/Localization/ko.lproj/WavesMarketPulse.strings b/MarketPulseWidget/Resources/Localization/ko.lproj/WavesMarketPulse.strings new file mode 100644 index 00000000..4c61617f --- /dev/null +++ b/MarketPulseWidget/Resources/Localization/ko.lproj/WavesMarketPulse.strings @@ -0,0 +1 @@ +"marketpulsewidget.button.update.title" = "업데이트"; diff --git a/MarketPulseWidget/Resources/Localization/nl-NL.lproj/WavesMarketPulse.strings b/MarketPulseWidget/Resources/Localization/nl-NL.lproj/WavesMarketPulse.strings new file mode 100644 index 00000000..db34538e --- /dev/null +++ b/MarketPulseWidget/Resources/Localization/nl-NL.lproj/WavesMarketPulse.strings @@ -0,0 +1 @@ +"marketpulsewidget.button.update.title" = "Update"; diff --git a/MarketPulseWidget/Resources/Localization/pl.lproj/WavesMarketPulce.strings b/MarketPulseWidget/Resources/Localization/pl.lproj/WavesMarketPulce.strings new file mode 100644 index 00000000..db34538e --- /dev/null +++ b/MarketPulseWidget/Resources/Localization/pl.lproj/WavesMarketPulce.strings @@ -0,0 +1 @@ +"marketpulsewidget.button.update.title" = "Update"; diff --git a/MarketPulseWidget/Resources/Localization/pl.lproj/WavesMarketPulse.strings b/MarketPulseWidget/Resources/Localization/pl.lproj/WavesMarketPulse.strings new file mode 100644 index 00000000..3d35a486 --- /dev/null +++ b/MarketPulseWidget/Resources/Localization/pl.lproj/WavesMarketPulse.strings @@ -0,0 +1 @@ +"marketpulsewidget.button.update.title" = "Aktualizacja"; diff --git a/MarketPulseWidget/Resources/Localization/pt-BR.lproj/WavesMarketPulse.strings b/MarketPulseWidget/Resources/Localization/pt-BR.lproj/WavesMarketPulse.strings new file mode 100644 index 00000000..07140153 --- /dev/null +++ b/MarketPulseWidget/Resources/Localization/pt-BR.lproj/WavesMarketPulse.strings @@ -0,0 +1 @@ +"marketpulsewidget.button.update.title" = "Atualizar"; diff --git a/MarketPulseWidget/Resources/Localization/pt-PT.lproj/WavesMarketPulse.strings b/MarketPulseWidget/Resources/Localization/pt-PT.lproj/WavesMarketPulse.strings new file mode 100644 index 00000000..07140153 --- /dev/null +++ b/MarketPulseWidget/Resources/Localization/pt-PT.lproj/WavesMarketPulse.strings @@ -0,0 +1 @@ +"marketpulsewidget.button.update.title" = "Atualizar"; diff --git a/MarketPulseWidget/Resources/Localization/ru.lproj/WavesMarketPulse.strings b/MarketPulseWidget/Resources/Localization/ru.lproj/WavesMarketPulse.strings new file mode 100644 index 00000000..043db0d2 --- /dev/null +++ b/MarketPulseWidget/Resources/Localization/ru.lproj/WavesMarketPulse.strings @@ -0,0 +1 @@ +"marketpulsewidget.button.update.title" = "Обновить"; diff --git a/MarketPulseWidget/Resources/Localization/tr.lproj/WavesMarketPulse.strings b/MarketPulseWidget/Resources/Localization/tr.lproj/WavesMarketPulse.strings new file mode 100644 index 00000000..83b5a65d --- /dev/null +++ b/MarketPulseWidget/Resources/Localization/tr.lproj/WavesMarketPulse.strings @@ -0,0 +1 @@ +"marketpulsewidget.button.update.title" = "Güncelleme"; diff --git a/MarketPulseWidget/Resources/Localization/zh-Hans-CN.lproj/WavesMarketPulse.strings b/MarketPulseWidget/Resources/Localization/zh-Hans-CN.lproj/WavesMarketPulse.strings new file mode 100644 index 00000000..39adf158 --- /dev/null +++ b/MarketPulseWidget/Resources/Localization/zh-Hans-CN.lproj/WavesMarketPulse.strings @@ -0,0 +1 @@ +"marketpulsewidget.button.update.title" = "更新"; diff --git a/MarketPulseWidget/Resources/WidgetAssets.xcassets/Contents.json b/MarketPulseWidget/Resources/WidgetAssets.xcassets/Contents.json new file mode 100644 index 00000000..da4a164c --- /dev/null +++ b/MarketPulseWidget/Resources/WidgetAssets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoBitcoin48.imageset/Contents.json b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoBitcoin48.imageset/Contents.json new file mode 100644 index 00000000..19ed10d9 --- /dev/null +++ b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoBitcoin48.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "logoBitcoin48.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoBitcoin48.imageset/logoBitcoin48.pdf b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoBitcoin48.imageset/logoBitcoin48.pdf new file mode 100644 index 00000000..59228630 Binary files /dev/null and b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoBitcoin48.imageset/logoBitcoin48.pdf differ diff --git a/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoBitcoincash48.imageset/Contents.json b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoBitcoincash48.imageset/Contents.json new file mode 100644 index 00000000..3c1bee8b --- /dev/null +++ b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoBitcoincash48.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "logoBitcoincash48.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoBitcoincash48.imageset/logoBitcoincash48.pdf b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoBitcoincash48.imageset/logoBitcoincash48.pdf new file mode 100644 index 00000000..ecf49039 Binary files /dev/null and b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoBitcoincash48.imageset/logoBitcoincash48.pdf differ diff --git a/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoDash48.imageset/Contents.json b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoDash48.imageset/Contents.json new file mode 100644 index 00000000..833cca2a --- /dev/null +++ b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoDash48.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "logoDash48.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoDash48.imageset/logoDash48.pdf b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoDash48.imageset/logoDash48.pdf new file mode 100644 index 00000000..6c08626b Binary files /dev/null and b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoDash48.imageset/logoDash48.pdf differ diff --git a/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoEthereum48.imageset/Contents.json b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoEthereum48.imageset/Contents.json new file mode 100644 index 00000000..0cb1ef8c --- /dev/null +++ b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoEthereum48.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "logoEthereum48.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoEthereum48.imageset/logoEthereum48.pdf b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoEthereum48.imageset/logoEthereum48.pdf new file mode 100644 index 00000000..bab98688 Binary files /dev/null and b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoEthereum48.imageset/logoEthereum48.pdf differ diff --git a/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoEuro48.imageset/Contents.json b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoEuro48.imageset/Contents.json new file mode 100644 index 00000000..242519b7 --- /dev/null +++ b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoEuro48.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "logoEuro48.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoEuro48.imageset/logoEuro48.pdf b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoEuro48.imageset/logoEuro48.pdf new file mode 100644 index 00000000..05475cee Binary files /dev/null and b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoEuro48.imageset/logoEuro48.pdf differ diff --git a/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoLira48.imageset/Contents.json b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoLira48.imageset/Contents.json new file mode 100644 index 00000000..253a2d65 --- /dev/null +++ b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoLira48.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "logoLira48.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoLira48.imageset/logoLira48.pdf b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoLira48.imageset/logoLira48.pdf new file mode 100644 index 00000000..f878cd63 Binary files /dev/null and b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoLira48.imageset/logoLira48.pdf differ diff --git a/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoLtc48.imageset/Contents.json b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoLtc48.imageset/Contents.json new file mode 100644 index 00000000..f61d6d24 --- /dev/null +++ b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoLtc48.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "logoLtc48.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoLtc48.imageset/logoLtc48.pdf b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoLtc48.imageset/logoLtc48.pdf new file mode 100644 index 00000000..630e0446 Binary files /dev/null and b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoLtc48.imageset/logoLtc48.pdf differ diff --git a/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoMonero48.imageset/Contents.json b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoMonero48.imageset/Contents.json new file mode 100644 index 00000000..00fd8a75 --- /dev/null +++ b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoMonero48.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "logoMonero48.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoMonero48.imageset/logoMonero48.pdf b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoMonero48.imageset/logoMonero48.pdf new file mode 100644 index 00000000..4c48f939 Binary files /dev/null and b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoMonero48.imageset/logoMonero48.pdf differ diff --git a/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoUsd48.imageset/Contents.json b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoUsd48.imageset/Contents.json new file mode 100644 index 00000000..4e91c21e --- /dev/null +++ b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoUsd48.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "logoUsd48.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoUsd48.imageset/logoUsd48.pdf b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoUsd48.imageset/logoUsd48.pdf new file mode 100644 index 00000000..92ca75f2 Binary files /dev/null and b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoUsd48.imageset/logoUsd48.pdf differ diff --git a/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoWaves48.imageset/Contents.json b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoWaves48.imageset/Contents.json new file mode 100644 index 00000000..b4b4f473 --- /dev/null +++ b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoWaves48.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "logoWaves48.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoWaves48.imageset/logoWaves48.pdf b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoWaves48.imageset/logoWaves48.pdf new file mode 100644 index 00000000..59d9dde4 Binary files /dev/null and b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoWaves48.imageset/logoWaves48.pdf differ diff --git a/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoWct48.imageset/Contents.json b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoWct48.imageset/Contents.json new file mode 100644 index 00000000..bbe1aaa9 --- /dev/null +++ b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoWct48.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "logoWct48.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoWct48.imageset/logoWct48.pdf b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoWct48.imageset/logoWct48.pdf new file mode 100644 index 00000000..a23faf5d Binary files /dev/null and b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoWct48.imageset/logoWct48.pdf differ diff --git a/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoZec48.imageset/Contents.json b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoZec48.imageset/Contents.json new file mode 100644 index 00000000..42eac129 --- /dev/null +++ b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoZec48.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "logoZec48.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoZec48.imageset/logoZec48.pdf b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoZec48.imageset/logoZec48.pdf new file mode 100644 index 00000000..f8487067 Binary files /dev/null and b/MarketPulseWidget/Resources/WidgetAssets.xcassets/logoZec48.imageset/logoZec48.pdf differ diff --git a/MarketPulseWidget/Resources/WidgetAssets.xcassets/scriptasset18White.imageset/Contents.json b/MarketPulseWidget/Resources/WidgetAssets.xcassets/scriptasset18White.imageset/Contents.json new file mode 100644 index 00000000..19d7f110 --- /dev/null +++ b/MarketPulseWidget/Resources/WidgetAssets.xcassets/scriptasset18White.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "scriptasset18White.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MarketPulseWidget/Resources/WidgetAssets.xcassets/scriptasset18White.imageset/scriptasset18White.pdf b/MarketPulseWidget/Resources/WidgetAssets.xcassets/scriptasset18White.imageset/scriptasset18White.pdf new file mode 100644 index 00000000..654c7579 Binary files /dev/null and b/MarketPulseWidget/Resources/WidgetAssets.xcassets/scriptasset18White.imageset/scriptasset18White.pdf differ diff --git a/MarketPulseWidget/Resources/WidgetAssets.xcassets/setting14Classic.imageset/Contents.json b/MarketPulseWidget/Resources/WidgetAssets.xcassets/setting14Classic.imageset/Contents.json new file mode 100644 index 00000000..be80e037 --- /dev/null +++ b/MarketPulseWidget/Resources/WidgetAssets.xcassets/setting14Classic.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "setting14Classic.pdf", + "idiom" : "universal" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MarketPulseWidget/Resources/WidgetAssets.xcassets/setting14Classic.imageset/setting14Classic.pdf b/MarketPulseWidget/Resources/WidgetAssets.xcassets/setting14Classic.imageset/setting14Classic.pdf new file mode 100644 index 00000000..52e136ca Binary files /dev/null and b/MarketPulseWidget/Resources/WidgetAssets.xcassets/setting14Classic.imageset/setting14Classic.pdf differ diff --git a/MarketPulseWidget/Resources/WidgetAssets.xcassets/sponsoritem18White.imageset/Contents.json b/MarketPulseWidget/Resources/WidgetAssets.xcassets/sponsoritem18White.imageset/Contents.json new file mode 100644 index 00000000..beabdd76 --- /dev/null +++ b/MarketPulseWidget/Resources/WidgetAssets.xcassets/sponsoritem18White.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "sponsoritem18White.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MarketPulseWidget/Resources/WidgetAssets.xcassets/sponsoritem18White.imageset/sponsoritem18White.pdf b/MarketPulseWidget/Resources/WidgetAssets.xcassets/sponsoritem18White.imageset/sponsoritem18White.pdf new file mode 100644 index 00000000..37d2d22b Binary files /dev/null and b/MarketPulseWidget/Resources/WidgetAssets.xcassets/sponsoritem18White.imageset/sponsoritem18White.pdf differ diff --git a/MarketPulseWidget/Resources/WidgetAssets.xcassets/update14Classic.imageset/Contents.json b/MarketPulseWidget/Resources/WidgetAssets.xcassets/update14Classic.imageset/Contents.json new file mode 100644 index 00000000..480afd29 --- /dev/null +++ b/MarketPulseWidget/Resources/WidgetAssets.xcassets/update14Classic.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "update14Classic.pdf", + "idiom" : "universal" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MarketPulseWidget/Resources/WidgetAssets.xcassets/update14Classic.imageset/update14Classic.pdf b/MarketPulseWidget/Resources/WidgetAssets.xcassets/update14Classic.imageset/update14Classic.pdf new file mode 100644 index 00000000..bf3cee17 Binary files /dev/null and b/MarketPulseWidget/Resources/WidgetAssets.xcassets/update14Classic.imageset/update14Classic.pdf differ diff --git a/MarketPulseWidget/Sources/Generated/Images.swift b/MarketPulseWidget/Sources/Generated/Images.swift new file mode 100644 index 00000000..82aa9519 --- /dev/null +++ b/MarketPulseWidget/Sources/Generated/Images.swift @@ -0,0 +1,121 @@ +// Generated using SwiftGen, by O.Halligon — https://github.com/SwiftGen/SwiftGen + +#if os(OSX) + import AppKit.NSImage + internal typealias AssetColorTypeAlias = NSColor + internal typealias Image = NSImage +#elseif os(iOS) || os(tvOS) || os(watchOS) + import UIKit.UIImage + internal typealias AssetColorTypeAlias = UIColor + internal typealias Image = UIImage +#endif + +// swiftlint:disable superfluous_disable_command +// swiftlint:disable file_length + +@available(*, deprecated, renamed: "ImageAsset") +internal typealias ImagesType = ImageAsset + +internal struct ImageAsset { + internal fileprivate(set) var name: String + + internal var image: Image { + let bundle = Bundle(for: BundleToken.self) + #if os(iOS) || os(tvOS) + let image = Image(named: name, in: bundle, compatibleWith: nil) + #elseif os(OSX) + let image = bundle.image(forResource: NSImage.Name(name)) + #elseif os(watchOS) + let image = Image(named: name) + #endif + guard let result = image else { fatalError("Unable to load image named \(name).") } + return result + } +} + +internal struct ColorAsset { + internal fileprivate(set) var name: String + + @available(iOS 11.0, tvOS 11.0, watchOS 4.0, OSX 10.13, *) + internal var color: AssetColorTypeAlias { + return AssetColorTypeAlias(asset: self) + } +} + +// swiftlint:disable identifier_name line_length nesting type_body_length type_name +internal enum Images { + internal static let logoBitcoin48 = ImageAsset(name: "logoBitcoin48") + internal static let logoBitcoincash48 = ImageAsset(name: "logoBitcoincash48") + internal static let logoDash48 = ImageAsset(name: "logoDash48") + internal static let logoEthereum48 = ImageAsset(name: "logoEthereum48") + internal static let logoEuro48 = ImageAsset(name: "logoEuro48") + internal static let logoLira48 = ImageAsset(name: "logoLira48") + internal static let logoLtc48 = ImageAsset(name: "logoLtc48") + internal static let logoMonero48 = ImageAsset(name: "logoMonero48") + internal static let logoUsd48 = ImageAsset(name: "logoUsd48") + internal static let logoWaves48 = ImageAsset(name: "logoWaves48") + internal static let logoWct48 = ImageAsset(name: "logoWct48") + internal static let logoZec48 = ImageAsset(name: "logoZec48") + internal static let scriptasset18White = ImageAsset(name: "scriptasset18White") + internal static let setting14Classic = ImageAsset(name: "setting14Classic") + internal static let sponsoritem18White = ImageAsset(name: "sponsoritem18White") + internal static let update14Classic = ImageAsset(name: "update14Classic") + + // swiftlint:disable trailing_comma + internal static let allColors: [ColorAsset] = [ + ] + internal static let allImages: [ImageAsset] = [ + logoBitcoin48, + logoBitcoincash48, + logoDash48, + logoEthereum48, + logoEuro48, + logoLira48, + logoLtc48, + logoMonero48, + logoUsd48, + logoWaves48, + logoWct48, + logoZec48, + scriptasset18White, + setting14Classic, + sponsoritem18White, + update14Classic, + ] + // swiftlint:enable trailing_comma + @available(*, deprecated, renamed: "allImages") + internal static let allValues: [ImagesType] = allImages +} +// swiftlint:enable identifier_name line_length nesting type_body_length type_name + +internal extension Image { + @available(iOS 1.0, tvOS 1.0, watchOS 1.0, *) + @available(OSX, deprecated, + message: "This initializer is unsafe on macOS, please use the ImageAsset.image property") + convenience init!(asset: ImageAsset) { + #if os(iOS) || os(tvOS) + let bundle = Bundle(for: BundleToken.self) + self.init(named: asset.name, in: bundle, compatibleWith: nil) + #elseif os(OSX) + self.init(named: NSImage.Name(asset.name)) + #elseif os(watchOS) + self.init(named: asset.name) + #endif + } +} + +internal extension AssetColorTypeAlias { + @available(iOS 11.0, tvOS 11.0, watchOS 4.0, OSX 10.13, *) + convenience init!(asset: ColorAsset) { + let bundle = Bundle(for: BundleToken.self) + #if os(iOS) || os(tvOS) + self.init(named: asset.name, in: bundle, compatibleWith: nil) + #elseif os(OSX) + self.init(named: NSColor.Name(asset.name), bundle: bundle) + #elseif os(watchOS) + self.init(named: asset.name) + #endif + } +} + +private final class BundleToken {} diff --git a/MarketPulseWidget/Sources/Generated/Localizable.swift b/MarketPulseWidget/Sources/Generated/Localizable.swift new file mode 100644 index 00000000..27fb1094 --- /dev/null +++ b/MarketPulseWidget/Sources/Generated/Localizable.swift @@ -0,0 +1,52 @@ +// Generated using SwiftGen, by O.Halligon — https://github.com/SwiftGen/SwiftGen + +import Foundation +import Extensions + +// swiftlint:disable superfluous_disable_command +// swiftlint:disable file_length + +// swiftlint:disable explicit_type_interface identifier_name line_length nesting type_body_length type_name +internal enum Localizable { + + internal enum Marketpulsewidget { + + internal enum Button { + + internal enum Update { + /// Update + internal static var title: String { return Localizable.tr("WavesMarketPulse", "marketpulsewidget.button.update.title") } + internal static var titleKey: String { return "marketpulsewidget.button.update.title" } + } + } + } +} +// swiftlint:enable explicit_type_interface identifier_name line_length nesting type_body_length type_name + +extension Localizable: LocalizableProtocol { + + struct Current { + var locale: Locale + var bundle: Bundle + } + + private static let english: Localizable.Current = Localizable.Current(locale: Locale(identifier: "en"), bundle: Bundle(for: BundleToken.self)) + + static var locale: Locale = Locale.current + static var bundle: Bundle = Bundle(for: BundleToken.self) + + private static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String { + let format = NSLocalizedString(key, tableName: table, bundle: bundle, comment: "") + + let value = String(format: format, locale: locale, arguments: args) + + if value.localizedLowercase == key.localizedLowercase { + let format = NSLocalizedString(key, tableName: table, bundle: english.bundle, comment: "") + return String(format: format, locale: english.locale, arguments: args) + } else { + return value + } + } +} + +private final class BundleToken {} diff --git a/MarketPulseWidget/Sources/Interactor/MarketPulseWidgetInteractor.swift b/MarketPulseWidget/Sources/Interactor/MarketPulseWidgetInteractor.swift new file mode 100644 index 00000000..881037ab --- /dev/null +++ b/MarketPulseWidget/Sources/Interactor/MarketPulseWidgetInteractor.swift @@ -0,0 +1,172 @@ +// +// MarketPulseWidgetInteractor.swift +// MarketPulseWidget +// +// Created by Pavel Gubin on 24.07.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import WavesSDK +import DomainLayer +import WavesSDKExtensions +import Extensions + +private enum Constants { + static let exchangeTxLimit: Int = 5 +} + +protocol MarketPulseWidgetInteractorProtocol { + func assets() -> Observable<[MarketPulse.DTO.Asset]> + func chachedAssets() -> Observable<[MarketPulse.DTO.Asset]> + func settings() -> Observable +} + +final class MarketPulseWidgetInteractor: MarketPulseWidgetInteractorProtocol { + + private let widgetSettingsRepository: WidgetSettingsInizializationUseCaseProtocol = WidgetSettingsInizialization() + private let pairsPriceRepository: WidgetPairsPriceRepositoryProtocol = WidgetPairsPriceRepositoryRemote() + private let dbRepository: MarketPulseDataBaseRepositoryProtocol = MarketPulseDataBaseRepository() + private let transactionsRepository: WidgetTransactionsRepositoryProtocol = WidgetTransactionsRepositoryRemote() + + init() { + _ = setupLayers() + } + + static var shared: MarketPulseWidgetInteractor = MarketPulseWidgetInteractor() + + private func setupLayers() -> Bool { + + guard let googleServiceInfoPath = Bundle.main.path(forResource: "GoogleService-Info", ofType: "plist") else { + return false + } + + guard let appsflyerInfoPath = Bundle.main.path(forResource: "Appsflyer-Info", ofType: "plist") else { + return false + } + + guard let amplitudeInfoPath = Bundle.main.path(forResource: "Amplitude-Info", ofType: "plist") else { + return false + } + + Address.walletEnvironment = WidgetSettings.environment + + WidgetAnalyticManagerInitialization.setup(resources: .init(googleServiceInfo: googleServiceInfoPath, + appsflyerInfo: appsflyerInfoPath, + amplitudeInfo: amplitudeInfoPath)) + + return true + } + + func settings() -> Observable { + + return Observable.zip(WidgetSettings.rx.currency(), + widgetSettingsRepository.settings()) + .flatMap({ (currency, marketPulseSettings) -> Observable in + return Observable.just(MarketPulse.DTO.Settings(currency: currency, + isDarkMode: marketPulseSettings.isDarkStyle, + inverval: marketPulseSettings.interval)) + }) + } + + func chachedAssets() -> Observable<[MarketPulse.DTO.Asset]> { + return dbRepository.chachedAssets() + } + + func assets() -> Observable<[MarketPulse.DTO.Asset]> { + + return widgetSettingsRepository.settings() + .flatMap({ [weak self] (settings) -> Observable<[MarketPulse.DTO.Asset]> in + + guard let self = self else { return Observable.empty() } + + var assets = settings.assets + + let iconStyle = AssetLogo.Icon.init(assetId: "", + name: "", + url: nil, + isSponsored: false, + hasScript: false) + + assets.append(.init(id: MarketPulse.usdAssetId, + name: "", + icon: iconStyle, + amountAsset: WavesSDKConstants.wavesAssetId, + priceAsset: MarketPulse.usdAssetId)) + + assets.append(.init(id: MarketPulse.eurAssetId, + name: "", + icon: iconStyle, + amountAsset: WavesSDKConstants.wavesAssetId, + priceAsset: MarketPulse.eurAssetId)) + + return self.loadAssets(assets: assets) + }) + } + + private func loadAssets(assets: [DomainLayer.DTO.MarketPulseSettings.Asset]) -> Observable<[MarketPulse.DTO.Asset]> { + + var arrayExchangeTx: [Observable<[DataService.DTO.ExchangeTransaction]>] = [] + + for asset in assets { + arrayExchangeTx.append(transactionsRepository.exchangeTransactions(amountAsset: asset.amountAsset, priceAsset: asset.priceAsset, limit: Constants.exchangeTxLimit)) + } + + let query = assets.map { DomainLayer.Query.Dex.SearchPairs.Pair.init(amountAsset: $0.amountAsset, + priceAsset: $0.priceAsset) } + + return pairsPriceRepository + .searchPairs(.init(kind: .pairs(query))) + .flatMap { (searchResult) -> Observable<[MarketPulse.DTO.Asset]> in + + return Observable.zip(arrayExchangeTx) + .flatMap({ [weak self] (arrayTx) -> Observable<[MarketPulse.DTO.Asset]> in + + guard let self = self else { return Observable.empty() } + + var pairs: [MarketPulse.DTO.Asset] = [] + + for (index, model) in searchResult.pairs.enumerated() { + + let exchangeAssetTxs = arrayTx[index] + let price = exchangeAssetTxs.count > 0 ? exchangeAssetTxs.map{$0.price}.reduce(0, {$0 + $1}) / Double(exchangeAssetTxs.count) : 0 + + let asset = assets[index] + + pairs.append(MarketPulse.DTO.Asset(id: asset.id, + name: asset.name, + icon: asset.icon, + price: price, + firstPrice: model?.firstPrice ?? 0, + lastPrice: model?.lastPrice ?? 0, + amountAsset: asset.amountAsset)) + } + return self.dbRepository.saveAsssets(assets: pairs) + .flatMap({ (_) -> Observable<[MarketPulse.DTO.Asset]> in + return Observable.just(pairs) + }) + }) + + } + } +} + +private struct AuthorizationInteractorLocalizableImp: AuthorizationInteractorLocalizableProtocol { + + var fallbackTitle: String { + return "" + } + + var cancelTitle: String { + return "" + } + + var readFromkeychain: String { + return "" + } + + var saveInkeychain: String { + return "" + } +} diff --git a/MarketPulseWidget/Sources/MarketPulseTypes.swift b/MarketPulseWidget/Sources/MarketPulseTypes.swift new file mode 100644 index 00000000..1ed9ae11 --- /dev/null +++ b/MarketPulseWidget/Sources/MarketPulseTypes.swift @@ -0,0 +1,118 @@ +// +// MarketPulseExtension.swift +// MarketPulseWidget +// +// Created by Pavel Gubin on 24.07.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import Extensions +import WavesSDK +import DomainLayer + +enum MarketPulse { + static let minimumCountAssets = 2 + + static let usdAssetId = "Ft8X1v1LTa1ABafufpaCWyVj8KkaxUWE6xBhW6sNFJck" + static let eurAssetId = "Gtb1WRznfchDnTh37ezoDTJ4wcoKaRsKqKjJjy7nm2zU" + + enum Currency: String { + case usd + case eur + + var title: String { + switch self { + case .eur: + return "EUR" + + case .usd: + return "USD" + } + } + + var ticker: String { + switch self { + + case .eur: + return "€" + case .usd: + return "$" + } + } + } + + enum DTO {} + enum ViewModel { } + + enum Event { + case readyView + case refresh + case changeCurrency(Currency) + case setAssets([DTO.Asset]) + case setSettings(DTO.Settings) + case setChachedAssets([DTO.Asset]) + } + + struct State: Mutating { + enum Action { + case none + case update + case didFailUpdate(NetworkError) + } + + var hasLoadSettings: Bool + var hasLoadChachedAsset: Bool + var isNeedRefreshing: Bool + var action: Action + var models: [ViewModel.Row] + var assets: [DTO.Asset] + var currency: Currency + var isDarkMode: Bool + var updateInterval: DomainLayer.DTO.MarketPulseSettings.Interval + } + +} + +extension MarketPulse.DTO { + + struct Asset: Codable { + let id: String + let name: String + let icon: AssetLogo.Icon + let price: Double + let firstPrice: Double + let lastPrice: Double + let amountAsset: String + } + + struct UIAsset { + let icon: AssetLogo.Icon + let name: String + let price: Double + let percent: Double + let currency: MarketPulse.Currency + let isDarkMode: Bool + } + + struct Settings { + let currency: MarketPulse.Currency + let isDarkMode: Bool + let inverval: DomainLayer.DTO.MarketPulseSettings.Interval + } +} + +extension MarketPulse.ViewModel { + + enum Row { + case model(MarketPulse.DTO.UIAsset) + } +} + +extension MarketPulse.State: Equatable { + static func == (lhs: MarketPulse.State, rhs: MarketPulse.State) -> Bool { + return lhs.isNeedRefreshing == rhs.isNeedRefreshing && + lhs.hasLoadSettings == rhs.hasLoadSettings && + lhs.hasLoadChachedAsset == rhs.hasLoadChachedAsset + } +} diff --git a/MarketPulseWidget/Sources/MarketPulseWidgetSettingsRepositoryMock.swift b/MarketPulseWidget/Sources/MarketPulseWidgetSettingsRepositoryMock.swift new file mode 100644 index 00000000..7bd7c8c4 --- /dev/null +++ b/MarketPulseWidget/Sources/MarketPulseWidgetSettingsRepositoryMock.swift @@ -0,0 +1,121 @@ +// +// MarketPulseWidgetSettingsRepositoryMock.swift +// DataLayer +// +// Created by Pavel Gubin on 30.07.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import DomainLayer +import RxSwift +import WavesSDK + +final class MarketPulseWidgetSettingsRepositoryMock: MarketPulseWidgetSettingsRepositoryProtocol { + + func settings() -> Observable { + + var initAssets: [DomainLayer.DTO.MarketPulseSettings.Asset] = [] + + let btcIcon = DomainLayer.DTO.MarketPulseSettings.Asset.IconStyle(icon: .init(assetId: "8LQW8f7P5d5PZM7GtZEBgaqRPGSzS3DfPuiXrURJ4AJS", + name: "Bitcoin", + url: "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/logo_bitcoin_48.png"), + isSponsored: false, + hasScript: false) + + let ethIcon = DomainLayer.DTO.MarketPulseSettings.Asset.IconStyle(icon: .init(assetId: "474jTeYx2r2Va35794tCScAXWJG9hU2HcgxzMowaZUnu", + name: "Ethereum", + url: "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/logo_ethereum_48.png"), + isSponsored: false, + hasScript: false) + + let zecIcon = DomainLayer.DTO.MarketPulseSettings.Asset.IconStyle(icon: .init(assetId: "BrjUWjndUanm5VsJkbUip8VRYy6LWJePtxya3FNv4TQa", + name: "zCash", + url: "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/logo_zec_48.png"), + isSponsored: false, + hasScript: false) + + let btcCashIcon = DomainLayer.DTO.MarketPulseSettings.Asset.IconStyle(icon: .init(assetId: "zMFqXuoyrn5w17PFurTqxB7GsS71fp9dfk6XFwxbPCy", + name: "Bitcoin Cash", + url: "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/logo_bitcoincash_48.png"), + isSponsored: false, + hasScript: false) + + let moneroIcon = DomainLayer.DTO.MarketPulseSettings.Asset.IconStyle(icon: .init(assetId: "5WvPKSJXzVE2orvbkJ8wsQmmQKqTv9sGBPksV4adViw3", + name: "Monero", + url: "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/logo_monero_48.png"), + isSponsored: false, + hasScript: false) + + let ltcIcon = DomainLayer.DTO.MarketPulseSettings.Asset.IconStyle(icon: .init(assetId: "HZk1mbfuJpmxU1Fs4AX5MWLVYtctsNcg6e2C6VKqK8zk", + name: "Litecoin", + url: "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/logo_ltc_48.png"), + isSponsored: false, + hasScript: false) + + let wavesIcon = DomainLayer.DTO.MarketPulseSettings.Asset.IconStyle(icon: .init(assetId: "WAVES", + name: "WAVES", + url: "https://d1jh0rcszsaxik.cloudfront.net/assset_icons/logo_waves_48.png"), + isSponsored: false, + hasScript: false) + + + + initAssets.append(.init(id: "8LQW8f7P5d5PZM7GtZEBgaqRPGSzS3DfPuiXrURJ4AJS", + name: "Bitcoin", + iconStyle: btcIcon, + amountAsset: "8LQW8f7P5d5PZM7GtZEBgaqRPGSzS3DfPuiXrURJ4AJS", + priceAsset: "Ft8X1v1LTa1ABafufpaCWyVj8KkaxUWE6xBhW6sNFJck")) + + initAssets.append(.init(id: "474jTeYx2r2Va35794tCScAXWJG9hU2HcgxzMowaZUnu", + name: "Ethereum", + iconStyle: ethIcon, + amountAsset: "474jTeYx2r2Va35794tCScAXWJG9hU2HcgxzMowaZUnu", + priceAsset: "WAVES")) + + initAssets.append(.init(id: "BrjUWjndUanm5VsJkbUip8VRYy6LWJePtxya3FNv4TQa", + name: "zCash", + iconStyle: zecIcon, + amountAsset: "BrjUWjndUanm5VsJkbUip8VRYy6LWJePtxya3FNv4TQa", + priceAsset: "WAVES")) + + initAssets.append(.init(id: "zMFqXuoyrn5w17PFurTqxB7GsS71fp9dfk6XFwxbPCy", + name: "Bitcoin Cash", + iconStyle: btcCashIcon, + amountAsset: "zMFqXuoyrn5w17PFurTqxB7GsS71fp9dfk6XFwxbPCy", + priceAsset: "WAVES")) + + initAssets.append(.init(id: "5WvPKSJXzVE2orvbkJ8wsQmmQKqTv9sGBPksV4adViw3", + name: "Monero", + iconStyle: moneroIcon, + amountAsset: "5WvPKSJXzVE2orvbkJ8wsQmmQKqTv9sGBPksV4adViw3", + priceAsset: "WAVES")) + + initAssets.append(.init(id: "HZk1mbfuJpmxU1Fs4AX5MWLVYtctsNcg6e2C6VKqK8zk", + name: "Litecoin", + iconStyle: ltcIcon, + amountAsset: "HZk1mbfuJpmxU1Fs4AX5MWLVYtctsNcg6e2C6VKqK8zk", + priceAsset: "WAVES")) + + initAssets.append(.init(id: "WAVES", + name: "WAVES", + iconStyle: wavesIcon, + amountAsset: "WAVES", + priceAsset: MarketPulse.eurAssetId)) + + + initAssets.append(.init(id: MarketPulse.eurAssetId, + name: "", + iconStyle: wavesIcon, + amountAsset: WavesSDKConstants.wavesAssetId, + priceAsset: MarketPulse.eurAssetId)) + + initAssets.append(.init(id: MarketPulse.usdAssetId, + name: "", + iconStyle: wavesIcon, + amountAsset: WavesSDKConstants.wavesAssetId, + priceAsset: MarketPulse.usdAssetId)) + + return Observable.just(.init(isDarkStyle: false, interval: .m1, assets: initAssets)) + } +} diff --git a/MarketPulseWidget/Sources/MarketPulseWidgetViewController.swift b/MarketPulseWidget/Sources/MarketPulseWidgetViewController.swift new file mode 100644 index 00000000..ce89c612 --- /dev/null +++ b/MarketPulseWidget/Sources/MarketPulseWidgetViewController.swift @@ -0,0 +1,319 @@ +// +// TodayViewController.swift +// MarketPulseWidget +// +// Created by Pavel Gubin on 24.07.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import UIKit +import NotificationCenter +import RxSwift +import RxCocoa +import RxFeedback +import WavesSDK +import DomainLayer +import Extensions + +private enum Constants { + static let bottomViewHeight: CGFloat = 34 + static let buttonUpdateOffset: CGFloat = 40 + + static let animationKey = "rotation" + static let animationDuration: TimeInterval = 1 +} + +final class MarketPulseWidgetViewController: UIViewController { + + @IBOutlet private weak var tableView: UITableView! + @IBOutlet private weak var buttonCurrency: UIButton! + @IBOutlet private weak var buttonUpdate: UIButton! + @IBOutlet private weak var buttonSettings: UIButton! + @IBOutlet private weak var buttonUpdateWidth: NSLayoutConstraint! + @IBOutlet private weak var viewDarkMode: UIView! + @IBOutlet private weak var labelError: UILabel! + + private var currency: MarketPulse.Currency! + private var isDarkMode: Bool = false + private var updateInverval: DomainLayer.DTO.MarketPulseSettings.Interval? + + private var presenter: MarketPulseWidgetPresenterProtocol! + private let sendEvent: PublishRelay = PublishRelay() + private var items: [MarketPulse.ViewModel.Row] = [] + private var disposeBag = DisposeBag() + + private var languages: [Language] { + let list: [Language] = JSONDecoder.decode(json: "Languages") ?? [] + return list + } + + override func viewDidLoad() { + super.viewDidLoad() + + Language.load(localizable: Localizable.self, languages: languages) + + buttonUpdate.setTitle(Localizable.Marketpulsewidget.Button.Update.title, for: .normal) + initPresenter() + + setupFeedBack() + setupButtonUpdateSize() + showUpdateAnimation() + hideError() + updatePrefferedSize() + } + + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + disposeBag = DisposeBag() + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + + setupUpdateTimer() + } + + private func setupUpdateTimer() { + + guard let inverval = updateInverval else { return } + + disposeBag = DisposeBag() + + if inverval != .manually { + + Observable + .interval(RxTimeInterval(inverval.rawValue), scheduler: MainScheduler.asyncInstance) + .subscribe(onNext: { [weak self] (value) in + guard let self = self else { return } + self.sendEvent.accept(.refresh) + }) + .disposed(by: disposeBag) + } + } + + private func initPresenter() { + presenter = MarketPulseWidgetPresenter() + presenter.interactor = MarketPulseWidgetInteractor.shared + } + + @IBAction private func settingsTapped(_ sender: Any) { + + WidgetAnalyticManager.shared.trackEvent(.widgets(.marketPulseActive)) + if let url = URL(string: DeepLink.widgetSettings) { + extensionContext?.open(url, completionHandler: nil) + } + } + + @IBAction private func updateTapped(_ sender: Any) { + + WidgetAnalyticManager.shared.trackEvent(.widgets(.marketPulseActive)) + + sendEvent.accept(.refresh) + showUpdateAnimation() + } + + @IBAction private func changeCurrency(_ sender: Any) { + if currency == .usd { + currency = .eur + } + else { + currency = .usd + } + + WidgetAnalyticManager.shared.trackEvent(.widgets(.marketPulseActive)) + sendEvent.accept(.changeCurrency(currency)) + } +} + +//MARK: - FeedBack + +extension MarketPulseWidgetViewController { + + + func setupFeedBack() { + + let readyViewFeedback: MarketPulseWidgetPresenter.Feedback = { [weak self] _ in + guard let self = self else { return Signal.empty() } + return self.rx.viewWillAppear.take(1).map { _ in MarketPulse.Event.readyView }.asSignal(onErrorSignalWith: Signal.empty()) + } + + let feedback = bind(self) { owner, state -> Bindings in + return Bindings(subscriptions: owner.subscriptions(state: state), + events: [owner.sendEvent.asSignal()]) + } + + presenter.system(feedbacks: [feedback, readyViewFeedback]) + } + + func subscriptions(state: Driver) -> [Disposable] { + let subscriptionSections = state + .drive(onNext: { [weak self] state in + + guard let self = self else { return } + + switch state.action { + + case .update: + self.items = state.models + self.currency = state.currency + self.isDarkMode = state.isDarkMode + self.updateInverval = state.updateInterval + self.updateUI() + self.setupUpdateTimer() + self.hideError() + + case .didFailUpdate(let error): + self.hideUpdateAnimation() + self.showError(error) + + default: + break + } + }) + + return [subscriptionSections] + } +} + +//MARK: - UI +private extension MarketPulseWidgetViewController { + + func hideError() { + labelError.isHidden = true + tableView.isHidden = false + buttonUpdate.isHidden = false + buttonCurrency.isHidden = false + buttonSettings.isHidden = false + } + + func showError(_ error: NetworkError) { + labelError.isHidden = false + tableView.isHidden = true + buttonUpdate.isHidden = true + buttonCurrency.isHidden = true + buttonSettings.isHidden = true + + //TODO: - change error message + labelError.text = error.localizedDescription + } + + func updateUI() { + tableView.reloadData() + updatePrefferedSize() + hideUpdateAnimation() + setupDarkMode() + setupCurrencyTitle() + } + + func showUpdateAnimation() { + if buttonUpdate.imageView?.layer.animation(forKey: Constants.animationKey) == nil { + let rotationAnimation = CABasicAnimation(keyPath: "transform.rotation") + + rotationAnimation.fromValue = 0.0 + rotationAnimation.toValue = Float.pi * 2.0 + rotationAnimation.duration = Constants.animationDuration + rotationAnimation.repeatCount = Float.infinity + + buttonUpdate.imageView?.layer.add(rotationAnimation, forKey: Constants.animationKey) + } + } + + func hideUpdateAnimation() { + buttonUpdate.imageView?.layer.removeAnimation(forKey: Constants.animationKey) + } + + var titleTextColor: UIColor { + return isDarkMode ? .disabled700 : .basic700 + } + + func setupDarkMode() { + buttonSettings.tintColor = titleTextColor + buttonUpdate.tintColor = titleTextColor + viewDarkMode.isHidden = !isDarkMode + labelError.textColor = isDarkMode ? .white : .black + } + + func setupButtonUpdateSize() { + guard let font = buttonUpdate.titleLabel?.font else { return } + let title = buttonUpdate.title(for: .normal) ?? "" + let size = title.maxWidth(font: font) + buttonUpdateWidth.constant = size + Constants.buttonUpdateOffset + } + + func setupCurrencyTitle() { + + let selectedColor: UIColor = isDarkMode ? .disabled400 : .disabled900 + + let text = MarketPulse.Currency.usd.title + " / " + MarketPulse.Currency.eur.title + let attr = NSMutableAttributedString.init(string: text, + attributes: [NSAttributedString.Key.font : UIFont.systemFont(ofSize: 12), + NSAttributedString.Key.foregroundColor : titleTextColor]) + attr.addAttributes([NSAttributedString.Key.font : UIFont.systemFont(ofSize: 12, weight: .medium), + NSAttributedString.Key.foregroundColor : selectedColor], + range: (text as NSString).range(of: currency.title)) + buttonCurrency.setAttributedTitle(attr, for: .normal) + } +} + +//MARK: - UITableViewDelegate +extension MarketPulseWidgetViewController: UITableViewDelegate { + + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return MarketPulseWidgetCell.viewHeight() + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return items.count + } +} + +//MARK: - UITableViewDataSource +extension MarketPulseWidgetViewController: UITableViewDataSource { + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + + let row = items[indexPath.row] + + switch row { + case .model(let model): + let cell = tableView.dequeueCell() as MarketPulseWidgetCell + cell.update(with: model) + return cell + } + } +} + +//MARK: - NCWidgetProviding +extension MarketPulseWidgetViewController: NCWidgetProviding { + + func widgetPerformUpdate(completionHandler: (@escaping (NCUpdateResult) -> Void)) { + // Perform any setup necessary in order to update the view. + + // If an error is encountered, use NCUpdateResult.Failed + // If there's no update required, use NCUpdateResult.NoData + // If there's an update, use NCUpdateResult.NewData + + completionHandler(NCUpdateResult.newData) + } + + func widgetActiveDisplayModeDidChange(_ activeDisplayMode: NCWidgetDisplayMode, withMaximumSize maxSize: CGSize) { + updatePrefferedSize() + } + + func updatePrefferedSize() { + + guard let extensionContext = self.extensionContext else { return } + extensionContext.widgetLargestAvailableDisplayMode = items.count > MarketPulse.minimumCountAssets ? .expanded : .compact + + let activeMode = extensionContext.widgetActiveDisplayMode + let maxSize = extensionContext.widgetMaximumSize(for: activeMode) + + if activeMode == .compact { + preferredContentSize = maxSize + } + else { + let height = CGFloat(items.count) * MarketPulseWidgetCell.viewHeight() + Constants.bottomViewHeight + preferredContentSize = .init(width: maxSize.width, height: height) + } + } +} diff --git a/MarketPulseWidget/Sources/Presenter/MarketPulseWidgetPresenter.swift b/MarketPulseWidget/Sources/Presenter/MarketPulseWidgetPresenter.swift new file mode 100644 index 00000000..f0924d86 --- /dev/null +++ b/MarketPulseWidget/Sources/Presenter/MarketPulseWidgetPresenter.swift @@ -0,0 +1,173 @@ +// +// MarketPulseWidgetPresenter.swift +// MarketPulseWidget +// +// Created by Pavel Gubin on 24.07.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import RxCocoa +import RxSwift +import RxFeedback +import WavesSDK + +protocol MarketPulseWidgetPresenterProtocol { + typealias Feedback = (Driver) -> Signal + var interactor: MarketPulseWidgetInteractorProtocol! { get set } + + func system(feedbacks: [MarketPulseWidgetPresenter.Feedback]) +} + +final class MarketPulseWidgetPresenter: MarketPulseWidgetPresenterProtocol { + + var interactor: MarketPulseWidgetInteractorProtocol! + private let disposeBag = DisposeBag() + + func system(feedbacks: [MarketPulseWidgetPresenter.Feedback]) { + var newFeedbacks = feedbacks + newFeedbacks.append(queryAssets()) + newFeedbacks.append(querySettings()) + newFeedbacks.append(queryChachedAsset()) + + Driver.system(initialState: MarketPulse.State.initialState, + reduce: MarketPulseWidgetPresenter.reduce, + feedback: newFeedbacks) + .drive() + .disposed(by: disposeBag) + } + + private func queryAssets() -> Feedback { + return react(request: { state -> MarketPulse.State? in + return state.isNeedRefreshing ? state : nil + }, effects: { [weak self] _ -> Signal in + guard let self = self else { return Signal.empty() } + return self.interactor.assets().map {.setAssets($0)}.asSignal(onErrorSignalWith: Signal.empty()) + }) + } + + private func querySettings() -> Feedback { + return react(request: { state -> MarketPulse.State? in + return state.hasLoadSettings == false ? state : nil + }, effects: { [weak self] _ -> Signal in + guard let self = self else { return Signal.empty() } + return self.interactor.settings().map {.setSettings($0)}.asSignal(onErrorSignalWith: Signal.empty()) + }) + } + + private func queryChachedAsset() -> Feedback { + return react(request: { state -> MarketPulse.State? in + return state.hasLoadChachedAsset == false ? state : nil + }, effects: { [weak self] _ -> Signal in + guard let self = self else { return Signal.empty() } + return self.interactor.chachedAssets().map {.setChachedAssets($0)}.asSignal(onErrorSignalWith: Signal.empty()) + }) + } + + private static func reduce(state: MarketPulse.State, event: MarketPulse.Event) -> MarketPulse.State { + + var newState = state + reduce(state: &newState, event: event) + return newState + } + + private static func reduce(state: inout MarketPulse.State, event: MarketPulse.Event) { + switch event { + case .readyView: + state.isNeedRefreshing = true + + case .refresh: + state.isNeedRefreshing = true + state.action = .none + + case .changeCurrency(let currency): + WidgetSettings.setCurrency(currency: currency) + + state.currency = currency + state.models = mapAssetModels(assets: state.assets, settings: .init(currency: currency, + isDarkMode: state.isDarkMode, + inverval: state.updateInterval)) + state.action = .update + + case .setAssets(let assets): + state.isNeedRefreshing = false + + state.assets = assets + state.models = mapAssetModels(assets: assets, settings: .init(currency: state.currency, + isDarkMode: state.isDarkMode, + inverval: state.updateInterval)) + state.action = .update + + case .setSettings(let settings): + state.currency = settings.currency + state.isDarkMode = settings.isDarkMode + state.hasLoadSettings = true + state.action = .update + + case .setChachedAssets(let chachedAssets): + state.assets = chachedAssets + state.hasLoadChachedAsset = true + state.models = mapAssetModels(assets: chachedAssets, settings: .init(currency: state.currency, + isDarkMode: state.isDarkMode, + inverval: state.updateInterval)) + state.action = .update + } + } +} + +private extension MarketPulseWidgetPresenter { + + static func mapAssetModels(assets: [MarketPulse.DTO.Asset], settings: MarketPulse.DTO.Settings) -> [MarketPulse.ViewModel.Row] { + + guard let wavesUSDAsset = assets.first(where: {$0.id == MarketPulse.usdAssetId}) else { return [] } + guard let wavesEURAsset = assets.first(where: {$0.id == MarketPulse.eurAssetId}) else { return [] } + + let wavesCurrencyAsset = settings.currency == .usd ? wavesUSDAsset : wavesEURAsset + let filteredAsset = assets.filter {$0.id != MarketPulse.eurAssetId && $0.id != MarketPulse.usdAssetId } + + return filteredAsset.map { asset in + + var price: Double = 0 + var percent: Double = 0 + + if asset.id == WavesSDKConstants.wavesAssetId { + let deltaPercent = (wavesCurrencyAsset.lastPrice - wavesCurrencyAsset.firstPrice) * 100 + percent = wavesCurrencyAsset.lastPrice != 0 ? deltaPercent / wavesCurrencyAsset.lastPrice : 0 + price = wavesCurrencyAsset.price + } + else { + + let deltaPercent = (asset.lastPrice - asset.firstPrice) * 100 + percent = asset.lastPrice != 0 ? deltaPercent / asset.lastPrice : 0 + + if asset.amountAsset == WavesSDKConstants.wavesAssetId { + price = asset.price != 0 ? 1 / asset.price * wavesCurrencyAsset.price : 0 + } + else { + price = asset.price * wavesCurrencyAsset.price + } + } + + return MarketPulse.ViewModel.Row.model(MarketPulse.DTO.UIAsset(icon: asset.icon, + name: asset.name, + price: price, + percent: percent, + currency: settings.currency, + isDarkMode: settings.isDarkMode)) + } + } +} + +fileprivate extension MarketPulse.State { + static var initialState: MarketPulse.State { + return MarketPulse.State(hasLoadSettings: false, + hasLoadChachedAsset: false, + isNeedRefreshing: false, + action: .none, + models: [], + assets: [], + currency: .usd, + isDarkMode: false, + updateInterval: .m1) + } +} diff --git a/MarketPulseWidget/Sources/Repositories/MarketPulseDataBaseRepository.swift b/MarketPulseWidget/Sources/Repositories/MarketPulseDataBaseRepository.swift new file mode 100644 index 00000000..f9019feb --- /dev/null +++ b/MarketPulseWidget/Sources/Repositories/MarketPulseDataBaseRepository.swift @@ -0,0 +1,57 @@ +// +// MarketPulseRepository.swift +// MarketPulseWidget +// +// Created by Pavel Gubin on 01.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import DomainLayer +import Extensions + +private enum Constants { + static let key = "widget.settings.chachedAssets" +} + +final class MarketPulseDataBaseRepository: MarketPulseDataBaseRepositoryProtocol { + + func chachedAssets() -> Observable<[MarketPulse.DTO.Asset]> { + return Observable.create({ (subscribe) -> Disposable in + + if let assetsData = UserDefaults.standard.object(forKey: Constants.key) as? Data { + if let assets = try? JSONDecoder().decode([MarketPulse.DTO.Asset].self, from: assetsData) { + subscribe.onNext(assets) + } + else { + subscribe.onNext([]) + } + } + else { + subscribe.onNext([]) + } + + subscribe.onCompleted() + return Disposables.create() + }) + } + + func saveAsssets(assets: [MarketPulse.DTO.Asset]) -> Observable { + return Observable.create({ (subscribe) -> Disposable in + + do { + let encodedData = try JSONEncoder().encode(assets) + UserDefaults.standard.set(encodedData, forKey: Constants.key) + subscribe.onNext(true) + } + catch _ { + subscribe.onNext(false) + } + subscribe.onCompleted() + + return Disposables.create() + }) + + } +} diff --git a/MarketPulseWidget/Sources/Repositories/MarketPulseDataBaseRepositoryProtocol.swift b/MarketPulseWidget/Sources/Repositories/MarketPulseDataBaseRepositoryProtocol.swift new file mode 100644 index 00000000..d513aae3 --- /dev/null +++ b/MarketPulseWidget/Sources/Repositories/MarketPulseDataBaseRepositoryProtocol.swift @@ -0,0 +1,17 @@ +// +// MarketPulseRepositoryProtocol.swift +// MarketPulseWidget +// +// Created by Pavel Gubin on 01.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift + +protocol MarketPulseDataBaseRepositoryProtocol { + + //TODO: Rename to assets + func chachedAssets() -> Observable<[MarketPulse.DTO.Asset]> + func saveAsssets(assets: [MarketPulse.DTO.Asset]) -> Observable +} diff --git a/MarketPulseWidget/Sources/Repositories/Network/WidgetAssetsRepositoryRemote.swift b/MarketPulseWidget/Sources/Repositories/Network/WidgetAssetsRepositoryRemote.swift new file mode 100644 index 00000000..5c8f7304 --- /dev/null +++ b/MarketPulseWidget/Sources/Repositories/Network/WidgetAssetsRepositoryRemote.swift @@ -0,0 +1,121 @@ +// +// WidgetAssetsRepositoryRemote.swift +// MarketPulseWidget +// +// Created by Pavel Gubin on 28.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import DomainLayer +import RxSwift +import WavesSDKExtensions +import WavesSDK + + +protocol WidgetAssetsRepositoryProtocol { + func assets(by ids: [String]) -> Observable<[DomainLayer.DTO.Asset]> +} + +final class WidgetAssetsRepositoryRemote: WidgetAssetsRepositoryProtocol { + + private let assetsDataService: WidgetAssetsDataServiceProtocol = WidgetAssetsDataService() + + func assets(by ids: [String]) -> Observable<[DomainLayer.DTO.Asset]> { + + let walletEnviroment = WalletEnvironment.Mainnet + + return assetsDataService + .assets(ids: ids) + .map({ (assets) -> [DomainLayer.DTO.Asset] in + + let map = walletEnviroment.hashMapAssets() + let mapGeneralAssets = walletEnviroment.hashMapGeneralAssets() + + + return assets.map { DomainLayer.DTO.Asset(asset: $0, + info: map[$0.id], + isSpam: false, + isMyWavesToken: false, + isGeneral: mapGeneralAssets[$0.id] != nil) } + }) + } +} + +//TODO: - Duplicate code from DataLayer + +fileprivate extension WalletEnvironment { + + func hashMapAssets() -> [String: WalletEnvironment.AssetInfo] { + + var allAssets = generalAssets + if let additionalAssets = assets { + allAssets.append(contentsOf: additionalAssets) + } + + return allAssets.reduce([String: WalletEnvironment.AssetInfo](), { map, info -> [String: WalletEnvironment.AssetInfo] in + var new = map + new[info.assetId] = info + return new + }) + } + + func hashMapGeneralAssets() -> [String: WalletEnvironment.AssetInfo] { + + let allAssets = generalAssets + + return allAssets.reduce([String: WalletEnvironment.AssetInfo](), { map, info -> [String: WalletEnvironment.AssetInfo] in + var new = map + new[info.assetId] = info + return new + }) + } +} + + +fileprivate extension DomainLayer.DTO.Asset { + + init(asset: DataService.DTO.Asset, info: WalletEnvironment.AssetInfo?, isSpam: Bool, isMyWavesToken: Bool, isGeneral: Bool) { + var isWaves = false + var isFiat = false + let isGateway = info?.isGateway ?? false + let isWavesToken = isFiat == false && isGateway == false && isWaves == false + var name = asset.name + + //TODO: Current code need move to AssetsInteractor! + if let info = info { + if info.assetId == WavesSDKConstants.wavesAssetId { + isWaves = true + } + + name = info.displayName + isFiat = info.isFiat + } + + self.init(id: asset.id, + gatewayId: info?.gatewayId, + wavesId: info?.wavesId, + displayName: name, + precision: asset.precision, + description: asset.description, + height: asset.height, + timestamp: asset.timestamp, + sender: asset.sender, + quantity: asset.quantity, + ticker: asset.ticker, + isReusable: asset.reissuable, + isSpam: isSpam, + isFiat: isFiat, + isGeneral: isGeneral, + isMyWavesToken: isMyWavesToken, + isWavesToken: isWavesToken, + isGateway: isGateway, + isWaves: isWaves, + modified: Date(), + addressRegEx: info?.addressRegEx ?? "", + iconLogoUrl: info?.iconUrls?.default, + hasScript: asset.hasScript, + minSponsoredFee: asset.minSponsoredFee ?? 0, + gatewayType: info?.gatewayType) + } +} diff --git a/MarketPulseWidget/Sources/Repositories/Network/WidgetMatcherRepositoryRemote.swift b/MarketPulseWidget/Sources/Repositories/Network/WidgetMatcherRepositoryRemote.swift new file mode 100644 index 00000000..192344b7 --- /dev/null +++ b/MarketPulseWidget/Sources/Repositories/Network/WidgetMatcherRepositoryRemote.swift @@ -0,0 +1,37 @@ +// +// WidgetMatcherRepositoryRemote.swift +// MarketPulseWidget +// +// Created by Pavel Gubin on 28.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import Moya +import DomainLayer +import WavesSDK +import WavesSDKCrypto + +final class WidgetMatcherRepositoryRemote: MatcherRepositoryProtocol { + + private let settingsMatcherService: WidgetMatcherSettingServiceProtocol = WidgetMatcherSettingService() + private let publicKeyMatcherService: PublicKeyMatcherServiceProtocol = WidgetPublicKeyMatcherService() + + func settingsIdsPairs() -> Observable<[String]> { + + return settingsMatcherService + .settings() + .map { + return $0.priceAssets + } + } + + func matcherPublicKey() -> Observable { + return publicKeyMatcherService + .publicKey() + .map { + return PublicKeyAccount(publicKey: Base58Encoder.decode($0)) + } + } +} diff --git a/MarketPulseWidget/Sources/Repositories/Network/WidgetPairsPriceRepositoryRemote.swift b/MarketPulseWidget/Sources/Repositories/Network/WidgetPairsPriceRepositoryRemote.swift new file mode 100644 index 00000000..e3ee1710 --- /dev/null +++ b/MarketPulseWidget/Sources/Repositories/Network/WidgetPairsPriceRepositoryRemote.swift @@ -0,0 +1,62 @@ +// +// WidgetPairsPriceRepositoryRemote.swift +// MarketPulseWidget +// +// Created by Pavel Gubin on 28.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import DomainLayer +import RxSwift +import Extensions + +protocol WidgetPairsPriceRepositoryProtocol { + + func searchPairs(_ query: DomainLayer.Query.Dex.SearchPairs) -> Observable +} + +final class WidgetPairsPriceRepositoryRemote: WidgetPairsPriceRepositoryProtocol { + + private let pairsPriceDataService = WidgetPairsPriceDataService() + + func searchPairs(_ query: DomainLayer.Query.Dex.SearchPairs) -> Observable { + + //TODO: Others type kinds + guard case let .pairs(pairs) = query.kind else { return Observable.never() } + + + let pairsForQuery = pairs.map { WidgetDataService.Query.PairsPrice.Pair(amountAssetId: $0.amountAsset, + priceAssetId: $0.priceAsset) } + + let query = WidgetDataService.Query.PairsPrice(pairs: pairsForQuery) + + return pairsPriceDataService + .pairsPrice(query: query) + .map({ (pairsSearch) -> DomainLayer.DTO.Dex.PairsSearch in + + let pairs = pairsSearch.map({ (pairPrice) -> DomainLayer + .DTO + .Dex + .PairsSearch + .Pair? in + + guard let pairPrice = pairPrice else { return nil } + + return DomainLayer + .DTO + .Dex + .PairsSearch + .Pair.init(firstPrice: pairPrice.firstPrice, + lastPrice: pairPrice.lastPrice, + volume: pairPrice.volume, + volumeWaves: pairPrice.volumeWaves, + quoteVolume: pairPrice.quoteVolume) + }) + + + + return DomainLayer.DTO.Dex.PairsSearch(pairs: pairs) + }) + } +} diff --git a/MarketPulseWidget/Sources/Repositories/Network/WidgetTransactionsRepositoryRemote.swift b/MarketPulseWidget/Sources/Repositories/Network/WidgetTransactionsRepositoryRemote.swift new file mode 100644 index 00000000..6547d1b5 --- /dev/null +++ b/MarketPulseWidget/Sources/Repositories/Network/WidgetTransactionsRepositoryRemote.swift @@ -0,0 +1,44 @@ +// +// WidgetTransactionsRepositoryRemote.swift +// MarketPulseWidget +// +// Created by Pavel Gubin on 29.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import DomainLayer +import RxSwift +import WavesSDK +import Extensions + + +protocol WidgetTransactionsRepositoryProtocol { + func exchangeTransactions(amountAsset: String, priceAsset: String, limit: Int) -> Observable<[DataService.DTO.ExchangeTransaction]> +} + +final class WidgetTransactionsRepositoryRemote: WidgetTransactionsRepositoryProtocol { + + private let transactionsDataService: TransactionsDataServiceProtocol = WidgetTransactionsDataService() + private let matcherRepository: MatcherRepositoryProtocol = MatcherRepositoryLocal(matcherRepositoryRemote: WidgetMatcherRepositoryRemote()) + + func exchangeTransactions(amountAsset: String, priceAsset: String, limit: Int) -> Observable<[DataService.DTO.ExchangeTransaction]> { + + return matcherRepository.matcherPublicKey() + .flatMap({[weak self] (publicKeyAccount) -> Observable<[DataService.DTO.ExchangeTransaction]> in + guard let self = self else { return Observable.empty() } + + let query = DataService.Query.ExchangeFilters(matcher: publicKeyAccount.address, + sender: nil, + timeStart: nil, + timeEnd: nil, + amountAsset: amountAsset, + priceAsset: priceAsset, + after: nil, + limit: limit) + + return self.transactionsDataService.transactionsExchange(query: query) + }) + + } +} diff --git a/WavesWallet-iOS/DataLayer/Service/Api/Models/PairPriceApi.swift b/MarketPulseWidget/Sources/Services/Data/Models/WidgetPairPriceData.swift similarity index 58% rename from WavesWallet-iOS/DataLayer/Service/Api/Models/PairPriceApi.swift rename to MarketPulseWidget/Sources/Services/Data/Models/WidgetPairPriceData.swift index c71596d1..0c882fe7 100644 --- a/WavesWallet-iOS/DataLayer/Service/Api/Models/PairPriceApi.swift +++ b/MarketPulseWidget/Sources/Services/Data/Models/WidgetPairPriceData.swift @@ -8,19 +8,23 @@ import Foundation -extension API.DTO { + +extension WidgetDataService.DTO { struct PairPrice: Decodable { + let firstPrice: Double let lastPrice: Double let volume: Double let volumeWaves: Double? + let quoteVolume: Double? + } - static var empty: PairPrice { - return PairPrice(firstPrice: 0, - lastPrice: 0, - volume: 0, - volumeWaves: 0) - } + struct PairPriceSearch: Decodable { + + let data: PairPrice + let amountAsset: String + let priceAsset: String } } + diff --git a/WavesWallet-iOS/DataLayer/Service/Api/Models/ResponseApi.swift b/MarketPulseWidget/Sources/Services/Data/Models/WidgetResponseData.swift similarity index 96% rename from WavesWallet-iOS/DataLayer/Service/Api/Models/ResponseApi.swift rename to MarketPulseWidget/Sources/Services/Data/Models/WidgetResponseData.swift index 11b165fa..1ffcb6a9 100644 --- a/WavesWallet-iOS/DataLayer/Service/Api/Models/ResponseApi.swift +++ b/MarketPulseWidget/Sources/Services/Data/Models/WidgetResponseData.swift @@ -8,7 +8,7 @@ import Foundation -extension API { +extension WidgetDataService { struct Response: Decodable { let type: String let data: T diff --git a/MarketPulseWidget/Sources/Services/Data/Services/WidgetAssetsDataService.swift b/MarketPulseWidget/Sources/Services/Data/Services/WidgetAssetsDataService.swift new file mode 100644 index 00000000..2935d250 --- /dev/null +++ b/MarketPulseWidget/Sources/Services/Data/Services/WidgetAssetsDataService.swift @@ -0,0 +1,43 @@ +// +// WidgetAssetsDataService.swift +// MarketPulseWidget +// +// Created by Pavel Gubin on 28.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import WavesSDK +import Moya +import WavesSDKExtensions + +protocol WidgetAssetsDataServiceProtocol { + + func assets(ids: [String]) -> Observable<[DataService.DTO.Asset]> +} + +final class WidgetAssetsDataService: WidgetAssetsDataServiceProtocol { + + private let assetsProvider: MoyaProvider = InternalWidgetService.moyaProvider() + + func assets(ids: [String]) -> Observable<[DataService.DTO.Asset]> { + + return self + .assetsProvider + .rx + .request(.init(kind: .getAssets(ids: ids), + dataUrl: InternalWidgetService.shared.dataUrl), + callbackQueue: DispatchQueue.global(qos: .userInteractive)) + .filterSuccessfulStatusAndRedirectCodes() + .catchError({ (error) -> Single in + return Single.error(NetworkError.error(by: error)) + }) + .map(WidgetDataService.Response<[WidgetDataService.Response]>.self, + atKeyPath: nil, + using: JSONDecoder.isoDecoderBySyncingTimestamp(0), + failsOnEmptyData: false) + .map { $0.data.map { $0.data } } + .asObservable() + } +} diff --git a/MarketPulseWidget/Sources/Services/Data/Services/WidgetPairsPriceDataService.swift b/MarketPulseWidget/Sources/Services/Data/Services/WidgetPairsPriceDataService.swift new file mode 100644 index 00000000..c30dc6bf --- /dev/null +++ b/MarketPulseWidget/Sources/Services/Data/Services/WidgetPairsPriceDataService.swift @@ -0,0 +1,39 @@ +// +// PairsPriceDataService.swift +// Alamofire +// +// Created by rprokofev on 06/05/2019. +// + +import Foundation +import RxSwift +import Moya +import WavesSDK + +protocol WidgetPairsPriceDataServiceProtocol { + func pairsPrice(query: WidgetDataService.Query.PairsPrice) -> Observable<[WidgetDataService.DTO.PairPrice?]> +} + + +final class WidgetPairsPriceDataService: WidgetPairsPriceDataServiceProtocol { + + private let pairsPriceProvider: MoyaProvider = InternalWidgetService.moyaProvider() + + func pairsPrice(query: WidgetDataService.Query.PairsPrice) -> Observable<[WidgetDataService.DTO.PairPrice?]> { + + return self + .pairsPriceProvider + .rx + .request(.init(query: query, + dataUrl: InternalWidgetService.shared.dataUrl), + callbackQueue: DispatchQueue.global(qos: .userInteractive)) + .filterSuccessfulStatusAndRedirectCodes() + .catchError({ (error) -> Single in + return Single.error(NetworkError.error(by: error)) + }) + .map(WidgetDataService.Response<[WidgetDataService.OptionalResponse]>.self) + .map { $0.data.map {$0.data }} + .asObservable() + } + +} diff --git a/MarketPulseWidget/Sources/Services/Data/Services/WidgetTransactionsDataService.swift b/MarketPulseWidget/Sources/Services/Data/Services/WidgetTransactionsDataService.swift new file mode 100644 index 00000000..2ffc4859 --- /dev/null +++ b/MarketPulseWidget/Sources/Services/Data/Services/WidgetTransactionsDataService.swift @@ -0,0 +1,38 @@ +// +// WidgetTransactionsDataService.swift +// MarketPulseWidget +// +// Created by Pavel Gubin on 29.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import WavesSDK +import WavesSDKExtensions +import Moya +import RxSwift + +final class WidgetTransactionsDataService: TransactionsDataServiceProtocol { + + private let transactionsProvider: MoyaProvider = InternalWidgetService.moyaProvider() + + func transactionsExchange(query: DataService.Query.ExchangeFilters) -> Observable<[DataService.DTO.ExchangeTransaction]> { + + return self + .transactionsProvider + .rx + .request(.init(kind: .getExchangeWithFilters(query), + dataUrl: InternalWidgetService.shared.dataUrl), + callbackQueue: DispatchQueue.global(qos: .userInteractive)) + .filterSuccessfulStatusAndRedirectCodes() + .catchError({ (error) -> Single in + return Single.error(NetworkError.error(by: error)) + }) + .map(WidgetDataService.Response<[WidgetDataService.Response]>.self, + atKeyPath: nil, + using: JSONDecoder.isoDecoderBySyncingTimestamp(0), + failsOnEmptyData: false) + .map { $0.data.map { $0.data } } + .asObservable() + } +} diff --git a/WavesWallet-iOS/DataLayer/Service/Api/Services/AssetsApiService.swift b/MarketPulseWidget/Sources/Services/Data/Targets/WidgetAssetsDataTarget.swift similarity index 59% rename from WavesWallet-iOS/DataLayer/Service/Api/Services/AssetsApiService.swift rename to MarketPulseWidget/Sources/Services/Data/Targets/WidgetAssetsDataTarget.swift index 684fe063..9325817f 100644 --- a/WavesWallet-iOS/DataLayer/Service/Api/Services/AssetsApiService.swift +++ b/MarketPulseWidget/Sources/Services/Data/Targets/WidgetAssetsDataTarget.swift @@ -8,31 +8,20 @@ import Foundation import Moya -import WavesSDKExtension -import WavesSDKCrypto -extension API.Service { +extension WidgetDataService.Target { struct Assets { enum Kind { - /** - Response: - - API.Response<[API.Response]>.self - */ case getAssets(ids: [String]) - /** - Response: - - API.Response.self - */ - case getAsset(id: String) } let kind: Kind - let environment: Environment + let dataUrl: URL } } -extension API.Service.Assets: ApiTargetType { +extension WidgetDataService.Target.Assets: WidgetDataTargetType { fileprivate enum Constants { static let assets = "assets" static let ids = "ids" @@ -40,8 +29,6 @@ extension API.Service.Assets: ApiTargetType { var path: String { switch kind { - case .getAsset(let id): - return Constants.assets + "/" + "\(id)".urlEscaped case .getAssets: return Constants.assets } @@ -49,8 +36,6 @@ extension API.Service.Assets: ApiTargetType { var method: Moya.Method { switch kind { - case .getAsset: - return .get case .getAssets: return .post } @@ -61,8 +46,6 @@ extension API.Service.Assets: ApiTargetType { case .getAssets(let ids): return Task.requestParameters(parameters: [Constants.ids: ids], encoding: JSONEncoding.default) - case .getAsset: - return .requestPlain } } } diff --git a/MarketPulseWidget/Sources/Services/Data/Targets/WidgetPairsPriceDataTarget.swift b/MarketPulseWidget/Sources/Services/Data/Targets/WidgetPairsPriceDataTarget.swift new file mode 100644 index 00000000..545a390b --- /dev/null +++ b/MarketPulseWidget/Sources/Services/Data/Targets/WidgetPairsPriceDataTarget.swift @@ -0,0 +1,94 @@ +// +// DexPairsApiService.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 12/25/18. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import Moya + +private enum TargetConstants { + static let pairs = "pairs" +} + +extension WidgetDataService.Query { + + struct PairsPrice { + + struct Pair { + let amountAssetId: String + let priceAssetId: String + } + + let pairs: [Pair] + } + + struct PairsPriceSearch { + + enum Kind { + case byAsset(String) + case byAssets(firstName: String, secondName: String) + } + + let kind: Kind + } +} + +extension WidgetDataService.Target { + + struct PairsPrice { + let query: WidgetDataService.Query.PairsPrice + let dataUrl: URL + } + + struct PairsPriceSearch { + let kind: WidgetDataService.Query.PairsPriceSearch.Kind + let dataUrl: URL + } +} + +extension WidgetDataService.Target.PairsPrice: WidgetDataTargetType { + + var path: String { + return TargetConstants.pairs + } + + var method: Moya.Method { + return .get + } + + var task: Task { + return .requestParameters(parameters: [TargetConstants.pairs: query.pairs.map { $0.amountAssetId + "/" + $0.priceAssetId } ], + encoding: URLEncoding.default) + } +} + +extension WidgetDataService.Target.PairsPriceSearch: WidgetDataTargetType { + + private enum Constants { + static let searchByAsset = "search_by_asset" + static let searchByAssets = "search_by_assets" + + } + + var path: String { + return TargetConstants.pairs + } + + var method: Moya.Method { + return .get + } + + var task: Task { + switch kind { + case .byAsset(let name): + return .requestParameters(parameters: [Constants.searchByAsset: name], encoding: URLEncoding.default) + + case .byAssets(let firstName, let secondName): + return .requestParameters(parameters: [Constants.searchByAssets: firstName + "," + secondName], + encoding: URLEncoding.default) + } + } +} diff --git a/WavesWallet-iOS/DataLayer/Service/Api/Services/TransactionsApiService.swift b/MarketPulseWidget/Sources/Services/Data/Targets/WidgetTransactionsDataTarget.swift similarity index 58% rename from WavesWallet-iOS/DataLayer/Service/Api/Services/TransactionsApiService.swift rename to MarketPulseWidget/Sources/Services/Data/Targets/WidgetTransactionsDataTarget.swift index 92666544..21506c9f 100644 --- a/WavesWallet-iOS/DataLayer/Service/Api/Services/TransactionsApiService.swift +++ b/MarketPulseWidget/Sources/Services/Data/Targets/WidgetTransactionsDataTarget.swift @@ -8,27 +8,21 @@ import Foundation import Moya -import WavesSDKCrypto +import WavesSDK -extension API.Service { +extension WidgetDataService.Target { struct Transactions { enum Kind { - - /** - Response: - - API.Response<[API.Response.self - */ - case getExchange(id: String) - case getExchangeWithFilters(API.Query.ExchangeFilters) + case getExchangeWithFilters(DataService.Query.ExchangeFilters) } let kind: Kind - let environment: Environment + let dataUrl: URL } } -extension API.Service.Transactions: ApiTargetType { +extension WidgetDataService.Target.Transactions: WidgetDataTargetType { private enum Constants { static let exchange = "transactions/exchange" @@ -36,8 +30,6 @@ extension API.Service.Transactions: ApiTargetType { var path: String { switch kind { - case .getExchange(let id): - return Constants.exchange + "/\(id)".urlEscaped case .getExchangeWithFilters: return Constants.exchange @@ -46,16 +38,13 @@ extension API.Service.Transactions: ApiTargetType { var method: Moya.Method { switch kind { - case .getExchange, .getExchangeWithFilters: + case .getExchangeWithFilters: return .get } } var task: Task { switch kind { - case .getExchange: - return .requestPlain - case .getExchangeWithFilters(let filter): return .requestParameters(parameters: filter.dictionary, encoding: URLEncoding.default) } diff --git a/MarketPulseWidget/Sources/Services/Data/WidgetDataServiceTypes.swift b/MarketPulseWidget/Sources/Services/Data/WidgetDataServiceTypes.swift new file mode 100644 index 00000000..70b85ee4 --- /dev/null +++ b/MarketPulseWidget/Sources/Services/Data/WidgetDataServiceTypes.swift @@ -0,0 +1,40 @@ +// +// WidgetDataService.swift +// MarketPulseWidget +// +// Created by Pavel Gubin on 28.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import Moya +import WavesSDK + +enum WidgetDataService {} + +extension WidgetDataService { + internal enum Target {} + enum DTO {} + enum Query {} +} + +protocol WidgetDataTargetType: TargetType { + var dataUrl: URL { get } +} + +extension WidgetDataTargetType { + + private var dataVersion: String { + return "/v0" + } + + var baseURL: URL { return URL(string: "\(dataUrl.relativeString)\(dataVersion)")! } + + var sampleData: Data { + return Data() + } + + var headers: [String: String]? { + return ContentType.applicationJson.headers + } +} diff --git a/MarketPulseWidget/Sources/Services/InternalWidgetService.swift b/MarketPulseWidget/Sources/Services/InternalWidgetService.swift new file mode 100644 index 00000000..b3f3ffb3 --- /dev/null +++ b/MarketPulseWidget/Sources/Services/InternalWidgetService.swift @@ -0,0 +1,38 @@ +// +// InternalWidgetService.swift +// MarketPulseWidget +// +// Created by Pavel Gubin on 28.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import DomainLayer +import Moya + +protocol InternalWidgetServiceProtocol { + var dataUrl: URL { get } + var matcherUrl: URL { get } +} + +internal class InternalWidgetService: InternalWidgetServiceProtocol { + + static var shared = InternalWidgetService() + + var dataUrl: URL { + return WalletEnvironment.Mainnet.servers.dataUrl + } + + var matcherUrl: URL { + return WalletEnvironment.Mainnet.servers.matcherUrl + } +} + +extension InternalWidgetService { + + static func moyaProvider() -> MoyaProvider { + return MoyaProvider(callbackQueue: nil, + plugins: []) + } +} + diff --git a/MarketPulseWidget/Sources/Services/Matcher/Services/WidgetMatcherSettingService.swift b/MarketPulseWidget/Sources/Services/Matcher/Services/WidgetMatcherSettingService.swift new file mode 100644 index 00000000..0e44259c --- /dev/null +++ b/MarketPulseWidget/Sources/Services/Matcher/Services/WidgetMatcherSettingService.swift @@ -0,0 +1,36 @@ +// +// WidgetMatcherSettingService.swift +// MarketPulseWidget +// +// Created by Pavel Gubin on 28.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import WavesSDK +import Moya + +protocol WidgetMatcherSettingServiceProtocol { + func settings() -> Observable +} + +final class WidgetMatcherSettingService: WidgetMatcherSettingServiceProtocol { + + private let settingsProvider: MoyaProvider = InternalWidgetService.moyaProvider() + + func settings() -> Observable { + + return settingsProvider + .rx + .request(.init(kind: .settings, + matcherUrl: InternalWidgetService.shared.matcherUrl), + callbackQueue: DispatchQueue.global(qos: .userInteractive)) + .filterSuccessfulStatusAndRedirectCodes() + .catchError({ (error) -> Single in + return Single.error(NetworkError.error(by: error)) + }) + .asObservable() + .map(MatcherService.DTO.Setting.self) + } +} diff --git a/MarketPulseWidget/Sources/Services/Matcher/Services/WidgetPublicKeyMatcherService.swift b/MarketPulseWidget/Sources/Services/Matcher/Services/WidgetPublicKeyMatcherService.swift new file mode 100644 index 00000000..016e68ae --- /dev/null +++ b/MarketPulseWidget/Sources/Services/Matcher/Services/WidgetPublicKeyMatcherService.swift @@ -0,0 +1,41 @@ +// +// PublicKeyMatcherService.swift +// Alamofire +// +// Created by rprokofev on 06/05/2019. +// + +import Foundation +import RxSwift +import Moya +import WavesSDK + +final class WidgetPublicKeyMatcherService: PublicKeyMatcherServiceProtocol { + + private let publicKeyProvider: MoyaProvider = InternalWidgetService.moyaProvider() + + func publicKey() -> Observable { + + return self + .publicKeyProvider + .rx + .request(.init(matcherUrl: InternalWidgetService.shared.matcherUrl), + callbackQueue: DispatchQueue.global(qos: .userInteractive)) + .filterSuccessfulStatusAndRedirectCodes() + .catchError({ (error) -> Single in + return Single.error(NetworkError.error(by: error)) + }) + .flatMap({ (response) -> Single in + + do { + guard let key = try JSONSerialization.jsonObject(with: response.data, options: .allowFragments) as? String else { + return Single.error(NetworkError.none) + } + return Single.just(key) + } catch let error { + return Single.error(error) + } + }) + .asObservable() + } +} diff --git a/WavesWallet-iOS/DataLayer/Service/Matcher/MatcherService.swift b/MarketPulseWidget/Sources/Services/Matcher/Targets/WidgetPublicKeyMatcherTarget.swift similarity index 58% rename from WavesWallet-iOS/DataLayer/Service/Matcher/MatcherService.swift rename to MarketPulseWidget/Sources/Services/Matcher/Targets/WidgetPublicKeyMatcherTarget.swift index 705eebd2..caffbf7f 100644 --- a/WavesWallet-iOS/DataLayer/Service/Matcher/MatcherService.swift +++ b/MarketPulseWidget/Sources/Services/Matcher/Targets/WidgetPublicKeyMatcherTarget.swift @@ -8,18 +8,22 @@ import Foundation import Moya -import WavesSDKCrypto -extension Matcher.Service { +extension WidgetMatcherService.Target { struct MatcherPublicKey { - var environment: Environment + var matcherUrl: URL } } -extension Matcher.Service.MatcherPublicKey: MatcherTargetType { +extension WidgetMatcherService.Target.MatcherPublicKey: WidgetMatcherTargetType { + + private enum Constants { + static let matcher: String = "matcher" + } + var path: String { - return "matcher" + return Constants.matcher } var method: Moya.Method { diff --git a/MarketPulseWidget/Sources/Services/Matcher/Targets/WidgetSettingsMarcherTarget.swift b/MarketPulseWidget/Sources/Services/Matcher/Targets/WidgetSettingsMarcherTarget.swift new file mode 100644 index 00000000..f0ddd3b0 --- /dev/null +++ b/MarketPulseWidget/Sources/Services/Matcher/Targets/WidgetSettingsMarcherTarget.swift @@ -0,0 +1,52 @@ +// +// WidgetSettingsMarcherTarget.swift +// MarketPulseWidget +// +// Created by Pavel Gubin on 28.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import Moya +import WavesSDK + +extension WidgetMatcherService.Target { + + struct Settings { + + enum Kind { + case settings + } + + var kind: Kind + var matcherUrl: URL + } +} + +extension WidgetMatcherService.Target.Settings: WidgetMatcherTargetType { + + fileprivate enum Constants { + static let matcher = "matcher" + static let settings = "settings" + } + + var path: String { + switch kind { + + case .settings: + return Constants.matcher + "/" + Constants.settings + } + } + + var method: Moya.Method { + return .get + } + + var task: Task { + return .requestPlain + } + + var headers: [String: String]? { + return ContentType.applicationJson.headers + } +} diff --git a/MarketPulseWidget/Sources/Services/Matcher/WidgetMatcherServiceTypes.swift b/MarketPulseWidget/Sources/Services/Matcher/WidgetMatcherServiceTypes.swift new file mode 100644 index 00000000..8c9a131a --- /dev/null +++ b/MarketPulseWidget/Sources/Services/Matcher/WidgetMatcherServiceTypes.swift @@ -0,0 +1,36 @@ +// +// MatcherServiceTypes.swift +// WavesWallet-iOS +// +// Created by mefilt on 20.07.2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import Moya +import WavesSDK + +enum WidgetMatcherService {} + +extension WidgetMatcherService { + enum DTO {} + enum Query {} + internal enum Target {} +} + +protocol WidgetMatcherTargetType: TargetType { + var matcherUrl: URL { get } +} + +extension WidgetMatcherTargetType { + + var baseURL: URL { return matcherUrl } + + var sampleData: Data { + return Data() + } + + var headers: [String: String]? { + return ContentType.applicationJson.headers + } +} diff --git a/MarketPulseWidget/Sources/Views/MarketPulseWidgetCell.swift b/MarketPulseWidget/Sources/Views/MarketPulseWidgetCell.swift new file mode 100644 index 00000000..28a3c188 --- /dev/null +++ b/MarketPulseWidget/Sources/Views/MarketPulseWidgetCell.swift @@ -0,0 +1,137 @@ +// +// MarketPulseWidgetCell.swift +// MarketPulseWidget +// +// Created by Pavel Gubin on 24.07.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import UIKit +import RxSwift +import Extensions + +private enum Constants { + static let height: CGFloat = 38 + + static let redTickerColor: UIColor = .error500 + static let greenTickerColor: UIColor = .successLime + static let tickerRightOffsetDefault: CGFloat = 10 + static let tickerRightOffsetDark: CGFloat = 4 +} + +final class MarketPulseWidgetCell: UITableViewCell, Reusable { + + @IBOutlet private weak var iconLogo: UIImageView! + @IBOutlet private weak var labelTitle: UILabel! + @IBOutlet private weak var labelPercent: UILabel! + @IBOutlet private weak var viewTicker: UIView! + @IBOutlet private weak var labelPrice: UILabel! + @IBOutlet private weak var tickerRightOffset: NSLayoutConstraint! + + private var disposeBag: DisposeBag = DisposeBag() + + + private static let numberFormatter: NumberFormatter = { + let numberFormatter = NumberFormatter() + numberFormatter.numberStyle = .decimal + numberFormatter.decimalSeparator = "." + numberFormatter.usesGroupingSeparator = true + numberFormatter.groupingSeparator = " " + numberFormatter.minimumFractionDigits = 2 + numberFormatter.maximumFractionDigits = 2 + return numberFormatter + }() + + override func prepareForReuse() { + super.prepareForReuse() + iconLogo.image = nil + disposeBag = DisposeBag() + } +} + +extension MarketPulseWidgetCell: ViewConfiguration { + + func update(with model: MarketPulse.DTO.UIAsset) { + + AssetLogo.logo(icon: model.icon, + style: .litle) + .observeOn(MainScheduler.instance) + .bind(to: iconLogo.rx.image) + .disposed(by: disposeBag) + + labelTitle.text = model.name + + let numberFormatter = MarketPulseWidgetCell.numberFormatter + let price = model.currency.ticker + (numberFormatter.string(from: NSNumber(value: model.price)) ?? "") + + let attr = NSMutableAttributedString(string: price, attributes: [NSAttributedString.Key.font : UIFont.systemFont(ofSize: 14)]) + + let separatorRange = (price as NSString).range(of: numberFormatter.decimalSeparator) + attr.addAttributes([NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16, weight: .semibold)], + range: NSMakeRange(0, separatorRange.location)) + + labelPrice.attributedText = attr + + if model.percent == 0 { + labelPercent.text = String(format: "%.0f", model.percent) + "%" + } + else if model.percent > 0 { + labelPercent.text = "+" + String(format: "%.02f", model.percent) + "%" + } + else { + labelPercent.text = "-" + String(format: "%.02f", model.percent * -1) + "%" + } + + tickerRightOffset.constant = model.isDarkMode ? Constants.tickerRightOffsetDark : Constants.tickerRightOffsetDefault + + labelTitle.textColor = model.isDarkMode ? .white : .black + labelPrice.textColor = model.isDarkMode ? .white : .black + + if model.isDarkMode { + viewTicker.backgroundColor = .clear + + if model.percent == 0 { + labelPercent.textColor = .disabled700 + } + else if model.percent > 0 { + labelPercent.textColor = Constants.greenTickerColor + } + else { + labelPercent.textColor = Constants.redTickerColor + } + } + else { + labelPercent.textColor = .white + + if model.percent == 0 { + viewTicker.backgroundColor = .basic700 + } + else if model.percent > 0 { + viewTicker.backgroundColor = Constants.greenTickerColor + } + else { + viewTicker.backgroundColor = Constants.redTickerColor + } + } + } + +} + +extension MarketPulseWidgetCell: ViewHeight { + static func viewHeight() -> CGFloat { + return Constants.height + } +} + +extension AssetLogo.Style { + + static var litle: AssetLogo.Style = { + return AssetLogo.Style.init(size: CGSize(width: 20, height: 20), + font: UIFont.systemFont(ofSize: 13), + specs: .init(sponsoredImage: Images.sponsoritem18White.image, + scriptImage: Images.scriptasset18White.image, + size: CGSize(width: 8, + height: 8))) + }() +} + diff --git a/MarketPulseWidget/Sources/WidgetAnalyticManager.swift b/MarketPulseWidget/Sources/WidgetAnalyticManager.swift new file mode 100644 index 00000000..9229c0bb --- /dev/null +++ b/MarketPulseWidget/Sources/WidgetAnalyticManager.swift @@ -0,0 +1,63 @@ +// +// WidgetAnalyticManager.swift +// MarketPulseWidget +// +// Created by Pavel Gubin on 29.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import DomainLayer +import Amplitude_iOS +//import FirebaseCore +//import FirebaseAnalytics +import AppsFlyerLib + +final class WidgetAnalyticManagerInitialization { + + struct Resources { + + typealias PathForFile = String + + let googleServiceInfo: PathForFile + let appsflyerInfo: PathForFile + let amplitudeInfo: PathForFile + } + + + static func setup(resources: Resources) { + + //TODO: Add FireBase analytics + +// if let options = FirebaseOptions(contentsOfFile: resources.googleServiceInfo) { +// FirebaseApp.configure(options: options) +// } + + if let root = NSDictionary(contentsOfFile: resources.appsflyerInfo)?["Appsflyer"] as? NSDictionary { + if let devKey = root["AppsFlyerDevKey"] as? String, + let appId = root["AppleAppID"] as? String { + AppsFlyerTracker.shared().appsFlyerDevKey = devKey + AppsFlyerTracker.shared().appleAppID = appId + } + } + + if let apiKey = NSDictionary(contentsOfFile: resources.amplitudeInfo)?["API_KEY"] as? String { + Amplitude.instance()?.initializeApiKey(apiKey) + Amplitude.instance()?.setDeviceId(UIDevice.uuid) + } + } +} + + +final class WidgetAnalyticManager: AnalyticManagerProtocol { + + static let shared = WidgetAnalyticManager() + + func setAUUID(_ AUUID: String) {} + + func trackEvent(_ event: AnalyticManagerEvent) { + Amplitude.instance().logEvent(event.name, withEventProperties: event.params) +// Analytics.logEvent(event.name.replacingOccurrences(of: " ", with: "_"), parameters: event.params) + AppsFlyerTracker.shared()?.trackEvent(event.name, withValues: event.params) + } +} diff --git a/MarketPulseWidget/Sources/WidgetSettings.swift b/MarketPulseWidget/Sources/WidgetSettings.swift new file mode 100644 index 00000000..5a2ef068 --- /dev/null +++ b/MarketPulseWidget/Sources/WidgetSettings.swift @@ -0,0 +1,58 @@ +// +// WidgetSettings.swift +// MarketPulseWidget +// +// Created by Pavel Gubin on 01.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import Extensions +import RxSwift +import WavesSDKExtensions +import DomainLayer + +extension WidgetSettings: ReactiveCompatible {} + +struct WidgetSettings: TSUD, Codable, Mutating { + + static let environment = WalletEnvironment.Mainnet + + private static let key = "com.waves.widget.settings.currency" + + init() {} + + var currency: String = "" + + init(currency: String) { + self.currency = currency + } + + static var defaultValue: WidgetSettings { + return WidgetSettings(currency: MarketPulse.Currency.usd.rawValue) + } + + static var stringKey: String { + return key + } + + static func setCurrency(currency: MarketPulse.Currency) { + var settings = WidgetSettings.get() + settings.currency = currency.rawValue + WidgetSettings.set(settings) + } +} + +extension Reactive where Base == WidgetSettings { + + static func currency() -> Observable { + return WidgetSettings.rx.get().flatMap({ (settings) -> Observable in + + guard let currency = MarketPulse.Currency(rawValue: settings.currency) else { + return Observable.empty() + } + return Observable.just(currency) + }) + } +} + diff --git a/MarketPulseWidget/Sources/WidgetSettingsInizialization.swift b/MarketPulseWidget/Sources/WidgetSettingsInizialization.swift new file mode 100644 index 00000000..083e0368 --- /dev/null +++ b/MarketPulseWidget/Sources/WidgetSettingsInizialization.swift @@ -0,0 +1,100 @@ +// +// WidgetSettingsInizialization.swift +// MarketPulseWidget +// +// Created by Pavel Gubin on 27.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import DomainLayer +import RxSwift +import WavesSDK +import WavesSDKCrypto + + +class WidgetSettingsInizialization: WidgetSettingsInizializationUseCaseProtocol { + + private let widgetSettingsStorage: WidgetSettingsRepositoryProtocol = WidgetSettingsRepositoryStorage() + private let matcherRepository: MatcherRepositoryProtocol = MatcherRepositoryLocal(matcherRepositoryRemote: WidgetMatcherRepositoryRemote()) + private let pairsPriceRepository: WidgetPairsPriceRepositoryProtocol = WidgetPairsPriceRepositoryRemote() + private let assetsRepository: WidgetAssetsRepositoryProtocol = WidgetAssetsRepositoryRemote() + + func settings() -> Observable { + + return widgetSettingsStorage + .settings() + .flatMap({ [weak self] settings -> Observable in + + guard let self = self else { return Observable.never() } + + if let settings = settings { + return Observable.just(settings) + } + + return self.initial() + }) + } + + private func initial() -> Observable { + + let assets = WidgetSettings.environment.generalAssets.prefix(DomainLayer.DTO.Widget.defaultCountAssets) + + return assetsRepository.assets(by: assets.map { $0.assetId }) + .flatMap({ [weak self] (assets) -> Observable in + guard let self = self else { return Observable.never() } + + return self + .correction(pairs: assets.map { DomainLayer.DTO.CorrectionPairs.Pair.init(amountAsset: $0.id, + priceAsset: WavesSDKConstants.wavesAssetId) }) + .flatMap({ (pairsAfterCorrection) -> Observable<[DomainLayer.DTO.CorrectionPairs.Pair]> in + + + //TODO: Remove + return self.pairsPriceRepository + .searchPairs(.init(kind: .pairs(pairsAfterCorrection.map { .init(amountAsset: $0.amountAsset, + priceAsset: $0.priceAsset) }))) + .map({ (pairs) -> [DomainLayer.DTO.CorrectionPairs.Pair] in + + return pairsAfterCorrection + }) + + }) + .map({ (pairs) -> DomainLayer.DTO.MarketPulseSettings in + + let marketPulseAssets: [DomainLayer.DTO.MarketPulseSettings.Asset] = assets.enumerated() + .map({ (element) -> DomainLayer.DTO.MarketPulseSettings.Asset in + + let asset = element.element + let pair = pairs[element.offset] + + return .init(id: asset.id, + name: asset.displayName, + icon: asset.iconLogo, + amountAsset: pair.amountAsset, + priceAsset: pair.priceAsset) + + }) + return DomainLayer.DTO.MarketPulseSettings(isDarkStyle: false, + interval: .m10, + assets: marketPulseAssets) + }) + }) + } +} + +private extension WidgetSettingsInizialization { + func correction(pairs: [DomainLayer.DTO.CorrectionPairs.Pair]) -> Observable<[DomainLayer.DTO.CorrectionPairs.Pair]> { + let pairs = matcherRepository + .settingsIdsPairs() + .flatMap { (pricePairs) -> Observable<[DomainLayer.DTO.CorrectionPairs.Pair]> in + + let result = CorrectionPairsUseCaseLogic.mapCorrectPairs(settingsIdsPairs: pricePairs, pairs: pairs) + + return Observable.just(result) + } + + return pairs + + } +} diff --git a/MonkeyTest/Info.plist b/MonkeyTest/Info.plist index be9719a5..a776b05a 100644 --- a/MonkeyTest/Info.plist +++ b/MonkeyTest/Info.plist @@ -17,6 +17,6 @@ CFBundleShortVersionString 1.0 CFBundleVersion - 3847 + 3901 diff --git a/MonkeyTest/MonkeyTest.swift b/MonkeyTest/MonkeyTest.swift index ff00061a..967fb15e 100644 --- a/MonkeyTest/MonkeyTest.swift +++ b/MonkeyTest/MonkeyTest.swift @@ -34,7 +34,7 @@ final class MonkeyTest: XCTestCase { // Workaround for bug in Xcode 7.3. Snapshots are not properly updated // when you initially call app.frame, resulting in a zero-sized rect. // Doing a random query seems to update everything properly. - // TODO: Remove this when the Xcode bug is fixed! + //TODO: Remove this when the Xcode bug is fixed! _ = application.descendants(matching: .any).element(boundBy: 0).frame // Initialise the monkey tester with the current device diff --git a/Podfile b/Podfile index 1a308d63..f6140727 100644 --- a/Podfile +++ b/Podfile @@ -1,12 +1,11 @@ -source 'https://github.com/wavesplatform/Specs.git' -source 'https://github.com/CocoaPods/Specs.git' - # Uncomment the next line to define a global platform for your project platform :ios, '11.0' # Ignore all warnings from all pods inhibit_all_warnings! +install! 'cocoapods', :disable_input_output_paths => true + use_frameworks!(true) # Enable the stricter search paths and module map generation for all pods @@ -17,16 +16,22 @@ target 'MonkeyTest' do pod 'SwiftMonkey' end +workspace 'WavesWallet-iOS.xcworkspace' +project 'Vendors/WavesSDK/WavesSDK.xcodeproj' +project 'WavesWallet-iOS.xcodeproj' + # Pods for WavesWallet-iOS target 'WavesWallet-iOS' do + # inherit! :search_paths - inherit! :search_paths - + project 'WavesWallet-iOS.xcodeproj' + # UI pod 'RxCocoa' - pod 'TTTAttributedLabel' + pod 'TTTAttributedLabel' pod 'UITextView+Placeholder' + pod 'Down' pod 'SwipeView' pod 'MGSwipeTableCell' @@ -48,68 +53,230 @@ target 'WavesWallet-iOS' do pod 'RxOptional' pod 'RxGesture' pod 'RxFeedback' - pod 'RxReachability' + pod 'IdentityImg', :git => 'https://github.com/wavesplatform/identity-img-swift.git' + pod 'QRCode' + pod 'QRCodeReader.swift', '~> 9.0.1' + pod 'SwiftDate' + pod 'Kingfisher' + + # Code Gen + pod 'SwiftGen', '~> 5.3.0' + + # Debug + # pod 'Reveal-SDK', :configurations => ['Debug'] + pod 'AppSpectorSDK', :configurations => ['dev-debug', 'dev-adhoc', 'test-dev', 'test-prod'] + pod 'SwiftMonkeyPaws', :configurations => ['dev-debug', 'dev-adhoc'] + + # pod 'Sentry', :git => 'https://github.com/getsentry/sentry-cocoa.git' +end + + +target 'MarketPulseWidget' do + project 'WavesWallet-iOS.xcodeproj' + + pod 'RxSwift' + pod 'RxSwiftExt' + pod 'RxOptional' + pod 'RxFeedback' + pod 'RxCocoa' + pod 'Moya' + pod 'Moya/RxSwift' + pod 'RealmSwift' + pod 'RxRealm' + + pod 'Kingfisher' + + pod 'Amplitude-iOS' + pod 'AppsFlyerFramework' + +end + +target 'DataLayer' do + inherit! :search_paths + project 'WavesWallet-iOS.xcodeproj' + # External Service pod 'Firebase/Core' pod 'Firebase/Database' pod 'Firebase/Auth' + pod 'Firebase' pod 'Firebase/InAppMessagingDisplay' - - pod 'Amplitude-iOS' + pod 'Firebase/Analytics' + pod 'Firebase/Messaging' pod 'AppsFlyerFramework' + pod 'Fabric' + pod 'Crashlytics' + pod 'Amplitude-iOS' + pod 'Sentry' - # Helperrs - pod 'IdentityImg' + # DB + pod 'RealmSwift' + pod 'RxRealm' - pod 'WavesSDKExtension', '~> 0.1.3' - pod 'WavesSDKCrypto', '~> 0.1.3' + # Assisstant + pod 'RxSwift' + pod 'RxSwiftExt' + pod 'RxOptional' + pod 'CSV.swift' + pod 'CryptoSwift' + pod 'DeviceKit' pod 'KeychainAccess' - pod 'QRCode' - pod 'QRCodeReader.swift', '~> 9.0.1' - pod 'SwiftDate' - pod 'DeviceKit', '~> 1.3' - - # Cache & Download Images - pod 'Kingfisher' + + pod 'RxSwift' + pod 'Moya' + pod 'Moya/RxSwift' +end + +target 'DomainLayer' do + # inherit! :search_paths + project 'WavesWallet-iOS.xcodeproj' # DB pod 'RealmSwift' pod 'RxRealm' - # Network - pod 'RxAlamofire' - pod 'Moya/RxSwift' + # Assisstant + pod 'RxSwift' + pod 'RxSwiftExt' + pod 'RxOptional' + pod 'RxReachability' + + pod 'KeychainAccess' + + pod 'CryptoSwift' +end - # Parser - pod 'CSV.swift' +target 'Extensions' do + # inherit! :search_paths + project 'WavesWallet-iOS.xcodeproj' - # Gen - pod 'SwiftGen', '~> 5.3.0' + # Assisstant + pod 'RxSwift' + pod 'RxSwiftExt' + pod 'RxOptional' + pod 'DeviceKit' + pod 'RxFeedback' + pod 'RxReachability' + pod 'Kingfisher' - # Debug - # pod 'Reveal-SDK', :configurations => ['Debug'] - pod 'AppSpectorSDK', :configurations => ['Debug', 'Test'] +end - pod 'SwiftMonkeyPaws', :configurations => ['Debug'] - - pod 'Sentry', :git => 'https://github.com/getsentry/sentry-cocoa.git' - pod 'Fabric' - pod 'Crashlytics' +target 'DomainLayerTests' do + project 'WavesWallet-iOS.xcodeproj' + inherit! :search_paths end -post_install do |installer| +target 'DataLayerTests' do + project 'WavesWallet-iOS.xcodeproj' +end + +target 'WavesSDK' do + project 'Vendors/WavesSDK/WavesSDK.xcodeproj' + pod 'RxSwift' + pod 'Moya' + pod 'Moya/RxSwift' +end - installer.pods_project.targets.each do |target| - +target 'WavesSDKExtensions' do + project 'Vendors/WavesSDK/WavesSDK.xcodeproj' + pod 'RxSwift' + pod 'Moya' + pod 'Moya/RxSwift' +end + +target 'WavesSDKCrypto' do + project 'Vendors/WavesSDK/WavesSDK.xcodeproj' + pod 'RxSwift' + pod 'Moya' + pod 'Moya/RxSwift' +end + +post_install do |installer| + + installer.pods_project.targets.each do |target| target.build_configurations.each do |config| config.build_settings['GCC_WARN_INHIBIT_ALL_WARNINGS'] = "YES" - config.build_settings['SWIFT_VERSION'] = '4.2' end + end + + remove_static_framework_duplicate_linkage({ + 'DataLayer' => ['Fabric', 'Crashlytics', + 'AppsFlyerFramework', + 'Amplitude-iOS', + 'Amplitude_iOS', + 'FirebaseCore', + 'FirebaseDatabase', + 'FirebaseAuth', + 'FIRAnalyticsConnector', + 'FirebaseAnalytics', + 'FirebaseCoreDiagnostics', + 'FirebaseInstanceID', + 'FirebaseInAppMessaging', + 'GoogleAppMeasurement', + 'GTMSessionFetcher', + 'GoogleUtilities'] + }) + +end + +## This code take from https://github.com/CocoaPods/CocoaPods/issues/7155#issuecomment-461395735 +PROJECT_ROOT_DIR = File.dirname(File.expand_path(__FILE__)) +PODS_DIR = File.join(PROJECT_ROOT_DIR, 'Pods') +PODS_TARGET_SUPPORT_FILES_DIR = File.join(PODS_DIR, 'Target Support Files') + +# CocoaPods provides the abstract_target mechanism for sharing dependencies between distinct targets. +# However, due to the complexity of our project and use of shared frameworks, we cannot simply bundle everything under +# a single abstract_target. Using a pod in a shared framework target and an app target will cause CocoaPods to generate +# a build configuration that links the pod's frameworks with both targets. This is not an issue with dynamic frameworks, +# as the linker is smart enough to avoid duplicate linkage at runtime. Yet for static frameworks the linkage happens at +# build time, thus when the shared framework target and app target are combined to form an executable, the static +# framework will reside within multiple distinct address spaces. The end result is duplicated symbols, and global +# variables that are confined to each target's address space, i.e not truly global within the app's address space. +# +# Previously we avoided this by linking the static framework with a single target using an abstract_target, and then +# provided a shim to expose their interfaces to other targets. The new approach implemented here removes the need for +# shim by modifying the build configuration generated by CocoaPods to restrict linkage to a single target. +def remove_static_framework_duplicate_linkage(static_framework_pods) + puts "Removing duplicate linkage of static frameworks" + + Dir.glob(File.join(PODS_TARGET_SUPPORT_FILES_DIR, "Pods-*")).each do |path| + pod_target = path.split('-', -1).last + + static_framework_pods.each do |target, pods| + next if pod_target == target + frameworks = pods.map { |pod| identify_frameworks(pod) }.flatten + + Dir.glob(File.join(path, "*.xcconfig")).each do |xcconfig| + lines = File.readlines(xcconfig) + + if other_ldflags_index = lines.find_index { |l| l.start_with?('OTHER_LDFLAGS') } + other_ldflags = lines[other_ldflags_index] + + frameworks.each do |framework| + other_ldflags.gsub!("-framework \"#{framework}\"", '') + end + + File.open(xcconfig, 'w') do |fd| + fd.write(lines.join) + end + end + end end + end +end + +def identify_frameworks(pod) + frameworks = Dir.glob(File.join(PODS_DIR, pod, "**/*.framework")).map { |path| File.basename(path) } + + if frameworks.any? + return frameworks.map { |f| f.split('.framework').first } + end + + return pod end diff --git a/Podfile.lock b/Podfile.lock index 75763a9d..888f1e63 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,140 +1,164 @@ PODS: - - Alamofire (4.8.1) + - Alamofire (4.8.2) - Amplitude-iOS (4.6.0) - - AppsFlyerFramework (4.9.0) - - AppSpectorSDK (1.1.7) - - Base58 (0.3) - - Blake2 (0.1) - - Charts (3.2.2): - - Charts/Core (= 3.2.2) - - Charts/Core (3.2.2) - - Crashlytics (3.12.0): - - Fabric (~> 1.9.0) + - AppsFlyerFramework (4.10.2) + - AppSpectorSDK (1.2.2) + - Charts (3.3.0): + - Charts/Core (= 3.3.0) + - Charts/Core (3.3.0) + - Crashlytics (3.13.4): + - Fabric (~> 1.10.2) - CryptoSwift (1.0.0) - - CSV.swift (2.3.1) - - Curve25519 (2.0.3) - - DeviceKit (1.12.0) - - Fabric (1.9.0) - - Firebase/Auth (5.20.2): + - CSV.swift (2.4.2) + - DeviceKit (2.3.0) + - Down (0.9.0) + - Fabric (1.10.2) + - Firebase (6.12.0): + - Firebase/Core (= 6.12.0) + - Firebase/Analytics (6.12.0): + - Firebase/Core + - Firebase/Auth (6.12.0): - Firebase/CoreOnly - - FirebaseAuth (= 5.4.2) - - Firebase/Core (5.20.2): + - FirebaseAuth (~> 6.3.1) + - Firebase/Core (6.12.0): - Firebase/CoreOnly - - FirebaseAnalytics (= 5.8.1) - - Firebase/CoreOnly (5.20.2): - - FirebaseCore (= 5.4.1) - - Firebase/Database (5.20.2): + - FirebaseAnalytics (= 6.1.5) + - Firebase/CoreOnly (6.12.0): + - FirebaseCore (= 6.3.3) + - Firebase/Database (6.12.0): - Firebase/CoreOnly - - FirebaseDatabase (= 5.1.1) - - Firebase/InAppMessagingDisplay (5.20.2): + - FirebaseDatabase (~> 6.1.2) + - Firebase/InAppMessagingDisplay (6.12.0): - Firebase/CoreOnly - - FirebaseInAppMessagingDisplay (= 0.13.1) - - FirebaseAnalytics (5.8.1): - - FirebaseCore (~> 5.4) - - FirebaseInstanceID (~> 3.8) - - GoogleAppMeasurement (= 5.8.1) - - GoogleUtilities/AppDelegateSwizzler (~> 5.2) - - GoogleUtilities/MethodSwizzler (~> 5.2) - - GoogleUtilities/Network (~> 5.2) - - "GoogleUtilities/NSData+zlib (~> 5.2)" - - nanopb (~> 0.3) - - FirebaseAnalyticsInterop (1.2.0) - - FirebaseAuth (5.4.2): + - FirebaseInAppMessagingDisplay (~> 0.15.5) + - Firebase/Messaging (6.12.0): + - Firebase/CoreOnly + - FirebaseMessaging (~> 4.1.8) + - FirebaseAnalytics (6.1.5): + - FirebaseCore (~> 6.3) + - FirebaseInstanceID (~> 4.2) + - GoogleAppMeasurement (= 6.1.5) + - GoogleUtilities/AppDelegateSwizzler (~> 6.0) + - GoogleUtilities/MethodSwizzler (~> 6.0) + - GoogleUtilities/Network (~> 6.0) + - "GoogleUtilities/NSData+zlib (~> 6.0)" + - nanopb (= 0.3.9011) + - FirebaseAnalyticsInterop (1.4.0) + - FirebaseAuth (6.3.1): - FirebaseAuthInterop (~> 1.0) - - FirebaseCore (~> 5.2) - - GoogleUtilities/Environment (~> 5.2) + - FirebaseCore (~> 6.2) + - GoogleUtilities/AppDelegateSwizzler (~> 6.2) + - GoogleUtilities/Environment (~> 6.2) - GTMSessionFetcher/Core (~> 1.1) - FirebaseAuthInterop (1.0.0) - - FirebaseCore (5.4.1): - - GoogleUtilities/Environment (~> 5.2) - - GoogleUtilities/Logger (~> 5.2) - - FirebaseDatabase (5.1.1): + - FirebaseCore (6.3.3): + - FirebaseCoreDiagnostics (~> 1.0) + - FirebaseCoreDiagnosticsInterop (~> 1.0) + - GoogleUtilities/Environment (~> 6.2) + - GoogleUtilities/Logger (~> 6.2) + - FirebaseCoreDiagnostics (1.1.1): + - FirebaseCoreDiagnosticsInterop (~> 1.0) + - GoogleDataTransportCCTSupport (~> 1.0) + - GoogleUtilities/Environment (~> 6.2) + - GoogleUtilities/Logger (~> 6.2) + - nanopb (~> 0.3.901) + - FirebaseCoreDiagnosticsInterop (1.1.0) + - FirebaseDatabase (6.1.2): - FirebaseAuthInterop (~> 1.0) - - FirebaseCore (~> 5.2) - - leveldb-library (~> 1.18) - - FirebaseInAppMessaging (0.13.0): - - FirebaseAnalytics - - FirebaseAnalyticsInterop - - FirebaseCore - - FirebaseInstanceID - - FirebaseInAppMessagingDisplay (0.13.1): - - FirebaseCore - - FirebaseInAppMessaging (>= 0.12.0) - - FirebaseInstanceID (3.8.1): - - FirebaseCore (~> 5.2) - - GoogleUtilities/Environment (~> 5.2) - - GoogleUtilities/UserDefaults (~> 5.2) - - GoogleAppMeasurement (5.8.1): - - GoogleUtilities/AppDelegateSwizzler (~> 5.2) - - GoogleUtilities/MethodSwizzler (~> 5.2) - - GoogleUtilities/Network (~> 5.2) - - "GoogleUtilities/NSData+zlib (~> 5.2)" - - nanopb (~> 0.3) - - GoogleUtilities/AppDelegateSwizzler (5.7.0): + - FirebaseCore (~> 6.0) + - leveldb-library (~> 1.22) + - FirebaseInAppMessaging (0.15.5): + - FirebaseAnalyticsInterop (~> 1.3) + - FirebaseCore (~> 6.2) + - FirebaseInstanceID (~> 4.0) + - GoogleDataTransportCCTSupport (~> 1.0) + - FirebaseInAppMessagingDisplay (0.15.5): + - FirebaseCore (~> 6.2) + - FirebaseInAppMessaging (>= 0.15.0) + - FirebaseInstanceID (4.2.7): + - FirebaseCore (~> 6.0) + - GoogleUtilities/Environment (~> 6.0) + - GoogleUtilities/UserDefaults (~> 6.0) + - FirebaseMessaging (4.1.8): + - FirebaseAnalyticsInterop (~> 1.3) + - FirebaseCore (~> 6.2) + - FirebaseInstanceID (~> 4.1) + - GoogleUtilities/AppDelegateSwizzler (~> 6.2) + - GoogleUtilities/Environment (~> 6.2) + - GoogleUtilities/Reachability (~> 6.2) + - GoogleUtilities/UserDefaults (~> 6.2) + - Protobuf (>= 3.9.2, ~> 3.9) + - GoogleAppMeasurement (6.1.5): + - GoogleUtilities/AppDelegateSwizzler (~> 6.0) + - GoogleUtilities/MethodSwizzler (~> 6.0) + - GoogleUtilities/Network (~> 6.0) + - "GoogleUtilities/NSData+zlib (~> 6.0)" + - nanopb (= 0.3.9011) + - GoogleDataTransport (3.0.1) + - GoogleDataTransportCCTSupport (1.2.1): + - GoogleDataTransport (~> 3.0) + - nanopb (~> 0.3.901) + - GoogleUtilities/AppDelegateSwizzler (6.3.1): - GoogleUtilities/Environment - GoogleUtilities/Logger - GoogleUtilities/Network - - GoogleUtilities/Environment (5.7.0) - - GoogleUtilities/Logger (5.7.0): + - GoogleUtilities/Environment (6.3.1) + - GoogleUtilities/Logger (6.3.1): - GoogleUtilities/Environment - - GoogleUtilities/MethodSwizzler (5.7.0): + - GoogleUtilities/MethodSwizzler (6.3.1): - GoogleUtilities/Logger - - GoogleUtilities/Network (5.7.0): + - GoogleUtilities/Network (6.3.1): - GoogleUtilities/Logger - "GoogleUtilities/NSData+zlib" - GoogleUtilities/Reachability - - "GoogleUtilities/NSData+zlib (5.7.0)" - - GoogleUtilities/Reachability (5.7.0): + - "GoogleUtilities/NSData+zlib (6.3.1)" + - GoogleUtilities/Reachability (6.3.1): - GoogleUtilities/Logger - - GoogleUtilities/UserDefaults (5.7.0): + - GoogleUtilities/UserDefaults (6.3.1): - GoogleUtilities/Logger - - GTMSessionFetcher/Core (1.2.1) + - GTMSessionFetcher/Core (1.3.0) - IdentityImg (0.2) - InfiniteCollectionView (1.3.2) - - IQKeyboardManagerSwift (6.2.0) - - Keccak (0.2) - - KeychainAccess (3.1.2) - - Kingfisher (5.3.0) - - Koloda (4.7): + - IQKeyboardManagerSwift (6.4.0) + - KeychainAccess (3.2.0) + - Kingfisher (5.7.0) + - Koloda (5.0): - pop (~> 1.0) - - leveldb-library (1.20) + - leveldb-library (1.22) - MGSwipeTableCell (1.6.8) - - Moya/Core (12.0.1): + - Moya (13.0.1): + - Moya/Core (= 13.0.1) + - Moya/Core (13.0.1): - Alamofire (~> 4.1) - - Result (~> 4.0) - - Moya/RxSwift (12.0.1): + - Result (~> 4.1) + - Moya/RxSwift (13.0.1): - Moya/Core - RxSwift (~> 4.0) - - nanopb (0.3.901): - - nanopb/decode (= 0.3.901) - - nanopb/encode (= 0.3.901) - - nanopb/decode (0.3.901) - - nanopb/encode (0.3.901) + - nanopb (0.3.9011): + - nanopb/decode (= 0.3.9011) + - nanopb/encode (= 0.3.9011) + - nanopb/decode (0.3.9011) + - nanopb/encode (0.3.9011) - pop (1.0.12) + - Protobuf (3.10.0) - QRCode (2.0) - QRCodeReader.swift (9.0.1) - - ReachabilitySwift (4.3.0) - - Realm (3.13.1): - - Realm/Headers (= 3.13.1) - - Realm/Headers (3.13.1) - - RealmSwift (3.13.1): - - Realm (= 3.13.1) + - ReachabilitySwift (4.3.1) + - Realm (3.17.1): + - Realm/Headers (= 3.17.1) + - Realm/Headers (3.17.1) + - RealmSwift (3.17.1): + - Realm (= 3.17.1) - RESideMenu (4.0.7) - Result (4.1.0) - - RxAlamofire (4.3.0): - - RxAlamofire/Core (= 4.3.0) - - RxAlamofire/Core (4.3.0): - - Alamofire (~> 4.5) - - RxSwift (~> 4) - - RxAtomic (4.4.2) - - RxCocoa (4.4.2): + - RxCocoa (4.5.0): - RxSwift (>= 4.4.2, ~> 4.4) - RxFeedback (2.0.0): - RxCocoa (~> 4.4) - RxSwift (~> 4.4) - - RxGesture (2.1.0): - - RxCocoa (~> 4.4.0) - - RxSwift (~> 4.4.0) + - RxGesture (2.2.0): + - RxCocoa (~> 4.5) + - RxSwift (~> 4.5) - RxOptional (3.6.2): - RxCocoa (~> 4.0) - RxSwift (~> 4.0) @@ -145,8 +169,7 @@ PODS: - RxRealm (0.7.6): - RealmSwift (~> 3.0) - RxSwift (~> 4.0) - - RxSwift (4.4.2): - - RxAtomic (>= 4.4.2, ~> 4.4) + - RxSwift (4.5.0) - RxSwiftExt (3.4.0): - RxSwiftExt/Core (= 3.4.0) - RxSwiftExt/RxCocoa (= 3.4.0) @@ -155,11 +178,11 @@ PODS: - RxSwiftExt/RxCocoa (3.4.0): - RxCocoa (~> 4.0) - RxSwiftExt/Core - - Sentry (4.3.1): - - Sentry/Core (= 4.3.1) - - Sentry/Core (4.3.1) + - Sentry (4.4.0): + - Sentry/Core (= 4.4.0) + - Sentry/Core (4.4.0) - Skeleton (0.3.1) - - SwiftDate (5.1.0) + - SwiftDate (6.0.3) - SwiftGen (5.3.0) - SwiftMonkey (2.1.1) - SwiftMonkeyPaws (2.1.1) @@ -168,16 +191,6 @@ PODS: - TTTAttributedLabel (2.0.0) - "UITextView+Placeholder (1.2.1)" - UPCarouselFlowLayout (1.1.2) - - WavesSDKCrypto (0.1.3): - - Base58 - - Blake2 - - CryptoSwift - - Curve25519 - - Keccak - - RxSwift (~> 4.0) - - WavesSDKExtension - - WavesSDKExtension (0.1.3): - - RxSwift (~> 4.0) DEPENDENCIES: - Amplitude-iOS @@ -185,26 +198,31 @@ DEPENDENCIES: - AppSpectorSDK - Charts - Crashlytics + - CryptoSwift - CSV.swift - - DeviceKit (~> 1.3) + - DeviceKit + - Down - Fabric + - Firebase + - Firebase/Analytics - Firebase/Auth - Firebase/Core - Firebase/Database - Firebase/InAppMessagingDisplay - - IdentityImg + - Firebase/Messaging + - IdentityImg (from `https://github.com/wavesplatform/identity-img-swift.git`) - InfiniteCollectionView (from `https://github.com/wavesplatform/InfiniteCollectionView.git`, branch `swift5`) - IQKeyboardManagerSwift - KeychainAccess - Kingfisher - Koloda - MGSwipeTableCell + - Moya - Moya/RxSwift - QRCode - QRCodeReader.swift (~> 9.0.1) - RealmSwift - RESideMenu (from `https://github.com/wavesplatform/RESideMenu.git`) - - RxAlamofire - RxCocoa - RxFeedback - RxGesture @@ -213,7 +231,7 @@ DEPENDENCIES: - RxRealm - RxSwift - RxSwiftExt - - Sentry (from `https://github.com/getsentry/sentry-cocoa.git`) + - Sentry - Skeleton - SwiftDate - SwiftGen (~> 5.3.0) @@ -224,11 +242,9 @@ DEPENDENCIES: - TTTAttributedLabel - "UITextView+Placeholder" - UPCarouselFlowLayout - - WavesSDKCrypto (~> 0.1.3) - - WavesSDKExtension (~> 0.1.3) SPEC REPOS: - https://github.com/cocoapods/specs.git: + https://github.com/CocoaPods/Specs.git: - Alamofire - Amplitude-iOS - AppsFlyerFramework @@ -237,29 +253,13 @@ SPEC REPOS: - Crashlytics - CryptoSwift - CSV.swift - - DeviceKit - Fabric - - Firebase - - FirebaseAnalytics - - FirebaseAnalyticsInterop - - FirebaseAuth - - FirebaseAuthInterop - - FirebaseCore - - FirebaseDatabase - - FirebaseInAppMessaging - - FirebaseInAppMessagingDisplay - - FirebaseInstanceID - - GoogleAppMeasurement - - GoogleUtilities - - GTMSessionFetcher - IQKeyboardManagerSwift - KeychainAccess - Kingfisher - Koloda - - leveldb-library - MGSwipeTableCell - Moya - - nanopb - pop - QRCode - QRCodeReader.swift @@ -267,8 +267,6 @@ SPEC REPOS: - Realm - RealmSwift - Result - - RxAlamofire - - RxAtomic - RxCocoa - RxFeedback - RxGesture @@ -277,6 +275,7 @@ SPEC REPOS: - RxRealm - RxSwift - RxSwiftExt + - Sentry - Skeleton - SwiftDate - SwiftGen @@ -287,94 +286,111 @@ SPEC REPOS: - TTTAttributedLabel - "UITextView+Placeholder" - UPCarouselFlowLayout - https://github.com/wavesplatform/Specs.git: - - Base58 - - Blake2 - - Curve25519 - - IdentityImg - - Keccak - - WavesSDKCrypto - - WavesSDKExtension + trunk: + - DeviceKit + - Down + - Firebase + - FirebaseAnalytics + - FirebaseAnalyticsInterop + - FirebaseAuth + - FirebaseAuthInterop + - FirebaseCore + - FirebaseCoreDiagnostics + - FirebaseCoreDiagnosticsInterop + - FirebaseDatabase + - FirebaseInAppMessaging + - FirebaseInAppMessagingDisplay + - FirebaseInstanceID + - FirebaseMessaging + - GoogleAppMeasurement + - GoogleDataTransport + - GoogleDataTransportCCTSupport + - GoogleUtilities + - GTMSessionFetcher + - leveldb-library + - nanopb + - Protobuf EXTERNAL SOURCES: + IdentityImg: + :git: https://github.com/wavesplatform/identity-img-swift.git InfiniteCollectionView: :branch: swift5 :git: https://github.com/wavesplatform/InfiniteCollectionView.git RESideMenu: :git: https://github.com/wavesplatform/RESideMenu.git - Sentry: - :git: https://github.com/getsentry/sentry-cocoa.git CHECKOUT OPTIONS: + IdentityImg: + :commit: 225bfa9f534eb09c3ac0e0dbd77e0a4d99a287f1 + :git: https://github.com/wavesplatform/identity-img-swift.git InfiniteCollectionView: :commit: 0ea9140787e243a76b511ffc04c62e623262ef31 :git: https://github.com/wavesplatform/InfiniteCollectionView.git RESideMenu: :commit: c4870be8caf988b3c164bbf5675a717a905e9952 :git: https://github.com/wavesplatform/RESideMenu.git - Sentry: - :commit: 9b7da88b3c6454d1b07e8a0a1f627b4b495264ae - :git: https://github.com/getsentry/sentry-cocoa.git SPEC CHECKSUMS: - Alamofire: 16ce2c353fb72865124ddae8a57c5942388f4f11 + Alamofire: ae5c501addb7afdbb13687d7f2f722c78734c2d3 Amplitude-iOS: ac1715ae68104b7a51723209ad574f60ab22ae5f - AppsFlyerFramework: f57e5d590ad3124d3e594a76032a181bc91ec6cd - AppSpectorSDK: e819dafad1a7137e0af68076effeccb77318ed5a - Base58: 419d6be274b8bb6ae4649e492bee67a0c1c09230 - Blake2: 682a2367efad6a4c85ecc691acfa3f9dfceeceb0 - Charts: f69cf0518b6d1d62608ca504248f1bbe0b6ae77e - Crashlytics: 07fb167b1694128c1c9a5a5cc319b0e9c3ca0933 + AppsFlyerFramework: 417e0ceeb58cb60d762f25808095eb4801e3132b + AppSpectorSDK: 6c32df6d66156daa2c1de6e028a74b9c7379753a + Charts: e0dd4cd8f257bccf98407b58183ddca8e8d5b578 + Crashlytics: 2dfd686bcb918dc10ee0e76f7f853fe42c7bd552 CryptoSwift: d81eeaa59dc5a8d03720fe919a6fd07b51f7439f - CSV.swift: d16f671b3090a2c0525d5f2165b18319074aae2b - Curve25519: 4c9483171010b27488a3bac6ee327588a1182fb4 - DeviceKit: f5dbd2e70cafd420d6a09379b8800cdf5fe92ba5 - Fabric: f988e33c97f08930a413e08123064d2e5f68d655 - Firebase: 0c8cf33f266410c61ab3e2265cfa412200351d9c - FirebaseAnalytics: ece1aa57a4f43c64d53a648b5a5e05151aae947b - FirebaseAnalyticsInterop: efbe45c8385ec626e29f9525e5ebd38520dfb6c1 - FirebaseAuth: dd7bbf03a5aee0eafb3a1aee4d2812bd74bac890 + CSV.swift: 9670cc1b3e3f01e9eebb1aeb603b17b4459e7493 + DeviceKit: da103891aa928d89f64ea8dd8aca738c5f3d8ac0 + Down: 1cdbca4963b542d0ef34ebb3e10ff48382bdf761 + Fabric: 706c8b8098fff96c33c0db69cbf81f9c551d0d74 + Firebase: da031bc7012374e3bed17a6731b89327b29863b9 + FirebaseAnalytics: 4e53a7eb7b76bc703c4d9239bc964545e9b23361 + FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 + FirebaseAuth: b401a012cc33b04df3b52bb308b04e8766f2693e FirebaseAuthInterop: 0ffa57668be100582bb7643d4fcb7615496c41fc - FirebaseCore: f1a9a8be1aee4bf71a2fc0f4096df6788bdfda61 - FirebaseDatabase: 2c15b0ea6f2c6eb5e57413f9d6340f1e50b81ae3 - FirebaseInAppMessaging: 25e8c4408829928b6727fb461e0aef6a43111467 - FirebaseInAppMessagingDisplay: 72f67cfe9711c9bf6d6768a1c538299ea2043042 - FirebaseInstanceID: a122b0c258720cf250551bb2bedf48c699f80d90 - GoogleAppMeasurement: ffe513e90551844a739e7bcbb1d2aca1c28a4338 - GoogleUtilities: 273e67030e0de313e7304f6dcfa96fc5214f6c23 - GTMSessionFetcher: 32aeca0aa144acea523e1c8e053089dec2cb98ca - IdentityImg: 9012dceefa148c3aac55c61ff2170a0e3a1a869a + FirebaseCore: bcd6c112429249d7921e907d661e8955a3549e26 + FirebaseCoreDiagnostics: af29e43048607588c050889d19204f4d7b758c9f + FirebaseCoreDiagnosticsInterop: e9b1b023157e3a2fc6418b5cb601e79b9af7b3a0 + FirebaseDatabase: 963515d232ded06f36f6ce830507c94551866170 + FirebaseInAppMessaging: acbfa8c5582b11ccc0366511d29ef1d288f302fc + FirebaseInAppMessagingDisplay: 60a65c8277f17675a8a5b92e9a97cd914b45d4ff + FirebaseInstanceID: ebd2ea79ee38db0cb5f5167b17a0d387e1cc7b6e + FirebaseMessaging: de30f83a372a390be6f2ba44ec43a45b7ccdb43f + GoogleAppMeasurement: 037f46d1d8ae8b312720f1042585ab961a1289e3 + GoogleDataTransport: 166f9b9f82cbf60a204e8fe2daa9db3e3ec1fb15 + GoogleDataTransportCCTSupport: f6ab1962e9dc05ab1fb938b795e5b310209edeec + GoogleUtilities: f895fde57977df4e0233edda0dbeac490e3703b6 + GTMSessionFetcher: 43b8b64263023d4f32caa0b40f4c8bfa3c5f36d8 + IdentityImg: 4c81857fc8a80294e6c480b4f72cb3e22cd360c2 InfiniteCollectionView: 49a7639a04c7cb21164de3840245f084fda257d0 - IQKeyboardManagerSwift: b07ccf9d8cafe993dcd6cb794eb4ba34611a0c4e - Keccak: 746b8f26ac04386f165f55998ca7c81666b8721d - KeychainAccess: b3816fddcf28aa29d94b10ec305cd52be14c472b - Kingfisher: 4692c783ffb99e9e2e40a6eb3e518c3b96c6fa8c - Koloda: f456d003d2ce15ef9f10c2874a444f1f570b490c - leveldb-library: 08cba283675b7ed2d99629a4bc5fd052cd2bb6a5 + IQKeyboardManagerSwift: ed9b04ee0e3067ffba543283462d619f944b05e5 + KeychainAccess: 3b1bf8a77eb4c6ea1ce9404c292e48f948954c6b + Kingfisher: c7d211b54f1f30d8060aadab177d52b4349c825b + Koloda: 75302d21882cc3e274c1561b1155805ea5919dab + leveldb-library: 55d93ee664b4007aac644a782d11da33fba316f7 MGSwipeTableCell: dc4eca3212ed38a563b27d6aa7b3c01ce656c1e2 - Moya: cf730b3cd9e005401ef37a85143aa141a12fd38f - nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48 + Moya: f4a4b80ff2f8a4ffc208dfb31cd91636622fee6e + nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd pop: d582054913807fd11fd50bfe6a539d91c7e1a55a + Protobuf: a4dc852ad69c027ca2166ed287b856697814375b QRCode: f98a1886c8f37523704a7512a4c0cd45b34c18a4 QRCodeReader.swift: 96292a5612fbc2fd9a0b26f93fa5164c8d02f59d - ReachabilitySwift: 408477d1b6ed9779dba301953171e017c31241f3 - Realm: 50071da38fe079e0735e47c9f2eae738c68c5996 - RealmSwift: 8a1e6a02b7a08cd17a31e3115143fb69fe5f3fb9 + ReachabilitySwift: 4032e2f59586e11e3b0ebe15b167abdd587a388b + Realm: c204f1a890f07dea43b14132a6aad118c054b8f2 + RealmSwift: 4d3c9233544b9cd08a8913e0872b9038eb99b054 RESideMenu: 4003aa053ff48d4152d464e512f1844aa82e807c Result: bd966fac789cc6c1563440b348ab2598cc24d5c7 - RxAlamofire: 09624d0f2d48ed8b686e4eb4cf68e28cbd2df556 - RxAtomic: d00e97c10db88c6f08540e0bf2752fc5a2404167 - RxCocoa: 477990dc3b4c3ff55fb0ac77e1cc06244e0aaec8 + RxCocoa: cbf70265dc65a981d4ac982e513c10cf23df24a0 RxFeedback: 49bb931caf6d05e315d5b5366c0991ad1474ea36 - RxGesture: 7f6dfb45dbde06e618c24442d38493e3144f2c95 + RxGesture: c1b7bf17166b0ef9d642a9510f8bac5785f18990 RxOptional: 80426a0ddbd092573e4c482d8cc13302078c4d5e RxReachability: 053f2d913db44998242ade488ccaef558f3ce7cb RxRealm: 5379eddd74f8d617ca7681d1f8d144af25b432b0 - RxSwift: 74c29b693c8e42b0f64400e8b06564575742d649 + RxSwift: f172070dfd1a93d70a9ab97a5a01166206e1c575 RxSwiftExt: 01f8ecbeeb355698e9c75365ebe908b00dacf45d - Sentry: 5267d493a398663538317e4dcc438c12c66202ed + Sentry: 26650184fe71eb7476dfd2737acb5ea6cc64b4b1 Skeleton: 4b11a4aa6fb289626aa7e486f0b16b9b394d0ba4 - SwiftDate: 6329e58969a2de31cea7f1ee1143b247693196e7 + SwiftDate: 8d4f14bf1ef68e95094511504856547bf9e3e1a6 SwiftGen: 4379bd3640b0a212a0f6ea3c494adba385513d10 SwiftMonkey: aea6f2707a4b7ab5277b4d2fd2f0723a083997b1 SwiftMonkeyPaws: 655524bb402df5ac2be836f9f604aca1068fbde6 @@ -383,9 +399,7 @@ SPEC CHECKSUMS: TTTAttributedLabel: 8cffe8e127e4e82ff3af1e5386d4cd0ad000b656 "UITextView+Placeholder": 0c3efd97f37ea64bde7f34cc6e90fe02e87b3909 UPCarouselFlowLayout: 4c7d2c43a10ebb1597bde502a53699d378341dad - WavesSDKCrypto: cabcc6030164e4da564dc9194e93d0e0ac24ad20 - WavesSDKExtension: caf0affcb40c4a56f55638bd3b3cc2987ce4427c -PODFILE CHECKSUM: 8a43ef1b50425b22722a9ce2f103718821679369 +PODFILE CHECKSUM: 097ab6a58a90c5434b15bb013d939f2fc7d874f5 -COCOAPODS: 1.7.2 +COCOAPODS: 1.8.1 diff --git a/README.md b/README.md index f61dacaf..fd59e28c 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,16 @@ [**Website**](https://wavesplatform.com/) | [**Discord**](https://discord.gg/cnFmDyA) | [**Forum**](https://forum.wavesplatform.com/) | [**Support**](https://support.wavesplatform.com/) | [**Documentation**](https://docs.wavesplatform.com) - + [Waves Wallet iOS app](https://itunes.apple.com/us/app/waves-wallet/id1233158971?mt=8) is the official wallet software designed with mass adoption in mind. It allows to access your Waves account, handle financial operations, and trade on DEX. +## Easy start with WavesSDK +* [Waves SDK for Android](https://github.com/wavesplatform/WavesSDK-android/wiki/Get-started-with-WavesSDK-for-Android) +* [Waves SDK for iOS](https://github.com/wavesplatform/WavesSDK-iOS/wiki/Get-started-with-WavesSDK-for-iOS) + ## Blockchain for the people Keep up with the latest news and articles, and find out all about events happening on the [Waves Platform](https://wavesplatform.com/). diff --git a/SwiftGen.Wallet.lock b/SwiftGen.Wallet.lock new file mode 100644 index 00000000..bfacb3a3 --- /dev/null +++ b/SwiftGen.Wallet.lock @@ -0,0 +1 @@ +{"storyboards":{"LaunchScreen.storyboard":"e0b6d21e3b64332ccd1f09dc5cf9417236e42d1356841b9325816b9e7c591819b3b4e860802fb2853dee78e26ac333805ffa9ee072099164cde1db9d08b2a66f","AccountPassword.storyboard":"866ca122191f46d4b809801685faba9aaa5ce54c76d9b5e539835c96737f0df61407198ae5e144f9e15d2f87b0734a1d7965b6fe0fe7208f4d2cf1d7fdfa81c4","ActionSheet.storyboard":"a9caea959738d5e9da06537f54a8d3fbe07f1642ed939590f84ce9f5ec2ddac5bf06a0c659186679d507258f1c5a5a778fb39add92d8fc398391a1f4b090045c","AddressBook.storyboard":"622dce60f6ccdcf461981d73ff7ecec0b0b0d6b0c8272adeedcb3f33bc31b7d2d55032e2beda779c9d98762dd18e738d298e57209a109a72af4103f7e0edb2fc","Asset.storyboard":"867635e6c36e336238e50562e38ae504c800a31acf9669ed64efae65421a4e8b6214e68a9148a64e365fac025076df2973e6b333af40cee2de4b4c27f53814c7","AssetList.storyboard":"c9c9e0548458fa994aff3bbeb33a8150b5171e66bbcbc5e49eff7c22f78d84576ace3698f2b75805df0cd35ea41e4b6730aff945ff9f5ba204d3708eb257432a","AssetsSearch.storyboard":"7a4f55d1bf7d871b1c8a771e1356e4dcf05ae66d59613f8d32075ba45b1f7ed03d19e21db8f952c21d8082e04382dd25d08cd1a68cbb6972e598a9891dac5c29","Backup.storyboard":"d65083b20760cacbd6f9ffedd58e1bec7fce0815198031750295d56546760b7f7712bf48ac7e34233e53411efff836d5aba2ae91d19822bb6a706bcabcbaac2b","ChangePassword.storyboard":"4086dddc65c30fcdbc172acd65027fb9c08dc7c60492c1cfb9f708d009409fc459702f7ce5714e50f14f890901f9153ea7fc536dc8dff4cb8c97cd3c68d18a19","ChooseAccount.storyboard":"b874c62f858c9d0ac406626319ee7801b66d58343484e60e5edd6a0069590b248e9c45ae3aa7e4857908122280bb0590180045dd137184eba9c93257c999bff1","Support.storyboard":"8553022a04aa98de64812120ac74a2b7ce44dbd7c02182c8a5854ede01a3ab71c564c5d0dc4927139c5dc1c14fe30f18632570955c19f56a71c51dfcd963cee7","Dex.storyboard":"fe1f7b6594732c02f63a870e19ca705895a69caea8e0438c2b7f49e361c1acb509b9fe59ac2bc6cab0614f95ff91a5707fbbdbb794b28616024a56442e30de9e","EditAccountName.storyboard":"71a62964b1c2445f49ee284646bbf17dfd0ea3806c715f7f0d4d3e3cb8152231dc314ffe21bdaf56a431f107972a76c9f13f3415f0c8162b5d011656a032b7bb","Enter.storyboard":"1c0cfa2b9addb83b00abf1ba9eaeadd2dbe18f24a3b174faf60b48eef7b66c6aecae5e95f89584d3c56b95d4af12dba4a1dbff5f0ac49fd2d91b97d279701753","ForceUpdateApp.storyboard":"94b95acc9bbfb70986e8f710081d6cdd829c6ee3f28e3fe4286f82ed646ec9b5f9e2d72ba0abca8a92636988526d953eee34d17d9c575a59a3fcbe298c95bf31","Hello.storyboard":"3d124e6e421cb14b20fa1ecb3ed43461377b317cfad63db629c9d6cde4091dc9b6828dfbdb4b15bf8cceee57b6d1b69f292b61339b0520d666f098dc2297198b","History.storyboard":"a086a8f65e59e700291fc270f9f377cb5c67e5b1e8e9d4d42160f3f7ff17d46b282c08d93d5346b0850b51566e5bb5e5f1eb64ba59a3c6a55706b86bab0164b8","Import.storyboard":"22ef9e0723c4769fbbc302858411e10d704684410e4f2e7e336289a0c571ab6b7ca2730108d9aaf4d015abbf257479f21955579ab78a4cfc704aae706005cd4f","Language.storyboard":"1ac1d54a67b9ed97d528e1a39dc2bef79082ae6366f57b66e0a3ff2b92fa5c674bb6782dd109b590af9ba0b887b22a5cad29e72e053f62e86addbe7c15fac731","Main.storyboard":"174685b072b21f6ad94bd6d9b415c2bee384ee66f38d92eab41be6756e8b429a089d45f9b619033eb8ab218088d152c1f5782512efe3888465f3369d2d5e1a5b","MobileKeeper.storyboard":"4900a703cf3b207fb69bfff1f1f88f8ea001c2e4cff9a35457eadeff574a6a854d8c48b34fc34e475850d139f028c7fde577f3335c93749f63c0bdd3ee4045b4","MyAddress.storyboard":"022e58398edd7db6b4ecc3aa5ed2110b0e95ed6578c6dfdaca1b076498d4f9c9ab1317679f0abb8512c3ff03ed748b7de0df9b89956bc39c009cb8c793a595c0","NewAccount.storyboard":"74750044fd7649717d5dc0851a731fcd3a9c44d2ec9107c251b17fdc297a4aafe941cf809f251ed9393fbfb70fb33e84679848bf710d7afa324619a09006e82e","Passcode.storyboard":"5c7028f8a442d53e9eaa50174528380ea6177eacafc21be8df69b4fc74a4bdece0ca3e6b1a03827d857f45dea5d145a7b548772a4f8f5d855cc38b429e9a296b","Profile.storyboard":"3ab19160c5e273116af930ee0ec0f18e087e1f817020380180980a78a20dbbc470f19cb2addbfc3ecd3d707458354d8087bb293749d30d369b33eb6bde62b4ab","Receive.storyboard":"946e06fb3b66030b8fda897f2e69db6413e44eb46b20c818de256aa9565bfde6783cf8b6f2bf277169af0dce2aa9f28388292e1156022081f129875dafd52c36","Send.storyboard":"04e57448fe125cd74fee14ebfaa7e4aa659fa21d03b5a3155c767d45597a8c3fefd54ebed96a8f7d45844669859ec463f05871c021827bb470ce2b8a7b58a0b0","StartLeasing.storyboard":"1388dc91d23666efad457e304d5f4fcd77d0175baa5451c5aed94aea3978dc2b82f227730b23157eac8d91598879facdffc6a19dec9ad426b15a8744c19f8481","TransactionCard.storyboard":"7e26fed9239629acdcdc483a736073acbba0f9f41da973f797b81807d732d9db97ce74727d0c41b4aa8437af21b226acb6de743c5f35b29eb64b4fc3f2d2c8fb","UseTouchID.storyboard":"6b8df20086f79560669c4843f4684c36025e9565713d122ffddb4895f60b45f6ea0fb9968d7680136273ec75caa7b7d890d81797e51b9835cd92d37a1188f9b4","Wallet.storyboard":"419b6039f984f018fa8fc019b71db975d8e6dc95fa88272b98a6375c833b97f92314b09d6433d6da26df2bbcba668524e0a686a08f5cb4d183d98069eca82186","Waves.storyboard":"2b30eae9fb071781322b2cc0e52e95078e6034a7aec9b2c97e7818dec4fbc3bc2efefbe9c5f2f26e3c2351ab9e33366f2335794315f9bd74dea569b034935c61","WidgetSettings.storyboard":"3f33a4a02cf04bfbefcf29d50855ec05d34102235ec2e17dedb7a670f75f96b9490162e4e418e03be9dca8c6c6f9d27bbde56aeafde23b22dc121e0565966696"},"assets":{"Assets.xcassets":{"Contents.json":"c8557e6769022ec3e55f43b753d13945a852dd16f394fc9cfc357354fda7e5a795d3989d23e5c7801cc4fa5cc3983ac059c04e2785ea37ea823ed9556f2f2a05"}},"strings":{"AccessibilityIdentifiers.strings":"91064b1599baa41fc99d929274563ee19720e6b13be049b1e2cdc3c6911e84f871115e34ec949b3f0e96c2a190746b321ba542427bca7ffc5288329542d0e7ac","InfoPlist.strings":"5f8ea88faee87a859540d7276e18eb4330daebb032326773a4e0a61efb0b75e2be4421447d35d6895d354fa35edf6e8a760e4c40730943ab8b34d636dba8ca3e","Waves.strings":"52ddd4f71b175a2b3c15ebdfa77cf7b7ff4dbe0adfbadff863272f86105286be8219a5254a0701aaa9684b4fb83cd5e2998437dd298117cc2b32ae87ad241224"}} \ No newline at end of file diff --git a/SwiftGen.Widget.lock b/SwiftGen.Widget.lock new file mode 100644 index 00000000..33cc98bb --- /dev/null +++ b/SwiftGen.Widget.lock @@ -0,0 +1 @@ +{"storyboards":{"MainInterface.storyboard":"384d956614f5dee9d10faaa48034a08f07684511e195f7f0c954dbda3381fc777536262fb863023b05f9c251ee365dc78785dd3a6002a8ce8bc57510793e99b4"},"assets":{"WidgetAssets.xcassets":{"Contents.json":"0a916e06a149c2ad1d6ee40ef7ccfbbc77fd677581ad0bc319969076c9f80f6193e61b71d873360cfd58deb78a724137a8cc64424aabe8d2e7849aefb302ec88"}},"strings":{"WavesMarketPulse.strings":"7ff4caa3e50aeb092b31be0feccbe0e67f48dec2e381bc02fc89e63f0b9905af64b3634b996096805c675d60c65b87ad068275b2f0bec3e09c4a121e774a4903","WavesMarketPulce.strings":"c3f76669380f18d65ecf95ea0c21eace963284a56c830f04294c1bf13c6c9974396c6f9cb3c85f3678d9d85fb785224c14aa4b2f5f306b05f33c1b8160825c56"}} \ No newline at end of file diff --git a/SwiftGen.lock b/SwiftGen.lock deleted file mode 100644 index b86ba968..00000000 --- a/SwiftGen.lock +++ /dev/null @@ -1 +0,0 @@ -{"storyboards":{"./Pods/FirebaseInAppMessagingDisplay/Firebase/InAppMessagingDisplay/Resources/FIRInAppMessageDisplayStoryboard.storyboard":"a1ba68e0eebb7475f8cd560d4c4922e87eccc0d8264d978279c548da898c758f0987d0067e244944ae42a5c5cd95e91b3c233b551083f4cd5a3b6ab946c67cf0","./WavesWallet-iOS/LaunchScreen.storyboard":"e0b6d21e3b64332ccd1f09dc5cf9417236e42d1356841b9325816b9e7c591819b3b4e860802fb2853dee78e26ac333805ffa9ee072099164cde1db9d08b2a66f","./WavesWallet-iOS/PresentationLayer/Modules/AccountPassword/AccountPassword.storyboard":"866ca122191f46d4b809801685faba9aaa5ce54c76d9b5e539835c96737f0df61407198ae5e144f9e15d2f87b0734a1d7965b6fe0fe7208f4d2cf1d7fdfa81c4","./WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddressBook.storyboard":"93190edd5be4e0b3129bacf0c9d17bbb2dcdabeee81b26a92be50c7473449ed660b008151540cbbe63a36338a416d60c14bd86783dbdd3e9385bf9e3c8d9f93c","./WavesWallet-iOS/PresentationLayer/Modules/Asset/Asset.storyboard":"0d9d3342bfa32307719e8002390901393c7c50a31c76daa01c7699ba649c1998605c41fd048464d33963b808e327003458b48a6d5bf2e9ec58b89e04a42a445d","./WavesWallet-iOS/PresentationLayer/Modules/AssetList/AssetList.storyboard":"e094577da72b25ed90ffc695ad78a984bae84b1879f4406fe322026a5b1b1165ce4c538af4b0affdbd7d6877507701276292f35fd57b535e1f479981de57abc8","./WavesWallet-iOS/PresentationLayer/Modules/Backup/Backup.storyboard":"d65083b20760cacbd6f9ffedd58e1bec7fce0815198031750295d56546760b7f7712bf48ac7e34233e53411efff836d5aba2ae91d19822bb6a706bcabcbaac2b","./WavesWallet-iOS/PresentationLayer/Modules/ChangePassword/ChangePassword.storyboard":"4086dddc65c30fcdbc172acd65027fb9c08dc7c60492c1cfb9f708d009409fc459702f7ce5714e50f14f890901f9153ea7fc536dc8dff4cb8c97cd3c68d18a19","./WavesWallet-iOS/PresentationLayer/Modules/ChooseAccount/ChooseAccount.storyboard":"c48f4fca14ed27ec579337f723c17be014ec37d9c64ccc67e4c88be671ecd8f793bbbfe049b6d23125f22ae66ae6f0805a1ca90158e64da1a9d0a2e39fc8965e","./WavesWallet-iOS/PresentationLayer/Modules/Dex/Dex.storyboard":"cdae5623f34296c76ede8825e31df271cc3023daa27cc05dc7dc083fcab60c08224d8524d69bbdfa3c858264b40fbd46d60178fa913ddea796740879d7962d4f","./WavesWallet-iOS/PresentationLayer/Modules/Enter/Edit/EditAccountName.storyboard":"71a62964b1c2445f49ee284646bbf17dfd0ea3806c715f7f0d4d3e3cb8152231dc314ffe21bdaf56a431f107972a76c9f13f3415f0c8162b5d011656a032b7bb","./WavesWallet-iOS/PresentationLayer/Modules/Enter/Enter.storyboard":"1c0cfa2b9addb83b00abf1ba9eaeadd2dbe18f24a3b174faf60b48eef7b66c6aecae5e95f89584d3c56b95d4af12dba4a1dbff5f0ac49fd2d91b97d279701753","./WavesWallet-iOS/PresentationLayer/Modules/Hello/Hello.storyboard":"3d124e6e421cb14b20fa1ecb3ed43461377b317cfad63db629c9d6cde4091dc9b6828dfbdb4b15bf8cceee57b6d1b69f292b61339b0520d666f098dc2297198b","./WavesWallet-iOS/PresentationLayer/Modules/History/History.storyboard":"a086a8f65e59e700291fc270f9f377cb5c67e5b1e8e9d4d42160f3f7ff17d46b282c08d93d5346b0850b51566e5bb5e5f1eb64ba59a3c6a55706b86bab0164b8","./WavesWallet-iOS/PresentationLayer/Modules/Import/Import.storyboard":"22ef9e0723c4769fbbc302858411e10d704684410e4f2e7e336289a0c571ab6b7ca2730108d9aaf4d015abbf257479f21955579ab78a4cfc704aae706005cd4f","./WavesWallet-iOS/PresentationLayer/Modules/Language/Language.storyboard":"ca1a7dc886a6634345e824c2cb66fe23af6c2c0f2ec50a5b583490cda680df2bfff0ad8c3698139f31f35f9431f6239badcd3ea79ca1811c2b715517f4b78305","./WavesWallet-iOS/PresentationLayer/Modules/Menu/Main.storyboard":"2688606e4c009796962df4f67ef6f92e240ab9dc5e6c369f2fa6478deeade9e6ea1602e27248a7045b932b5b300ae59fb0058846546094c55a4a88d63dcfbb9f","./WavesWallet-iOS/PresentationLayer/Modules/MyAddress/MyAddress.storyboard":"022e58398edd7db6b4ecc3aa5ed2110b0e95ed6578c6dfdaca1b076498d4f9c9ab1317679f0abb8512c3ff03ed748b7de0df9b89956bc39c009cb8c793a595c0","./WavesWallet-iOS/PresentationLayer/Modules/NewAccount/NewAccount.storyboard":"74750044fd7649717d5dc0851a731fcd3a9c44d2ec9107c251b17fdc297a4aafe941cf809f251ed9393fbfb70fb33e84679848bf710d7afa324619a09006e82e","./WavesWallet-iOS/PresentationLayer/Modules/Passcode/Passcode.storyboard":"5c7028f8a442d53e9eaa50174528380ea6177eacafc21be8df69b4fc74a4bdece0ca3e6b1a03827d857f45dea5d145a7b548772a4f8f5d855cc38b429e9a296b","./WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile.storyboard":"a64d51910aee6ac5d044a03aabb123299e715946afa43c5b121282c480b8af48404ef6f1df355ad8c356628343c1b3949ba3db970c27f8d5b85ac17e1b46ef74","./WavesWallet-iOS/PresentationLayer/Modules/Receive/Receive.storyboard":"946e06fb3b66030b8fda897f2e69db6413e44eb46b20c818de256aa9565bfde6783cf8b6f2bf277169af0dce2aa9f28388292e1156022081f129875dafd52c36","./WavesWallet-iOS/PresentationLayer/Modules/Send/Send.storyboard":"1cafea87db7a36aecc668a670a6ac8cc81767c9b27f7c955ab1c1bf1049468888c7a4ae05a8a2e9f5ad2b05011ef1cdb23a6e26d4ca2565c604734d7c31ef5c5","./WavesWallet-iOS/PresentationLayer/Modules/StartLeasing/StartLeasing.storyboard":"57356a8291ff6ff5ddd096931822cf50f11f1cd941167761daeded096892aef1531b71d0a0b4b57e02355c0f286cc60f14e82673a37c791d50dce03a9f04951b","./WavesWallet-iOS/PresentationLayer/Modules/Support/Support.storyboard":"1b3c745512e2f71c5c0c71d10a95ae76dea9ab06568f3199f9c6d2bf010310a0b54aeccf40eba7de0b5c3fc011bc5998d091ac298cc738eb2f2b51857fe2deb5","./WavesWallet-iOS/PresentationLayer/Modules/TransactionCard/TransactionCard.storyboard":"6456778c694311627f1e2a3d91c5a6c9bd6a2c82e688f0c78386605dce780805d1e66e279ef8ca00c8dcbb82d098cc9fbf5aed56c5cbc5d3d06d43268fcb8201","./WavesWallet-iOS/PresentationLayer/Modules/UseTouchID/UseTouchID.storyboard":"6b8df20086f79560669c4843f4684c36025e9565713d122ffddb4895f60b45f6ea0fb9968d7680136273ec75caa7b7d890d81797e51b9835cd92d37a1188f9b4","./WavesWallet-iOS/PresentationLayer/Modules/Wallet/Wallet.storyboard":"d34d396aca71ea7dd8c195b04568c9a9ec6ef8b58bca0d8865be98bcd864ac8688603dd6975e5465ee22d8c62349a43cb81f2bd115d8bf1c9e8fdad05f0d7700","./WavesWallet-iOS/PresentationLayer/Modules/WavesPopup/Waves.storyboard":"2b30eae9fb071781322b2cc0e52e95078e6034a7aec9b2c97e7818dec4fbc3bc2efefbe9c5f2f26e3c2351ab9e33366f2335794315f9bd74dea569b034935c61"},"assets":{"./WavesWallet-iOS/Resources/Assets.xcassets":{"./WavesWallet-iOS/Resources/Assets.xcassets/AppIcon-Dev.appiconset/Contents.json":"60f05a5daf1cf6c2a488cf05ac763e175e8c6e14c7c355e72bf59ad3a9caf5c63472623df6007863b38d9d7e9fb2fa31a13d61cd14f891a4539a805be85feb3f","./WavesWallet-iOS/Resources/Assets.xcassets/AppIcon-Test.appiconset/Contents.json":"7a4131220bd80d954e45afb4f919edd420822d5aa1918f40485244f46e8323897abe9edcbe5525b6b011553805b840424063e9b73f3c789f565ec3ad3afa5d12","./WavesWallet-iOS/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json":"75b4ee4d9080fbccae0df80f6189bc709d9b2f6409f7fb882278dcb07f56217c23851a28c2089780fa502029b11a617f8cd128b3529c4237965553d00d46bf3a","./WavesWallet-iOS/Resources/Assets.xcassets/Contents.json":"30a88ca0637f5bfdae1f46376d9520ec98362ed6de7cb2d940cbb0ba8165b5de313f759482cf48f227663abc5d9800aca7c2af64e8b3d7616c9aba7f3460bba8","./WavesWallet-iOS/Resources/Assets.xcassets/Image.imageset/Contents.json":"f904712de6d45298ef76d32c7c8aa9dd0a420aa04208f4b8d40881e15cdceadb9464f450017290a84d35594e978c55ebb35963022359177e5ff5c40af74d0619","./WavesWallet-iOS/Resources/Assets.xcassets/add_address_icon.imageset/Contents.json":"105ef5ed58b6dc7dd7c80e6ff734062549bb22cf99b4dc52328d4024a40de116f4d6ffc71344a885bacb47926faf1bfd0f0054a85254fb35f141e024228e60b4","./WavesWallet-iOS/Resources/Assets.xcassets/addaddress24Submit200.imageset/Contents.json":"969ed1fa913b072d0eb25d9d06cf7b2a0b95b77580febddd6f6e6bde9cd44e6a1f84075a1bb1ae0dc281042a6fb6a7f40db46f3580c12a3dba5ae2fe3046a870","./WavesWallet-iOS/Resources/Assets.xcassets/addaddress24Submit300.imageset/Contents.json":"105ef5ed58b6dc7dd7c80e6ff734062549bb22cf99b4dc52328d4024a40de116f4d6ffc71344a885bacb47926faf1bfd0f0054a85254fb35f141e024228e60b4","./WavesWallet-iOS/Resources/Assets.xcassets/arrow_green.imageset/Contents.json":"0c99666593dbf05ab3d0d9ec8f074dfa9c8bddd2350d17fa18d2bfdccb9767824a8d038b7247472ca979f8a03a47f81a4eacb0c0447403575d0462b6f9410b52","./WavesWallet-iOS/Resources/Assets.xcassets/arrow_left.imageset/Contents.json":"f8504ef9a722cb75feef3f099b0e081f5f848151fb8784d4a9af151451c236d4d9c59e30f5b1e279c68a4599a12548fb90ae299cda3ff232c607b35da6523840","./WavesWallet-iOS/Resources/Assets.xcassets/arrow_red.imageset/Contents.json":"0d70486f55134f9467c4b6f5b3630a3bfd3d432c275d3297f11e1d8d829a3fa94727006497969b8f0cd92f785a8d87986933f5eb691bcc278cd830a3a89dcdf2","./WavesWallet-iOS/Resources/Assets.xcassets/arrow_right.imageset/Contents.json":"8a46294107aa699684ce71e9be9f0f46b02f07e3026245f41e45e5e1f6f3af4e3b716c53ac9c50127897a6f01f93be42339ea06f03dc669098c7ef97e4de21a4","./WavesWallet-iOS/Resources/Assets.xcassets/arrow_transfer.imageset/Contents.json":"21e3cb29e072b193f22fa29fbb25a1799a4c709e34b02e103d3e1f021fe316b1fa7606a8f8ce470b4b74dde0fe402f008559ee9d28d9562e34c1774cab4085e6","./WavesWallet-iOS/Resources/Assets.xcassets/arrowdown14Basic300.imageset/Contents.json":"f9e1ba6d8aeee174643ad19b8fbacd672a46df6b6cbe7fb7dc444132b6eb58c78b88c1a1a020b35330d0f199f5ba67b3206b13d5cb12f47455d0ac73d378f744","./WavesWallet-iOS/Resources/Assets.xcassets/arrowdown24Black.imageset/Contents.json":"3e8743fb06f6272e8234220de2b354fcd9ff0a8e1798ad08477ad72617edba7c166f462e34be712a24ad1389d8d3b0c704eb9a09ee49114525169995cb3bb457","./WavesWallet-iOS/Resources/Assets.xcassets/arrowright14Basic200.imageset/Contents.json":"8a46294107aa699684ce71e9be9f0f46b02f07e3026245f41e45e5e1f6f3af4e3b716c53ac9c50127897a6f01f93be42339ea06f03dc669098c7ef97e4de21a4","./WavesWallet-iOS/Resources/Assets.xcassets/arrowup14Basic300.imageset/Contents.json":"d20eb1be11d52b396db5d243d2e98b830277addd99a8b14fa03996925dafc3bee8b1265dbd21bee6389ca69d3134810a3a3292aae5bef4e6f89494811e8c9494","./WavesWallet-iOS/Resources/Assets.xcassets/asset_change_arrows.imageset/Contents.json":"022b519271a83134a28cd6a39f36b2cabfa7a7c4261651923e98a5c6b8424991cfc44339f4ee3b4e47d63f33e01ab73ce8fb3fe104da7644df30475b0fde81ba","./WavesWallet-iOS/Resources/Assets.xcassets/asset_receive.imageset/Contents.json":"695da5045d01ade8f2dca987bba8fdb5f6efbf6c4ba137ae129e5c9728644ac631a04681505d314af51fd7fe9ac3e8bcf0a8219ba4ab0041af10b7f6bdc8dae0","./WavesWallet-iOS/Resources/Assets.xcassets/assets.imageset/Contents.json":"6accde842418bb70e8c531ab79a7f73f33ad5d46c6f6458b2b6f9a6e418f2a6e666da5182b92366eb712ce86fe773a70b3a12aa1740af7b8e1b7a32291faaaf1","./WavesWallet-iOS/Resources/Assets.xcassets/back-chevron.imageset/Contents.json":"507192fa23f7ae5ab0062dbc4998a61964c16bd0eaae8453005fe8e2f7cc8b60e94ff36f426346fcd0958987b16e16bbabffac41de4a301912a20a77fe724cd7","./WavesWallet-iOS/Resources/Assets.xcassets/backspace48Disabled900.imageset/Contents.json":"ce1d32b7b3f5b6a0d5a7f7f3b7d305a73f5a695f09c8730bbce3202f00846378567987f61309d6f4f0c92a4b53dc199f640472779d118f2beaff0966f26f07ea","./WavesWallet-iOS/Resources/Assets.xcassets/bchHardforkPart1.imageset/Contents.json":"689d785f0c46e614ca3b67383f2adcb136b1d35c6e5f99719e564af4d8fcba4b88ce1bd42a37c13b1a246f4bda408a10288568babc90c1a215e62b1516a7a255","./WavesWallet-iOS/Resources/Assets.xcassets/bg-iphone5.imageset/Contents.json":"a0f664a5f6593cad84b59ddad1c83a0331fc41ef817294d6f2ecccb930b05b80a4310fcde155221794ce16857323ef8fc0318088ca1b39a870d2fe6a103c1327","./WavesWallet-iOS/Resources/Assets.xcassets/bg-iphone8.imageset/Contents.json":"1ba241e00d08e0caf937f9b07ba4d1aafc1a7804cc18cdb1e219d1413d19188640ed2e3246012fe8b93c2d9b4e1e811fd488ee140275a85027e9429815b7d6d9","./WavesWallet-iOS/Resources/Assets.xcassets/bg-iphone8plus.imageset/Contents.json":"b23c0a2ea821bfb735936f903bb2f2182b6af89d0612dba09ac27aee4cd0c5c32f113328e9718686578ffd9d7c28a279399d7d6cef8f17ab1d1ec40a296fb5c4","./WavesWallet-iOS/Resources/Assets.xcassets/bg-iphonex.imageset/Contents.json":"1ed5762f4e08ea78debde5a9a019e9bacd7deb76564efa62f00ccf41f029f56a3b15d07959238906b24e90ad8ba96444878ec86ca68c62f07dc963c0ef27c1a2","./WavesWallet-iOS/Resources/Assets.xcassets/bg-iphonexr.imageset/Contents.json":"284fcbb3cf16572425dbc30ba3980e1de632856c2d1d94483a0920d3092ea9bb188ed5e7fced29f38e2a7aea0cea61eeca81b623aad5c98e570731cb9a45c92d","./WavesWallet-iOS/Resources/Assets.xcassets/bg-iphonexsmax.imageset/Contents.json":"f70409d5d987341ff521618dd271e79866296f9d318e0ec5523f441f5735035bdded06ecc39401b5098005bddbc5626b7bf4a01456ca1f040b4a40cc9a0ace48","./WavesWallet-iOS/Resources/Assets.xcassets/blockchain80.imageset/Contents.json":"b3a1a7394aec20def3cf4a3a0fb90202d2e8f119882632cdeb54de79a37e10416e97902e76138eb99ac2f83550c14eaf244a9a541436a21464f22ac63238a9ce","./WavesWallet-iOS/Resources/Assets.xcassets/btn_back.imageset/Contents.json":"973067822edacd2fe0b3cf99ea847d3b86c1f577c55b206b0f46482138c6cd8694e1c1715e81835939d2e0f9ec899e5b6769bde8002df9c9fda198023c731e9c","./WavesWallet-iOS/Resources/Assets.xcassets/btn_bars.imageset/Contents.json":"d84d005311dc78374058fd925f4b5983223fa0b2533b82362b13bc74dd338cbe00a496f899b1143bbed05713d534313a27866bd01b764dd0a5705afaf7ec92b9","./WavesWallet-iOS/Resources/Assets.xcassets/btn_order.imageset/Contents.json":"fcc3653fc02a588173da16cba777821f4f8dcacb3570fa5c3500e2f0caf352b2b4d99a6846beb2217111a05aaed0e74223570a9e3c17ac74682d707005f9c2df","./WavesWallet-iOS/Resources/Assets.xcassets/changearrows14Basic500.imageset/Contents.json":"022b519271a83134a28cd6a39f36b2cabfa7a7c4261651923e98a5c6b8424991cfc44339f4ee3b4e47d63f33e01ab73ce8fb3fe104da7644df30475b0fde81ba","./WavesWallet-iOS/Resources/Assets.xcassets/chart_arrow_green.imageset/Contents.json":"5db3c4dcf7fd5e59150fb82773683b36beada0a4d002d14b3c7c91139e0e6bf7f74181671ae909cb503de85ba9d2c4c0cfa062b0ca9f727a8fe54334449f3f90","./WavesWallet-iOS/Resources/Assets.xcassets/chart_arrow_red.imageset/Contents.json":"6f8a5cc2ff77f90ecaa74f4adba62f8f2da49306791478b536ee9059c8e5505560b5083ee148994edf4856217b2291948b4936e48b394fbbadab710f47afa076","./WavesWallet-iOS/Resources/Assets.xcassets/chart_empty.imageset/Contents.json":"ab4ca534ce5c070599f769e4d02c1f99b509be97d75fe83477d948da40306e0cb9f243487d49de7335930d230587e1b63d585d732b54ea674181be9af89b7487","./WavesWallet-iOS/Resources/Assets.xcassets/chartarrow22Accent100.imageset/Contents.json":"e022504c9093a266923cdca2eca2336f1d0006bba8213bb705f1470ef7d77d7b11ca67d233a26f3f570cc8ed83381e4ddef9dacdd1b13db1ab5b316b6ffae671","./WavesWallet-iOS/Resources/Assets.xcassets/chartarrow22Error500.imageset/Contents.json":"6f8a5cc2ff77f90ecaa74f4adba62f8f2da49306791478b536ee9059c8e5505560b5083ee148994edf4856217b2291948b4936e48b394fbbadab710f47afa076","./WavesWallet-iOS/Resources/Assets.xcassets/chartarrow22Success400.imageset/Contents.json":"5db3c4dcf7fd5e59150fb82773683b36beada0a4d002d14b3c7c91139e0e6bf7f74181671ae909cb503de85ba9d2c4c0cfa062b0ca9f727a8fe54334449f3f90","./WavesWallet-iOS/Resources/Assets.xcassets/check18Success400.imageset/Contents.json":"ed77413519a6ed95a2ecadca46e9e0d86d330627518702440593c90da30bf914739e3a103cbec068612b35017964a98b1b6eaea72e107b3001ce9d5e4b0cbbc4","./WavesWallet-iOS/Resources/Assets.xcassets/check_mark.imageset/Contents.json":"ff8ba44887ae473d5789ac1198ec93bbc0ea7db877b8d1ed8fe45c9041a0927b68f7bd9040cbc96b5f871fb38d3c28dce2489ede265ef1ab256a167d5a35a878","./WavesWallet-iOS/Resources/Assets.xcassets/check_success.imageset/Contents.json":"ed77413519a6ed95a2ecadca46e9e0d86d330627518702440593c90da30bf914739e3a103cbec068612b35017964a98b1b6eaea72e107b3001ce9d5e4b0cbbc4","./WavesWallet-iOS/Resources/Assets.xcassets/checkbox-off.imageset/Contents.json":"1881a3fc3dd7e3335f78a8a963120534bdfdec564ef42c0bfe5843a0a0ddcc5d6bca460ad76e48371fe92872b275504151b16a382c75dbf8e3a8c48f031822aa","./WavesWallet-iOS/Resources/Assets.xcassets/checkbox-on.imageset/Contents.json":"3cb6f4e7c6f2fafc9d49f9288084ed467c60fb54bb36d241a7c764aaedd10fec4b719f41ab76cde9c77060a1f07ce392f40259bcfa461081e5040777e7d43fad","./WavesWallet-iOS/Resources/Assets.xcassets/clear14Basic300.imageset/Contents.json":"9c333f0ec627894766390a8cfe9bee15e3b45f2e3326a0e94a44318d1e0eff88418e4b84008ac805854a99932deea0e4586af97c475422ac75e6a9568710a028","./WavesWallet-iOS/Resources/Assets.xcassets/close.imageset/Contents.json":"bc49a5a6ceb4304adda2da1698c1edc9c44a1e722370d2ef09fc23199ede8c8781b5a3001769894993468bf58a63257fe9fac9d4a820763eab73d0771b4aa562","./WavesWallet-iOS/Resources/Assets.xcassets/close_lease_icon.imageset/Contents.json":"6d9afe42880f278e2c8b52c1ef03a171fc0a7e66588491f33923ecc16237aab5e9a62946539c13366c39027b675821bd048fc9ab3c00335923b18dfb69ae45b2","./WavesWallet-iOS/Resources/Assets.xcassets/copy18Black.imageset/Contents.json":"b1384225d4bf933aaf97321f9bf04cb17ae1302cc3581c4f47e4e75de16663b925e89166c30a96f7c05506d5720f301be1b26bdb391bee5bbdda1b0edd218288","./WavesWallet-iOS/Resources/Assets.xcassets/copy18Submit400.imageset/Contents.json":"0c94d08e42d2134274ec2dff21a1e46a1da990dccf46e9f456abfdd6229a30bf9b39e12bf721bf393056438a50bc64675019783294050cb83289a1c3099995fb","./WavesWallet-iOS/Resources/Assets.xcassets/copy_address.imageset/Contents.json":"0c94d08e42d2134274ec2dff21a1e46a1da990dccf46e9f456abfdd6229a30bf9b39e12bf721bf393056438a50bc64675019783294050cb83289a1c3099995fb","./WavesWallet-iOS/Resources/Assets.xcassets/copy_black.imageset/Contents.json":"3000de98e86408b260ad6273e8c716dc16c1c03f423af009dc32d24bf1d5c8ca63aacbf8588c898d23593bf383a8a97260db2d2c3fd9d14e239347c46ced82c6","./WavesWallet-iOS/Resources/Assets.xcassets/deladdress24Error400.imageset/Contents.json":"b2045335943c0d1255c624830c447bcd598688ea5312a2dc42734bccf55abd23ec74804f996fbc65bec68219b7083007a15bcd6147f3e3f7887391365980ac56","./WavesWallet-iOS/Resources/Assets.xcassets/delete.imageset/Contents.json":"b4f92c72388dd1bf9e501e684eb0d20a817597c18498afc2cd3cf73e6960e1a3ff13d66ce682000e4ac45d44eab197b5292f59e1511a73128ac796ad0d5694e5","./WavesWallet-iOS/Resources/Assets.xcassets/delete22Error500.imageset/Contents.json":"6c69d6bde8aa72404e8b3d3c4c6de10a754edcd80e2b48e7694435659020b2333d67aa8b4472bad8b503f967afd922fb3143b49ec157789a30422fd2d68dfdf6","./WavesWallet-iOS/Resources/Assets.xcassets/dex.imageset/Contents.json":"7709021c8bed9e1bc6b541912c0ab5d24148ee2d7cb3357e7b9b76662d540889a280b15a0f159fed918f08099d4b52e6e0d0a22e5bc46f81270098ffbea87eff","./WavesWallet-iOS/Resources/Assets.xcassets/dex80.imageset/Contents.json":"68d5e813bd4536455cc7f0280dd02029add94a662438626c9d888e8b00e7061c7ad5b0dae4e2b736d625014983b0a287a15f77c7d16683f7dae398527fea5551","./WavesWallet-iOS/Resources/Assets.xcassets/disclosure.imageset/Contents.json":"1c49f13b72f32d9238d5fc2a9ec8beaaefe9877c7e0227c47ea2325c783891793068f0be26bfa1b289a623d205cb85f5cfefa692c88b4e8a4566fef1cc87b918","./WavesWallet-iOS/Resources/Assets.xcassets/done_btn.imageset/Contents.json":"e68bad5fe9a16b54a60c3da5e7e16b8ba282f1c0845e3bf223fc398bc8b5cc508d4237360a044377e46cc58cc484bfa1b73ee6092f5a131bc64a2f9171aafcc7","./WavesWallet-iOS/Resources/Assets.xcassets/down-chevron.imageset/Contents.json":"ed176181b4c14d26af5149e1517b749c8b1157e0bb5171f4c110b11f4e5eda35bc86099b54db4adf5cd9a26599788847d71ad1c9f6ae49a472d40d86b564def4","./WavesWallet-iOS/Resources/Assets.xcassets/down.imageset/Contents.json":"815bc6c7a93b1c049e8ba7d5bf96bf3875e28eb10c0e45cf2f408bad400272f7df2675d8485f62f559cfddd202fdff82df035eaa0a78b0c1ef40c8b4f13207a8","./WavesWallet-iOS/Resources/Assets.xcassets/dragElem.imageset/Contents.json":"647ea43205784d751cd50fe43579a44bff94956f802c49f6f2bb78dc92ab3698d824e04f635d2cc208d9fc1b693279550b47aa89b4a7b6d477e6c04368bf2bc5","./WavesWallet-iOS/Resources/Assets.xcassets/dragelem22Disabled400.imageset/Contents.json":"577265127240785cf92eab7841856d12f7882936b314d9ea9fabe5bb7c304e9a8cd804e4c0523afbc8886f92924b1ede510cef61a3c9689659a2bae10fc9ad6a","./WavesWallet-iOS/Resources/Assets.xcassets/draglock22Disabled400.imageset/Contents.json":"deea1aaa390e1155ad1a062723d8bff5faf0bf407a96a8ca6e1f79e3b2912aeab46401b00f7a28ff8bef7dc23a02ab678078ca622be4a36a67a254f58662bf52","./WavesWallet-iOS/Resources/Assets.xcassets/edit_address_icon.imageset/Contents.json":"e616c3c53358b1ee80c3a9e7dd536f185e4e3f85f767b090b990a82baef456b417d542440bc13ceab98603048d4ae4aebf449abd438a02f29582053a5545f829","./WavesWallet-iOS/Resources/Assets.xcassets/editaddress24Submit200.imageset/Contents.json":"8fcc90fa8fa7629efba15f3286494ee0fcc0d9176b3c5212afa34d745ba1b2810c0127bc58be4a5a659a04753d54635b4591bcce361ad18a2ac1432e061244f8","./WavesWallet-iOS/Resources/Assets.xcassets/editaddress24Submit300.imageset/Contents.json":"e616c3c53358b1ee80c3a9e7dd536f185e4e3f85f767b090b990a82baef456b417d542440bc13ceab98603048d4ae4aebf449abd438a02f29582053a5545f829","./WavesWallet-iOS/Resources/Assets.xcassets/eyeclsoe24Basic500.imageset/Contents.json":"18480b32ebaa61075872708b9db3b85800fc4a5e683695abb7f0b9a85dd167d8a4e52e491063100a04e236994713ef05f0c87f49e715ebdb5485a9492b4be6dd","./WavesWallet-iOS/Resources/Assets.xcassets/eyeopen24Basic500.imageset/Contents.json":"11954150342e1aec0c288b297e13bc3ccf7e30233f45155107cc1a9aeedac35b598d2395ea63f76e8843e56448126fd66454ec2dc47601b4f9cdd26c5033ee16","./WavesWallet-iOS/Resources/Assets.xcassets/faceid48Submit300.imageset/Contents.json":"60d1147e25b545fb3424b1b579b01b03fa77252f48a7849cd3804b24282e2028df579f5fd008edeb5afdcc4e4ff05d6b8945f25d15866608b76fd00bb747b807","./WavesWallet-iOS/Resources/Assets.xcassets/favorite14Submit300.imageset/Contents.json":"1f76d0641c2bfcd5b27b553e3fe330dbbd73e154f4458565c33a8e0b7d5294b05874950190ae460e5bd6e52467263bf4579ef9bcbb7431228f70b5a8c93b612e","./WavesWallet-iOS/Resources/Assets.xcassets/favoriteMini14Submit300.imageset/Contents.json":"425d228ea1b8f147fe3a95600d5ecfdd2235b7846e44cdfb5b818804a604c42e035276eb8b97eea8787974c5c31c3abd08749955e793897ce347100f6fc72373","./WavesWallet-iOS/Resources/Assets.xcassets/flag18Brazil.imageset/Contents.json":"6961a1323363ea1222efba0a9254154454641bafbee237fbe5a797488f3602760fdbf9d47c9aaf48166b2f62126a24fb2453026dfecd74e051d7c1554fc4c458","./WavesWallet-iOS/Resources/Assets.xcassets/flag18Britain.imageset/Contents.json":"13cbfaef05e92820919f13bed6b577205a877c543e7dd7bec7181f0df3f865a46d52daaafd8fa5b68759a8dcb99db946c31d6d2dadb0f8f0e5c3d545c3019bfb","./WavesWallet-iOS/Resources/Assets.xcassets/flag18China.imageset/Contents.json":"2ccc43fec266b77a97efebad44ddbbb2f5af8709034984602461c738dfe01d4fe50ab3df0b0a36f881dad5f67213d3970c6b0e90317d23c9046a3557c8191241","./WavesWallet-iOS/Resources/Assets.xcassets/flag18Danish.imageset/Contents.json":"32f1ed0cfac41e668919016132c753a56155d1640dfad437c1ceb2432a215af6de19d456e4f16ef3d22927698a030d729d9c12dee0c358b7df0e8cac866f9b72","./WavesWallet-iOS/Resources/Assets.xcassets/flag18Estonia.imageset/Contents.json":"9963592c03f14dadf6084395366c3d6173a912dc757b0e2743ebcbaad5b596559207ca12944393e95fc7f732f6bec39736ac0e59abe5908b6c893fb15af319f4","./WavesWallet-iOS/Resources/Assets.xcassets/flag18France.imageset/Contents.json":"ed030a3860ef58884e06c6ab1277a9cb1bf1fe9474fef749c9ae06399e38b59b6f9fba55245289467b259b3cd4ba823d9ae403ba3140d54619a74efcbef8fac6","./WavesWallet-iOS/Resources/Assets.xcassets/flag18Germany.imageset/Contents.json":"580893c8f157f0d23c14f125a20b7abe5ff8b8c747338cf27399763251f38a0322c8900818bb7191f34c9a631ed89f9be834562673644fa220cbd3fd6aa28098","./WavesWallet-iOS/Resources/Assets.xcassets/flag18Hindi.imageset/Contents.json":"b33022fcde29a3fee6bffb8d301934647eb41ec642757f41d808f8da07e7a9a2010ba74a78419038ec3fbb033a9349652f7f3b8f9db2fdb4e2aba14f9d1284b5","./WavesWallet-iOS/Resources/Assets.xcassets/flag18Indonesia.imageset/Contents.json":"c691fc2971c198b2d4ef9a3932c95d3671f91e974e388a0a3bbb708da7033c467754bd044f5ecb42517278386c001cf5527518e7610d514606b1f574ffae119b","./WavesWallet-iOS/Resources/Assets.xcassets/flag18Italiano.imageset/Contents.json":"9b425de25f9d00722fe2dee63fbe053312023c92a0894623bd7eb310f5543da2f873d00387efe062d42fc97505dc1e31651c64b48fc79d56d4f2a8ef70457eee","./WavesWallet-iOS/Resources/Assets.xcassets/flag18Japan.imageset/Contents.json":"426be79b43be600a9e7c54d06e26130db11197cf3f665a25825212dbd974e47f9c8edaaf5894c5dc2cc13ad3bb07d01db660cb7c70afb0c41d750a530db1a425","./WavesWallet-iOS/Resources/Assets.xcassets/flag18Korea.imageset/Contents.json":"97792332dc60ebbd16fab759f7df545410e5c59b99a3d15babe11b24a624018f3b1aae3b6912279a8d6ca9cde4b0624ff1c59a52776eef41633d189f3b97c7a7","./WavesWallet-iOS/Resources/Assets.xcassets/flag18Nederland.imageset/Contents.json":"4303a6f3889719496bd87dc4874459f8c5a1e1c37967f2aadd59b73ac491f2e38106bdefd76489b12c142cd1a38fe694f1b9ec4a34d510247b75c9e1830e4a25","./WavesWallet-iOS/Resources/Assets.xcassets/flag18Polszczyzna.imageset/Contents.json":"264725a158ac1acc1f974c9e5880df216034ec8479acdb0868ef4c63f0a1284de07602e69e328a404ae66638d1fa6719cc460d63e53258aa92685011eadc08a5","./WavesWallet-iOS/Resources/Assets.xcassets/flag18Portugal.imageset/Contents.json":"73310c8524e56cbfb7d938ffc3e5ddfce650937963d3b05359c423aebb1933961ad934ba004ec7b3ac8fd03f9cba0e4ef44a61adc537174f685cc2852f1aff88","./WavesWallet-iOS/Resources/Assets.xcassets/flag18Rus.imageset/Contents.json":"38670372ff45778390065225debe0ae2d2891b2eb9aedc86bb321d618bb3abf9dae1566c0e86717b19ac2c292aaeb07261b41df4204e50ed9d346b43e2486265","./WavesWallet-iOS/Resources/Assets.xcassets/flag18Spain.imageset/Contents.json":"489067d285e8ee2861438f287f061a5d080c240b7f7dbbe461690c55b51aa86ff292b174aa1a848b4934c7bb83d4dacc2410175eab90328c206b5a0ec5577200","./WavesWallet-iOS/Resources/Assets.xcassets/flag18Turkey.imageset/Contents.json":"0605f5ffbb9f302ee9565dbbfbf36eabe8895531a420687fd6bab97677a4bf5092d91445adb4456384d6ddebb5d3f004a3c269ffa60ac438fd40354a2a95e9e2","./WavesWallet-iOS/Resources/Assets.xcassets/forward-chevron.imageset/Contents.json":"17814b14be355e4bd582db53a573b51ecde525a65813fef3b041afa354ad2bd4db54fd024e698dd5563ac50646471caf0f69808e6441642daf231feb5cec8576","./WavesWallet-iOS/Resources/Assets.xcassets/hide.imageset/Contents.json":"431ec1c80ab91a13a1558ca5a291f2694f4e67ad4085c4efabc95e5743ec17ebe9b456d3b19b97b5d1af5de63ea743e008a3cff197d40b5f57194f2aa0af1614","./WavesWallet-iOS/Resources/Assets.xcassets/history.imageset/Contents.json":"136e427e3f42321d35565e9ff3a1fec1523c8a02f91c5684373fcd8528b10250cf51f41d395145b5d90d14e506e3467b8ae55ac8b00d22a2a7dd8482465fd3d8","./WavesWallet-iOS/Resources/Assets.xcassets/iAnonim42Submit400.imageset/Contents.json":"b9337382bfa1fff449c7ef35ad105359d531be7b4d2b6272c8a4795c2b35ad761be8a7c17326e02592a528ca8380a02a931674c0cd1c8da56d93bbc59d0bbbec","./WavesWallet-iOS/Resources/Assets.xcassets/iBackup42Submit400.imageset/Contents.json":"2220f1d796a539977b965fd90811ebce21f9c05acd35e0b501305e100693896441e10e22409d068d325f25ea110c6df1afd3dce30a67242cd39b3c0f05f8c47b","./WavesWallet-iOS/Resources/Assets.xcassets/iMailopen42Submit400.imageset/Contents.json":"e2a3f52264cf52d6e805315be244bb25d4ad3fc08f4fbb4e0bc996ac0b7b7d8c60565d30011cbb7805cf003bd6a7abc1aa0aa450031ce0df4021c98c333b7584","./WavesWallet-iOS/Resources/Assets.xcassets/iOs42Submit400.imageset/Contents.json":"a29d5a819b52d7dd5bf15f1edaed771dfffbf16ed42611ab9a33f00dd6defd23df0a0fb863ed5979868aceea997ecd3eb956bc749ff6c74d5eadde0f210116a1","./WavesWallet-iOS/Resources/Assets.xcassets/iPassbrowser42Submit400.imageset/Contents.json":"d253c88c1c81eec21962459dfab29617e334b97c4676f1c73d1c4ec1a29a64f030d92caaddfd046db091ab1dd3a87c72fcf210698631cb30bba9757c782452df","./WavesWallet-iOS/Resources/Assets.xcassets/iRefreshbrowser42Submit400.imageset/Contents.json":"040d61176b5d7cd1611ed0a0601fc8c99148e43b8e1cbeaddf2e6223f0768c1c58a14cc20ec15d488b0299820cd83ad0f496633172e4942026c5dcab97c9c592","./WavesWallet-iOS/Resources/Assets.xcassets/iShredder42Submit400.imageset/Contents.json":"59ea7fc487235cb67446b020ff3e3aaeb126831fceefbd1ba12f3c11aaba8a9172bcfc7991e638100c8841d079a55498aae28d105e07821381f2b20370d43ffe","./WavesWallet-iOS/Resources/Assets.xcassets/iWifi42Submit400.imageset/Contents.json":"69370cfe9c80fe4864db6a0717dfb7d562a584b40a06f3b16a513e6d893644c8d142482cdf9b20dc9c252fd2ef2dd4d37b8578cb23fc2c15f1f87056fd87b8ec","./WavesWallet-iOS/Resources/Assets.xcassets/icon-btc.imageset/Contents.json":"c28613265353d8f81aa835daa31e3eea4f0644d1a5844bd5caa3da58273952142554f8593371615707793e16a7a3c456dd981a21160ea3d12781c3af3596b460","./WavesWallet-iOS/Resources/Assets.xcassets/icon-eth.imageset/Contents.json":"1777840b6f7bfb28b52395b2f141524e199d23910a7d9d3e2716ec597e635c785d075068bf8d348e17c4628e150893e85c8e6232484c7b0a68cdd2cce8a560e4","./WavesWallet-iOS/Resources/Assets.xcassets/icon_action.imageset/Contents.json":"afbc69922cc68ed675801889f4dc4e36bdcc733dbec75b235a1b7d81bae9e5080ff36e8b6460561ade20be4a62f2a4d66b444c81ed13bc25d3f754b8de294f71","./WavesWallet-iOS/Resources/Assets.xcassets/icon_cert.imageset/Contents.json":"03f433bb6c185cbd1a008f7a04e9d9235b4522052051aaf13acadbcf5bd8e0b996568964567ff660d59c465fd55467611acbee3fba3b345cf6d79dc31ff6d5b1","./WavesWallet-iOS/Resources/Assets.xcassets/icon_exchange.imageset/Contents.json":"ee77f7f5939cd2d370f8be18782f5b39612ced1c808b99fa999c5d6da6e7dc243b76f8528a1ce0359b3e023bc84b7a8a7df267f63248a191551a304b4c793f8f","./WavesWallet-iOS/Resources/Assets.xcassets/icon_fav_empty.imageset/Contents.json":"3fec0a95e9a210c7a51f6c54c1c293fcc61ab3b668bda57d92c209cbeeb33c210c8924c46bde755f074836c65bf5be95f29874e2efc0ea0c475307ca3af9253f","./WavesWallet-iOS/Resources/Assets.xcassets/icon_lock.imageset/Contents.json":"deea1aaa390e1155ad1a062723d8bff5faf0bf407a96a8ca6e1f79e3b2912aeab46401b00f7a28ff8bef7dc23a02ab678078ca622be4a36a67a254f58662bf52","./WavesWallet-iOS/Resources/Assets.xcassets/icon_menu.imageset/Contents.json":"441ed443a1c9bbd49643bd9b4bf9c99c31469e6ab6ac135cd0f001f95eb5fe6e51f74fbed9c4fb199a1e9ca1da477d2f890725571654c1a425006b762b1b7351","./WavesWallet-iOS/Resources/Assets.xcassets/icon_receive.imageset/Contents.json":"46a26c7220647eb1355974d6fb193381742d7c464cd52c058acecd73dc5b2feb54b6c589b82e63185b2097d3152790198f96f049e718bbf2b3b08803ece3aea2","./WavesWallet-iOS/Resources/Assets.xcassets/icon_send.imageset/Contents.json":"945aa0881c5272269e024993ecc4bbf755889e019d874cb8872dff760a6be4100eb9a2cb42966c2c908cd1fd791546bbff751de684521d8fc5149a58d5ab2182","./WavesWallet-iOS/Resources/Assets.xcassets/icon_waves.imageset/Contents.json":"0a76cd41830d37999aea7b06b35728fad9abd6268f162c56e89b83cb8f12873e1afa6e1a2cffae76e8a3fbd87ccef1dc160172de2864a99999ebad112392d27f","./WavesWallet-iOS/Resources/Assets.xcassets/identifiergateway14Ocean.imageset/Contents.json":"c24b8e3e4f62118bee06a7222b88a0e097887dce40415da336843d578a3fe6a3f14ec38a892a03a59ff3458d87c67a161c56a08ea2aa37380fbbcd5e4b4a9ea2","./WavesWallet-iOS/Resources/Assets.xcassets/info18Basic300.imageset/Contents.json":"98d7772358eb986ce0fc7e2452c66d0183d5984fb4b246b73713027f162d717d1cfe731075ae3b1820d4ea457b58f6c297dc3755b9a7e700b6143ce5295d43cf","./WavesWallet-iOS/Resources/Assets.xcassets/info18Error500.imageset/Contents.json":"53af1ab831dcdd6d4131a74035da141e4df2fc2898515ef51f3746de1faed3eb1c3071b3f5881e261e203e603c017c8583269ca771c9a903b9477eb222c83128","./WavesWallet-iOS/Resources/Assets.xcassets/info18Warning600.imageset/Contents.json":"1c732dfaf70bdba1fc7d48a031a518fb7b4a38a28519e25728d2b4c73ad20e18492a5616fb867061569856dbc7a0ab7d3f4acef72bb7a6e2395998938687ad37","./WavesWallet-iOS/Resources/Assets.xcassets/information22Multy.imageset/Contents.json":"1f0d901b0cfe6ba07b431a76d7ab108531eacc7ec9cd29ed5ce942f20007d24ce5eb1f507fe7b4b7c144fdde1dd34b68ca8ed0f7252f3eda82dacd069cf8dcdc","./WavesWallet-iOS/Resources/Assets.xcassets/launcher34.imageset/Contents.json":"b6ab8b03b450bc8220f207d020a2c4085b384c7e6453e4f68b43e1210cc7c97ced59f9c4f3e932943bae95801198bba16e2a8e2a6b9f47c7a6d6f716bea0b630","./WavesWallet-iOS/Resources/Assets.xcassets/logoBitcoin48.imageset/Contents.json":"d62c20e68e31b925927375fb10f2cb9d4a2103dbdc0d3343a94be545cd633b989e68d351e1043d4af84411c26d71177e8ca2b7ccc8af5ad20a3664616295f69b","./WavesWallet-iOS/Resources/Assets.xcassets/logoBitcoincash48.imageset/Contents.json":"17e8d6a58e0bd482db54612a6fba2aa8880c20776da0bfaaff2ee7ec4ac4cff623f58e961632a0111eb05897a8d7479d402efaae630ada6781424b768d9d39da","./WavesWallet-iOS/Resources/Assets.xcassets/logoDash48.imageset/Contents.json":"d1a7a34a595af630eecc5a03beac22453c4aed9a82b8deadbd415aad424753c3704377dd23c6f5192bf25e6398409d87116cd84ac90eb0f932ccd39ed691e959","./WavesWallet-iOS/Resources/Assets.xcassets/logoEthereum48.imageset/Contents.json":"100e2084c8ac32f9c3097ee6d144a5ce1d098135ae33aff8caf139310a006a83a65d6619129228c9dcd540992cecb0d3ff57906a4025925627a52f32902eeda7","./WavesWallet-iOS/Resources/Assets.xcassets/logoEuro48.imageset/Contents.json":"f20ae566501e180d6384ed03e7e8ac623e9222caca389cf676da749675b12e0c14c5b9c83e91bccd7ea19847f0a043ed76e7a0d6400963accff383d6f7dde739","./WavesWallet-iOS/Resources/Assets.xcassets/logoLira48.imageset/Contents.json":"51b3ffdc1d9c45bb546eb9328778c01988ca18f9cfc40444068e5f2124f25f7032e7439e7ca3cdfd4a52429f549710a8e778be95129deeb2801f248184096e6e","./WavesWallet-iOS/Resources/Assets.xcassets/logoLtc48.imageset/Contents.json":"30d479022b33745f064d99bc97c93caa93feafb1e2dbc4d5c1d687adc7a98a1f69f2471261c8034d06520c7bc15d72320167eae5f66262577ced00fdf3e8795d","./WavesWallet-iOS/Resources/Assets.xcassets/logoMonero48.imageset/Contents.json":"348920d52fbc8878ac750abe031e5bbd98e13de82c515feec9b7604713972cae7df8594dfaf30bc76c914d5e62942a2cea8d1f26ff8d7bb4be94e1e26d680245","./WavesWallet-iOS/Resources/Assets.xcassets/logoUsd48.imageset/Contents.json":"4c5c17e6d7e1a3bb348d6288f6150aa4f88cf04fd72c0c8b75e2ca282281ae3e3d6107464790d44112ea5e3ba31517623066a37a0f622fb2cbf12f1c28290d1c","./WavesWallet-iOS/Resources/Assets.xcassets/logoWaves48.imageset/Contents.json":"090966951bb363ff97afe48112cf30a2e677f179b585e73f9f576e95c9b8f213a569abb49219d25986d0949543d6a926629e1537fa11b09e9b5ac9ae8c4b3772","./WavesWallet-iOS/Resources/Assets.xcassets/logoWct48.imageset/Contents.json":"900e0bdbf00ab18ad38c4c3fd9c18ba076be77312cb96f64c7ef073bf965ac110ea15ffc0930825999f56b47698d217bb571ddbcd7d8585af4f58d51de2f95fa","./WavesWallet-iOS/Resources/Assets.xcassets/logoZec48.imageset/Contents.json":"38296beb829d96c660d4ec2fa864746ae6c257043e9d40fb340bfd912aee4d729b005a94f5b78d87e069ab5db93b890965c4c8b8f8018fb43165197878d32709","./WavesWallet-iOS/Resources/Assets.xcassets/menu_discord.imageset/Contents.json":"aed58673fb6ad6c71a6daae6029100ec754e5ae76a2f1e37d2ef513d3c31c401e44ba42b6fe7338979f110ced511247f05c221d7cca1483040fb697f4013d627","./WavesWallet-iOS/Resources/Assets.xcassets/menu_git.imageset/Contents.json":"ba3a7e51d6342fb117fdc13eae3d9966fe331d0195c5c95b20cb8b444a4362c5f5c95a5f6c9443d76299b722f1a53182a64c34aa43770105ad8373b784ad6e78","./WavesWallet-iOS/Resources/Assets.xcassets/menu_tel.imageset/Contents.json":"cada708b2e902827fee5cd522d6c992e069d2f86506d60887358ba4cac92b9d589cd9a7b22902842d0d9ed1c1816854f0e2c9b431516802575b13ecce62fdb5c","./WavesWallet-iOS/Resources/Assets.xcassets/menu_title_logo.imageset/Contents.json":"b6ab8b03b450bc8220f207d020a2c4085b384c7e6453e4f68b43e1210cc7c97ced59f9c4f3e932943bae95801198bba16e2a8e2a6b9f47c7a6d6f716bea0b630","./WavesWallet-iOS/Resources/Assets.xcassets/menu_twitter.imageset/Contents.json":"2e685a625a0900b1b68b12b976bf8fea906923937d16a63f41bc0ad314d0be7ce437880d9c41ac4bb4d91e139faa954bf1f3668fee564765e3e2ffc62760edc9","./WavesWallet-iOS/Resources/Assets.xcassets/minus18Disabled900.imageset/Contents.json":"7f94f594b982225ab71bfc9cab87a36f563e36b0b28604ec1f70ff9b9b9776babaf2bab1b38768bbd149c6b29d68c5f2dd66086dbeead704de99e505517c4147","./WavesWallet-iOS/Resources/Assets.xcassets/not_star.imageset/Contents.json":"dcb4386a35113ddf21f2ae56dd664e419f1c013fafeb7810baa877aa73aa357ee836cb72ad095a523465db80493c04f49d0e929978db0a27c59daedc3ccd2586","./WavesWallet-iOS/Resources/Assets.xcassets/not_star_btn.imageset/Contents.json":"a0acda4f41d78287d30d3a6a4c17d4bf752a57ec17659c374ce99be8c15fcca20db2165b7bdefae22d21f8684f76ba7d7669efc104b27d27d72f08ff53fcc6bd","./WavesWallet-iOS/Resources/Assets.xcassets/off.imageset/Contents.json":"46a0f867bff0c3d1cb40324017648ba87d5938308fb22caa8713cc581a09be0b852c0404aa397f3f05c3fcdb67f841f9acd8cb12c19b815d4ad5758b9dd4af4a","./WavesWallet-iOS/Resources/Assets.xcassets/on.imageset/Contents.json":"7911ba1ca19bb82fea09bec4fd1f2ab78da3f8739e28f50ce8280a9680eda2dffa34763b1f077ec00d6894c2929a3d2f820811c8212d9dc9675b9385acc4fbcd","./WavesWallet-iOS/Resources/Assets.xcassets/pMastercard28.imageset/Contents.json":"3035abeee64cb6a00985d83521cb32df905c47b079dd3058cb826d2302549824031723bcf2625212c5a1fff4906bfdec82115a16a271272a35b0eb2feb04b0f0","./WavesWallet-iOS/Resources/Assets.xcassets/pVisa28.imageset/Contents.json":"0855dc48050bb126d61304ef93f0baf5acbd0e452d83c7b0a89ff9e73f3e85e29cfcc54ed5e7a2f3bb004652a17477616813434bb233ecaf0c12b288e196f0c2","./WavesWallet-iOS/Resources/Assets.xcassets/pair-not-selected.imageset/Contents.json":"b1129e433015ff5c6cb6f9708387d7ef098358073c29c82d7a44979fe9abc0c509e5e31c5975fec9d78977a30ac098ed03d3fca12da519c5e1606d1e05e3010c","./WavesWallet-iOS/Resources/Assets.xcassets/pair-selected.imageset/Contents.json":"99010a71cbc8228e8d6805a6957241e8d5899362d6f47c7051b56b55d7067d03d128decebd1b0e9714c2a872452d8ddf5ab6afa1bc8a85f067b7842d5a208096","./WavesWallet-iOS/Resources/Assets.xcassets/plus18Disabled900.imageset/Contents.json":"8491bb0b53b3a5de63908cb2173cb90fcd318ffac351c70a8e07194c4114b07f2497d65e70916eb2be2dd177b7040b6854b6c457d0d40d0a8868e5034d91a54d","./WavesWallet-iOS/Resources/Assets.xcassets/position18Black.imageset/Contents.json":"c2ecd8d3679173108608508379b438e7113cf9f56850e37601fab62367709a1acd21a1109404365d80ff9cf595da0b836e6076bc78ca68f7ab86157b74b54815","./WavesWallet-iOS/Resources/Assets.xcassets/qrcode.imageset/Contents.json":"9b009283476acb61c04f6998239dc0866f7ea5514379f1504e3425362ee785004f1b2f6f211397270632e67bb064a3e9251e9cb204a225acbdb0423637089641","./WavesWallet-iOS/Resources/Assets.xcassets/qrcode24Basic500.imageset/Contents.json":"9e052134db4615378f8be4bb121480ec108d16f97b9df1396f50ca5525b1044d8640da8f343555741ce7ebbbeca69b105eef8ab650cd0ba5459cc7c4558c41fe","./WavesWallet-iOS/Resources/Assets.xcassets/rBank14Basic500.imageset/Contents.json":"a3d69be2414ef6ebe2910df8b21d8c58804086f2edc33529473da45b7253efb39942b0e552584c49b21b5da42812b5d614c9d18dc847e385cf55cf2a9183a4aa","./WavesWallet-iOS/Resources/Assets.xcassets/rBank14White.imageset/Contents.json":"18869461dd0194d3fd38ef273b0992079ab2923d5be794bad571bd173118396631c8bc3a771f2e31e8668038d98beef7ba432d7a7d988073e318cd55cc057090","./WavesWallet-iOS/Resources/Assets.xcassets/rCard14Basic500.imageset/Contents.json":"946d7bfa74eeee5a23ccc1635b5b92fafc3b886e3e3f15b612949355db560e0d27306777e82ea53f599cfbbb6e256d2d1432cef9b4d69596253a2981257f8e76","./WavesWallet-iOS/Resources/Assets.xcassets/rCard14White.imageset/Contents.json":"41d9536ed94b1c2964760f56aacf3087ffd3860271659996547b8d28c055d7f9f8644ecb2a96ea35572e7c2665ed10d0ad150a4ed3bb78a24d103578966be1b9","./WavesWallet-iOS/Resources/Assets.xcassets/rGateway14Basic500.imageset/Contents.json":"e4a4f561c1c43c3dad19d2fc7d63b8946b51b7a323c98346d89a1519d96e462a9d13eaa59b036179c150be828308c4ce08de66d6547880ba9c026dbbdf2eaed9","./WavesWallet-iOS/Resources/Assets.xcassets/rGateway14White.imageset/Contents.json":"32119c4135c631360e586729b8f0de336e14fdc2af4f40e81f007213b310028e658e04c03935a5019c2a9af4c7ec4d528008133b32f2efa9300c9b1991ea5ea2","./WavesWallet-iOS/Resources/Assets.xcassets/rInwaves14Basic500.imageset/Contents.json":"92f6893105be7b8a6ce65a9bb48e24a0e05046a18e9087ce3ca44ab78ff8c44a18850216c54a3c4de56bf583c00d300f5aaf183a098f0948b3aa90a3343a9585","./WavesWallet-iOS/Resources/Assets.xcassets/rInwaves14White.imageset/Contents.json":"0a702bab5b1ec58314842504a63da3655062f9de513e8c797454c868625d2641c38028e2383f11ceb0aa3fa9807b35011ce4693ffe97e5cdaa03010655bd72bc","./WavesWallet-iOS/Resources/Assets.xcassets/receive.imageset/Contents.json":"f254360953fa6a37638d8f56d16e04982baa28995e4341e12a079ae5251466911e9f74bd04b2220907acd5dfd241d0b77a149bd3f5a5bb0cac752b360774935e","./WavesWallet-iOS/Resources/Assets.xcassets/receive_btn.imageset/Contents.json":"d78e7b9744232e7fa67e0346cc94d256bec66b7dacf54121cbdb88c712ed0a894e168fbd069af4e7fda68c19676e2c3f4e423b53baf27f7a156a80f5dc1fee1f","./WavesWallet-iOS/Resources/Assets.xcassets/refresh18Basic500.imageset/Contents.json":"3f799958383150d6762c056e223c8e9920ef597aae87aa1f9f4270b649e58beba5881615ea7da7b8f4e6ee8038f62550be0b0185e0f27fa5dc7160e7b62cd3cc","./WavesWallet-iOS/Resources/Assets.xcassets/refresh18White.imageset/Contents.json":"68589a3c44cfe59889e50bf4cd2d18240243fcca3ecd028594315f48e672c8e59c2988669c35905aeb7e9bdea54ce64543067d242746a3dcec07d42b692be724","./WavesWallet-iOS/Resources/Assets.xcassets/repeat_btn.imageset/Contents.json":"ed5e3fee971ad999a3e0f78491156aae224df24a4cdea1eecb8e549a64131367ecb646e1c72f5cf87c72c707a231e5e8890d156fde1381f57f52802424bae86c","./WavesWallet-iOS/Resources/Assets.xcassets/resend_icon.imageset/Contents.json":"571b3a6d244f0430d5ad0659083dee160f51f3c91909480a96f3fabd322538ecf62294eb0b87837ae2ea58d8451096cfe6985d996322aa7bf7c10c5b273550f6","./WavesWallet-iOS/Resources/Assets.xcassets/sReddit28.imageset/Contents.json":"1db109e5e3af4cecb9842399dfed54a7c122101369d2de14266f8c477838b19eac72e4b1f65c1d05ab0e094682b608974a40e7c9c2f15ba6256389641f9a3b50","./WavesWallet-iOS/Resources/Assets.xcassets/scriptasset18White.imageset/Contents.json":"69b25608ad8121fc3710b798f499b482f9f2830e5eec43edd36bdd66ae3400e3966f817055b1f084920433b19cb928e9375fa6c64c81e6c7b56bb5e6e11a5a78","./WavesWallet-iOS/Resources/Assets.xcassets/search.imageset/Contents.json":"96dcc05e8c594ebffdfb3f64aafc6f14d3faa8f74d171204ebbfec2d165adce48feddce16d52aba4175e7b503be21c07c6bd1f8772ffe46b892947ebaec66edb","./WavesWallet-iOS/Resources/Assets.xcassets/search24Basic500.imageset/Contents.json":"557d5013d8415a9626ddc66a3fc7aa20977cce69a6306ac560c6d11e5faeab566acefb36bb83de57e307ad2fb3534ba2a7bad54ffa6f79953ac604193a525b85","./WavesWallet-iOS/Resources/Assets.xcassets/search24Black.imageset/Contents.json":"33a1cd71624eb3d4ab8b7a96236c6d2bbf9a0ec1243188b7b840f34e439d8a4fee54cc041691fce5542d81530b72a8fe0a4f23d817c61a63aa41ca85166db203","./WavesWallet-iOS/Resources/Assets.xcassets/send.imageset/Contents.json":"419b8c6544a1edcbfd51bb9451d868b34383ff2cf3aedc3439883511c10dba3a20a88ce46cab5fa834a60c74e9df9b9e30bff2c15d5358960d1096277efa4d27","./WavesWallet-iOS/Resources/Assets.xcassets/send_btn.imageset/Contents.json":"3620c6b6101927000653fe417fd6f30aed4fcea234268d19a9187e341235bc0b5411303078f5dfe31e0dc2d742fca9316698820cacdfe4beebd4131decac2a1d","./WavesWallet-iOS/Resources/Assets.xcassets/settings.imageset/Contents.json":"015c33c0a45bd2e172c0b3742e41eb443461a9d0242e97c60075d19b8a7b937a6bc7505128595bebc0096b0f9fad4ad7685312b7e8b48ee833eef86c92c9d50a","./WavesWallet-iOS/Resources/Assets.xcassets/share18Submit400.imageset/Contents.json":"2b1b113053b3e6814b407677fccadc11528699cf2b7694b178fee468a9d86e216c6cea8c6d2e6790553e5c2395c6cea6623b2b1e48f7d69a9483e71b081410bf","./WavesWallet-iOS/Resources/Assets.xcassets/share_address.imageset/Contents.json":"2b1b113053b3e6814b407677fccadc11528699cf2b7694b178fee468a9d86e216c6cea8c6d2e6790553e5c2395c6cea6623b2b1e48f7d69a9483e71b081410bf","./WavesWallet-iOS/Resources/Assets.xcassets/sizefull14Basic500.imageset/Contents.json":"20912c0293e494e14ffeb474442719e62bc62c75ebe99e12c0e8e6e94467a09ac1d5facfc0b687b38111fa7cf620c852269830befc41addfa77c0e79b710b619","./WavesWallet-iOS/Resources/Assets.xcassets/sponsoritem18White.imageset/Contents.json":"136a3507c0ddc3e396053c0de8fa93ef995a21ba030cb4f9a73862960131b397387a1f467b1cb72c1857b2dcbbb323d9839e11014c842f44402c4e00c31c8f50","./WavesWallet-iOS/Resources/Assets.xcassets/star.imageset/Contents.json":"5d5a31d30d4ed9604c63c6d82cd33391a6a491d307f682ff992791eebd5c25e0443fce2ea5d2071ab2b02cd42f86d10c0fabb83822a5bab0fb5b07f30e83d794","./WavesWallet-iOS/Resources/Assets.xcassets/star_btn.imageset/Contents.json":"4204312c3a3ed6505329151e751a09cdd340f0d5f627a7e0e12deed52f2f4779e4a0e4946e0816a30d8c754e113b13485c8bdc84398da49804362c7c89c3f065","./WavesWallet-iOS/Resources/Assets.xcassets/swipe_left.imageset/Contents.json":"0cd1db75ef404caabeb4d80d5dfe507d653dcb595174adb41364c639694212bb14019fc79736c8ff995c3d3a6181600181577e82b84363eeeaf20662c37dec0c","./WavesWallet-iOS/Resources/Assets.xcassets/swipe_right.imageset/Contents.json":"7f579e7c440cc96e43fb31ce6817ffb7df4c4d353b5d46756d48db51aa050156dc5c2c4f2acd54a225414fda1da6b3b74bbe9ec691b2fd3d0d579014fe9f8c82","./WavesWallet-iOS/Resources/Assets.xcassets/tAlias48.imageset/Contents.json":"1c7b7bacc4b3d33f908e0790a06011c440ee8d70649a703c88776bc716a6a92cd188903b4b79b97fe502553267ae85586ca9377e219803f5718343f62fdd294b","./WavesWallet-iOS/Resources/Assets.xcassets/tCloselease18.imageset/Contents.json":"7f92b81cf978f241ebd61737a0a8e79c24bcf906b5339d2e9f7038a5115f3e223d5eaa215b5e6aec3526ecb132ddcae1a342da2eae8fa8e7c44131e7feaeaab1","./WavesWallet-iOS/Resources/Assets.xcassets/tCloselease48.imageset/Contents.json":"33869619beee42d4e819c245143f1f8accca021c5b479e427686853d59f7e6b631b4727a15b737a54b78aa3526360aca040ae6c38dc96b839bbea1d44f513ede","./WavesWallet-iOS/Resources/Assets.xcassets/tData48.imageset/Contents.json":"d1f862fd57a014a9e1fcb0da51dcf3f2b7ffa31b01e0ec3a01f8510a596ce04a1b2bf33bed6334edd906aaa54f9ba3a92ae3dfa39962d8e570630b3dd9635702","./WavesWallet-iOS/Resources/Assets.xcassets/tExchange48.imageset/Contents.json":"c6c74a0f0b44ecd37f5c2e283cece21faa24410d0625137fa7fcaf083b5c221e149c96511f9144349b70f4956a12b00ee1e873c35b0db321bb9f5e1f0c09259a","./WavesWallet-iOS/Resources/Assets.xcassets/tIncominglease48.imageset/Contents.json":"8ddf4092a3532162cbed32596fce113c365fc9d219f564f2346f0aa74560632c86d3f42c676f123c3421138fb57a257bbf1405bf632f4d7b1a5e635880b403c2","./WavesWallet-iOS/Resources/Assets.xcassets/tInvocationscript48.imageset/Contents.json":"95129dd1ce25c4fc79a535d11387d2a6f6468bc7d4aa3b9dcf6740e3cb86972b56c72d0802e30a3363bd505bedeec7fdf6adaf30b93795298795270aaf5ff419","./WavesWallet-iOS/Resources/Assets.xcassets/tMassreceived48.imageset/Contents.json":"c91b871b9270c813bc63c21344f9307c90a393a4a55b6552af8c3b5d0dfa1bb3eccdbc3e19c2c68ed62e2799388511bc5a3f0bdf332e4ab4a5a42305c6371bd9","./WavesWallet-iOS/Resources/Assets.xcassets/tMasstransfer48.imageset/Contents.json":"be1e47a21c913fcee79436b91aead730d808b422048e62cf1b2439cdb001438bef2e4862100ea79bdaa82284168ac3471fc085d4e73371a25ad92e1bda882d1e","./WavesWallet-iOS/Resources/Assets.xcassets/tResend18.imageset/Contents.json":"0d62f9198d8fc9793a608b14f67bf2cbfdc0c30a3a39ea7486a263704acaf098a8dd31ba9e21ef1145ef699162f9d8b045b39934c5ab6fc991766cf7e6ade96d","./WavesWallet-iOS/Resources/Assets.xcassets/tSelftrans48.imageset/Contents.json":"53eccd1f58a33b6cf7f691a665be62455c9d9c148861205eb04863f1e10f1990b421f0032e95a110ee76bfdf611a2b6224e436bbd2b107c46353f003bac245ae","./WavesWallet-iOS/Resources/Assets.xcassets/tSend48.imageset/Contents.json":"56fffb4e9562eb70233c92aeb89b3c8c507b308d577581b41862534641ef6131925b90b6fb0062c4428ea61512c43a8a11262b271f452146011533931b9b4165","./WavesWallet-iOS/Resources/Assets.xcassets/tSetassetscript48.imageset/Contents.json":"b929b2f8a5c8417f5e87bec572b08192be674dd9d2a8741d2db4ec3c8da645d42184be7c0d422b4216f32c8be3c07ef19f181dd82dfae99be4d03c3addb26163","./WavesWallet-iOS/Resources/Assets.xcassets/tSetscript48.imageset/Contents.json":"422c6345cca38ac873cc0d57c5f666d2f3332d761970c9f1a657abaf0c524aa4ca8c664735574b4c165d99752958690fc5e1f1e51fcb5c055f39ef48b43c599e","./WavesWallet-iOS/Resources/Assets.xcassets/tSetscriptCancel48.imageset/Contents.json":"e0a2afcbb8ec9a571ac5421c4bf7b7f7465300a63fc6d68325d2284c84370b1f65de250f49274a00017608eb073809b2644582e48c8ece17d8d880ee8e1d9bfe","./WavesWallet-iOS/Resources/Assets.xcassets/tSoonExchange28.imageset/Contents.json":"aaa374820b9dabb5d5a7f093e30d2a54ac78f1553bdbf9bb8175b9bff40b1dbd88de2b6c35e6d57836cfd86ba472ff2c12fd3792be1e99646ac46af878109a96","./WavesWallet-iOS/Resources/Assets.xcassets/tSoonExchange48.imageset/Contents.json":"6e7c9a86bcc40f5d29d2cf66184216195af49a3f1c3a665a9b082a13852de444a1fde2b32295c1b2ae22b2444f88dd8e0b45a301fb92d37011ca56939ada55de","./WavesWallet-iOS/Resources/Assets.xcassets/tSpamMassreceived48.imageset/Contents.json":"c59495c8e9de4c59f19be2d159bdb5b428ebfe8760ec8ccba8e21973e441f7dccf678931729d6afdbcbc9023d72ad630685925bdf976a145d3f3c6cea03f369c","./WavesWallet-iOS/Resources/Assets.xcassets/tSpamReceive48.imageset/Contents.json":"9d572cd5ac008135667799b8c664a1200c8e7838ab5d2560896d418e7174559dd7a0e260766ce6fc43c4e202eb03faece8200bd84d1266efbaae776c534694b8","./WavesWallet-iOS/Resources/Assets.xcassets/tSponsoredDisable48.imageset/Contents.json":"bd974facf4041f101d04329cff727e9bb7ab11cd236ab349f86565a14d24cca16f727d944cb2f96a1d6bd795ac7105dffe0ff0532ce6e9e8fad6b2e555f56ebb","./WavesWallet-iOS/Resources/Assets.xcassets/tSponsoredEnable48.imageset/Contents.json":"9dedbabb3ebfe6b53c9d840cffd86214884ae70b310cf93f4e550f42ec964b8ae968fb04434e8cb2f8a0c1c0381e7d36d74fb3aad7fe5c1a8564eedcfad3715c","./WavesWallet-iOS/Resources/Assets.xcassets/tSponsoredPlus48.imageset/Contents.json":"0bda9e6cf9286bbc527da2d60627b439697ae406e402154813fca526d59f8efa295274e5f63d67aca4fb1c57eb65ed1605874f1ad4e64bc93a8af9beb83e19d2","./WavesWallet-iOS/Resources/Assets.xcassets/tStartlease48.imageset/Contents.json":"663168556e648c30f2a4883280665b35bcc1e1f52a2ef4acd483a479b1d61e019b032d899fbe26940e2cdcc843cebd345b1dd2ce4a604673e01d6a27508c8d18","./WavesWallet-iOS/Resources/Assets.xcassets/tTokenburn24.imageset/Contents.json":"749de2300952aa2fc439018e72e239a426f16eea0f9799d217684e7a8d7230256c2c9ef7505a6a5401d41ba42be4354a39aa01668ee324ba4754ae5d9da7dd34","./WavesWallet-iOS/Resources/Assets.xcassets/tTokenburn48.imageset/Contents.json":"f5a32606b0fcd87be77d4ab0bb9738afd3a4b1d01bce589d88dbbb0ecb46f2ca9000fb5e7af23635d8ce3b092cd8ce82eec94d9b7c932445067d1ae8677cde28","./WavesWallet-iOS/Resources/Assets.xcassets/tTokengen48.imageset/Contents.json":"44777dbc707b6b86c510a918199af6b6991b85fb7ae0a994bfcbb01011e5e92a51cdc7bc2f632e58b67c13c918564f4751ac6d9dcff6b2bb1a3d8053fc843768","./WavesWallet-iOS/Resources/Assets.xcassets/tTokenreis48.imageset/Contents.json":"242b9de6364b9516e37a3599ffb56d4265a6ca3272d8c8a01e5b6db6cec6914f637edcd939a112edc037bdfd76a6699fc875ffeb5842f9f4b63445e69bfe9343","./WavesWallet-iOS/Resources/Assets.xcassets/tUndefined48.imageset/Contents.json":"ef706fe8eb2bb4f90ac7be4a2805d8b6b4eab8aef9170109fb396560cd45113abbffd9d32b1d9c4e80e9be5a5e1d8eedd6ad0a01a792857b20558cee6fbab384","./WavesWallet-iOS/Resources/Assets.xcassets/tab_bar_dex.imageset/Contents.json":"c50d396c2ef6b51a9ecb62322942a77715202bcda4a20d8a0e45835c254416dcee60ad8a0633206d99b77579622944b02bae3b69ca930e8856a2c45ff7b4f73a","./WavesWallet-iOS/Resources/Assets.xcassets/tab_bar_dex_active.imageset/Contents.json":"c5becc4fa45881ea14ad3e777051c990f26733d4db2be6b5d576b5e969616d89443df5f1be3daff51a2692cd3feffc6d834b9603bc476a83777ee1d16c3dd449","./WavesWallet-iOS/Resources/Assets.xcassets/tab_bar_history.imageset/Contents.json":"2b28cfe504e92630b521fe460d06de398ba084d06c8d609e3b3ac10921f4b11b4e4942ce73026984859f201a64716f83ee6029485c6b6f4a627d7b2accf89d4c","./WavesWallet-iOS/Resources/Assets.xcassets/tab_bar_history_active.imageset/Contents.json":"36aefe00ebabd6ae2c6c446eb8a4a1f27cfc2b5d0207dfffaa56286f0474bc4acf6ddeb30ea4b6fd6346199293cfe8615e1774af0a67b7ccd563a227cc5aace2","./WavesWallet-iOS/Resources/Assets.xcassets/tab_bar_plus.imageset/Contents.json":"a4a18a66f3a08dba300779dc4dbebd27332037984d1fc08292afc8b57f221d582661e67ae3491e755e9c0f8262ee589edba7a0509c92b325d3c249ace87f158c","./WavesWallet-iOS/Resources/Assets.xcassets/tab_bar_plus_active.imageset/Contents.json":"fa6a1db6899503a801ecbf076d1f482f45d1bb909b25843aba5f88e9d332649f85b7ea4f4801925f7804092edf93531a03cd5ab656f652b1c789962253707914","./WavesWallet-iOS/Resources/Assets.xcassets/tab_bar_profile.imageset/Contents.json":"0fc1995e0793b5c5c61c6bb1860d630ca040ff62e5ada9c94c233411bbcb68863e871f1ab56dc09819cb047f13a1f1a5daa1142db87aeef4632a09ebe270e372","./WavesWallet-iOS/Resources/Assets.xcassets/tab_bar_profile_active.imageset/Contents.json":"c24cf92d240f5ae4537f72cf0fc678cbdfcfb9cd541811d3a8223f2c8e488c461b22572dc8640fcfdfe8edb29c92d74ab7d3abc8b2e82b36a048f079407cdb69","./WavesWallet-iOS/Resources/Assets.xcassets/tab_bar_wallet.imageset/Contents.json":"6455140dba14464ccad23c907641e3330bd006fa9bd7b4ddfbc5742f0e05e204b1ab34045402d2cbb1d4e7e0c46e3d798c81f6222e590a7fae874c72d7e96b97","./WavesWallet-iOS/Resources/Assets.xcassets/tab_bar_wallet_active.imageset/Contents.json":"909d9aa301263e89f243ce30fcf7cb177d40195aec4ddf8a5a9d4c8ddd6f1b12dbcccb825155554defdbbd8fe77272c8caa1773d17ce0c10edd218fd6075fab2","./WavesWallet-iOS/Resources/Assets.xcassets/tabbarWavesActive.imageset/Contents.json":"55cc8aacda5fe18a2334c5163213eac299e3e591ff246a2240cccb7ce3ef137aa3003df6863f134a6ba1fb0d875c276bfb234a22c14f87a47c41c5ee3b98cb19","./WavesWallet-iOS/Resources/Assets.xcassets/tabbarWavesDefault.imageset/Contents.json":"a1da0c694219682b0bc12c5f78ad1dfe79d8e59ce2b6a4c4a7fced45a699d90e014281dbb019e6290b69510dff1234d707a9936e68774720a05ae18e412680d1","./WavesWallet-iOS/Resources/Assets.xcassets/token80.imageset/Contents.json":"a8bf7f645a6a31758554574830b79e0c94f3a91646162e53748af58b8a98bfa3426a43554937ec4b025314e6e810e8c30ff8e0b8721898b59a1d47dafe71d787","./WavesWallet-iOS/Resources/Assets.xcassets/topbarAddaddress.imageset/Contents.json":"edb7ef86c22c9b4dd38cf60e191f0c36b18cc7f285bf4af82145c03a0e29e323d0711cb6a8ed2d4c899f95e702513230589c27dee0be9fefafdfecb465ad4420","./WavesWallet-iOS/Resources/Assets.xcassets/topbarAddmarkets.imageset/Contents.json":"56f2395be168309692910df275171bd7bb86154c3210e9fdd34ef991273194499b6ec72ae8e530bfab2c8c16e2550274032f11ac223f76c233e82b049833f62a","./WavesWallet-iOS/Resources/Assets.xcassets/topbarBackwhite.imageset/Contents.json":"0e26b2fe65d0d897efe8efa86a183c9f2d48574fe12ea3cb0d6feccfacc8a6046f57e7da77361a390a91af87f4bd0d6b8ab59a0c8ad381bce01c084888b40371","./WavesWallet-iOS/Resources/Assets.xcassets/topbarClose.imageset/Contents.json":"350fce60def06fa1b6d32119e3496d5dfb1fdc841f1fa2ffea9d1b9857845dc7e3188c95ee7664598a1976dd47d07cc173c00d8b0c49b9c4d153420d6aa85211","./WavesWallet-iOS/Resources/Assets.xcassets/topbarClosewhite.imageset/Contents.json":"8db431a6501de074da45e93f584b7fdc9a75a5786ab02a57f59d5821b63fb1c5828ae63fb04d947d9ffdc220870eed9e8baf032c07e78a3e7a8ae3000babc000","./WavesWallet-iOS/Resources/Assets.xcassets/topbarFavoriteOff.imageset/Contents.json":"da4fc7abbd0357da7e7ba9c4e728d6a1ffa399a5d5b35cf23c937364a532fa11032a300b6c32f20c72c401bc73a8584b47a3af2ad780d215fa4c73d4dc48e714","./WavesWallet-iOS/Resources/Assets.xcassets/topbarFavoriteOn.imageset/Contents.json":"8b1435675843f418c1cecc6e605a7b1ad98db7d1281544c37e14d94cee91c6a5b04ca7aeb5dca4143cdebb1b601b65c3890d027336b88add9888ceb06c86ad40","./WavesWallet-iOS/Resources/Assets.xcassets/topbarFilter.imageset/Contents.json":"11ad520ba9916c16c63e67cf4a9976a5c8ff2a6c079211c53c8b8fa06b23af303d6f2ac517daaf7bb70f2328ac8a416b62bad80c584596a0c754a3b61714bde1","./WavesWallet-iOS/Resources/Assets.xcassets/topbarFlashOff.imageset/Contents.json":"2bcb09aef06460c62779e57052283c114a872de844ceabbaa98f8656402c1adf478158ba12bd5919d000728351f9c9c4a58b8aaf69feb28f75af7f5477450d35","./WavesWallet-iOS/Resources/Assets.xcassets/topbarFlashOn.imageset/Contents.json":"fc7dd178cf5c0bf8ef9284399ce96610c474c5ed08d094f9490fa20b0ffcb5098c817f2862887fe20d0f355aeb89dc8e1ab2b4160d465ffeb61db64b2fc661e6","./WavesWallet-iOS/Resources/Assets.xcassets/topbarInfowhite.imageset/Contents.json":"c0b06e2906905bd3eef9d3a6ea4337b086874eb0297b500b93d37dcecee6a0a3c4cf9c84fc3acc8883d39a6269222ab07849e0a4625115d8771daeb0eabc8b82","./WavesWallet-iOS/Resources/Assets.xcassets/topbarLogout.imageset/Contents.json":"c86f4c726e0112cfa240540f7b122fa0a1a01da27e02972f6d05f2de0443d99822a4aebd775769ccd19a756863515c2ab9d66ee9972d883e046820ce93ca2f93","./WavesWallet-iOS/Resources/Assets.xcassets/topbarMenuwhite.imageset/Contents.json":"1505117dcdb70b18ec6cf19767b4ffff57e2cc8176504e297225e3e918b3fd5c7ddfb51c70dab6d522331a26484c476c02ccce7e6ac73454bd901fd9d09640bc","./WavesWallet-iOS/Resources/Assets.xcassets/topbarSort.imageset/Contents.json":"d4230422c48e0f5c1ba260f7b84738482f5dd41e99ebce9cbcd96acfc30aef938354db2ec39a2ec2ae94399fdda09d807f0bb5b8e7a2f702f4535954a6d4b457","./WavesWallet-iOS/Resources/Assets.xcassets/touchid48Submit300.imageset/Contents.json":"a437eafcbd5f46097637a6614069a985cf6e02b8f1530a80e9493d354dbee4a7f4a4cfc2187d09a80e61cc6167f37193d5df814ecd9402cd0415468bc4e579a7","./WavesWallet-iOS/Resources/Assets.xcassets/unhide.imageset/Contents.json":"7e6e06f7fd208848495f00554968be35c3d3c06a568067a58c5cf584df91d421876eee1f071509de71aca9bb78e768eddc8d133cff94186f9f75bcadc1e59455","./WavesWallet-iOS/Resources/Assets.xcassets/up-chevron@.imageset/Contents.json":"01cdfe5cd0dccfeeb815405357283a3c5dabb658d3683800da80919d4efc977233a05cda0c6862c974bdb5d621d0df745e7f4e1df7c3c5b43ea323b49482b63d","./WavesWallet-iOS/Resources/Assets.xcassets/userimgBackup100.imageset/Contents.json":"d33c2b639099686512e06a68fb12d3b608c63fa2568f3fd1e66eda3fbf7bcea0524fc2d500c6f25688e74b3eff89baa1511a1d10d25cdf00ad6a01d848a177f9","./WavesWallet-iOS/Resources/Assets.xcassets/userimgBlockchain80.imageset/Contents.json":"45c57ef965eeab824dbc3940b849550e8f07bc7c170624d84c9d9110dc25407780c9072f73bdf63852dedc79f1b9234978ac42b85b0ca45e2d586f8cdc102abd","./WavesWallet-iOS/Resources/Assets.xcassets/userimgBlockchain80White.imageset/Contents.json":"a0e0284cd78799bc3aa01c795d13da42a6cabaeb2b39f556f5cc5e1e0569937bb072389950d428a9984d863a129fb575aad560885f85cfeab0e1b158244408fb","./WavesWallet-iOS/Resources/Assets.xcassets/userimgDex80.imageset/Contents.json":"b250ef1b12cb288f125e2648dd3423a8d837373f937c01acd77fe60233ce5f7b53a0fadf5a61507d38ccbf0da1a6eadc5f1065afd8517580268daa66a9eef972","./WavesWallet-iOS/Resources/Assets.xcassets/userimgDex80Multy.imageset/Contents.json":"85af3f2d206de565d5813e0cfc2afd34c309aee75f668757f0465c5dc835a81e4423f03bc55ef656b3e4971e9aea422fb4a229a7bd564b05c06ccd0455462523","./WavesWallet-iOS/Resources/Assets.xcassets/userimgDex80White.imageset/Contents.json":"8e7659ad415b9de0e98a85c2b71372ee7c9189076cfdb6bd72d351dd553f3c2bebd0d83a8f9bab28f204c27de5e0eff5bb43de55493071cbfe3ee698115504c4","./WavesWallet-iOS/Resources/Assets.xcassets/userimgDisconnect80Multy.imageset/Contents.json":"312fb4dc61fe33f716332c02c0f3407a0a882a9e5b64000de0c5c11bf7fac660935369f6606d4f4b09872b105c0ac6217d035318ab438def69ac6f68935aad6e","./WavesWallet-iOS/Resources/Assets.xcassets/userimgDone80Success400.imageset/Contents.json":"3d59739de1d8e25c6f1e5d878276949f39a79020f5eaf0e9141f602668cfa008fd79ffe1dfe8376bac6c2a09633814c7220c3ea07156914d74dc5ace502e3df6","./WavesWallet-iOS/Resources/Assets.xcassets/userimgEmpty80.imageset/Contents.json":"3aadce836c340b2e491854cd98a0d2bc0fee601897993de839a57fc5a33a532fbe5503d32d9234a35914f523e981565a8bff6102f91f6d8a507b2b2a2d38677e","./WavesWallet-iOS/Resources/Assets.xcassets/userimgPairing80.imageset/Contents.json":"844457b44446125dbc3dc0973e2e1c3dd633af10ffc576299291e0df8891b78a6321c0965f4e7f9a2d29b21b7e90fa500edf546d011bcdd1b94e6fa89fc2f93e","./WavesWallet-iOS/Resources/Assets.xcassets/userimgRocket48.imageset/Contents.json":"b561bf73f4700c5b70e20f6c10fb5b52fb51df4e76eaf6718c8a1a1129883d89507f508bf62c09fcf74b72a0f38b371670c8aedf43b761f6e7d9396601d90af0","./WavesWallet-iOS/Resources/Assets.xcassets/userimgSeed80Submit400.imageset/Contents.json":"34b682e238546f3f756c70e7c72c2589cec6d98eabd271e6a010159f464c18e65333f48d9f252d18bc45fc2fb16b6106e002503f6111a314b20fff06f3ba0896","./WavesWallet-iOS/Resources/Assets.xcassets/userimgServerdown80Multy.imageset/Contents.json":"7180f1103acef250f99545275c7daa97dbc82c1387dd217a44e4b11d37ccd56f0ca5b66649d882fed31e1f21749447e846dcebae2a2109c418145566bf912337","./WavesWallet-iOS/Resources/Assets.xcassets/userimgWallet80.imageset/Contents.json":"daeb2f6b4519a768eda56baaf74acf74afebc7d0c2cb067f9fcae9c5338005b31c4d81d024fea88cb80b1b133e8b676fe476f7011955be8a9a575bdb94f3b011","./WavesWallet-iOS/Resources/Assets.xcassets/userimgWallet80White.imageset/Contents.json":"32cb813da360da9f6cf4e62d69e381dc734fe75865e92c1c165401db39f04cb08aa89ad61a50a3c5231408be1d233d78c366b029340e7d94e7ed4af678961e67","./WavesWallet-iOS/Resources/Assets.xcassets/verification28Error500.imageset/Contents.json":"feb6db194890d521dfb30d170c93beb96d015b57cd370fdbef1aaa00f95eadb79c0f68527ac65d2806d0695915add453038c2720d5e952339634f84f8542d124","./WavesWallet-iOS/Resources/Assets.xcassets/verification28Success400.imageset/Contents.json":"9d3c33291469b894fedd36c7202b4056f55156042f10e74f14565370b5b91904d500f844e20de10f9ab2b662ac87940ecb7d361a753ce9afb14b0a42e93ace52","./WavesWallet-iOS/Resources/Assets.xcassets/verified.imageset/Contents.json":"588b0d141edba4f4e0f87174498e158dcd4e795b788f98b3d4f11c075922a6eb1de01545fb5c20e581cbefc0c8c564c32084f81db848ee695267f8137185ce7e","./WavesWallet-iOS/Resources/Assets.xcassets/viewexplorer18Black.imageset/Contents.json":"4e01cd2e5c0d4f3ebe18e475f16271b3899e58ac93ffe3b3fbafe9266a9b9423dcb4896904d2601fecec9fc7c5c51f40e3a20dc842919106e01d24e867096cf3","./WavesWallet-iOS/Resources/Assets.xcassets/visibility18Basic500.imageset/Contents.json":"42b4db08dfe68ccbd938910ed982cb93a10610b46bf173614e9d668bfacce9f6b0e6102267776c8bcdddf9d89759c2cce495c6b1bcb84a1546a21bf45f28efe7","./WavesWallet-iOS/Resources/Assets.xcassets/visibility18Black.imageset/Contents.json":"266e38478be7ca3da7a8a4a21656f08d200ac129dbcf3ba76a5152942af63a9f6b2785d954fc5e72bd970503345f7c526f6fa5f7e869f90d098ec511e822cf22","./WavesWallet-iOS/Resources/Assets.xcassets/wallet80.imageset/Contents.json":"ee978415ea983bafe7a1824c583e394d750ce36f42ad47d6ec3a1c1a1ec0cb114755c3162ee67a8cbbf1827b13e18454104e0a7de8ed484b6719bbad9b8f60c3","./WavesWallet-iOS/Resources/Assets.xcassets/wallet_arrow_green.imageset/Contents.json":"d44202e742ffba503875aeb8a3b925be1b73bcb4b7eb7681e4ec3c4b200bd229310c78b77d9e59bebfcb7251df7fa520509d08cd1f2972565a1c00f516947679","./WavesWallet-iOS/Resources/Assets.xcassets/wallet_arrow_header.imageset/Contents.json":"3ac887aba87c46b5d8398062a21199068337a05821dff74276dcac2bc1ce221da3ac3587c3abec12f5df917c5d5b06cf6e001c033f85a2818b73bb77cba223d6","./WavesWallet-iOS/Resources/Assets.xcassets/wallet_arrow_right.imageset/Contents.json":"8a46294107aa699684ce71e9be9f0f46b02f07e3026245f41e45e5e1f6f3af4e3b716c53ac9c50127897a6f01f93be42339ea06f03dc669098c7ef97e4de21a4","./WavesWallet-iOS/Resources/Assets.xcassets/wallet_icon_fav.imageset/Contents.json":"da2841e4ac3cbd606a67ef50d60768107102f18249bd0730cc361f9c83b211cf4bbe5775f11861c4a292f6520e58c5ad284b8d98a77cad28bf0d734499f47259","./WavesWallet-iOS/Resources/Assets.xcassets/wallet_info.imageset/Contents.json":"7bc0652e5350db4d368b1c87819b584d811378ff806552f50bf64b99f5907ad512c9cbe2c09cbe7a3ecc529e50ca5d068bf51e6e67533baeb500404db243eb3e","./WavesWallet-iOS/Resources/Assets.xcassets/wallet_quick_note.imageset/Contents.json":"7b32125f0a46bb041ddbfc9d6adb7ecd95a8bbdaf44e7256c0ef942eedeea065790520e4e6f0bfe208862685e068e3cdce09e8d6e2516dcd195db1dfbd5fe91b","./WavesWallet-iOS/Resources/Assets.xcassets/wallet_scanner.imageset/Contents.json":"82698f02fb78abe1c736e8985952af5e0c3218bea1d4bb36f5a8704d7fab28fbb7df7bc66f1d39342b46d58d822f105bcc1e2ca0ae1ebb75811946caee8187a6","./WavesWallet-iOS/Resources/Assets.xcassets/wallet_sort.imageset/Contents.json":"6ccd00374816f869d8560dec406e26bbbbff51e9a98d0c28047797fc1a002acc2b9424916aedef99a14de021427bbe70313dbcb587c344ca6d7fead87f4de4dd","./WavesWallet-iOS/Resources/Assets.xcassets/wallet_start_lease.imageset/Contents.json":"663168556e648c30f2a4883280665b35bcc1e1f52a2ef4acd483a479b1d61e019b032d899fbe26940e2cdcc843cebd345b1dd2ce4a604673e01d6a27508c8d18","./WavesWallet-iOS/Resources/Assets.xcassets/warning18Black.imageset/Contents.json":"37fcd43a3107a7077c9f351c1c077435242ad4d07db02d2e4107e3f394405b7bbf871bd63dd067143aa25378eb384cb846fa68c35bf1a09507464527122f4115","./WavesWallet-iOS/Resources/Assets.xcassets/warning18Disabled500.imageset/Contents.json":"d87615d8e8c5a1b38f0d37a26d276751f213359d89dfd6723a56e86bd56025ddf388882a9c0f048ab3c1f625bfa216393bec7607a4d267642f77e8bd1ea6b10f","./WavesWallet-iOS/Resources/Assets.xcassets/warning18White.imageset/Contents.json":"6686591d2f92dadee3d7e703c54135fb7955edf57a6e23e438201f3c062a89e95af4bf86b085d910ab93ec7e172248143bab215497e1d0e134eca39642203325","./WavesWallet-iOS/Resources/Assets.xcassets/warning_address.imageset/Contents.json":"6e27d3f010f36aa40670fc5c27bfb0101bd0f246dc9d47019da2d93ffc4877a60fc35858b85f98490213e685056c5f0c97660aeda0c4e72314f1856c473d4754","./WavesWallet-iOS/Resources/Assets.xcassets/waves_logo.imageset/Contents.json":"e0b7d9ae528527cb34bacdd4fad11f44f7d33020b0017735aaf6900eefda1ab39bfd84bcc548b340b1d517bb3b8187ca77e18decb0f88d19d7582e91553d9025"}},"strings":{"./Temp/vendor/bundle/ruby/2.4.0/gems/terminal-notifier-2.0.0/vendor/terminal-notifier/Terminal Notifier/en.lproj/InfoPlist.strings":"22b0c518333ab93a5078ff4e5ba56159855cf552b9566e07e30141b481c6d235b345eecf5d222a6f56e5d7c1587ab2c8b38e7bce4874873d411758d76583a885","./Temp/vendor/bundle/ruby/2.4.0/gems/terminal-notifier-2.0.0/vendor/terminal-notifier/terminal-notifier.app/Contents/Resources/en.lproj/InfoPlist.strings":"3952a908b72d44040f5072f6344f6327fc78981c3aa55e931acae84c0c9bcc0d148991cd564af4803765c328cbf5f7efe9eb558fc56e47e8206b7b706026f30a","./WavesWallet-iOS/Resources/AccessibilityIdentifiers.strings":"91064b1599baa41fc99d929274563ee19720e6b13be049b1e2cdc3c6911e84f871115e34ec949b3f0e96c2a190746b321ba542427bca7ffc5288329542d0e7ac","./WavesWallet-iOS/Resources/Localization/InfoPlist/de.lproj/InfoPlist.strings":"c631f79e0c6a0cf2c3b3d73f0efcf3f9c7f65b5983ee05bb089b7932b42a3a4d4249e4306256de6ecf413bc74aeb910ff0e969a98290f529b3aa619ff7533046","./WavesWallet-iOS/Resources/Localization/InfoPlist/en.lproj/InfoPlist.strings":"436e6f93feb77259132d67fa2ecd7167aa4dac98c45bf4ee54caf9337f7f724e90e1a7c98c0d418890aa1346c5b664d4ee79efe9f9beb866192bc40e1b3cb68b","./WavesWallet-iOS/Resources/Localization/InfoPlist/es.lproj/InfoPlist.strings":"13f41cde4626ec6dad395fa8539bd2c0bee5abddc973957972e06fbc1cfea7cb7b1fedb270b92ff2e79ec2accbe4df6acd230bd479f071d7e76ead67e3999809","./WavesWallet-iOS/Resources/Localization/InfoPlist/fr-FR.lproj/InfoPlist.strings":"a8b1ac81282fc333de72e7f56b10482f17a6b47def80964186e460c72990d7b17495e70b85778dbb86127afce7eb80f6700f0bbcc117e8856f230ae43956abb5","./WavesWallet-iOS/Resources/Localization/InfoPlist/hi-IN.lproj/InfoPlist.strings":"9a3c0959c66e2eab32c57231649753fd21228e02a5d9e79a8e995fd3d3d5c528c292c9a2840fa6c3e4beafc739b36bd0f11ff57d6b605939d72dc71e89f0897a","./WavesWallet-iOS/Resources/Localization/InfoPlist/id.lproj/InfoPlist.strings":"a34d1d1b991356a81f87fd6ee6845a305c05acc406faa46c162f5da479c5de7626a9230e489a4245eb38bc5e0d241435e375846d56b576c8ab83b465d84ed747","./WavesWallet-iOS/Resources/Localization/InfoPlist/it.lproj/InfoPlist.strings":"834ffae84250595153aadc7b71e6ce21e85d6988d1b1d38ed8d35a208f4761adbbd41db2e3ce76f62e68e0307914b2a741e98a52d893bbeceb4b1295a6e20bf4","./WavesWallet-iOS/Resources/Localization/InfoPlist/ja.lproj/InfoPlist.strings":"5633d29226fd4d62bcad68daa2c58cd55cfeb97a87956345ecc2c1ceb57541d05e8dda5278119dcde78e7b0ae4f62502fbd73bedb17858e9f8e6007e48b72898","./WavesWallet-iOS/Resources/Localization/InfoPlist/ko.lproj/InfoPlist.strings":"679d1545c01bae6c958726ab00c8c3fff0b3fb656f0fd345d68530d59abf7e3180a295a2c9dcffe126cb4a02181ad0a63e5f7e642eeee9da86737bee0ef2d11a","./WavesWallet-iOS/Resources/Localization/InfoPlist/nl-NL.lproj/InfoPlist.strings":"2ed5dc05fe485aea78844017bfd042dc0a71d72ab386c477d1e4bfd0163f0ef1f9dca47e21257379e13a17cc0d33f6e7423902a088bc870a21c40a9ff7d6b4f0","./WavesWallet-iOS/Resources/Localization/InfoPlist/pl.lproj/InfoPlist.strings":"26e34ac8280903858d2a10fc826521a3f48a97c1116f49157c820045d389182a9d051d7c9f008698732eac47c039c8ef84ec1a6c87ebec076eed5747474cf315","./WavesWallet-iOS/Resources/Localization/InfoPlist/pt-BR.lproj/InfoPlist.strings":"3b8f4aead55d4a337b9b6f82a27dac4fa62872e22429764617d5fe78d7bcfa2c9c5bbfe8f7df1201f67cab7075bdfb2e522fea0c7385ba1c8ef68423f57236f8","./WavesWallet-iOS/Resources/Localization/InfoPlist/pt-PT.lproj/InfoPlist.strings":"0d0abe3f3e1fe9f19495ddc48a528aeb37d1af868619cd12d03a23c0147f872627b481f4347887d334490b481dd9400b07553c80640f2f6fcb3d2cceae3b6725","./WavesWallet-iOS/Resources/Localization/InfoPlist/ru.lproj/InfoPlist.strings":"31f7c06e2f8e5e0a9d949fbbd773934425268f077a26dc4d29d20ee417fc03652e00193dba707d8602cac2d371b6a48906d073363f804e11a35430ceef390f5b","./WavesWallet-iOS/Resources/Localization/InfoPlist/tr.lproj/InfoPlist.strings":"ae155c453aae1595625a8becf9b883b34d0e501f3fcf9f5d19897d46abae91d540e9f60ebcaf71c58c36feab82248553a15c9cb5ec8e2e738c5f568759366238","./WavesWallet-iOS/Resources/Localization/InfoPlist/zh-Hans-CN.lproj/InfoPlist.strings":"5f8ea88faee87a859540d7276e18eb4330daebb032326773a4e0a61efb0b75e2be4421447d35d6895d354fa35edf6e8a760e4c40730943ab8b34d636dba8ca3e","./WavesWallet-iOS/Resources/Localization/Waves/de.lproj/Waves.strings":"2c824a49c3ce74587b16629fc5c25c6d480daad9b175099eb179595f70aad7df12bb8e28f8fd9927300eb794e85bcd78ba2e9d749d4e14d9ce6cd8fd558cda24","./WavesWallet-iOS/Resources/Localization/Waves/en.lproj/Waves.strings":"e762b7160ef4f0bed0e746b77648bbec12f9fc374f62708b8cffbb63f90983cf7df911cea0aeb3bdfcc5c0bef315fd36ec52332309b41afb1eb28bb4ce0abf9a","./WavesWallet-iOS/Resources/Localization/Waves/es.lproj/Waves.strings":"fc68b1b01948b390e112fd2e894ac0885e3b5000b4498b959884b4e475a7e2a2252fe8f69366efaef108126f1941245216c6f195820aea10d4cdd3f2e1b878a6","./WavesWallet-iOS/Resources/Localization/Waves/fr-FR.lproj/Waves.strings":"b3e5261867929043016fcb7e7d4d825e187368ad002ac9e544d770d0bcc37e4f48c99024760cc2586c3af89617bc6227ba824758d9eaf1f941950c1b1d17e77d","./WavesWallet-iOS/Resources/Localization/Waves/hi-IN.lproj/Waves.strings":"1e09f813c4e40b8a2ad0099a40dbf0be521befc5d87a80bbb2c90e9bb3d197baee82a770c9aba68c1b346a9a27d229e42b5dd5f91e8fdab9f5913270c86531ba","./WavesWallet-iOS/Resources/Localization/Waves/id.lproj/Waves.strings":"7373ce90071def645292504dbada2d78094326c8176c089f55b75beb51c4e77999a1ca275ad4b49301071854516464086baa62bd049005ed27ddbc4a2cf81763","./WavesWallet-iOS/Resources/Localization/Waves/it.lproj/Waves.strings":"5b27f5ccc12b0e3324dee194120af0f5f1d9155593a5ac3245280bfed64e4863bc1d76fec4591597d1400998cc66a6f3d5fe6cf370cfc93fce395a8c7533cbfd","./WavesWallet-iOS/Resources/Localization/Waves/ja.lproj/Waves.strings":"23f3c85231bb7053c693ae1ddcd442dd71c9e2b0e468ab86d2b0c5d0bec3e0e4b2d0fc4057dfe9722df333877b78a848a39181ab65d940247c8d906738e2f92d","./WavesWallet-iOS/Resources/Localization/Waves/ko.lproj/Waves.strings":"bc298594e04a2fc612427a8dbb0052ffce00b21023c21d9b122c6263c6d7b57b7ca89dcf0eef25db1ba2dfa6cb3cf59582bbb5de9333bea2a41f3534f1e96c8b","./WavesWallet-iOS/Resources/Localization/Waves/nl-NL.lproj/Waves.strings":"481e3195e98c4a862e7943780f87e727d7716e6ec7ffb2e50bb867cde3ca1dbc86d246d9f2a595e7e544d1f0a8f024525278eaa437d581a245bff75cafb1da78","./WavesWallet-iOS/Resources/Localization/Waves/pl.lproj/Waves.strings":"10048762afdfd16ef6933b40435eb709239f033fa2b359d874afa768b193481be5be0f84fe61b0da73d1f45e8a589ba292f790d375678552cea4f0af23aa5312","./WavesWallet-iOS/Resources/Localization/Waves/pt-BR.lproj/Waves.strings":"272252745b62f3f0a2c967085e94082e6507775c84bf4b7a14142660b93d19243bb0d6b328672f64194835115914d024262af665a1f30b47af55f8b138332b17","./WavesWallet-iOS/Resources/Localization/Waves/pt-PT.lproj/Waves.strings":"ba90c4c5c93f86f52e168675c9e887efd66725adb427bf2c685b614cdbf0225138c3272aaa66fc50b0f414143e6e19f1443f4dfa8429a22828204bb667b8b43f","./WavesWallet-iOS/Resources/Localization/Waves/ru.lproj/Waves.strings":"6e11a09938c016a4e2cb53910d8560586275f0b781fd4f58c2cc77b1cd1a193c418ebaa48bf4d330ca0c923dd475483c887760295304b91dc3b297e24b39b70e","./WavesWallet-iOS/Resources/Localization/Waves/tr.lproj/Waves.strings":"7d82e7eecb3bd985d765b11d50b1b6b267481d8a29730cd34eef44d23aa28d845f37e102b3c19055ecceede87d149c211f45312aa2af2760f02b7b5e57a0964c","./WavesWallet-iOS/Resources/Localization/Waves/zh-Hans-CN.lproj/Waves.strings":"ce1820ab90cbfbcc5c71596fac63d6a7ccba8e2c0019d0c8178d31eb1aeeae3c00c927d07398e747eceba4aab82579be189561edd3a5a5c79f8f3c95bffe204a"}} \ No newline at end of file diff --git a/Templates/structured-swift4.stencil b/Templates/structured-swift4.stencil index 57cdb120..17de2cde 100644 --- a/Templates/structured-swift4.stencil +++ b/Templates/structured-swift4.stencil @@ -3,6 +3,7 @@ {% if tables.count > 0 %} {% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %} import Foundation +import Extensions // swiftlint:disable superfluous_disable_command // swiftlint:disable file_length @@ -54,7 +55,7 @@ import Foundation } // swiftlint:enable explicit_type_interface identifier_name line_length nesting type_body_length type_name -extension {{enumName}} { +extension {{enumName}}: LocalizableProtocol { struct Current { var locale: Locale @@ -63,12 +64,13 @@ extension {{enumName}} { private static let english: Localizable.Current = Localizable.Current(locale: Locale(identifier: "en"), bundle: Bundle(for: BundleToken.self)) - static var current: Localizable.Current = Localizable.Current(locale: Locale.current, bundle: Bundle(for: BundleToken.self)) + static var locale: Locale = Locale.current + static var bundle: Bundle = Bundle(for: BundleToken.self) private static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String { - let format = NSLocalizedString(key, tableName: table, bundle: current.bundle, comment: "") + let format = NSLocalizedString(key, tableName: table, bundle: bundle, comment: "") - let value = String(format: format, locale: current.locale, arguments: args) + let value = String(format: format, locale: locale, arguments: args) if value.localizedLowercase == key.localizedLowercase { let format = NSLocalizedString(key, tableName: table, bundle: english.bundle, comment: "") diff --git a/Vendors/KeeperExample/KeeperExample/KeeperExample.xcodeproj/project.pbxproj b/Vendors/KeeperExample/KeeperExample/KeeperExample.xcodeproj/project.pbxproj new file mode 100644 index 00000000..e6300373 --- /dev/null +++ b/Vendors/KeeperExample/KeeperExample/KeeperExample.xcodeproj/project.pbxproj @@ -0,0 +1,433 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 51; + objects = { + +/* Begin PBXBuildFile section */ + 321D36EE23312F0000D81E8E /* SDKViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 321D36ED23312F0000D81E8E /* SDKViewController.swift */; }; + 321D36F023312F0F00D81E8E /* KeeperViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 321D36EF23312F0F00D81E8E /* KeeperViewController.swift */; }; + 321D36F22331345800D81E8E /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 321D36F12331345800D81E8E /* Constants.swift */; }; + 323B8DE12331418200034343 /* CustomNavigationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 323B8DE02331418200034343 /* CustomNavigationViewController.swift */; }; + 7B0B6FA9231FE7D200CC5DCB /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B0B6FA8231FE7D200CC5DCB /* AppDelegate.swift */; }; + 7B0B6FAE231FE7D200CC5DCB /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7B0B6FAC231FE7D200CC5DCB /* Main.storyboard */; }; + 7B0B6FB0231FE7D500CC5DCB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7B0B6FAF231FE7D500CC5DCB /* Assets.xcassets */; }; + 7B0B6FB3231FE7D500CC5DCB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7B0B6FB1231FE7D500CC5DCB /* LaunchScreen.storyboard */; }; + 812A0E129CE2957D25792974 /* Pods_KeeperExample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 27B95FEAA32BFDCCA2146064 /* Pods_KeeperExample.framework */; }; + E9BFFA3B23215949000F59FC /* Transactions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9BFFA3A23215949000F59FC /* Transactions.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1617F8A74DB2172DB83913FF /* Pods-KeeperExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-KeeperExample.release.xcconfig"; path = "Target Support Files/Pods-KeeperExample/Pods-KeeperExample.release.xcconfig"; sourceTree = ""; }; + 27B95FEAA32BFDCCA2146064 /* Pods_KeeperExample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_KeeperExample.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 321D36ED23312F0000D81E8E /* SDKViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SDKViewController.swift; sourceTree = ""; }; + 321D36EF23312F0F00D81E8E /* KeeperViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeeperViewController.swift; sourceTree = ""; }; + 321D36F12331345800D81E8E /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; }; + 323B8DE02331418200034343 /* CustomNavigationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomNavigationViewController.swift; sourceTree = ""; }; + 66AA2D092A1DAAA641D55F44 /* Pods-KeeperExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-KeeperExample.debug.xcconfig"; path = "Target Support Files/Pods-KeeperExample/Pods-KeeperExample.debug.xcconfig"; sourceTree = ""; }; + 7B0B6FA5231FE7D200CC5DCB /* KeeperExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = KeeperExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 7B0B6FA8231FE7D200CC5DCB /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7B0B6FAD231FE7D200CC5DCB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 7B0B6FAF231FE7D500CC5DCB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 7B0B6FB2231FE7D500CC5DCB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 7B0B6FB4231FE7D500CC5DCB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + E9BFFA3A23215949000F59FC /* Transactions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Transactions.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 7B0B6FA2231FE7D200CC5DCB /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 812A0E129CE2957D25792974 /* Pods_KeeperExample.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 186FC67489E6D85D026B69F6 /* Pods */ = { + isa = PBXGroup; + children = ( + 66AA2D092A1DAAA641D55F44 /* Pods-KeeperExample.debug.xcconfig */, + 1617F8A74DB2172DB83913FF /* Pods-KeeperExample.release.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; + 433BEB3BD50D8B41E21ACDC3 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 27B95FEAA32BFDCCA2146064 /* Pods_KeeperExample.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 7B0B6F9C231FE7D200CC5DCB = { + isa = PBXGroup; + children = ( + 7B0B6FA7231FE7D200CC5DCB /* KeeperExample */, + 7B0B6FA6231FE7D200CC5DCB /* Products */, + 186FC67489E6D85D026B69F6 /* Pods */, + 433BEB3BD50D8B41E21ACDC3 /* Frameworks */, + ); + sourceTree = ""; + }; + 7B0B6FA6231FE7D200CC5DCB /* Products */ = { + isa = PBXGroup; + children = ( + 7B0B6FA5231FE7D200CC5DCB /* KeeperExample.app */, + ); + name = Products; + sourceTree = ""; + }; + 7B0B6FA7231FE7D200CC5DCB /* KeeperExample */ = { + isa = PBXGroup; + children = ( + 7B0B6FA8231FE7D200CC5DCB /* AppDelegate.swift */, + 321D36F12331345800D81E8E /* Constants.swift */, + 323B8DE02331418200034343 /* CustomNavigationViewController.swift */, + E9BFFA3A23215949000F59FC /* Transactions.swift */, + 321D36ED23312F0000D81E8E /* SDKViewController.swift */, + 321D36EF23312F0F00D81E8E /* KeeperViewController.swift */, + 7B0B6FAC231FE7D200CC5DCB /* Main.storyboard */, + 7B0B6FAF231FE7D500CC5DCB /* Assets.xcassets */, + 7B0B6FB1231FE7D500CC5DCB /* LaunchScreen.storyboard */, + 7B0B6FB4231FE7D500CC5DCB /* Info.plist */, + ); + path = KeeperExample; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 7B0B6FA4231FE7D200CC5DCB /* KeeperExample */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7B0B6FB7231FE7D500CC5DCB /* Build configuration list for PBXNativeTarget "KeeperExample" */; + buildPhases = ( + 564BCC1E38339ADD3E6597E0 /* [CP] Check Pods Manifest.lock */, + 7B0B6FA1231FE7D200CC5DCB /* Sources */, + 7B0B6FA2231FE7D200CC5DCB /* Frameworks */, + 7B0B6FA3231FE7D200CC5DCB /* Resources */, + A06B845665CDE7E661094008 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = KeeperExample; + productName = KeeperExample; + productReference = 7B0B6FA5231FE7D200CC5DCB /* KeeperExample.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 7B0B6F9D231FE7D200CC5DCB /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1030; + LastUpgradeCheck = 1030; + ORGANIZATIONNAME = Waves; + TargetAttributes = { + 7B0B6FA4231FE7D200CC5DCB = { + CreatedOnToolsVersion = 10.3; + }; + }; + }; + buildConfigurationList = 7B0B6FA0231FE7D200CC5DCB /* Build configuration list for PBXProject "KeeperExample" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 7B0B6F9C231FE7D200CC5DCB; + productRefGroup = 7B0B6FA6231FE7D200CC5DCB /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 7B0B6FA4231FE7D200CC5DCB /* KeeperExample */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 7B0B6FA3231FE7D200CC5DCB /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7B0B6FB3231FE7D500CC5DCB /* LaunchScreen.storyboard in Resources */, + 7B0B6FB0231FE7D500CC5DCB /* Assets.xcassets in Resources */, + 7B0B6FAE231FE7D200CC5DCB /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 564BCC1E38339ADD3E6597E0 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-KeeperExample-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + A06B845665CDE7E661094008 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-KeeperExample/Pods-KeeperExample-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-KeeperExample/Pods-KeeperExample-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-KeeperExample/Pods-KeeperExample-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 7B0B6FA1231FE7D200CC5DCB /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E9BFFA3B23215949000F59FC /* Transactions.swift in Sources */, + 323B8DE12331418200034343 /* CustomNavigationViewController.swift in Sources */, + 321D36F023312F0F00D81E8E /* KeeperViewController.swift in Sources */, + 7B0B6FA9231FE7D200CC5DCB /* AppDelegate.swift in Sources */, + 321D36EE23312F0000D81E8E /* SDKViewController.swift in Sources */, + 321D36F22331345800D81E8E /* Constants.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 7B0B6FAC231FE7D200CC5DCB /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 7B0B6FAD231FE7D200CC5DCB /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 7B0B6FB1231FE7D500CC5DCB /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 7B0B6FB2231FE7D500CC5DCB /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 7B0B6FB5231FE7D500CC5DCB /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.4; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 7B0B6FB6231FE7D500CC5DCB /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.4; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 7B0B6FB8231FE7D500CC5DCB /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 66AA2D092A1DAAA641D55F44 /* Pods-KeeperExample.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 96SW78M3KJ; + INFOPLIST_FILE = KeeperExample/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = WV.KeeperExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 7B0B6FB9231FE7D500CC5DCB /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 1617F8A74DB2172DB83913FF /* Pods-KeeperExample.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 96SW78M3KJ; + INFOPLIST_FILE = KeeperExample/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = WV.KeeperExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 7B0B6FA0231FE7D200CC5DCB /* Build configuration list for PBXProject "KeeperExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7B0B6FB5231FE7D500CC5DCB /* Debug */, + 7B0B6FB6231FE7D500CC5DCB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 7B0B6FB7231FE7D500CC5DCB /* Build configuration list for PBXNativeTarget "KeeperExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7B0B6FB8231FE7D500CC5DCB /* Debug */, + 7B0B6FB9231FE7D500CC5DCB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 7B0B6F9D231FE7D200CC5DCB /* Project object */; +} diff --git a/Vendors/KeeperExample/KeeperExample/KeeperExample/AppDelegate.swift b/Vendors/KeeperExample/KeeperExample/KeeperExample/AppDelegate.swift new file mode 100644 index 00000000..f69532ee --- /dev/null +++ b/Vendors/KeeperExample/KeeperExample/KeeperExample/AppDelegate.swift @@ -0,0 +1,64 @@ +// +// AppDelegate.swift +// KeeperExample +// +// Created by rprokofev on 04.09.2019. +// Copyright © 2019 Waves. All rights reserved. +// + +import UIKit +import WavesSDK + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + + var url: URL? + + if let path = launchOptions?[.url] as? String { + url = URL(string: path) + } + + let sourceApplication = (launchOptions?[.sourceApplication] as? String) ?? "" + + + WavesSDK.initialization(servicesPlugins: .init(data: [], node: [], matcher: []), + enviroment: .init(server: .mainNet, timestampServerDiff: 0)) + + WavesKeeper.initialization(application: .init(name: "Keeper Example", iconUrl: "https://rampaga.ru/_sf/135/72786352.jpg", schemeUrl: "keeperExample")) + + + if let url = url { + let response = WavesKeeper.shared.decodableResponse(url, sourceApplication: sourceApplication) + + } + + setupUI() + + return true + } + + private func setupUI() { + + UITabBar.appearance().tintColor = GlobalConstants.Colors.blue + UINavigationBar.appearance().barTintColor = GlobalConstants.Colors.blue + UINavigationBar.appearance().tintColor = .white + UINavigationBar.appearance().titleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.white] + } + + func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { + + let sourceApplication: String = (options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String) ?? "" + + WavesKeeper.shared.applicationOpenURL(url, sourceApplication) + + + return true + } + +} + diff --git a/Vendors/KeeperExample/KeeperExample/KeeperExample/Assets.xcassets/AppIcon.appiconset/Contents.json b/Vendors/KeeperExample/KeeperExample/KeeperExample/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d8db8d65 --- /dev/null +++ b/Vendors/KeeperExample/KeeperExample/KeeperExample/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Vendors/KeeperExample/KeeperExample/KeeperExample/Assets.xcassets/Contents.json b/Vendors/KeeperExample/KeeperExample/KeeperExample/Assets.xcassets/Contents.json new file mode 100644 index 00000000..da4a164c --- /dev/null +++ b/Vendors/KeeperExample/KeeperExample/KeeperExample/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/WavesWallet-iOS/Resources/Assets.xcassets/Image.imageset/Contents.json b/Vendors/KeeperExample/KeeperExample/KeeperExample/Assets.xcassets/phone.imageset/Contents.json similarity index 79% rename from WavesWallet-iOS/Resources/Assets.xcassets/Image.imageset/Contents.json rename to Vendors/KeeperExample/KeeperExample/KeeperExample/Assets.xcassets/phone.imageset/Contents.json index f8f827e4..60967e2a 100644 --- a/WavesWallet-iOS/Resources/Assets.xcassets/Image.imageset/Contents.json +++ b/Vendors/KeeperExample/KeeperExample/KeeperExample/Assets.xcassets/phone.imageset/Contents.json @@ -6,10 +6,12 @@ }, { "idiom" : "universal", + "filename" : "phone@2x.png", "scale" : "2x" }, { "idiom" : "universal", + "filename" : "phone@3x.png", "scale" : "3x" } ], diff --git a/Vendors/KeeperExample/KeeperExample/KeeperExample/Assets.xcassets/phone.imageset/phone@2x.png b/Vendors/KeeperExample/KeeperExample/KeeperExample/Assets.xcassets/phone.imageset/phone@2x.png new file mode 100644 index 00000000..734cbea1 Binary files /dev/null and b/Vendors/KeeperExample/KeeperExample/KeeperExample/Assets.xcassets/phone.imageset/phone@2x.png differ diff --git a/Vendors/KeeperExample/KeeperExample/KeeperExample/Assets.xcassets/phone.imageset/phone@3x.png b/Vendors/KeeperExample/KeeperExample/KeeperExample/Assets.xcassets/phone.imageset/phone@3x.png new file mode 100644 index 00000000..39ada55a Binary files /dev/null and b/Vendors/KeeperExample/KeeperExample/KeeperExample/Assets.xcassets/phone.imageset/phone@3x.png differ diff --git a/Vendors/KeeperExample/KeeperExample/KeeperExample/Assets.xcassets/settings.imageset/Contents.json b/Vendors/KeeperExample/KeeperExample/KeeperExample/Assets.xcassets/settings.imageset/Contents.json new file mode 100644 index 00000000..224bf4d8 --- /dev/null +++ b/Vendors/KeeperExample/KeeperExample/KeeperExample/Assets.xcassets/settings.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "settings@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "settings@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Vendors/KeeperExample/KeeperExample/KeeperExample/Assets.xcassets/settings.imageset/settings@2x.png b/Vendors/KeeperExample/KeeperExample/KeeperExample/Assets.xcassets/settings.imageset/settings@2x.png new file mode 100644 index 00000000..356f9d3b Binary files /dev/null and b/Vendors/KeeperExample/KeeperExample/KeeperExample/Assets.xcassets/settings.imageset/settings@2x.png differ diff --git a/Vendors/KeeperExample/KeeperExample/KeeperExample/Assets.xcassets/settings.imageset/settings@3x.png b/Vendors/KeeperExample/KeeperExample/KeeperExample/Assets.xcassets/settings.imageset/settings@3x.png new file mode 100644 index 00000000..a25064a3 Binary files /dev/null and b/Vendors/KeeperExample/KeeperExample/KeeperExample/Assets.xcassets/settings.imageset/settings@3x.png differ diff --git a/Vendors/KeeperExample/KeeperExample/KeeperExample/Base.lproj/LaunchScreen.storyboard b/Vendors/KeeperExample/KeeperExample/KeeperExample/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..bfa36129 --- /dev/null +++ b/Vendors/KeeperExample/KeeperExample/KeeperExample/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Vendors/KeeperExample/KeeperExample/KeeperExample/Base.lproj/Main.storyboard b/Vendors/KeeperExample/KeeperExample/KeeperExample/Base.lproj/Main.storyboard new file mode 100644 index 00000000..cd3bfc52 --- /dev/null +++ b/Vendors/KeeperExample/KeeperExample/KeeperExample/Base.lproj/Main.storyboard @@ -0,0 +1,300 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Vendors/KeeperExample/KeeperExample/KeeperExample/Constants.swift b/Vendors/KeeperExample/KeeperExample/KeeperExample/Constants.swift new file mode 100644 index 00000000..14700f9d --- /dev/null +++ b/Vendors/KeeperExample/KeeperExample/KeeperExample/Constants.swift @@ -0,0 +1,7 @@ +import UIKit + +enum GlobalConstants { + enum Colors { + static let blue = UIColor.init(red: 31.0/255.0, green: 90.0/255.0, blue: 246.0/255.0, alpha: 1) + } +} diff --git a/Vendors/KeeperExample/KeeperExample/KeeperExample/CustomNavigationViewController.swift b/Vendors/KeeperExample/KeeperExample/KeeperExample/CustomNavigationViewController.swift new file mode 100644 index 00000000..0a31e405 --- /dev/null +++ b/Vendors/KeeperExample/KeeperExample/KeeperExample/CustomNavigationViewController.swift @@ -0,0 +1,16 @@ +// Copyright © 2019 Waves. All rights reserved. +// + +import UIKit + +class CustomNavigationViewController: UINavigationController { + + override func viewDidLoad() { + super.viewDidLoad() + + } + + override var preferredStatusBarStyle: UIStatusBarStyle { + return .lightContent + } +} diff --git a/Vendors/KeeperExample/KeeperExample/KeeperExample/Info.plist b/Vendors/KeeperExample/KeeperExample/KeeperExample/Info.plist new file mode 100644 index 00000000..4eb3631a --- /dev/null +++ b/Vendors/KeeperExample/KeeperExample/KeeperExample/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLIconFile + + CFBundleURLName + keeperExample + CFBundleURLSchemes + + keeperExample + + + + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarStyle + UIStatusBarStyleDefault + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/Vendors/KeeperExample/KeeperExample/KeeperExample/KeeperViewController.swift b/Vendors/KeeperExample/KeeperExample/KeeperExample/KeeperViewController.swift new file mode 100644 index 00000000..1d979cbe --- /dev/null +++ b/Vendors/KeeperExample/KeeperExample/KeeperExample/KeeperViewController.swift @@ -0,0 +1,163 @@ +// Copyright © 2019 Waves. All rights reserved. +// + +import UIKit +import WavesSDK +import TextFieldEffects +import RxSwift + +class KeeperViewController: UIViewController { + + @IBOutlet private weak var textField: HoshiTextField! + @IBOutlet var pickerView: UIPickerView! + @IBOutlet var toolBar: UIToolbar! + @IBOutlet private weak var labelInfo: UILabel! + + private var currentServer: Enviroment.Server! + private var transaction: NodeService.Query.Transaction? + private let disposeBag = DisposeBag() + + override func viewDidLoad() { + super.viewDidLoad() + + navigationItem.title = "Keeper" + + pickerView.backgroundColor = .white + toolBar.barTintColor = .white + textField.inputView = pickerView + textField.inputAccessoryView = toolBar + labelInfo.text = nil + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + currentServer = WavesSDK.shared.enviroment.server + setupButton() + } + + @IBAction private func selectPicker(_ sender: Any) { + + transaction = Transactions.list[pickerView.selectedRow(inComponent: 0)].type + textField.text = Transactions.list[pickerView.selectedRow(inComponent: 0)].name + + textField.resignFirstResponder() + + var text = "Request" + text += "\n\n" + text += transaction?.jsonString ?? "" + + let attr = NSMutableAttributedString(string: text) + attr.addAttributes([NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: labelInfo.font.pointSize)], + range: (text as NSString).range(of: "Request")) + labelInfo.attributedText = attr + } + + @IBAction private func dismissPicker(_ sender: Any) { + textField.resignFirstResponder() + } + + @objc private func changeNetwork() { + if currentServer.isMainNet { + currentServer = .testNet + } + else { + currentServer = .mainNet + } + setupButton() + WavesSDK.initialization(servicesPlugins: .init(data: [], node: [], matcher: []), enviroment: .init(server: currentServer, timestampServerDiff: 0)) + } + + @IBAction private func sendTapped(_ sender: Any) { + + if let tx = transaction { + WavesKeeper.shared + .send(tx) + .subscribe(onNext: { [weak self] (response) in + + guard let self = self else { return } + self.showInfo(response: response) + + }, onError: { [weak self] (error) in + + guard let self = self else { return } + + let vc = UIAlertController(title: "Error", message: error.localizedDescription, preferredStyle: .alert) + let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil) + vc.addAction(cancel) + self.present(vc, animated: true, completion: nil) + + }).disposed(by: disposeBag) + } + } + + @IBAction private func signTapped(_ sender: Any) { + + if let tx = transaction { + WavesKeeper.shared + .sign(tx) + .subscribe(onNext: { [weak self] (response) in + + guard let self = self else { return } + self.showInfo(response: response) + }, onError: { [weak self] (error) in + + guard let self = self else { return } + + let vc = UIAlertController(title: "Error", message: error.localizedDescription, preferredStyle: .alert) + let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil) + vc.addAction(cancel) + self.present(vc, animated: true, completion: nil) + + }).disposed(by: disposeBag) + } + } + +} + +extension KeeperViewController: UIPickerViewDelegate, UIPickerViewDataSource { + + func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { + return Transactions.list.count + } + + func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { + return Transactions.list[row].name + } + + func numberOfComponents(in pickerView: UIPickerView) -> Int { + return 1 + } +} + +private extension KeeperViewController { + + func showInfo(response: WavesKeeper.Response?) { + + var text = "Request" + text += "\n\n" + text += transaction?.jsonString ?? "" + + if let response = response { + text += "\n\n\n" + text += "Response" + text += "\n\n" + text += response.jsonString ?? "" + } + let attr = NSMutableAttributedString(string: text) + attr.addAttributes([NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: labelInfo.font.pointSize)], + range: (text as NSString).range(of: "Request")) + + let rangeResponse = (text as NSString).range(of: "Response") + if rangeResponse.location != NSNotFound { + attr.addAttributes([NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: labelInfo.font.pointSize)], + range: rangeResponse) + } + + labelInfo.attributedText = attr + } + + func setupButton() { + let buttonTitle = currentServer.isMainNet ? "MainNet" : "TestNet" + navigationItem.rightBarButtonItem = UIBarButtonItem(title: buttonTitle, style: .done, target: self, action: #selector(changeNetwork)) + } +} diff --git a/Vendors/KeeperExample/KeeperExample/KeeperExample/SDKViewController.swift b/Vendors/KeeperExample/KeeperExample/KeeperExample/SDKViewController.swift new file mode 100644 index 00000000..fe3931ed --- /dev/null +++ b/Vendors/KeeperExample/KeeperExample/KeeperExample/SDKViewController.swift @@ -0,0 +1,116 @@ +// Copyright © 2019 Waves. All rights reserved. +// + +import UIKit +import WavesSDK +import RxSwift +import WavesSDKCrypto + +final class SDKViewController: UIViewController { + + private var currentServer: Enviroment.Server! + private let disposeBag = DisposeBag() + + @IBOutlet private weak var labelInfo: UILabel! + @IBOutlet private weak var acitivityIndicatorBalance: UIActivityIndicatorView! + @IBOutlet private weak var buttonLoadBalance: UIButton! + + override func viewDidLoad() { + super.viewDidLoad() + + navigationItem.title = "My Waves dApp" + labelInfo.text = nil + acitivityIndicatorBalance.isHidden = true + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + currentServer = WavesSDK.shared.enviroment.server + setupButton() + } + + @IBAction private func generateNewSeed(_ sender: Any) { + let seed = WavesCrypto.shared.randomSeed() + self.setupInfo(title: "New seed is:", value: seed) + } + + @IBAction private func loadWavesBalance(_ sender: Any) { + + guard let address = WavesCrypto.shared.address(seed: "", chainId: WavesSDK.shared.enviroment.chainId) else { return } + + self.buttonLoadBalance.isEnabled = false + self.buttonLoadBalance.setTitle(nil, for: .normal) + self.acitivityIndicatorBalance.isHidden = false + self.acitivityIndicatorBalance.startAnimating() + + WavesSDK.shared.services + .nodeServices + .addressesNodeService + .addressBalance(address: address) + .observeOn(MainScheduler.instance) + .subscribe(onNext: { [weak self] (balance) in + guard let self = self else { return } + self.setupInfo(title: "Balance is:", value: String(balance.balance)) + self.setupDefaultButtonBalanceState() + + }, onError: { [weak self] (error) in + + guard let self = self else { return } + self.setupDefaultButtonBalanceState() + + let vc = UIAlertController(title: "Error", message: error.localizedDescription, preferredStyle: .alert) + let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil) + vc.addAction(cancel) + self.present(vc, animated: true, completion: nil) + + }).disposed(by: disposeBag) + } + + + @objc private func changeNetwork() { + if currentServer.isMainNet { + currentServer = .testNet + } + else { + currentServer = .mainNet + } + setupButton() + WavesSDK.initialization(servicesPlugins: .init(data: [], node: [], matcher: []), enviroment: .init(server: currentServer, timestampServerDiff: 0)) + } +} + +private extension SDKViewController { + + func setupDefaultButtonBalanceState() { + self.acitivityIndicatorBalance.stopAnimating() + self.acitivityIndicatorBalance.isHidden = true + self.buttonLoadBalance.isEnabled = true + self.buttonLoadBalance.setTitle("Load address Waves balance", for: .normal) + } + + func setupInfo(title: String, value: String) { + + let text = title + " " + value + + let attr = NSMutableAttributedString(string: text) + attr.addAttributes([NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: labelInfo.font.pointSize)], + range: (text as NSString).range(of: title)) + labelInfo.attributedText = attr + } + + func setupButton() { + let buttonTitle = currentServer.isMainNet ? "MainNet" : "TestNet" + navigationItem.rightBarButtonItem = UIBarButtonItem(title: buttonTitle, style: .done, target: self, action: #selector(changeNetwork)) + } +} + +extension Enviroment.Server { + var isMainNet: Bool { + switch self { + case .mainNet: + return true + default: + return false + } + } +} diff --git a/Vendors/KeeperExample/KeeperExample/KeeperExample/Transactions.swift b/Vendors/KeeperExample/KeeperExample/KeeperExample/Transactions.swift new file mode 100644 index 00000000..2f32557e --- /dev/null +++ b/Vendors/KeeperExample/KeeperExample/KeeperExample/Transactions.swift @@ -0,0 +1,171 @@ +// +// Transactions.swift +// KeeperExample +// +// Created by Pavel Gubin on 05.09.2019. +// Copyright © 2019 Waves. All rights reserved. +// + +import Foundation +import WavesSDK +import WavesSDKCrypto + +final class Transactions { + + struct Transaction { + let name: String + let type: NodeService.Query.Transaction + } + + static var list: [Transaction] { + + return [.init(name: "Transfer", type: .transfer(txTansfer)), + .init(name: "Invoke Script", type: .invokeScript(txInvokeScript)), + .init(name: "Data", type: .data(txData)), + .init(name: "Transfer Error", type: .transfer(txTransferError)), + .init(name: "Invoke Script Error", type: .invokeScript(txInvokeScriptError)), + .init(name: "Data empty", type: .data(txDataEmpty)), + .init(name: "Data error", type: .data(txDataError)), + .init(name: "Burn", type: .burn(txBurn))] + } + + private static var chainId: String { + return WavesSDK.shared.enviroment.chainId + } +} + +extension WavesKeeper.Response { + var jsonString: String? { + + if let data = try? JSONSerialization.data(withJSONObject: dictionary, options: .prettyPrinted) { + return String(data: data, encoding: .utf8) + } + + return nil + } +} + +extension NodeService.Query.Transaction { + + var jsonString: String? { + + if let data = try? JSONSerialization.data(withJSONObject: dictionary, options: .prettyPrinted) { + return String(data: data, encoding: .utf8) + } + + return nil + } +} + +private extension Transactions { + + static var txTansfer: NodeService.Query.Transaction.Transfer { + return .init(recipient: "3PNaua1fMrQm4TArqeTuakmY1u985CgMRk6", + assetId: "WAVES", + amount: 1000, + fee: 100000, + attachment: "First", + feeAssetId: "WAVES", + chainId: chainId) + } + + static var txInvokeScript: NodeService.Query.Transaction.InvokeScript { + let fee: Int64 = 900000 + let dApp: String = "3Mv9XDntij4ZRE1XiNZed6J74rncBpiYNDV" + + let arg1 = NodeService.Query.Transaction.InvokeScript.Arg(value: .string("Some string!")) + let arg2 = NodeService.Query.Transaction.InvokeScript.Arg(value: .integer(128)) + let arg3 = NodeService.Query.Transaction.InvokeScript.Arg(value: .integer(-127)) + let arg4 = NodeService.Query.Transaction.InvokeScript.Arg(value: .bool(true)) + let arg5 = NodeService.Query.Transaction.InvokeScript.Arg(value: .bool(false)) + let arg6 = NodeService.Query.Transaction.InvokeScript.Arg(value: .binary("base64:VGVzdA==")) + + let queryModel = NodeService.Query.Transaction.InvokeScript(chainId: chainId, + fee: fee, + feeAssetId: "WAVES", + dApp: dApp, + call: .init(function: "testarg", args: [arg1, arg2, arg3, + arg4, arg5, arg6]), + payment: [.init(amount: 1, assetId: "WAVES")]) + return queryModel + } + + static var txData: NodeService.Query.Transaction.Data { + let fee: Int64 = 900000 + let timestamp = Int64(Date().timeIntervalSince1970) * 1000 + + let data = NodeService.Query.Transaction.Data.Value(key: "size", value: .integer(10)) + + let data1 = NodeService.Query.Transaction.Data.Value(key: "name", value: .string("Maks")) + + let data2 = NodeService.Query.Transaction.Data.Value(key: "isMan", value: .boolean(true)) + + let binary = WavesCrypto.shared.base64encode(input: "Hello!".toBytes) + + let data3 = NodeService.Query.Transaction.Data.Value(key: "secret", value: .binary(binary)) + + let queryModel = NodeService.Query.Transaction.Data(fee: fee, + timestamp: timestamp, + senderPublicKey: "", + data: [data, data1, data2, data3], + chainId: chainId) + return queryModel + } + + static var txTransferError: NodeService.Query.Transaction.Transfer { + return .init(recipient: "", + assetId: "WAVES", + amount: 1000, + fee: 100000, + attachment: "First", + feeAssetId: "WAVES", + chainId: chainId) + } + + static var txInvokeScriptError: NodeService.Query.Transaction.InvokeScript { + return NodeService.Query.Transaction.InvokeScript(chainId: chainId, + fee: 0, + timestamp: 0, + senderPublicKey: "", + feeAssetId: "WAVES", + dApp: "", + call: nil, + payment: [.init(amount: 1, assetId: "WAVES")]) + } + + static var txDataEmpty: NodeService.Query.Transaction.Data { + let fee: Int64 = 900000 + let timestamp = Int64(Date().timeIntervalSince1970) * 1000 + + let queryModel = NodeService.Query.Transaction.Data(fee: fee, + timestamp: timestamp, + senderPublicKey: "", + data: [], + chainId: chainId) + + return queryModel + } + + static var txDataError: NodeService.Query.Transaction.Data { + let queryModel = NodeService.Query.Transaction.Data(fee: 0, + timestamp: 0, + senderPublicKey: "", + data: [], + chainId: chainId) + return queryModel + } + + static var txBurn: NodeService.Query.Transaction.Burn { + let fee: Int64 = 500000 + let timestamp = Int64(Date().timeIntervalSince1970) * 1000 + + let queryModel = NodeService.Query.Transaction.Burn(chainId: chainId, + fee: fee, + assetId: "C5XD7iTdyx868yRE7DS9BmqonF1TBcM5W2hfTEWW5Dfm", + quantity: 1, + timestamp: timestamp, + senderPublicKey: "") + return queryModel + } + +} diff --git a/Vendors/KeeperExample/KeeperExample/Podfile b/Vendors/KeeperExample/KeeperExample/Podfile new file mode 100644 index 00000000..17001a50 --- /dev/null +++ b/Vendors/KeeperExample/KeeperExample/Podfile @@ -0,0 +1,16 @@ +platform :ios, '11.0' + +# Ignore all warnings from all pods +inhibit_all_warnings! + +use_frameworks!(true) + +# Pods for WavesWallet-iOS +target 'KeeperExample' do + project 'KeeperExample.xcodeproj' + + pod "WavesSDK", :git => "git@github.com:wavesplatform/WavesSDK-iOS.git", :branch => "develop" + pod 'CryptoSwift' + pod 'TextFieldEffects' + +end diff --git a/Vendors/KeeperExample/KeeperExample/Podfile.lock b/Vendors/KeeperExample/KeeperExample/Podfile.lock new file mode 100644 index 00000000..4f1bd252 --- /dev/null +++ b/Vendors/KeeperExample/KeeperExample/Podfile.lock @@ -0,0 +1,65 @@ +PODS: + - Alamofire (4.9.0) + - CryptoSwift (1.0.0) + - Moya (12.0.1): + - Moya/Core (= 12.0.1) + - Moya/Core (12.0.1): + - Alamofire (~> 4.1) + - Result (~> 4.0) + - Moya/RxSwift (12.0.1): + - Moya/Core + - RxSwift (~> 4.0) + - Result (4.1.0) + - RxSwift (4.5.0) + - TextFieldEffects (1.6.0) + - WavesSDK (0.1.9): + - Moya (~> 12.0.1) + - Moya/RxSwift (~> 12.0.1) + - RxSwift (~> 4.0) + - WavesSDKCrypto + - WavesSDKExtensions + - WavesSDKCrypto (0.1.9): + - WavesSDKExtensions + - WavesSDKExtensions (0.1.9): + - RxSwift (~> 4.0) + +DEPENDENCIES: + - CryptoSwift + - TextFieldEffects + - "WavesSDK (from `git@github.com:wavesplatform/WavesSDK-iOS.git`, branch `develop`)" + +SPEC REPOS: + https://github.com/cocoapods/specs.git: + - Alamofire + - CryptoSwift + - Moya + - Result + - RxSwift + - TextFieldEffects + - WavesSDKCrypto + - WavesSDKExtensions + +EXTERNAL SOURCES: + WavesSDK: + :branch: develop + :git: "git@github.com:wavesplatform/WavesSDK-iOS.git" + +CHECKOUT OPTIONS: + WavesSDK: + :commit: cc135790205e7a13ba4ebdf67a1c7e4268c2091d + :git: "git@github.com:wavesplatform/WavesSDK-iOS.git" + +SPEC CHECKSUMS: + Alamofire: afc3e7c6db61476cb45cdd23fed06bad03bbc321 + CryptoSwift: d81eeaa59dc5a8d03720fe919a6fd07b51f7439f + Moya: cf730b3cd9e005401ef37a85143aa141a12fd38f + Result: bd966fac789cc6c1563440b348ab2598cc24d5c7 + RxSwift: f172070dfd1a93d70a9ab97a5a01166206e1c575 + TextFieldEffects: 529b8aff706fb40f82c41c780c0777941a893796 + WavesSDK: f0513d8e00c4b0d8e0bfc1a05678a886e8d0c927 + WavesSDKCrypto: 1a9205f4ac4a2a17fb6fd981d3b518f81487b379 + WavesSDKExtensions: 040099258b4d793ef8eb08fda45ba8cd66ea04d8 + +PODFILE CHECKSUM: 3f9383a1fc178113cf358039b20745a9b197cf84 + +COCOAPODS: 1.7.5 diff --git a/Vendors/WavesSDK b/Vendors/WavesSDK new file mode 160000 index 00000000..4e3145c5 --- /dev/null +++ b/Vendors/WavesSDK @@ -0,0 +1 @@ +Subproject commit 4e3145c5531e9a0416cc93097248cb623253b8fa diff --git a/WavesWallet-iOS.xcodeproj/project.pbxproj b/WavesWallet-iOS.xcodeproj/project.pbxproj index 7043cea9..f1e4469f 100644 --- a/WavesWallet-iOS.xcodeproj/project.pbxproj +++ b/WavesWallet-iOS.xcodeproj/project.pbxproj @@ -23,9 +23,6 @@ 04831F6421691429006D1ED6 /* SuccessSystemMessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04831F6121691429006D1ED6 /* SuccessSystemMessageView.swift */; }; 04831F7421691659006D1ED6 /* HistoryTransactionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0444E7B3212C81E1004C7DF2 /* HistoryTransactionView.swift */; }; 04831F76216916EE006D1ED6 /* WalletInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE491F92107A531009223DB /* WalletInteractor.swift */; }; - 04831F78216916EE006D1ED6 /* TransactionApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A1DAD7920F3A9AE004DA625 /* TransactionApi.swift */; }; - 04831F7A216917B0006D1ED6 /* ApiServiceTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5C918420F3CD0500443CE6 /* ApiServiceTypes.swift */; }; - 04831F7B216917EF006D1ED6 /* SmartTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A14CFC62141DA9800C3A4D5 /* SmartTransactionDomainDTO.swift */; }; 04831F7C2169210B006D1ED6 /* PasscodeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A96F1CD2151B699005E148F /* PasscodeViewController.swift */; }; 04831F8421697A4F006D1ED6 /* CustomGradientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04831F8321697A4F006D1ED6 /* CustomGradientView.swift */; }; 04831F87216A363F006D1ED6 /* LanguageTableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04831F86216A363E006D1ED6 /* LanguageTableCell.swift */; }; @@ -36,7 +33,6 @@ 04A2CFA5211213BE00784FEC /* History.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 04A2CFA4211213BE00784FEC /* History.storyboard */; }; 04A403222164D80200652F21 /* EnterStartTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04A403212164D80200652F21 /* EnterStartTypes.swift */; }; 04A403242164D89700652F21 /* EnterStartBlockCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04A403232164D89700652F21 /* EnterStartBlockCell.swift */; }; - 04D4431C21885F50009CEB22 /* Fabric-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 04D4431A21885F4F009CEB22 /* Fabric-Info.plist */; }; 04D882BF21706FEF00EAAB90 /* InfoPagesCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04D882BE21706FEF00EAAB90 /* InfoPagesCell.swift */; }; 04E1C3562126157000C702BA /* HeaderSkeletonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04E1C3552126157000C702BA /* HeaderSkeletonView.swift */; }; 04E1C358212615CA00C702BA /* HeaderSkeletonView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 04E1C357212615CA00C702BA /* HeaderSkeletonView.xib */; }; @@ -46,10 +42,7 @@ 04EFAF4D2164F8D800277CCF /* EnterStartBlockCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 04EFAF4C2164F8D800277CCF /* EnterStartBlockCell.xib */; }; 04F2DD2E219F27AB0070AF9D /* MultilineTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04F2DD2D219F27AB0070AF9D /* MultilineTextField.swift */; }; 04F9979621AA197B0036768D /* CameraAccess.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04F9979521AA197B0036768D /* CameraAccess.swift */; }; - 0A00B185221AE325005A9053 /* AssetsBalanceSettingsRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A00B184221AE325005A9053 /* AssetsBalanceSettingsRepositoryProtocol.swift */; }; - 0A02D20721AEA1B1005DF820 /* Appsflyer-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 0A02D20621AEA1B1005DF820 /* Appsflyer-Info.plist */; }; 0A071E41215AEF61007D9750 /* AccountPassword.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0A071E40215AEF61007D9750 /* AccountPassword.storyboard */; }; - 0A071E43215B0A1B007D9750 /* SigningWalletsProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A071E42215B0A1B007D9750 /* SigningWalletsProtocol.swift */; }; 0A071E64215C65D2007D9750 /* UseTouchID.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0A071E63215C65D2007D9750 /* UseTouchID.storyboard */; }; 0A071E77215DB07C007D9750 /* ChooseAccountTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A071E76215DB07C007D9750 /* ChooseAccountTypes.swift */; }; 0A071E7A215DB0A9007D9750 /* ChooseAccount.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0A071E79215DB0A9007D9750 /* ChooseAccount.storyboard */; }; @@ -58,8 +51,6 @@ 0A071E85215DB1B3007D9750 /* ChooseAccountCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A071E84215DB1B3007D9750 /* ChooseAccountCell.swift */; }; 0A110CB82153CE31002A8FD7 /* Import.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0A110CB72153CE31002A8FD7 /* Import.storyboard */; }; 0A110CC62153F36F002A8FD7 /* SkeletonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A110CC52153F36F002A8FD7 /* SkeletonView.swift */; }; - 0A14CFCF2144159300C3A4D5 /* Asset+Assistants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A14CFCE2144159300C3A4D5 /* Asset+Assistants.swift */; }; - 0A14CFD221441FDB00C3A4D5 /* TransactionDomainDTO+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A14CFD0214415C100C3A4D5 /* TransactionDomainDTO+Mapper.swift */; }; 0A14E3E42187184000EA7E91 /* AliasesPresenterProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A14E3E32187184000EA7E91 /* AliasesPresenterProtocol.swift */; }; 0A14E3E62187185700EA7E91 /* AliasesViewModuleBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A14E3E52187185700EA7E91 /* AliasesViewModuleBuilder.swift */; }; 0A14E3E821871B7700EA7E91 /* AliasesHeadCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A14E3E721871B7700EA7E91 /* AliasesHeadCell.swift */; }; @@ -70,153 +61,49 @@ 0A14E3F321875B3C00EA7E91 /* CreateAliasTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A14E3F221875B3C00EA7E91 /* CreateAliasTypes.swift */; }; 0A14E3F521875B5100EA7E91 /* CreateAliasModuleBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A14E3F421875B5100EA7E91 /* CreateAliasModuleBuilder.swift */; }; 0A14E3F721875F5600EA7E91 /* CreateAliasInputCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A14E3F621875F5600EA7E91 /* CreateAliasInputCell.swift */; }; - 0A150824219B0D6B00516037 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 0A150821219B0D6B00516037 /* GoogleService-Info.plist */; }; - 0A1DAD6220F3876C004DA625 /* AssetApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A1DAD6120F3876C004DA625 /* AssetApi.swift */; }; - 0A1DAD6520F395F2004DA625 /* AssetsInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A1DAD6420F395F2004DA625 /* AssetsInteractor.swift */; }; - 0A1DAD6920F39AE3004DA625 /* ResponseApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A1DAD6820F39AE3004DA625 /* ResponseApi.swift */; }; - 0A1DAD6D20F39F94004DA625 /* NodeServiceTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A1DAD6C20F39F94004DA625 /* NodeServiceTypes.swift */; }; - 0A1DAD7120F3A112004DA625 /* AddressesNodeService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A1DAD7020F3A112004DA625 /* AddressesNodeService.swift */; }; - 0A1DAD7320F3A12B004DA625 /* AssetsNodeService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A1DAD7220F3A12B004DA625 /* AssetsNodeService.swift */; }; - 0A2060642181C2C20048CF83 /* environment_mainnet.json in Resources */ = {isa = PBXBuildFile; fileRef = 0A2060622181C2C10048CF83 /* environment_mainnet.json */; }; - 0A2060652181C2C20048CF83 /* environment_testnet.json in Resources */ = {isa = PBXBuildFile; fileRef = 0A2060632181C2C20048CF83 /* environment_testnet.json */; }; 0A20606821822C3A0048CF83 /* AddressesKeysViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A20606721822C3A0048CF83 /* AddressesKeysViewController.swift */; }; - 0A218B812155180C00B989A1 /* WalletDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A218B802155180C00B989A1 /* WalletDomainDTO.swift */; }; - 0A218B8521551D1400B989A1 /* WalletsRepositoryLocal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A218B8421551D1400B989A1 /* WalletsRepositoryLocal.swift */; }; - 0A218B8721551E6600B989A1 /* WalletsRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A218B8621551E6600B989A1 /* WalletsRepositoryProtocol.swift */; }; - 0A218B892155221F00B989A1 /* Wallet+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A218B882155221F00B989A1 /* Wallet+Mapper.swift */; }; - 0A218B8B2155335F00B989A1 /* WalletSeedRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A218B8A2155335F00B989A1 /* WalletSeedRepositoryProtocol.swift */; }; - 0A218B8E215534E000B989A1 /* WalletSeedRepositoryLocal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A218B8D215534E000B989A1 /* WalletSeedRepositoryLocal.swift */; }; - 0A218B95215556F600B989A1 /* AuthenticationRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A218B94215556F600B989A1 /* AuthenticationRepositoryProtocol.swift */; }; - 0A218B9721555A4B00B989A1 /* AuthenticationRepositoryRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A218B9621555A4B00B989A1 /* AuthenticationRepositoryRemote.swift */; }; 0A26549121BAE153005EA637 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F7E954F01EA8FE0700A804DE /* Assets.xcassets */; }; 0A2B7D34216037FD0098438D /* AssetViewHistoryCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0A2B7D32216037FD0098438D /* AssetViewHistoryCell.xib */; }; 0A2B7D35216037FD0098438D /* AssetViewHistoryCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A2B7D33216037FD0098438D /* AssetViewHistoryCell.swift */; }; 0A2B7D37216038540098438D /* HalfModalInteractiveTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A2B7D36216038540098438D /* HalfModalInteractiveTransition.swift */; }; - 0A2B7D39216038A80098438D /* SpamService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A2B7D38216038A80098438D /* SpamService.swift */; }; - 0A2B7D3B216038F80098438D /* AssetsSpamService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A2B7D3A216038F70098438D /* AssetsSpamService.swift */; }; - 0A2CD238216D0F0000162063 /* AuthorizationInteractorProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A2CD237216D0F0000162063 /* AuthorizationInteractorProtocol.swift */; }; - 0A344E2F2194747E007809B1 /* MigrationInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A344E2E2194747E007809B1 /* MigrationInteractor.swift */; }; 0A36A37D215E493D0060F49E /* NeedBackupViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A36A37B215E493D0060F49E /* NeedBackupViewController.swift */; }; - 0A3AD40721492E9400F8A929 /* ExchangeApiFilters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A1DAD7520F3A6A6004DA625 /* ExchangeApiFilters.swift */; }; 0A3FE8A62135AC2B00DBF4E1 /* AssetTransactionsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A3FE8A52135AC2A00DBF4E1 /* AssetTransactionsCell.swift */; }; 0A3FE8A82135AE3600DBF4E1 /* AssetTransactionCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0A3FE8A72135AE3600DBF4E1 /* AssetTransactionCell.xib */; }; 0A3FE8AA2135AE4000DBF4E1 /* AssetTransactionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A3FE8A92135AE4000DBF4E1 /* AssetTransactionCell.swift */; }; - 0A3FE8AC2136AF4B00DBF4E1 /* TransactionsRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A3FE8AB2136AF4B00DBF4E1 /* TransactionsRepositoryProtocol.swift */; }; - 0A3FE8AE2136E51900DBF4E1 /* TransactionContainersNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A3FE8AD2136E51900DBF4E1 /* TransactionContainersNode.swift */; }; - 0A3FE8B82137007500DBF4E1 /* TransferTransactionNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5B6E74211A3103005A7F09 /* TransferTransactionNode.swift */; }; - 0A3FE8B92137007500DBF4E1 /* ReissueTransactionNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5B6E76211A3161005A7F09 /* ReissueTransactionNode.swift */; }; - 0A3FE8BA2137007500DBF4E1 /* LeaseTransactionNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A485E8C20FFB02100079B49 /* LeaseTransactionNode.swift */; }; - 0A3FE8BB2137007500DBF4E1 /* MassTransferTransactionNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5B6E70211A2F77005A7F09 /* MassTransferTransactionNode.swift */; }; - 0A3FE8BC2137007500DBF4E1 /* BurnTransactionNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5B6E78211A319C005A7F09 /* BurnTransactionNode.swift */; }; - 0A3FE8BD2137007500DBF4E1 /* ExchangeTransactionNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5B6E7A211A327C005A7F09 /* ExchangeTransactionNode.swift */; }; - 0A3FE8BE2137007500DBF4E1 /* LeaseCancelTransactionNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5B6E7C211A3343005A7F09 /* LeaseCancelTransactionNode.swift */; }; - 0A3FE8BF2137007500DBF4E1 /* AliasTransactionNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5B6E7E211A3373005A7F09 /* AliasTransactionNode.swift */; }; - 0A3FE8C02137007500DBF4E1 /* DataTransactionNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5B6E80211A33D9005A7F09 /* DataTransactionNode.swift */; }; - 0A3FE8C121370B1100DBF4E1 /* IssueTransactionNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5B6E72211A3065005A7F09 /* IssueTransactionNode.swift */; }; 0A4140EB2174F09C00B1310E /* ChangePassword.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0A4140EA2174F09C00B1310E /* ChangePassword.storyboard */; }; 0A41410B217603F800B1310E /* ChangePasswordPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A41410A217603F800B1310E /* ChangePasswordPresenter.swift */; }; 0A4399662150465E0032E608 /* NewAccount.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0A4399652150465E0032E608 /* NewAccount.storyboard */; }; 0A43996921504CF60032E608 /* SideMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A43996821504CF60032E608 /* SideMenu.swift */; }; 0A4508F82177970F00EBF669 /* AlertDeleteAccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4508F72177970F00EBF669 /* AlertDeleteAccountViewController.swift */; }; - 0A4508FA2178938C00EBF669 /* EnvironmentRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4508F92178938C00EBF669 /* EnvironmentRepositoryProtocol.swift */; }; - 0A485E8720FF570000079B49 /* AssetBalanceSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A485E8620FF570000079B49 /* AssetBalanceSettings.swift */; }; - 0A485E8B20FFAC6C00079B49 /* LeasingNodeService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A485E8A20FFAC6C00079B49 /* LeasingNodeService.swift */; }; - 0A485E9A2100A8ED00079B49 /* TransferTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A485E992100A8ED00079B49 /* TransferTransaction.swift */; }; - 0A485E9E2100AE9B00079B49 /* IssueTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A485E9D2100AE9B00079B49 /* IssueTransaction.swift */; }; - 0A485EA02100B0BD00079B49 /* LeaseTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A485E9F2100B0BD00079B49 /* LeaseTransaction.swift */; }; - 0A485EA22100C4FA00079B49 /* LeaseTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A485EA12100C4FA00079B49 /* LeaseTransaction+Mapper.swift */; }; 0A4C9A2820ED443C0095A417 /* WalletPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4C9A2720ED443C0095A417 /* WalletPresenter.swift */; }; - 0A4C9AA120EE65800095A417 /* WalletItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4C9AA020EE65800095A417 /* WalletItem.swift */; }; - 0A4C9AA320EE65910095A417 /* SeedItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4C9AA220EE65910095A417 /* SeedItem.swift */; }; - 0A4C9AAB20EF6BFF0095A417 /* AssetsApiService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4C9AAA20EF6BFF0095A417 /* AssetsApiService.swift */; }; - 0A4D221E21809E3600155A8E /* AccountEnvironmentDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4D221D21809E3600155A8E /* AccountEnvironmentDomainDTO.swift */; }; 0A4E71962216E98200A46613 /* SendFeeIndicatorCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4E71952216E98200A46613 /* SendFeeIndicatorCell.swift */; }; - 0A4E7DEC22018C5F007BBA39 /* ModalPresentationAnimatorContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4E7DE822018C5E007BBA39 /* ModalPresentationAnimatorContext.swift */; }; - 0A4E7DED22018C5F007BBA39 /* ModalViewControllerTransitioning.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4E7DE922018C5E007BBA39 /* ModalViewControllerTransitioning.swift */; }; - 0A4E7DEE22018C5F007BBA39 /* ModalPresentationAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4E7DEA22018C5F007BBA39 /* ModalPresentationAnimator.swift */; }; - 0A4E7DEF22018C5F007BBA39 /* ModalPresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4E7DEB22018C5F007BBA39 /* ModalPresentationController.swift */; }; - 0A57C38C21F74E21003B5386 /* ScriptTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A57C38B21F74E20003B5386 /* ScriptTransaction+Mapper.swift */; }; - 0A57C38E21F74E2E003B5386 /* AssetScriptTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A57C38D21F74E2E003B5386 /* AssetScriptTransaction+Mapper.swift */; }; - 0A57C39021F74EB0003B5386 /* ScriptTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A57C38F21F74EB0003B5386 /* ScriptTransaction.swift */; }; - 0A57C39221F74EBA003B5386 /* AssetScriptTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A57C39121F74EBA003B5386 /* AssetScriptTransaction.swift */; }; 0A59330C218343B00059A77A /* AddressesKeysAliacesCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A59330B218343B00059A77A /* AddressesKeysAliacesCell.swift */; }; 0A593312218344000059A77A /* AddressesKeysHiddenPrivateKeyCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A593311218344000059A77A /* AddressesKeysHiddenPrivateKeyCell.swift */; }; 0A59331421835C9C0059A77A /* AddressesKeysTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A59331321835C9C0059A77A /* AddressesKeysTypes.swift */; }; 0A5933162183604F0059A77A /* AddressesKeysPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5933152183604F0059A77A /* AddressesKeysPresenter.swift */; }; 0A59331821870ABB0059A77A /* AliasesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A59331721870ABB0059A77A /* AliasesViewController.swift */; }; 0A59331B21870B130059A77A /* AliasesTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A59331A21870B130059A77A /* AliasesTypes.swift */; }; - 0A5B6E6F211A2B6D005A7F09 /* TransactionNodeService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5B6E6E211A2B6D005A7F09 /* TransactionNodeService.swift */; }; - 0A5C3202213D916900420004 /* AnyTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5C3201213D916900420004 /* AnyTransaction.swift */; }; - 0A5C3204213E93C700420004 /* UnrecognisedTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5C3203213E93C700420004 /* UnrecognisedTransaction.swift */; }; - 0A5C53DD2139491C00667E34 /* UnrecognisedTransactionNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5C53DC2139491C00667E34 /* UnrecognisedTransactionNode.swift */; }; - 0A5C53DF2139498800667E34 /* UnrecognisedTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5C53DE2139498800667E34 /* UnrecognisedTransactionDomainDTO.swift */; }; - 0A5C53E121394A2B00667E34 /* UnrecognisedTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5C53E021394A2B00667E34 /* UnrecognisedTransaction+Mapper.swift */; }; - 0A5C53E52139609600667E34 /* TransactionsRepositoryLocal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5C53E42139609600667E34 /* TransactionsRepositoryLocal.swift */; }; - 0A5C919820F3DB1100443CE6 /* AccountBalanceNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5C919720F3DB1100443CE6 /* AccountBalanceNode.swift */; }; - 0A5C919A20F3DB4C00443CE6 /* AccountAssetsBalanceNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5C919920F3DB4C00443CE6 /* AccountAssetsBalanceNode.swift */; }; - 0A5C919C20F3E7DD00443CE6 /* Asset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5C919B20F3E7DD00443CE6 /* Asset.swift */; }; 0A5D32F72154579C0009CDF3 /* MultyTextField.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0A110CC7215417DD002A8FD7 /* MultyTextField.xib */; }; 0A5D32F9215461E90009CDF3 /* ImportTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5D32F8215461E90009CDF3 /* ImportTypes.swift */; }; - 0A5D3302215842860009CDF3 /* AuthorizationInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5D3301215842860009CDF3 /* AuthorizationInteractor.swift */; }; - 0A5E4BAF213801C400E3C3C3 /* ReissueTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5E4BAE213801C400E3C3C3 /* ReissueTransaction.swift */; }; - 0A5E4BB12138034500E3C3C3 /* LeaseCancelTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5E4BB02138034500E3C3C3 /* LeaseCancelTransaction.swift */; }; - 0A5E4BB32138046E00E3C3C3 /* AliasTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5E4BB22138046E00E3C3C3 /* AliasTransaction.swift */; }; - 0A5E4BB5213805B400E3C3C3 /* MassTransferTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5E4BB4213805B400E3C3C3 /* MassTransferTransaction.swift */; }; - 0A5E4BB721380B3300E3C3C3 /* BurnTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5E4BB621380B3300E3C3C3 /* BurnTransaction.swift */; }; - 0A5E4BBA21381E3400E3C3C3 /* DataTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5E4BB921381E3400E3C3C3 /* DataTransaction.swift */; }; - 0A5E4BC8213820C500E3C3C3 /* DataTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5E4BBC213820C500E3C3C3 /* DataTransactionDomainDTO.swift */; }; - 0A5E4BC9213820C500E3C3C3 /* LeaseCancelTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5E4BBD213820C500E3C3C3 /* LeaseCancelTransactionDomainDTO.swift */; }; - 0A5E4BCA213820C500E3C3C3 /* MassTransferTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5E4BBE213820C500E3C3C3 /* MassTransferTransactionDomainDTO.swift */; }; - 0A5E4BCC213820C500E3C3C3 /* IssueTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5E4BC0213820C500E3C3C3 /* IssueTransactionDomainDTO.swift */; }; - 0A5E4BCD213820C500E3C3C3 /* TransferTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5E4BC1213820C500E3C3C3 /* TransferTransactionDomainDTO.swift */; }; - 0A5E4BCE213820C500E3C3C3 /* ExchangeTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5E4BC2213820C500E3C3C3 /* ExchangeTransactionDomainDTO.swift */; }; - 0A5E4BCF213820C500E3C3C3 /* ReissueTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5E4BC3213820C500E3C3C3 /* ReissueTransactionDomainDTO.swift */; }; - 0A5E4BD0213820C500E3C3C3 /* BurnTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5E4BC4213820C500E3C3C3 /* BurnTransactionDomainDTO.swift */; }; - 0A5E4BD1213820C500E3C3C3 /* LeaseTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5E4BC5213820C500E3C3C3 /* LeaseTransactionDomainDTO.swift */; }; - 0A5E4BD2213820C500E3C3C3 /* AnyTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5E4BC6213820C500E3C3C3 /* AnyTransactionDomainDTO.swift */; }; - 0A5E4BD3213820C500E3C3C3 /* AliasTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5E4BC7213820C500E3C3C3 /* AliasTransactionDomainDTO.swift */; }; - 0A5E4BD92138297000E3C3C3 /* TransactionsRepositoryRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5E4BD82138297000E3C3C3 /* TransactionsRepositoryRemote.swift */; }; - 0A5E4BDB21382C2200E3C3C3 /* IssueTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5E4BDA21382C2200E3C3C3 /* IssueTransaction+Mapper.swift */; }; - 0A5E4BDD2138311C00E3C3C3 /* TransferTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5E4BDC2138311C00E3C3C3 /* TransferTransaction+Mapper.swift */; }; - 0A5E4BDF213832A000E3C3C3 /* ReissueTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5E4BDE213832A000E3C3C3 /* ReissueTransaction+Mapper.swift */; }; - 0A5E4BE12138378500E3C3C3 /* LeaseCancelTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5E4BE02138378500E3C3C3 /* LeaseCancelTransaction+Mapper.swift */; }; - 0A5E4BE32138395200E3C3C3 /* AliasTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5E4BE22138395200E3C3C3 /* AliasTransaction+Mapper.swift */; }; - 0A5E4BE521383B3600E3C3C3 /* MassTransferTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5E4BE421383B3600E3C3C3 /* MassTransferTransaction+Mapper.swift */; }; - 0A5E4BE721383E1600E3C3C3 /* BurnTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5E4BE621383E1600E3C3C3 /* BurnTransaction+Mapper.swift */; }; - 0A5E4BE921383F3D00E3C3C3 /* ExchangeTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5E4BE821383F3D00E3C3C3 /* ExchangeTransaction+Mapper.swift */; }; 0A5F953F2185FAD4005308AC /* AliasWithoutViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5F953E2185FAD4005308AC /* AliasWithoutViewController.swift */; }; 0A61B59A214ACFD500EC60FC /* Languages.json in Resources */ = {isa = PBXBuildFile; fileRef = 0A61B599214ACFD500EC60FC /* Languages.json */; }; 0A6AC3D921839F4E005D2525 /* AddressesKeysValueCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6AC3D821839F4E005D2525 /* AddressesKeysValueCell.swift */; }; 0A6AC3DE2183CEFF005D2525 /* AddressesKeysSkeletonCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6AC3DD2183CEFF005D2525 /* AddressesKeysSkeletonCell.swift */; }; 0A6AC3E021847F8D005D2525 /* AddressesKeysModuleBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6AC3DF21847F8D005D2525 /* AddressesKeysModuleBuilder.swift */; }; - 0A6AC3E421848920005D2525 /* AliasesRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6AC3E321848920005D2525 /* AliasesRepositoryProtocol.swift */; }; - 0A6AC3E8218489F5005D2525 /* AliasDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6AC3E7218489F5005D2525 /* AliasDomainDTO.swift */; }; - 0A6CCD3B20F4CE250023E36E /* Asset+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6CCD3A20F4CE250023E36E /* Asset+Mapper.swift */; }; - 0A6CCD3D20F4CF490023E36E /* AccountBalanceInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6CCD3C20F4CF490023E36E /* AccountBalanceInteractor.swift */; }; 0A6F60E8216F888B00A5C615 /* DexMyOrdersTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9B087632163886800937644 /* DexMyOrdersTypes.swift */; }; 0A6F60E9216F88B200A5C615 /* WalletTypes+ViewModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE491F22107A51A009223DB /* WalletTypes+ViewModels.swift */; }; 0A6F60EA216F893600A5C615 /* WalletTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4C9A9E20EE425B0095A417 /* WalletTypes.swift */; }; 0A6F60EB216F895A00A5C615 /* WalletTypes+DTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A93FED220FCAADC0058179E /* WalletTypes+DTO.swift */; }; - 0A6F60EC216F89B300A5C615 /* SmartTransactionDomain+Assistants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04E80A11214EF20C00D00AA4 /* SmartTransactionDomain+Assistants.swift */; }; - 0A751D3222170EF60024D523 /* NotificationNewsRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A751D3122170EF60024D523 /* NotificationNewsRepositoryProtocol.swift */; }; - 0A751D3422170F3D0024D523 /* NotificationNewsDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A751D3322170F3D0024D523 /* NotificationNewsDomainDTO.swift */; }; - 0A751D36221711380024D523 /* NotificationNewsRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A751D35221711380024D523 /* NotificationNewsRepository.swift */; }; 0A751D38221715F80024D523 /* AppNewsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A751D37221715F80024D523 /* AppNewsCoordinator.swift */; }; - 0A751D3A22171ABB0024D523 /* Kingfisher+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A751D3922171ABA0024D523 /* Kingfisher+Rx.swift */; }; 0A762D11214FDFA100BE9204 /* NewAccountAvatarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A762D10214FDFA100BE9204 /* NewAccountAvatarView.swift */; }; 0A762D13214FE23E00BE9204 /* NewAccountAvatarView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0A762D12214FE23E00BE9204 /* NewAccountAvatarView.xib */; }; 0A762D15214FE3F300BE9204 /* InputTextField.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0A762D14214FE3F300BE9204 /* InputTextField.xib */; }; 0A762D17214FF1CD00BE9204 /* InputTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A762D16214FF1CD00BE9204 /* InputTextField.swift */; }; 0A762D9721639FCC0019D447 /* WavesButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A762D9621639FCC0019D447 /* WavesButton.swift */; }; - 0A762D9B2163A0B60019D447 /* FactoryInteractors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7643FD21187DF500B633E1 /* FactoryInteractors.swift */; }; 0A762D9C2163A1C90019D447 /* HistoryTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04EB74272113335B004A065B /* HistoryTypes.swift */; }; 0A762DA02163AD0F0019D447 /* Support.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0A762D9F2163AD0F0019D447 /* Support.storyboard */; }; - 0A762DA22163AD1A0019D447 /* SupportViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A762DA12163AD1A0019D447 /* SupportViewController.swift */; }; 0A762DAA21661AC40019D447 /* ProfileModuleBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A762DA921661AC40019D447 /* ProfileModuleBuilder.swift */; }; 0A762DAC21661B000019D447 /* ProfilePresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A762DAB21661B000019D447 /* ProfilePresenter.swift */; }; - 0A7643FA211874F400B633E1 /* FactoryInteractorsProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7643F9211874F400B633E1 /* FactoryInteractorsProtocol.swift */; }; - 0A764401211881A500B633E1 /* FactoryRepositories.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7643FF21187E3A00B633E1 /* FactoryRepositories.swift */; }; - 0A764402211881A900B633E1 /* FactoryRepositoriesProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7643FB211876DF00B633E1 /* FactoryRepositoriesProtocol.swift */; }; 0A7CCDAC218A138D005D372B /* MyAddressPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7CCDA1218A138D005D372B /* MyAddressPresenter.swift */; }; 0A7CCDAD218A138D005D372B /* MyAddressTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7CCDA2218A138D005D372B /* MyAddressTypes.swift */; }; 0A7CCDAE218A138D005D372B /* MyAddressViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7CCDA3218A138D005D372B /* MyAddressViewController.swift */; }; @@ -226,18 +113,7 @@ 0A7CCDB4218A138D005D372B /* MyAddressAliacesCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7CCDAA218A138D005D372B /* MyAddressAliacesCell.swift */; }; 0A7CCDB5218A138D005D372B /* MyAddressInfoAddressCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7CCDAB218A138D005D372B /* MyAddressInfoAddressCell.swift */; }; 0A7CCDB7218A17A9005D372B /* MyAddress.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0A7CCDB6218A17A9005D372B /* MyAddress.storyboard */; }; - 0A7E0CD120F2AF6C0010CA6C /* BaseTargetType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7E0CD020F2AF6C0010CA6C /* BaseTargetType.swift */; }; - 0A7E0CD920F2BCFF0010CA6C /* TransactionsApiService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7E0CD820F2BCFF0010CA6C /* TransactionsApiService.swift */; }; - 0A84F00121F4BBA000C0B7DB /* AddressRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A84F00021F4BBA000C0B7DB /* AddressRepositoryProtocol.swift */; }; - 0A84F00321F4C68000C0B7DB /* TransactionFeeRulesGitHub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A84F00221F4C68000C0B7DB /* TransactionFeeRulesGitHub.swift */; }; 0A88CBFE2177FE130083874C /* ChangePasswordTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A88CBFD2177FE130083874C /* ChangePasswordTypes.swift */; }; - 0A88CC02217D217D0083874C /* SpamCSV+Assisstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A88CC01217D217D0083874C /* SpamCSV+Assisstants.swift */; }; - 0A88CC04217D27370083874C /* AccountSettingsRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A88CC03217D27370083874C /* AccountSettingsRepositoryProtocol.swift */; }; - 0A88CC06217D27DF0083874C /* AccountSettingsDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A88CC05217D27DF0083874C /* AccountSettingsDomainDTO.swift */; }; - 0A88CC08217D281F0083874C /* AccountEnvironmentRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A88CC07217D281F0083874C /* AccountEnvironmentRepository.swift */; }; - 0A88CC0A217E80040083874C /* WalletRealmFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A88CC09217E80040083874C /* WalletRealmFactory.swift */; }; - 0A8AFF282101F37200D0582B /* MatcherServiceTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A8AFF272101F37200D0582B /* MatcherServiceTypes.swift */; }; - 0A8AFF2A2101F47F00D0582B /* OrderBookMatcherService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A8AFF292101F47F00D0582B /* OrderBookMatcherService.swift */; }; 0A96F1CC2151B392005E148F /* Passcode.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0A96F1CB2151B392005E148F /* Passcode.storyboard */; }; 0A96F1D12151B6B5005E148F /* PasscodeNumberButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A96F1D02151B6B5005E148F /* PasscodeNumberButton.swift */; }; 0A96F1D32151BD46005E148F /* PasscodeTopBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A96F1D22151BD46005E148F /* PasscodeTopBarView.swift */; }; @@ -251,106 +127,34 @@ 0A9797602108A11A00407F67 /* Wallet.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0A97975F2108A11A00407F67 /* Wallet.storyboard */; }; 0A9797612108A60000407F67 /* Storyboards.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A979757210886EA00407F67 /* Storyboards.swift */; }; 0A9797652108B18C00407F67 /* WalletModuleOutput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A9797642108B18C00407F67 /* WalletModuleOutput.swift */; }; - 0A98D14A2138910600550FE0 /* DataTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A98D1492138910600550FE0 /* DataTransaction+Mapper.swift */; }; - 0A98D14C2138A30700550FE0 /* AnyTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A98D14B2138A30700550FE0 /* AnyTransaction+Mapper.swift */; }; 0A9D6B62216E059F006822C5 /* WalletTypes+DisplayState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A16784720FD3E4F00AA5980 /* WalletTypes+DisplayState.swift */; }; 0A9D6B68216E070E006822C5 /* WalletTypes+State.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE491F12107A51A009223DB /* WalletTypes+State.swift */; }; 0AA8CAC921516077000D09E6 /* Backup.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0AA8CAC821516077000D09E6 /* Backup.storyboard */; }; 0AA8CAD22152763A000D09E6 /* PasscodeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AA8CAD12152763A000D09E6 /* PasscodeView.swift */; }; 0AA8CAD421527672000D09E6 /* PasscodeView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0AA8CAD321527672000D09E6 /* PasscodeView.xib */; }; - 0AAB15C12165534500F1F7BC /* DomainLayerTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A485E942100A0D400079B49 /* DomainLayerTypes.swift */; }; 0AAB15C321655BDB00F1F7BC /* ProfileInfoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AAB15C221655BDB00F1F7BC /* ProfileInfoCell.swift */; }; 0AAB15C521655BEC00F1F7BC /* ProfileBackupPhraseCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AAB15C421655BEC00F1F7BC /* ProfileBackupPhraseCell.swift */; }; 0AAB15C721655C0600F1F7BC /* ProfileDisabledButtomTableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AAB15C621655C0600F1F7BC /* ProfileDisabledButtomTableCell.swift */; }; 0AAB15C921655C1800F1F7BC /* ProfileValueCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AAB15C821655C1800F1F7BC /* ProfileValueCell.swift */; }; 0AAB15CA21655EB000F1F7BC /* ProfileViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9193B8420D8A98500F5D983 /* ProfileViewController.swift */; }; - 0AAC2811221438B200D8A404 /* UIImageView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AAC2810221438B200D8A404 /* UIImageView+Rx.swift */; }; 0AAC28132215C4C700D8A404 /* SendFeeHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0AAC28122215C4C700D8A404 /* SendFeeHeaderView.xib */; }; - 0AAC2A442146C40A00F6EB27 /* TransactionsInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5EC393213ED90F00659350 /* TransactionsInteractor.swift */; }; - 0AAC2A462146C65900F6EB27 /* BlockRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AAC2A452146C65900F6EB27 /* BlockRepositoryProtocol.swift */; }; - 0AAC2A482146C69700F6EB27 /* BlockRepositoryRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AAC2A472146C69600F6EB27 /* BlockRepositoryRemote.swift */; }; 0AACD59B21A59E7100B30815 /* SweetSnackbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AACD59821A59E7000B30815 /* SweetSnackbar.swift */; }; 0AACD59C21A59E7100B30815 /* SweetSnackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AACD59921A59E7000B30815 /* SweetSnackView.swift */; }; 0AACD59D21A59E7100B30815 /* SweetSnackView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0AACD59A21A59E7100B30815 /* SweetSnackView.xib */; }; 0AACD5AB21A6CAC800B30815 /* SweetSnackBack+Factory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AACD5AA21A6CAC800B30815 /* SweetSnackBack+Factory.swift */; }; - 0AADFD0621F9F4AC001F5C0A /* AppSpector-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 0AADFD0521F9F4AB001F5C0A /* AppSpector-Info.plist */; }; 0AB63C1E216F952E0056B17E /* HistoryTransactionView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0444E7B1212C8057004C7DF2 /* HistoryTransactionView.xib */; }; 0AB63C2C2170EBF00056B17E /* Language.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0AB63C2B2170EBF00056B17E /* Language.storyboard */; }; - 0ABD1BE621469CE70027A7A2 /* AddressInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD1BE521469CE70027A7A2 /* AddressInteractor.swift */; }; - 0ABD1BE821469D2F0027A7A2 /* AddressDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD1BE721469D2F0027A7A2 /* AddressDomainDTO.swift */; }; - 0ABD1BEC2146BFEE0027A7A2 /* BlockNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD1BEB2146BFEE0027A7A2 /* BlockNode.swift */; }; - 0ABD1BED2146C2760027A7A2 /* BlocksNodeService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD1BE92146BEED0027A7A2 /* BlocksNodeService.swift */; }; 0AC1251221A758BD00357C93 /* LongInfoPageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AC1251121A758BC00357C93 /* LongInfoPageView.swift */; }; - 0AC33AF021A826B700B66747 /* NetworkError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AC33AEF21A826B700B66747 /* NetworkError.swift */; }; 0ACC0233217E2BA1000E3EE0 /* DynamicHeaderTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ACC0232217E2BA1000E3EE0 /* DynamicHeaderTableView.swift */; }; 0AD63240217633C20047D467 /* ChangePasswordModuleBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AD6323F217633C20047D467 /* ChangePasswordModuleBuilder.swift */; }; - 0AD83601217A0D25004413E9 /* GitHubService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AD83600217A0D25004413E9 /* GitHubService.swift */; }; - 0AD83606217A1C14004413E9 /* AccountEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AD83605217A1C14004413E9 /* AccountEnvironment.swift */; }; - 0AD83608217A1C26004413E9 /* AccountSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AD83607217A1C26004413E9 /* AccountSettings.swift */; }; - 0AD8360E217DD34B004413E9 /* AccountSettings+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AD8360D217DD34B004413E9 /* AccountSettings+Mapper.swift */; }; 0AD83612217DDD94004413E9 /* NetworkSettingsTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AD83611217DDD94004413E9 /* NetworkSettingsTypes.swift */; }; 0AD83614217DDDAC004413E9 /* NetworkSettingsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AD83613217DDDAC004413E9 /* NetworkSettingsPresenter.swift */; }; 0AD83616217DE071004413E9 /* NetworkSettingsModuleBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AD83615217DE071004413E9 /* NetworkSettingsModuleBuilder.swift */; }; - 0ADC179E2204A23000472130 /* ModalRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADC179D2204A23000472130 /* ModalRootView.swift */; }; - 0ADC17A02204A24C00472130 /* ModalScrollViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADC179F2204A24C00472130 /* ModalScrollViewController.swift */; }; - 0ADC17A22204A34100472130 /* ModalTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADC17A12204A34100472130 /* ModalTableView.swift */; }; 0ADD6C822167948500B06917 /* ProfileHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0ADD6C802167948400B06917 /* ProfileHeaderView.xib */; }; 0ADD6C832167948500B06917 /* ProfileHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD6C812167948400B06917 /* ProfileHeaderView.swift */; }; 0ADD6C87216796DB00B06917 /* ProfileLanguageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD6C86216796DB00B06917 /* ProfileLanguageCell.swift */; }; 0ADD6C892167980E00B06917 /* ProfileBiometricCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD6C882167980E00B06917 /* ProfileBiometricCell.swift */; }; - 0ADD7F8F21F22FB60075FC59 /* CALayer+Shadow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F1F21F22FB60075FC59 /* CALayer+Shadow.swift */; }; - 0ADD7F9021F22FB60075FC59 /* ControlEvent+ScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F2021F22FB60075FC59 /* ControlEvent+ScrollView.swift */; }; - 0ADD7F9121F22FB60075FC59 /* UIButton+WithoutAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F2121F22FB60075FC59 /* UIButton+WithoutAnimation.swift */; }; - 0ADD7F9221F22FB60075FC59 /* UIScrollView+Pagination.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F2221F22FB60075FC59 /* UIScrollView+Pagination.swift */; }; - 0ADD7F9421F22FB60075FC59 /* UIFeedbackGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F2421F22FB60075FC59 /* UIFeedbackGenerator.swift */; }; - 0ADD7F9521F22FB60075FC59 /* UIColor+Asset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F2521F22FB60075FC59 /* UIColor+Asset.swift */; }; - 0ADD7F9621F22FB60075FC59 /* UIColor+Hex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F2621F22FB60075FC59 /* UIColor+Hex.swift */; }; - 0ADD7F9721F22FB60075FC59 /* UIView+Additionals.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F2721F22FB60075FC59 /* UIView+Additionals.swift */; }; - 0ADD7F9821F22FB60075FC59 /* UITableView+HeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F2821F22FB60075FC59 /* UITableView+HeaderView.swift */; }; - 0ADD7F9921F22FB60075FC59 /* UITableView+Animation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F2921F22FB60075FC59 /* UITableView+Animation.swift */; }; - 0ADD7F9A21F22FB60075FC59 /* UIFont+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F2A21F22FB60075FC59 /* UIFont+Additions.swift */; }; - 0ADD7F9B21F22FB60075FC59 /* UIApplication+OpenURL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F2B21F22FB60075FC59 /* UIApplication+OpenURL.swift */; }; - 0ADD7F9C21F22FB60075FC59 /* UIViewController+Additionals.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F2C21F22FB60075FC59 /* UIViewController+Additionals.swift */; }; - 0ADD7F9D21F22FB60075FC59 /* UIResponder+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F2D21F22FB60075FC59 /* UIResponder+Rx.swift */; }; - 0ADD7F9F21F22FB60075FC59 /* UIViewController+Alert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F2F21F22FB60075FC59 /* UIViewController+Alert.swift */; }; - 0ADD7FA021F22FB60075FC59 /* RateApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F3021F22FB60075FC59 /* RateApp.swift */; }; - 0ADD7FA121F22FB60075FC59 /* UIColor+Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F3121F22FB60075FC59 /* UIColor+Colors.swift */; }; - 0ADD7FA221F22FB60075FC59 /* ControlEvent+Signal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F3221F22FB60075FC59 /* ControlEvent+Signal.swift */; }; - 0ADD7FA321F22FB60075FC59 /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F3321F22FB60075FC59 /* Notifications.swift */; }; - 0ADD7FA421F22FB60075FC59 /* UIView+SafeArea.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F3421F22FB60075FC59 /* UIView+SafeArea.swift */; }; - 0ADD7FA521F22FB60075FC59 /* UINavigationController+Additionals.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F3521F22FB60075FC59 /* UINavigationController+Additionals.swift */; }; - 0ADD7FA621F22FB60075FC59 /* UIView+TouchInset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F3621F22FB60075FC59 /* UIView+TouchInset.swift */; }; - 0ADD7FA721F22FB60075FC59 /* ActivityIndicator+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F3721F22FB60075FC59 /* ActivityIndicator+Rx.swift */; }; - 0ADD7FA821F22FB60075FC59 /* UIImage+Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F3821F22FB60075FC59 /* UIImage+Color.swift */; }; - 0ADD7FA921F22FB60075FC59 /* UIViewController+SafeArea.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F3921F22FB60075FC59 /* UIViewController+SafeArea.swift */; }; 0ADD7FAB21F22FB60075FC59 /* PasteboardButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F3B21F22FB60075FC59 /* PasteboardButton.swift */; }; - 0ADD7FAC21F22FB60075FC59 /* UIViewController+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F3C21F22FB60075FC59 /* UIViewController+Rx.swift */; }; - 0ADD7FAD21F22FB60075FC59 /* QRCodeReader+Factory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F3D21F22FB60075FC59 /* QRCodeReader+Factory.swift */; }; - 0ADD7FAE21F22FB60075FC59 /* UIView+Passtrough.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F3E21F22FB60075FC59 /* UIView+Passtrough.swift */; }; - 0ADD7FAF21F22FB60075FC59 /* MailCompose+Support.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F3F21F22FB60075FC59 /* MailCompose+Support.swift */; }; - 0ADD7FB021F22FB60075FC59 /* UIView+Shadow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F4021F22FB60075FC59 /* UIView+Shadow.swift */; }; - 0ADD7FB121F22FB60075FC59 /* UIScrollView+ContentInset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F4121F22FB60075FC59 /* UIScrollView+ContentInset.swift */; }; - 0ADD7FB221F22FB60075FC59 /* CALayer+RoundingCorners.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F4221F22FB60075FC59 /* CALayer+RoundingCorners.swift */; }; - 0ADD7FB321F22FB60075FC59 /* TimingFunction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F4321F22FB60075FC59 /* TimingFunction.swift */; }; - 0ADD7FB421F22FB60075FC59 /* UIView+Animation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F4421F22FB60075FC59 /* UIView+Animation.swift */; }; - 0ADD7FB921F22FB60075FC59 /* UIAlertController+Factory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F4A21F22FB60075FC59 /* UIAlertController+Factory.swift */; }; - 0ADD7FBA21F22FB60075FC59 /* CGFloat+Min.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F4B21F22FB60075FC59 /* CGFloat+Min.swift */; }; - 0ADD7FBF21F22FB60075FC59 /* NSAttributedString+Styles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F5021F22FB60075FC59 /* NSAttributedString+Styles.swift */; }; - 0ADD7FCA21F22FB60075FC59 /* DisplayError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F5B21F22FB60075FC59 /* DisplayError.swift */; }; - 0ADD7FD021F22FB60075FC59 /* GlobalConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F6121F22FB60075FC59 /* GlobalConstants.swift */; }; - 0ADD7FD321F22FB60075FC59 /* AssetLogo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F6521F22FB60075FC59 /* AssetLogo.swift */; }; - 0ADD7FEA21F22FB60075FC59 /* UITableView+Skeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F7F21F22FB60075FC59 /* UITableView+Skeleton.swift */; }; - 0ADD7FEB21F22FB60075FC59 /* SkeletonAnimatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F8021F22FB60075FC59 /* SkeletonAnimatable.swift */; }; - 0ADD7FEC21F22FB60075FC59 /* ModuleBuilderOutput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F8221F22FB60075FC59 /* ModuleBuilderOutput.swift */; }; - 0ADD7FED21F22FB60075FC59 /* ModuleBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F8321F22FB60075FC59 /* ModuleBuilder.swift */; }; - 0ADD7FEE21F22FB60075FC59 /* ViewConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F8421F22FB60075FC59 /* ViewConfiguration.swift */; }; - 0ADD7FF021F22FB60075FC59 /* ViewCalculate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F8621F22FB60075FC59 /* ViewCalculate.swift */; }; - 0ADD7FF121F22FB60075FC59 /* SectionDisplayCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F8721F22FB60075FC59 /* SectionDisplayCollection.swift */; }; - 0ADD7FF221F22FB60075FC59 /* UICollectionView+Reusable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F8921F22FB60075FC59 /* UICollectionView+Reusable.swift */; }; - 0ADD7FF321F22FB60075FC59 /* Reusable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F8A21F22FB60075FC59 /* Reusable.swift */; }; - 0ADD7FF421F22FB60075FC59 /* UITableView+Reusable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F8B21F22FB60075FC59 /* UITableView+Reusable.swift */; }; - 0ADD7FF521F22FB60075FC59 /* NibLoadable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F8C21F22FB60075FC59 /* NibLoadable.swift */; }; - 0ADD7FF621F22FB60075FC59 /* NibOwnerLoadable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7F8D21F22FB60075FC59 /* NibOwnerLoadable.swift */; }; 0ADD801D21F22FFA0075FC59 /* DexCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7FF821F22FFA0075FC59 /* DexCoordinator.swift */; }; 0ADD801E21F22FFA0075FC59 /* PresentationCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7FFA21F22FFA0075FC59 /* PresentationCoordinator.swift */; }; 0ADD801F21F22FFA0075FC59 /* RoutingCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD7FFB21F22FFA0075FC59 /* RoutingCoordinator.swift */; }; @@ -379,36 +183,12 @@ 0ADD803821F22FFB0075FC59 /* BackupCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD801A21F22FFA0075FC59 /* BackupCoordinator.swift */; }; 0ADD803921F22FFB0075FC59 /* BackupTostCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD801B21F22FFA0075FC59 /* BackupTostCoordinator.swift */; }; 0ADD803A21F22FFB0075FC59 /* MainTabBarCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD801C21F22FFA0075FC59 /* MainTabBarCoordinator.swift */; }; - 0ADD803C21F5B60D0075FC59 /* AddressScriptInfoNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD803B21F5B60D0075FC59 /* AddressScriptInfoNode.swift */; }; - 0ADD803E21F5B7090075FC59 /* AssetDetailNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD803D21F5B7090075FC59 /* AssetDetailNode.swift */; }; - 0ADD804021F5D2DD0075FC59 /* AddressRepositoryRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD803F21F5D2DD0075FC59 /* AddressRepositoryRemote.swift */; }; - 0ADD804221F71FDA0075FC59 /* ScriptTransactionNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD804121F71FD90075FC59 /* ScriptTransactionNode.swift */; }; - 0ADD804421F72B2C0075FC59 /* AssetScriptTransactionNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD804321F72B2C0075FC59 /* AssetScriptTransactionNode.swift */; }; - 0ADD804821F73C280075FC59 /* AssetScriptTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD804721F73C280075FC59 /* AssetScriptTransactionDomainDTO.swift */; }; - 0ADD804A21F73C360075FC59 /* ScriptTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADD804921F73C360075FC59 /* ScriptTransactionDomainDTO.swift */; }; 0AE491E1210786BC009223DB /* ConfirmBackupStackInputView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E945B19E20F75B420081F4D2 /* ConfirmBackupStackInputView.swift */; }; 0AE491F62107A529009223DB /* WalletInteractorProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE491F52107A529009223DB /* WalletInteractorProtocol.swift */; }; 0AE491F82107A52E009223DB /* WalletPresenterProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE491F72107A52D009223DB /* WalletPresenterProtocol.swift */; }; - 0AE6572F2106340A003D2DB8 /* Signature.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE6572E2106340A003D2DB8 /* Signature.swift */; }; - 0AE657312106368F003D2DB8 /* BalanceMatcherService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE657302106368F003D2DB8 /* BalanceMatcherService.swift */; }; - 0AE657342106375D003D2DB8 /* TimestampSignature.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE657332106375D003D2DB8 /* TimestampSignature.swift */; }; - 0AEB358C2115DB3C00EDD63C /* AssetsRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AEB358B2115DB3C00EDD63C /* AssetsRepositoryProtocol.swift */; }; - 0AEB358F2115DFF500EDD63C /* AssetDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AEB358E2115DFF500EDD63C /* AssetDomainDTO.swift */; }; - 0AEB35912115E44300EDD63C /* AssetsRepositoryLocal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AEB35902115E44300EDD63C /* AssetsRepositoryLocal.swift */; }; - 0AEB35942115E45500EDD63C /* AssetsRepositoryRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AEB35932115E45500EDD63C /* AssetsRepositoryRemote.swift */; }; - 0AEB35A021165CBF00EDD63C /* AssetBalanceDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AEB359F21165CBF00EDD63C /* AssetBalanceDomainDTO.swift */; }; - 0AEB35A221165D2100EDD63C /* AccountBalanceRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AEB35A121165D2100EDD63C /* AccountBalanceRepositoryProtocol.swift */; }; - 0AEB35A421165E1300EDD63C /* AccountBalanceRepositoryRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AEB35A321165E1300EDD63C /* AccountBalanceRepositoryRemote.swift */; }; - 0AEB35A621165E1D00EDD63C /* AccountBalanceRepositoryLocal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AEB35A521165E1D00EDD63C /* AccountBalanceRepositoryLocal.swift */; }; 0AED6BBA216620F000481B42 /* ProfileTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AED6BB9216620F000481B42 /* ProfileTypes.swift */; }; - 0AF0C67221A97C4700602197 /* AliasesInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AF0C67121A97C4700602197 /* AliasesInteractor.swift */; }; - 0AF0C67421A97D3500602197 /* AliasesRepositoryLocal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AF0C67321A97D3500602197 /* AliasesRepositoryLocal.swift */; }; - 0AF0C67721A97E1400602197 /* Alias.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AF0C67621A97E1400602197 /* Alias.swift */; }; - 0AF0C67921AA25B200602197 /* AliasesRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AF0C67821AA25B200602197 /* AliasesRepository.swift */; }; 0AF0C67B21AACA4F00602197 /* GlobalErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AF0C67A21AACA4F00602197 /* GlobalErrorView.swift */; }; 0AF0C67D21AACB3700602197 /* GlobalErrorView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0AF0C67C21AACB3700602197 /* GlobalErrorView.xib */; }; - 0AF2536321B0351A00B8F7DF /* AssetsBalanceSettingsInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AF2536221B0351A00B8F7DF /* AssetsBalanceSettingsInteractor.swift */; }; - 0AF2536521B6C2F900B8F7DF /* AssetsBalanceSettingsRepositoryLocal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AF2536421B6C2F900B8F7DF /* AssetsBalanceSettingsRepositoryLocal.swift */; }; 0AF58F902191BC9300C8A4B3 /* PasscodePresenterProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AF58F8F2191BC9300C8A4B3 /* PasscodePresenterProtocol.swift */; }; 0AF58F942191C1D300C8A4B3 /* PasscodeRegistationPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AF58F932191C1D300C8A4B3 /* PasscodeRegistationPresenter.swift */; }; 0AF58F962191C95A00C8A4B3 /* PasscodeLogInPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AF58F952191C95A00C8A4B3 /* PasscodeLogInPresenter.swift */; }; @@ -416,7 +196,6 @@ 0AF58F9B2191D6D000C8A4B3 /* PasscodeChangePasscodeByPasswordPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AF58F9A2191D6D000C8A4B3 /* PasscodeChangePasscodeByPasswordPresenter.swift */; }; 0AF58F9D2191DEA300C8A4B3 /* PasscodeEnableBiometricPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AF58F9C2191DEA300C8A4B3 /* PasscodeEnableBiometricPresenter.swift */; }; 0AF58F9F2192056400C8A4B3 /* PasscodeChangePasswordPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AF58F9E2192056300C8A4B3 /* PasscodeChangePasswordPresenter.swift */; }; - 0AF58FA121931AD400C8A4B3 /* WalletEncryption.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AF58FA021931AD400C8A4B3 /* WalletEncryption.swift */; }; 0AF6AD25218A54840004F107 /* CopyableImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AF6AD24218A54840004F107 /* CopyableImageView.swift */; }; 0AF921E8212E07B3003BA067 /* AssetDetailPresenterProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AF921C1212E07B2003BA067 /* AssetDetailPresenterProtocol.swift */; }; 0AF921EB212E07B3003BA067 /* Asset.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0AF921C4212E07B2003BA067 /* Asset.storyboard */; }; @@ -481,11 +260,6 @@ 0AF92303212E1424003BA067 /* Waves.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0AF92301212E1424003BA067 /* Waves.strings */; }; 0AFA0C7D2174A2300003FE3B /* BrowserViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AFA0C742174A2300003FE3B /* BrowserViewController.swift */; }; 0AFB59402209AD56001F0DD8 /* TestViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AFB593F2209AD56001F0DD8 /* TestViewController.swift */; }; - 0AFB59422209B2BD001F0DD8 /* SponsorshipTransactionNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AFB59412209B2BD001F0DD8 /* SponsorshipTransactionNode.swift */; }; - 0AFB59442209B5F3001F0DD8 /* SponsorshipTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AFB59432209B5F3001F0DD8 /* SponsorshipTransaction.swift */; }; - 0AFB59462209C20E001F0DD8 /* SponsorshipTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AFB59452209C20E001F0DD8 /* SponsorshipTransaction+Mapper.swift */; }; - 0AFB59482209C2F8001F0DD8 /* SponsorshipTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AFB59472209C2F8001F0DD8 /* SponsorshipTransactionDomainDTO.swift */; }; - 0AFB594A2209F167001F0DD8 /* Sentry-io-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 0AFB59492209F167001F0DD8 /* Sentry-io-Info.plist */; }; 0AFBCA80211306F600285BCB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0AFBCA7F211306F600285BCB /* LaunchScreen.storyboard */; }; 0AFBCA852113173300285BCB /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0AFBCA832113173300285BCB /* InfoPlist.strings */; }; 0AFBCA8A2113254100285BCB /* WalletModuleBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AFBCA892113254100285BCB /* WalletModuleBuilder.swift */; }; @@ -495,7 +269,38 @@ 0AFF5C7F215BD08E00B82940 /* AccountPasswordInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AFF5C7E215BD08E00B82940 /* AccountPasswordInteractor.swift */; }; 0AFF5C81215BD09500B82940 /* AccountPasswordPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AFF5C80215BD09500B82940 /* AccountPasswordPresenter.swift */; }; 0AFF5C8D215CE2D000B82940 /* UseTouchIDModuleBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AFF5C8C215CE2D000B82940 /* UseTouchIDModuleBuilder.swift */; }; - 53AA2F7E1F0FB6ED983FDF2F /* Pods_WavesWallet_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B2F04F55A260735DF3584D3E /* Pods_WavesWallet_iOS.framework */; }; + 1BAB29B6B58AFE20D3FD1998 /* (null) in Frameworks */ = {isa = PBXBuildFile; }; + 2D5B6193C022056CD73DEFBE /* Pods_DataLayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BB158FA7ECE6E5227A7AF0B /* Pods_DataLayer.framework */; }; + 3EC73C513F8BB9C83B92E17B /* Pods_DataLayerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5F1A2C7157881DA75A52C4BA /* Pods_DataLayerTests.framework */; }; + 4BEC9D5887FACABD00BD4154 /* Pods_MarketPulseWidget.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 20735B3922DF223C5F8F7C79 /* Pods_MarketPulseWidget.framework */; }; + 53E8DAD5791F388085BF04A3 /* (null) in Frameworks */ = {isa = PBXBuildFile; }; + 6B2551D9571ABC864B16A7EE /* (null) in Frameworks */ = {isa = PBXBuildFile; }; + 7B0FD985231952740004B52B /* ConfirmRequestLoadingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B0FD984231952740004B52B /* ConfirmRequestLoadingViewController.swift */; }; + 7B0FD98723195D6A0004B52B /* ConfirmRequestCompleteViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B0FD98623195D6A0004B52B /* ConfirmRequestCompleteViewController.swift */; }; + 7B0FD98923196A3F0004B52B /* ConfirmRequestDTOTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B0FD98823196A3F0004B52B /* ConfirmRequestDTOTransaction+Mapper.swift */; }; + 7B0FD98B23196C430004B52B /* ConfirmRequestDTORequest+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B0FD98A23196C430004B52B /* ConfirmRequestDTORequest+Mapper.swift */; }; + 7B0FD98F2319C0EA0004B52B /* MobileKeeperRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B0FD98E2319C0EA0004B52B /* MobileKeeperRepositoryProtocol.swift */; }; + 7B16BCE622DBE49A00540418 /* DomainLayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7B66860022B3F70D0029E6F1 /* DomainLayer.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 7B2408002317F26100D35F59 /* ConfirmRequestButtonsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B2407FF2317F26100D35F59 /* ConfirmRequestButtonsCell.swift */; }; + 7B26A87D22ED129300E7B024 /* WidgetSettings.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7B26A87C22ED129300E7B024 /* WidgetSettings.storyboard */; }; + 7B26A87F22ED13F300E7B024 /* WidgetSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B26A87E22ED13F300E7B024 /* WidgetSettingsViewController.swift */; }; + 7B26A88122ED140100E7B024 /* WidgetSettingsType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B26A88022ED140000E7B024 /* WidgetSettingsType.swift */; }; + 7B26A88322ED14DA00E7B024 /* WidgetSettingsSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B26A88222ED14DA00E7B024 /* WidgetSettingsSystem.swift */; }; + 7B26A88A22ED180A00E7B024 /* UIDeveloperCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B26A88922ED180A00E7B024 /* UIDeveloperCoordinator.swift */; }; + 7B26A88C22ED191900E7B024 /* WidgetSettingsModuleBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B26A88B22ED191900E7B024 /* WidgetSettingsModuleBuilder.swift */; }; + 7B26A88E22EEEA7000E7B024 /* WidgetSettingsModuleOutput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B26A88D22EEEA7000E7B024 /* WidgetSettingsModuleOutput.swift */; }; + 7B26A89022EEECC200E7B024 /* WidgetSettingsAssetCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B26A88F22EEECC200E7B024 /* WidgetSettingsAssetCell.swift */; }; + 7B3681982314260C000D5592 /* ConfirmRequestViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B3681972314260C000D5592 /* ConfirmRequestViewController.swift */; }; + 7B36819A23142625000D5592 /* ConfirmRequestType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B36819923142625000D5592 /* ConfirmRequestType.swift */; }; + 7B36819D23142639000D5592 /* ConfirmRequestSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B36819C23142639000D5592 /* ConfirmRequestSystem.swift */; }; + 7B36819F23142A0F000D5592 /* ConfirmRequestModuleBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B36819E23142A0F000D5592 /* ConfirmRequestModuleBuilder.swift */; }; + 7B3681A123142A33000D5592 /* ConfirmRequestModuleOutput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B3681A023142A33000D5592 /* ConfirmRequestModuleOutput.swift */; }; + 7B3681A72315534E000D5592 /* ConfirmRequestTransactionKindCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B3681A62315534E000D5592 /* ConfirmRequestTransactionKindCell.swift */; }; + 7B3681A923155499000D5592 /* ConfirmRequestFromToCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B3681A823155499000D5592 /* ConfirmRequestFromToCell.swift */; }; + 7B3681AB231555B8000D5592 /* ConfirmRequestKeyValueCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B3681AA231555B8000D5592 /* ConfirmRequestKeyValueCell.swift */; }; + 7B3681AD231556B4000D5592 /* ConfirmRequestFeeAndTimestampCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B3681AC231556B4000D5592 /* ConfirmRequestFeeAndTimestampCell.swift */; }; + 7B3681AF23155805000D5592 /* ConfirmRequestBalanceCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B3681AE23155805000D5592 /* ConfirmRequestBalanceCell.swift */; }; + 7B3681B12315612C000D5592 /* ConfirmRequestSkeletonCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B3681B02315612C000D5592 /* ConfirmRequestSkeletonCell.swift */; }; 7B39029522366B8E00AAFDB8 /* TransactionCardAddressCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B39029422366B8E00AAFDB8 /* TransactionCardAddressCell.swift */; }; 7B39029722366D0100AAFDB8 /* AddressBookButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B39029622366D0100AAFDB8 /* AddressBookButton.swift */; }; 7B390299223698D300AAFDB8 /* TransactionCardKeyValueCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B390298223698D300AAFDB8 /* TransactionCardKeyValueCell.swift */; }; @@ -511,6 +316,25 @@ 7B3902AD2237D31900AAFDB8 /* TransactionCardShowAllCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B3902AC2237D31900AAFDB8 /* TransactionCardShowAllCell.swift */; }; 7B3902B02237D8FA00AAFDB8 /* TransactionCardExchangeCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B3902AF2237D8FA00AAFDB8 /* TransactionCardExchangeCell.swift */; }; 7B3A51A8223AA08F00C3BF38 /* TransactionCardAssetCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B3A51A7223AA08F00C3BF38 /* TransactionCardAssetCell.swift */; }; + 7B3A9AB4231BE3900025CDCA /* MobileKeeperRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B3A9AB3231BE3900025CDCA /* MobileKeeperRepository.swift */; }; + 7B3A9AB6231D66B80025CDCA /* NetworkError+Title.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B3A9AB5231D66B80025CDCA /* NetworkError+Title.swift */; }; + 7B431A7E22BCFF3800DE73B9 /* AssetsUseCaseProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B431A7C22BCFE8A00DE73B9 /* AssetsUseCaseProtocol.swift */; }; + 7B431A8122BCFF7100DE73B9 /* AssetsBalanceSettingsUseCaseProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B431A7F22BCFF5700DE73B9 /* AssetsBalanceSettingsUseCaseProtocol.swift */; }; + 7B431A8322BCFFA900DE73B9 /* TransactionsUseCaseProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B431A8222BCFFA900DE73B9 /* TransactionsUseCaseProtocol.swift */; }; + 7B431A8622BD030600DE73B9 /* AddressUseCaseProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B431A8422BD02E700DE73B9 /* AddressUseCaseProtocol.swift */; }; + 7B431A8F22BD176D00DE73B9 /* DomainLayerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B431A8E22BD176D00DE73B9 /* DomainLayerTests.swift */; }; + 7B431A9F22BD185B00DE73B9 /* DataLayerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B431A9E22BD185B00DE73B9 /* DataLayerTests.swift */; }; + 7B48F35F2330F7C000923E9E /* environment_stagenet.json in Resources */ = {isa = PBXBuildFile; fileRef = 7B48F35E2330F7BF00923E9E /* environment_stagenet.json */; }; + 7B49911722F874B0005B7123 /* AssetsSearchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B49911622F874B0005B7123 /* AssetsSearchViewController.swift */; }; + 7B49911A22F874DD005B7123 /* AssetsSearchAssetCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B49911922F874DD005B7123 /* AssetsSearchAssetCell.swift */; }; + 7B49911C22F8754A005B7123 /* AssetsSearch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B49911B22F8754A005B7123 /* AssetsSearch.swift */; }; + 7B49911E22F875A1005B7123 /* AssetsSearchViewBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B49911D22F875A1005B7123 /* AssetsSearchViewBuilder.swift */; }; + 7B49912022F875D4005B7123 /* AssetsSearch.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7B49911F22F875D4005B7123 /* AssetsSearch.storyboard */; }; + 7B49912222F876AA005B7123 /* AssetsSearchHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B49912122F876AA005B7123 /* AssetsSearchHeaderView.swift */; }; + 7B49912622F876E1005B7123 /* AssetsSearchHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7B49912522F876E1005B7123 /* AssetsSearchHeaderView.xib */; }; + 7B49912822F87C7A005B7123 /* AssetsSearchSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B49912722F87C7A005B7123 /* AssetsSearchSystem.swift */; }; + 7B49912C22F99B76005B7123 /* AssetsSearchEmptyCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B49912B22F99B76005B7123 /* AssetsSearchEmptyCell.swift */; }; + 7B49912E22F9B470005B7123 /* AssetsSearchModuleOutput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B49912D22F9B470005B7123 /* AssetsSearchModuleOutput.swift */; }; 7B5E7465223907AA00746ADD /* TransactionCardHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5E7464223907AA00746ADD /* TransactionCardHeaderView.swift */; }; 7B5E74672239088800746ADD /* TransactionCardHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7B5E74662239088800746ADD /* TransactionCardHeaderView.xib */; }; 7B5E746922390B8200746ADD /* TransactionCardBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5E746822390B8200746ADD /* TransactionCardBuilder.swift */; }; @@ -518,32 +342,227 @@ 7B5EDEC222522837009C2B3B /* TransactionCardSystemOrder+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5EDEC122522837009C2B3B /* TransactionCardSystemOrder+Mapper.swift */; }; 7B5EDEC42253618C009C2B3B /* AccessibilityIdentifiers.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7B5EDEC32253618C009C2B3B /* AccessibilityIdentifiers.strings */; }; 7B5EDEC622536269009C2B3B /* AccessibilityIdentifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5EDEC522536268009C2B3B /* AccessibilityIdentifiers.swift */; }; - 7B601B2A2240C4B80040975C /* SmartTransactionDTO+EncodingToString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B601B292240C4B80040975C /* SmartTransactionDTO+EncodingToString.swift */; }; + 7B5FAA6922BBE3EC00621A44 /* UseCasesFactoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA0522BBE3EB00621A44 /* UseCasesFactoryProtocol.swift */; }; + 7B5FAA6A22BBE3EC00621A44 /* RepositoriesFactoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA0622BBE3EB00621A44 /* RepositoriesFactoryProtocol.swift */; }; + 7B5FAA6B22BBE3EC00621A44 /* TransactionDomainDTO+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA0822BBE3EB00621A44 /* TransactionDomainDTO+Mapper.swift */; }; + 7B5FAA6C22BBE3EC00621A44 /* Asset+Assistants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA0922BBE3EB00621A44 /* Asset+Assistants.swift */; }; + 7B5FAA6D22BBE3EC00621A44 /* DomainDexQueries.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA0B22BBE3EB00621A44 /* DomainDexQueries.swift */; }; + 7B5FAA6E22BBE3EC00621A44 /* WalletsRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA0D22BBE3EB00621A44 /* WalletsRepositoryProtocol.swift */; }; + 7B5FAA6F22BBE3EC00621A44 /* AccountSettingsRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA0E22BBE3EB00621A44 /* AccountSettingsRepositoryProtocol.swift */; }; + 7B5FAA7022BBE3EC00621A44 /* CoinomatRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA0F22BBE3EB00621A44 /* CoinomatRepositoryProtocol.swift */; }; + 7B5FAA7122BBE3EC00621A44 /* AddressRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA1022BBE3EB00621A44 /* AddressRepositoryProtocol.swift */; }; + 7B5FAA7222BBE3EC00621A44 /* AssetsBalanceSettingsRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA1122BBE3EB00621A44 /* AssetsBalanceSettingsRepositoryProtocol.swift */; }; + 7B5FAA7322BBE3EC00621A44 /* MatcherRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA1222BBE3EB00621A44 /* MatcherRepositoryProtocol.swift */; }; + 7B5FAA7422BBE3EC00621A44 /* DexRealmRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA1322BBE3EB00621A44 /* DexRealmRepositoryProtocol.swift */; }; + 7B5FAA7522BBE3EC00621A44 /* NotificationNewsRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA1422BBE3EB00621A44 /* NotificationNewsRepositoryProtocol.swift */; }; + 7B5FAA7622BBE3EC00621A44 /* ApplicationVersionRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA1522BBE3EB00621A44 /* ApplicationVersionRepositoryProtocol.swift */; }; + 7B5FAA7722BBE3EC00621A44 /* DexPairsPriceRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA1622BBE3EB00621A44 /* DexPairsPriceRepositoryProtocol.swift */; }; + 7B5FAA7822BBE3EC00621A44 /* AddressBookRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA1722BBE3EB00621A44 /* AddressBookRepositoryProtocol.swift */; }; + 7B5FAA7922BBE3EC00621A44 /* WalletSeedRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA1822BBE3EB00621A44 /* WalletSeedRepositoryProtocol.swift */; }; + 7B5FAA7A22BBE3EC00621A44 /* CandlesRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA1922BBE3EB00621A44 /* CandlesRepositoryProtocol.swift */; }; + 7B5FAA7B22BBE3EC00621A44 /* TransactionsRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA1A22BBE3EB00621A44 /* TransactionsRepositoryProtocol.swift */; }; + 7B5FAA7C22BBE3EC00621A44 /* LastTradesRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA1B22BBE3EB00621A44 /* LastTradesRepositoryProtocol.swift */; }; + 7B5FAA7D22BBE3EC00621A44 /* AssetsRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA1C22BBE3EB00621A44 /* AssetsRepositoryProtocol.swift */; }; + 7B5FAA7E22BBE3EC00621A44 /* BlockRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA1D22BBE3EB00621A44 /* BlockRepositoryProtocol.swift */; }; + 7B5FAA7F22BBE3EC00621A44 /* AliasesRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA1E22BBE3EB00621A44 /* AliasesRepositoryProtocol.swift */; }; + 7B5FAA8022BBE3EC00621A44 /* AccountBalanceRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA1F22BBE3EB00621A44 /* AccountBalanceRepositoryProtocol.swift */; }; + 7B5FAA8122BBE3EC00621A44 /* DexOrderBookRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA2022BBE3EB00621A44 /* DexOrderBookRepositoryProtocol.swift */; }; + 7B5FAA8222BBE3EC00621A44 /* AuthenticationRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA2122BBE3EB00621A44 /* AuthenticationRepositoryProtocol.swift */; }; + 7B5FAA8322BBE3EC00621A44 /* EnvironmentRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA2222BBE3EB00621A44 /* EnvironmentRepositoryProtocol.swift */; }; + 7B5FAA8422BBE3EC00621A44 /* UtilsRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA2322BBE3EB00621A44 /* UtilsRepositoryProtocol.swift */; }; + 7B5FAA8522BBE3EC00621A44 /* DomainLayerTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA2422BBE3EB00621A44 /* DomainLayerTypes.swift */; }; + 7B5FAA8622BBE3EC00621A44 /* AccountEnvironmentDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA2722BBE3EC00621A44 /* AccountEnvironmentDomainDTO.swift */; }; + 7B5FAA8722BBE3EC00621A44 /* CandleDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA2822BBE3EC00621A44 /* CandleDomainDTO.swift */; }; + 7B5FAA8822BBE3EC00621A44 /* AssetBalanceDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA2922BBE3EC00621A44 /* AssetBalanceDomainDTO.swift */; }; + 7B5FAA8922BBE3EC00621A44 /* DexDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA2A22BBE3EC00621A44 /* DexDomainDTO.swift */; }; + 7B5FAA8A22BBE3EC00621A44 /* WalletDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA2B22BBE3EC00621A44 /* WalletDomainDTO.swift */; }; + 7B5FAA8B22BBE3EC00621A44 /* AliasDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA2C22BBE3EC00621A44 /* AliasDomainDTO.swift */; }; + 7B5FAA8C22BBE3EC00621A44 /* SponsorshipTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA2E22BBE3EC00621A44 /* SponsorshipTransactionDomainDTO.swift */; }; + 7B5FAA8D22BBE3EC00621A44 /* AddressDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA2F22BBE3EC00621A44 /* AddressDomainDTO.swift */; }; + 7B5FAA8E22BBE3EC00621A44 /* InvokeScriptTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA3022BBE3EC00621A44 /* InvokeScriptTransactionDomainDTO.swift */; }; + 7B5FAA8F22BBE3EC00621A44 /* DataTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA3122BBE3EC00621A44 /* DataTransactionDomainDTO.swift */; }; + 7B5FAA9022BBE3EC00621A44 /* AssetScriptTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA3222BBE3EC00621A44 /* AssetScriptTransactionDomainDTO.swift */; }; + 7B5FAA9122BBE3EC00621A44 /* SmartTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA3322BBE3EC00621A44 /* SmartTransactionDomainDTO.swift */; }; + 7B5FAA9222BBE3EC00621A44 /* LeaseCancelTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA3422BBE3EC00621A44 /* LeaseCancelTransactionDomainDTO.swift */; }; + 7B5FAA9322BBE3EC00621A44 /* MassTransferTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA3522BBE3EC00621A44 /* MassTransferTransactionDomainDTO.swift */; }; + 7B5FAA9422BBE3EC00621A44 /* ScriptTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA3622BBE3EC00621A44 /* ScriptTransactionDomainDTO.swift */; }; + 7B5FAA9522BBE3EC00621A44 /* AnyTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA3722BBE3EC00621A44 /* AnyTransactionDomainDTO.swift */; }; + 7B5FAA9622BBE3EC00621A44 /* UnrecognisedTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA3822BBE3EC00621A44 /* UnrecognisedTransactionDomainDTO.swift */; }; + 7B5FAA9722BBE3EC00621A44 /* IssueTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA3922BBE3EC00621A44 /* IssueTransactionDomainDTO.swift */; }; + 7B5FAA9822BBE3EC00621A44 /* TransferTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA3A22BBE3EC00621A44 /* TransferTransactionDomainDTO.swift */; }; + 7B5FAA9922BBE3EC00621A44 /* ExchangeTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA3B22BBE3EC00621A44 /* ExchangeTransactionDomainDTO.swift */; }; + 7B5FAA9A22BBE3EC00621A44 /* ReissueTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA3C22BBE3EC00621A44 /* ReissueTransactionDomainDTO.swift */; }; + 7B5FAA9B22BBE3EC00621A44 /* BurnTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA3D22BBE3EC00621A44 /* BurnTransactionDomainDTO.swift */; }; + 7B5FAA9C22BBE3EC00621A44 /* LeaseTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA3E22BBE3EC00621A44 /* LeaseTransactionDomainDTO.swift */; }; + 7B5FAA9D22BBE3EC00621A44 /* AliasTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA3F22BBE3EC00621A44 /* AliasTransactionDomainDTO.swift */; }; + 7B5FAA9E22BBE3EC00621A44 /* NotificationNewsDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA4022BBE3EC00621A44 /* NotificationNewsDomainDTO.swift */; }; + 7B5FAA9F22BBE3EC00621A44 /* AssetDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA4122BBE3EC00621A44 /* AssetDomainDTO.swift */; }; + 7B5FAAA022BBE3EC00621A44 /* CoinomatDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA4222BBE3EC00621A44 /* CoinomatDomainDTO.swift */; }; + 7B5FAAA122BBE3EC00621A44 /* ContactDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA4322BBE3EC00621A44 /* ContactDomainDTO.swift */; }; + 7B5FAAA222BBE3EC00621A44 /* AccountSettingsDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA4422BBE3EC00621A44 /* AccountSettingsDomainDTO.swift */; }; + 7B5FAAA322BBE3EC00621A44 /* ResponseType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA4522BBE3EC00621A44 /* ResponseType.swift */; }; + 7B5FAAA422BBE3EC00621A44 /* WalletEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA4622BBE3EC00621A44 /* WalletEnvironment.swift */; }; + 7B5FAAA522BBE3EC00621A44 /* UseCasesFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA4722BBE3EC00621A44 /* UseCasesFactory.swift */; }; + 7B5FAAA722BBE3EC00621A44 /* AnalyticManagerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA4A22BBE3EC00621A44 /* AnalyticManagerProtocol.swift */; }; + 7B5FAAA822BBE3EC00621A44 /* AnalyticAssetManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA4B22BBE3EC00621A44 /* AnalyticAssetManager.swift */; }; + 7B5FAAAB22BBE3EC00621A44 /* AnalyticManager+Dex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA4E22BBE3EC00621A44 /* AnalyticManager+Dex.swift */; }; + 7B5FAAAC22BBE3EC00621A44 /* AccountBalanceUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA5022BBE3EC00621A44 /* AccountBalanceUseCase.swift */; }; + 7B5FAAAD22BBE3EC00621A44 /* AuthorizationUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA5122BBE3EC00621A44 /* AuthorizationUseCase.swift */; }; + 7B5FAAAE22BBE3EC00621A44 /* AuthorizationUseCaseProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA5222BBE3EC00621A44 /* AuthorizationUseCaseProtocol.swift */; }; + 7B5FAAAF22BBE3EC00621A44 /* AliasesUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA5322BBE3EC00621A44 /* AliasesUseCase.swift */; }; + 7B5FAAB022BBE3EC00621A44 /* MigrationUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA5422BBE3EC00621A44 /* MigrationUseCase.swift */; }; + 7B5FAAB122BBE3EC00621A44 /* AddressUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA5522BBE3EC00621A44 /* AddressUseCase.swift */; }; + 7B5FAAB222BBE3EC00621A44 /* AssetsUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA5622BBE3EC00621A44 /* AssetsUseCase.swift */; }; + 7B5FAAB322BBE3EC00621A44 /* ApplicationVersionUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA5722BBE3EC00621A44 /* ApplicationVersionUseCase.swift */; }; + 7B5FAAB422BBE3EC00621A44 /* TransactionsUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA5822BBE3EC00621A44 /* TransactionsUseCase.swift */; }; + 7B5FAAB522BBE3EC00621A44 /* AssetsBalanceSettingsUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA5922BBE3EC00621A44 /* AssetsBalanceSettingsUseCase.swift */; }; + 7B5FAAB622BBE3EC00621A44 /* ApplicationDebugSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA5B22BBE3EC00621A44 /* ApplicationDebugSettings.swift */; }; + 7B5FAAB722BBE3EC00621A44 /* CleanerWalletManagerBanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA5C22BBE3EC00621A44 /* CleanerWalletManagerBanner.swift */; }; + 7B5FAAB822BBE3EC00621A44 /* SmartTransactionDomain+Assistants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA5D22BBE3EC00621A44 /* SmartTransactionDomain+Assistants.swift */; }; + 7B5FAAB922BBE3EC00621A44 /* CleanerWalletManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA5E22BBE3EC00621A44 /* CleanerWalletManager.swift */; }; + 7B5FAABA22BBE3EC00621A44 /* SigningWalletsProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA5F22BBE3EC00621A44 /* SigningWalletsProtocol.swift */; }; + 7B5FAABB22BBE3EC00621A44 /* WordList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA6122BBE3EC00621A44 /* WordList.swift */; }; + 7B5FAABC22BBE3EC00621A44 /* Hash.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA6222BBE3EC00621A44 /* Hash.swift */; }; + 7B5FAABD22BBE3EC00621A44 /* Address.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA6322BBE3EC00621A44 /* Address.swift */; }; + 7B5FAABE22BBE3EC00621A44 /* PublicKeyAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA6422BBE3EC00621A44 /* PublicKeyAccount.swift */; }; + 7B5FAABF22BBE3EC00621A44 /* PrivateKeyAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA6522BBE3EC00621A44 /* PrivateKeyAccount.swift */; }; + 7B5FAAC022BBE3EC00621A44 /* RXCrypto+SHA.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA6622BBE3EC00621A44 /* RXCrypto+SHA.swift */; }; + 7B5FAAC122BBE3EC00621A44 /* Data+AES.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA6722BBE3EC00621A44 /* Data+AES.swift */; }; + 7B5FAAC222BBE3EC00621A44 /* BiometricManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAA6822BBE3EC00621A44 /* BiometricManager.swift */; }; + 7B5FAACF22BCEA3500621A44 /* AliasesUseCaseProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAACB22BCE8D800621A44 /* AliasesUseCaseProtocol.swift */; }; + 7B5FAADB22BCEA4200621A44 /* AccountBalanceUseCaseProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAAC922BCE71400621A44 /* AccountBalanceUseCaseProtocol.swift */; }; + 7B5FAADC22BCEA4200621A44 /* MigrationUseCaseProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FAACD22BCE98F00621A44 /* MigrationUseCaseProtocol.swift */; }; + 7B60E2BC2316CBEA00113C38 /* ConfirmRequestTransactionKindView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B60E2BB2316CBEA00113C38 /* ConfirmRequestTransactionKindView.swift */; }; + 7B60E2BE2316CC0500113C38 /* ConfirmRequestTransactionKindView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7B60E2BD2316CC0400113C38 /* ConfirmRequestTransactionKindView.xib */; }; + 7B65B6F322F9D03E007D5C53 /* WidgetSettingsSkeletonCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B65B6F222F9D03E007D5C53 /* WidgetSettingsSkeletonCell.swift */; }; + 7B65B6F522F9D63D007D5C53 /* KeyboardControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B65B6F422F9D63D007D5C53 /* KeyboardControl.swift */; }; + 7B65B6F722F9D647007D5C53 /* KeyboardControl.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7B65B6F622F9D647007D5C53 /* KeyboardControl.xib */; }; + 7B66860422B3F70E0029E6F1 /* DomainLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B66860222B3F70E0029E6F1 /* DomainLayer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7B6686F222B7C5120029E6F1 /* Extensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B6686F022B7C5120029E6F1 /* Extensions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7B66872722B7E68B0029E6F1 /* DataLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B66872522B7E68B0029E6F1 /* DataLayer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 7B6922C6223BA1730056DA67 /* TransactionCardSystemTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B6922C5223BA1730056DA67 /* TransactionCardSystemTransaction+Mapper.swift */; }; - 7B951116225CD55F0030390C /* Mutating.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B951115225CD55F0030390C /* Mutating.swift */; }; - 7B951118225CD5850030390C /* DatabaseReference+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B951117225CD5850030390C /* DatabaseReference+Rx.swift */; }; - 7B95111A225CD5B70030390C /* BiometricType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B951119225CD5B70030390C /* BiometricType.swift */; }; - 7B95111C225CD5EE0030390C /* Results+Limit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B95111B225CD5EE0030390C /* Results+Limit.swift */; }; - 7B95111E225CD6140030390C /* RunLoopThreadScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B95111D225CD6140030390C /* RunLoopThreadScheduler.swift */; }; - 7B951121225CD6790030390C /* Language.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B951120225CD6790030390C /* Language.swift */; }; - 7B951123225CD6AD0030390C /* SentryNetworkLoggerPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B951122225CD6AD0030390C /* SentryNetworkLoggerPlugin.swift */; }; - 7B951127225CD7160030390C /* QRCodeParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B951126225CD7160030390C /* QRCodeParser.swift */; }; - 7B951129225CD7350030390C /* AppSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B951128225CD7350030390C /* AppSettings.swift */; }; - 7B95112E225CDA880030390C /* Balance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B95112A225CDA860030390C /* Balance.swift */; }; - 7B95112F225CDA880030390C /* Money.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B95112B225CDA870030390C /* Money.swift */; }; - 7B951130225CDA880030390C /* MoneyUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B95112C225CDA870030390C /* MoneyUtil.swift */; }; - 7B951131225CDA880030390C /* Sync.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B95112D225CDA880030390C /* Sync.swift */; }; - 7B951133225CDAA00030390C /* Decimal+Assisstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B951132225CDA9F0030390C /* Decimal+Assisstants.swift */; }; - 7B951135225CDAA90030390C /* CGSize+Hashable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B951134225CDAA80030390C /* CGSize+Hashable.swift */; }; - 7B951137225CF7A00030390C /* Reachability+Shared.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B951136225CF7A00030390C /* Reachability+Shared.swift */; }; - 7B95115F225F7BA80030390C /* DateFormatter+UI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B95115E225F7BA80030390C /* DateFormatter+UI.swift */; }; - 7BAA9F7B22A032DF003B6D01 /* ApplicationVersionUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BAA9F7A22A032DE003B6D01 /* ApplicationVersionUseCase.swift */; }; - 7BAA9F7D22A03329003B6D01 /* ApplicationVersionRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BAA9F7C22A03329003B6D01 /* ApplicationVersionRepository.swift */; }; - 7BAA9F7F22A03361003B6D01 /* ApplicationVersionRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BAA9F7E22A03361003B6D01 /* ApplicationVersionRepositoryProtocol.swift */; }; - 7BBDA0B62226CA5C00A83411 /* NodePlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BBDA0B52226CA5C00A83411 /* NodePlugin.swift */; }; + 7B7A4B7E22D625B300E0A8CD /* DexCreateOrderInvalidPriceView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7B7A4B7D22D625B300E0A8CD /* DexCreateOrderInvalidPriceView.xib */; }; + 7B83A7D322D8C74F0038180D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B83A7D222D8C74F0038180D /* AppDelegate.swift */; }; + 7B83A7D522D8C74F0038180D /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B83A7D422D8C74F0038180D /* ViewController.swift */; }; + 7B83A7D822D8C74F0038180D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7B83A7D622D8C74F0038180D /* Main.storyboard */; }; + 7B83A7DA22D8C7500038180D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7B83A7D922D8C7500038180D /* Assets.xcassets */; }; + 7B83A7DD22D8C7500038180D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7B83A7DB22D8C7500038180D /* LaunchScreen.storyboard */; }; + 7B83A7E922D8D72F0038180D /* Extensions.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7B83A7E822D8D72F0038180D /* Extensions.framework */; }; + 7B848A5B230075920092AD18 /* Sentry-io-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 7B848A52230075920092AD18 /* Sentry-io-Info.plist */; }; + 7B848A5C230075920092AD18 /* Appsflyer-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 7B848A53230075920092AD18 /* Appsflyer-Info.plist */; }; + 7B848A5D230075920092AD18 /* AppSpector-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 7B848A54230075920092AD18 /* AppSpector-Info.plist */; }; + 7B848A5E230075920092AD18 /* environment_testnet.json in Resources */ = {isa = PBXBuildFile; fileRef = 7B848A55230075920092AD18 /* environment_testnet.json */; }; + 7B848A5F230075920092AD18 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 7B848A56230075920092AD18 /* GoogleService-Info.plist */; }; + 7B848A60230075920092AD18 /* Fabric-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 7B848A57230075920092AD18 /* Fabric-Info.plist */; }; + 7B848A61230075920092AD18 /* Amplitude-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 7B848A58230075920092AD18 /* Amplitude-Info.plist */; }; + 7B848A62230075920092AD18 /* environment_mainnet.json in Resources */ = {isa = PBXBuildFile; fileRef = 7B848A59230075920092AD18 /* environment_mainnet.json */; }; + 7B848A63230075920092AD18 /* spam.csv in Resources */ = {isa = PBXBuildFile; fileRef = 7B848A5A230075920092AD18 /* spam.csv */; }; + 7B848A69230076AE0092AD18 /* Localizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B848A68230076AE0092AD18 /* Localizable.swift */; }; + 7B848A6B230077550092AD18 /* Images.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B848A6A230077540092AD18 /* Images.swift */; }; + 7B848A6D2301784B0092AD18 /* WidgetSettingsUseCaseProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B848A6C2301784B0092AD18 /* WidgetSettingsUseCaseProtocol.swift */; }; + 7B848A6F230178B70092AD18 /* WidgetSettingsUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B848A6E230178B70092AD18 /* WidgetSettingsUseCase.swift */; }; + 7B848A7123018C0E0092AD18 /* WidgetSettingsInizializationUseCaseProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B848A7023018C0E0092AD18 /* WidgetSettingsInizializationUseCaseProtocol.swift */; }; + 7B848A742301AD0D0092AD18 /* WalletsRealmFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B848A732301AD0D0092AD18 /* WalletsRealmFactory.swift */; }; + 7B848A7A2301C0950092AD18 /* WidgetSettingsInizializationUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B848A792301C0950092AD18 /* WidgetSettingsInizializationUseCase.swift */; }; + 7B848A7C2301C95A0092AD18 /* PairsPathUseCaseProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B848A7B2301C95A0092AD18 /* PairsPathUseCaseProtocol.swift */; }; + 7B848A7E2301CB0F0092AD18 /* CorrectionPairsUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B848A7D2301CB0F0092AD18 /* CorrectionPairsUseCase.swift */; }; + 7B848AA12304073B0092AD18 /* WavesMarketPulse.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7B848A912304073B0092AD18 /* WavesMarketPulse.strings */; }; + 7B88185F2304279A00AB0549 /* Language.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFB47FC22FC742F002B19F8 /* Language.swift */; }; + 7B8818602304474E00AB0549 /* AuthorizationInteractorLocalizableImp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFB47F822FC742E002B19F8 /* AuthorizationInteractorLocalizableImp.swift */; }; + 7B88186223044B7F00AB0549 /* Language+List.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B88186123044B7F00AB0549 /* Language+List.swift */; }; + 7B88186423044FCC00AB0549 /* Languages.json in Resources */ = {isa = PBXBuildFile; fileRef = 7B88186323044FCC00AB0549 /* Languages.json */; }; + 7B88186E2305639600AB0549 /* ActionSheetViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B8818662305639600AB0549 /* ActionSheetViewController.swift */; }; + 7B88186F2305639600AB0549 /* ActionSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B8818672305639600AB0549 /* ActionSheet.swift */; }; + 7B8818702305639600AB0549 /* ActionSheetElementCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B8818692305639600AB0549 /* ActionSheetElementCell.swift */; }; + 7B8818712305639600AB0549 /* ActionSheetHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7B88186A2305639600AB0549 /* ActionSheetHeaderView.xib */; }; + 7B8818722305639600AB0549 /* ActionSheetHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B88186B2305639600AB0549 /* ActionSheetHeaderView.swift */; }; + 7B8818732305639700AB0549 /* ActionSheetViewBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B88186C2305639600AB0549 /* ActionSheetViewBuilder.swift */; }; + 7B8818742305639700AB0549 /* ActionSheet.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7B88186D2305639600AB0549 /* ActionSheet.storyboard */; }; + 7B881876230590BB00AB0549 /* DeepLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B881875230590BB00AB0549 /* DeepLink.swift */; }; + 7B8818782305926E00AB0549 /* WidgetSettingsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B8818772305926E00AB0549 /* WidgetSettingsCoordinator.swift */; }; + 7B9393C622DF5827006634A6 /* WavesSDKExtensions.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BDC624F22DCB04F0029DA37 /* WavesSDKExtensions.framework */; }; + 7B9393C722DF5827006634A6 /* WavesSDKExtensions.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 7BDC624F22DCB04F0029DA37 /* WavesSDKExtensions.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 7B9393C822DF5827006634A6 /* WavesSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BDC624722DC973E0029DA37 /* WavesSDK.framework */; }; + 7B9393C922DF5827006634A6 /* WavesSDK.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 7BDC624722DC973E0029DA37 /* WavesSDK.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 7B9393CA22DF5827006634A6 /* WavesSDKCrypto.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BDC624922DC973E0029DA37 /* WavesSDKCrypto.framework */; }; + 7B9393CB22DF5827006634A6 /* WavesSDKCrypto.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 7BDC624922DC973E0029DA37 /* WavesSDKCrypto.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 7B9393CD22DF582D006634A6 /* DomainLayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BF50AD722D8BB0C00582783 /* DomainLayer.framework */; }; + 7B9393CE22DF582D006634A6 /* DomainLayer.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 7BF50AD722D8BB0C00582783 /* DomainLayer.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 7B9393CF22DF5830006634A6 /* DataLayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BF50AD322D8BB0100582783 /* DataLayer.framework */; }; + 7B9393D022DF5830006634A6 /* DataLayer.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 7BF50AD322D8BB0100582783 /* DataLayer.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 7B9393D122DF5835006634A6 /* Extensions.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7B83A7E822D8D72F0038180D /* Extensions.framework */; }; + 7B9393D222DF5835006634A6 /* Extensions.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 7B83A7E822D8D72F0038180D /* Extensions.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 7B9393F722DF8982006634A6 /* DexCreateOrderInvalidPriceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B7A4B7B22D6258C00E0A8CD /* DexCreateOrderInvalidPriceView.swift */; }; + 7B97B07222FC784F008BA3F4 /* CALayer+Shadow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B03822FC784F008BA3F4 /* CALayer+Shadow.swift */; }; + 7B97B07322FC784F008BA3F4 /* ControlEvent+ScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B03922FC784F008BA3F4 /* ControlEvent+ScrollView.swift */; }; + 7B97B07422FC784F008BA3F4 /* CGFloat+Min.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B03A22FC784F008BA3F4 /* CGFloat+Min.swift */; }; + 7B97B07522FC784F008BA3F4 /* UIButton+WithoutAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B03B22FC784F008BA3F4 /* UIButton+WithoutAnimation.swift */; }; + 7B97B07622FC784F008BA3F4 /* UIImageView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B03C22FC784F008BA3F4 /* UIImageView+Rx.swift */; }; + 7B97B07722FC784F008BA3F4 /* UIScrollView+Pagination.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B03D22FC784F008BA3F4 /* UIScrollView+Pagination.swift */; }; + 7B97B07822FC784F008BA3F4 /* UIFeedbackGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B03E22FC784F008BA3F4 /* UIFeedbackGenerator.swift */; }; + 7B97B07922FC784F008BA3F4 /* UIColor+Asset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B03F22FC784F008BA3F4 /* UIColor+Asset.swift */; }; + 7B97B07A22FC784F008BA3F4 /* UIColor+Hex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B04022FC784F008BA3F4 /* UIColor+Hex.swift */; }; + 7B97B07B22FC784F008BA3F4 /* UIView+Additionals.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B04122FC784F008BA3F4 /* UIView+Additionals.swift */; }; + 7B97B07C22FC784F008BA3F4 /* UITableView+HeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B04222FC784F008BA3F4 /* UITableView+HeaderView.swift */; }; + 7B97B07D22FC784F008BA3F4 /* UITableView+Animation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B04322FC784F008BA3F4 /* UITableView+Animation.swift */; }; + 7B97B07E22FC784F008BA3F4 /* UIFont+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B04422FC784F008BA3F4 /* UIFont+Additions.swift */; }; + 7B97B07F22FC784F008BA3F4 /* String+Size.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B04522FC784F008BA3F4 /* String+Size.swift */; }; + 7B97B08022FC784F008BA3F4 /* UIApplication+OpenURL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B04622FC784F008BA3F4 /* UIApplication+OpenURL.swift */; }; + 7B97B08222FC784F008BA3F4 /* UIColor+Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B04822FC784F008BA3F4 /* UIColor+Colors.swift */; }; + 7B97B08422FC784F008BA3F4 /* UIView+SafeArea.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B04A22FC784F008BA3F4 /* UIView+SafeArea.swift */; }; + 7B97B08522FC784F008BA3F4 /* UINavigationController+Additionals.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B04B22FC784F008BA3F4 /* UINavigationController+Additionals.swift */; }; + 7B97B08622FC784F008BA3F4 /* TableViewNoShadow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B04C22FC784F008BA3F4 /* TableViewNoShadow.swift */; }; + 7B97B08722FC784F008BA3F4 /* UIView+TouchInset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B04D22FC784F008BA3F4 /* UIView+TouchInset.swift */; }; + 7B97B08922FC784F008BA3F4 /* UIImage+Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B04F22FC784F008BA3F4 /* UIImage+Color.swift */; }; + 7B97B08A22FC784F008BA3F4 /* UIViewController+SafeArea.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B05022FC784F008BA3F4 /* UIViewController+SafeArea.swift */; }; + 7B97B08B22FC784F008BA3F4 /* CGSize+Hashable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B05122FC784F008BA3F4 /* CGSize+Hashable.swift */; }; + 7B97B08C22FC784F008BA3F4 /* UIViewController+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B05222FC784F008BA3F4 /* UIViewController+Rx.swift */; }; + 7B97B08D22FC784F008BA3F4 /* UIView+Passtrough.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B05322FC784F008BA3F4 /* UIView+Passtrough.swift */; }; + 7B97B08F22FC784F008BA3F4 /* UIView+Shadow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B05522FC784F008BA3F4 /* UIView+Shadow.swift */; }; + 7B97B09022FC784F008BA3F4 /* UIScrollView+ContentInset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B05622FC784F008BA3F4 /* UIScrollView+ContentInset.swift */; }; + 7B97B09122FC784F008BA3F4 /* CALayer+RoundingCorners.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B05722FC784F008BA3F4 /* CALayer+RoundingCorners.swift */; }; + 7B97B09222FC784F008BA3F4 /* TimingFunction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B05822FC784F008BA3F4 /* TimingFunction.swift */; }; + 7B97B09322FC784F008BA3F4 /* ModuleBuilderOutput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B05B22FC784F008BA3F4 /* ModuleBuilderOutput.swift */; }; + 7B97B09422FC784F008BA3F4 /* ModuleBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B05C22FC784F008BA3F4 /* ModuleBuilder.swift */; }; + 7B97B09522FC784F008BA3F4 /* ViewConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B05D22FC784F008BA3F4 /* ViewConfiguration.swift */; }; + 7B97B09622FC784F008BA3F4 /* ViewCalculate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B05E22FC784F008BA3F4 /* ViewCalculate.swift */; }; + 7B97B09722FC784F008BA3F4 /* SectionDisplayCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B05F22FC784F008BA3F4 /* SectionDisplayCollection.swift */; }; + 7B97B09822FC784F008BA3F4 /* UICollectionView+Reusable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B06122FC784F008BA3F4 /* UICollectionView+Reusable.swift */; }; + 7B97B09922FC784F008BA3F4 /* Reusable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B06222FC784F008BA3F4 /* Reusable.swift */; }; + 7B97B09A22FC784F008BA3F4 /* UITableView+Reusable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B06322FC784F008BA3F4 /* UITableView+Reusable.swift */; }; + 7B97B09B22FC784F008BA3F4 /* NibLoadable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B06422FC784F008BA3F4 /* NibLoadable.swift */; }; + 7B97B09C22FC784F008BA3F4 /* NibOwnerLoadable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B06522FC784F008BA3F4 /* NibOwnerLoadable.swift */; }; + 7B97B09D22FC784F008BA3F4 /* UIView+Animation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B06622FC784F008BA3F4 /* UIView+Animation.swift */; }; + 7B97B09E22FC784F008BA3F4 /* MoneyUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B06822FC784F008BA3F4 /* MoneyUtil.swift */; }; + 7B97B09F22FC784F008BA3F4 /* Sync.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B06922FC784F008BA3F4 /* Sync.swift */; }; + 7B97B0A022FC784F008BA3F4 /* Decimal+Assisstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B06A22FC784F008BA3F4 /* Decimal+Assisstants.swift */; }; + 7B97B0A122FC784F008BA3F4 /* Balance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B06B22FC784F008BA3F4 /* Balance.swift */; }; + 7B97B0A222FC784F008BA3F4 /* Money.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B06C22FC784F008BA3F4 /* Money.swift */; }; + 7B97B0A322FC784F008BA3F4 /* TSUD+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B06D22FC784F008BA3F4 /* TSUD+Rx.swift */; }; + 7B97B0A422FC784F008BA3F4 /* RunLoopThreadScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B06E22FC784F008BA3F4 /* RunLoopThreadScheduler.swift */; }; + 7B97B0A522FC784F008BA3F4 /* Mutating.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B06F22FC784F008BA3F4 /* Mutating.swift */; }; + 7B97B0A622FC784F008BA3F4 /* System.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B07022FC784F008BA3F4 /* System.swift */; }; + 7B97B0A722FC784F008BA3F4 /* Platform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B07122FC784F008BA3F4 /* Platform.swift */; }; + 7B97B0A822FC78EA008BA3F4 /* DateFormatter+UI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B05422FC784F008BA3F4 /* DateFormatter+UI.swift */; }; + 7B97B0A922FC78FE008BA3F4 /* UIViewController+Additionals.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B04722FC784F008BA3F4 /* UIViewController+Additionals.swift */; }; + 7B97B0AD22FCB2BD008BA3F4 /* Reachability+Shared.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B0AC22FCB2BD008BA3F4 /* Reachability+Shared.swift */; }; + 7B97B0B222FCB5DA008BA3F4 /* Localizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B0B122FCB5D9008BA3F4 /* Localizable.swift */; }; + 7B97B0B822FCBF56008BA3F4 /* Kingfisher+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFB47DE22FC742D002B19F8 /* Kingfisher+Rx.swift */; }; + 7B97B0BA22FD71A8008BA3F4 /* AssetLogo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B0B522FCBD59008BA3F4 /* AssetLogo.swift */; }; + 7B97B0BC22FD92AC008BA3F4 /* AssetLogo+Styles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B97B0BB22FD92AC008BA3F4 /* AssetLogo+Styles.swift */; }; + 7B9B326122E6004700DB1C59 /* DebugRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B9B326022E6004700DB1C59 /* DebugRootView.swift */; }; + 7BB03E4A22EF2C84008F179D /* WidgetSettingsHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BB03E4922EF2C84008F179D /* WidgetSettingsHeaderView.swift */; }; + 7BB03E4C22EF2DAB008F179D /* WidgetSettingsHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7BB03E4B22EF2DAB008F179D /* WidgetSettingsHeaderView.xib */; }; 7BD2313B224E55090074C3BF /* TransactionCardOrderCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD2313A224E55090074C3BF /* TransactionCardOrderCell.swift */; }; 7BD2FD35223C5E1F0098CFB9 /* TransactionCardCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD2FD34223C5E1F0098CFB9 /* TransactionCardCoordinator.swift */; }; - 7BDA6AD5222D8C82001DE71C /* System.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDA6AD4222D8C81001DE71C /* System.swift */; }; + 7BD6E0FE22E228DC00BAAFC8 /* DebugView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD6E0FD22E228DC00BAAFC8 /* DebugView.swift */; }; + 7BD6E10022E228F000BAAFC8 /* DebugView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7BD6E0FF22E228F000BAAFC8 /* DebugView.xib */; }; + 7BD6E10222E50EB200BAAFC8 /* DebugViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD6E10122E50EB200BAAFC8 /* DebugViewController.swift */; }; + 7BD6E10522E5AE0200BAAFC8 /* DebugHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD6E10422E5AE0200BAAFC8 /* DebugHeaderView.swift */; }; + 7BD6E10822E5AE7000BAAFC8 /* DebugInfoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD6E10722E5AE7000BAAFC8 /* DebugInfoCell.swift */; }; + 7BD6E10A22E5AEEB00BAAFC8 /* DebugHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7BD6E10922E5AEEB00BAAFC8 /* DebugHeaderView.xib */; }; + 7BD6E10C22E5B6D700BAAFC8 /* DebugSwitchCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD6E10B22E5B6D700BAAFC8 /* DebugSwitchCell.swift */; }; + 7BD6E10E22E5CD5E00BAAFC8 /* DebugEnviromentsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD6E10D22E5CD5E00BAAFC8 /* DebugEnviromentsCell.swift */; }; 7BDA6AD7222D8CA1001DE71C /* TransactionCardViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDA6AD6222D8CA1001DE71C /* TransactionCardViewController.swift */; }; 7BDA6AD9222D8D0A001DE71C /* TransactionCardSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDA6AD8222D8D0A001DE71C /* TransactionCardSystem.swift */; }; 7BDA6ADB222D8D16001DE71C /* TransactionCardType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDA6ADA222D8D16001DE71C /* TransactionCardType.swift */; }; @@ -554,19 +573,175 @@ 7BDA6AE6223028DC001DE71C /* BalanceLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDA6AE5223028DC001DE71C /* BalanceLabel.swift */; }; 7BDA6AE822313E59001DE71C /* TransactionImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDA6AE722313E59001DE71C /* TransactionImageView.swift */; }; 7BDA6AEA22313E85001DE71C /* TransactionImageView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7BDA6AE922313E85001DE71C /* TransactionImageView.xib */; }; - 7BDA6AF02231405D001DE71C /* SmartTransactionKind+UIImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDA6AEF2231405D001DE71C /* SmartTransactionKind+UIImage.swift */; }; 7BDA6AF222315024001DE71C /* ContactDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDA6AF122315024001DE71C /* ContactDetailView.swift */; }; 7BDA6AF422315466001DE71C /* ContactDetailView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7BDA6AF322315466001DE71C /* ContactDetailView.xib */; }; 7BDA6AF622316078001DE71C /* TransactionCardMassSentRecipientCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDA6AF522316078001DE71C /* TransactionCardMassSentRecipientCell.swift */; }; - 7BF89E892226E00800853F9D /* SentryManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF89E882226E00800853F9D /* SentryManager.swift */; }; + 7BDC624222DC972E0029DA37 /* WavesSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BDC624122DC972E0029DA37 /* WavesSDK.framework */; }; + 7BDC624422DC972E0029DA37 /* WavesSDKCrypto.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BDC624322DC972E0029DA37 /* WavesSDKCrypto.framework */; }; + 7BDC624622DC972E0029DA37 /* WavesSDKExtensions.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BDC624522DC972E0029DA37 /* WavesSDKExtensions.framework */; }; + 7BDC624822DC973E0029DA37 /* WavesSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BDC624722DC973E0029DA37 /* WavesSDK.framework */; }; + 7BDC624A22DC973E0029DA37 /* WavesSDKCrypto.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BDC624922DC973E0029DA37 /* WavesSDKCrypto.framework */; }; + 7BDC624C22DC973E0029DA37 /* WavesSDKExtensions.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BDC624B22DC973E0029DA37 /* WavesSDKExtensions.framework */; }; + 7BDC625022DCB04F0029DA37 /* WavesSDKExtensions.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BDC624F22DCB04F0029DA37 /* WavesSDKExtensions.framework */; }; + 7BDC6D3E22C2522F00614E6B /* SpamAssetsRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDC6D3D22C2522F00614E6B /* SpamAssetsRepositoryProtocol.swift */; }; + 7BDC6D4122C3961F00614E6B /* AnalyticManagerEvent+CreateANewAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDC6D3F22C395F500614E6B /* AnalyticManagerEvent+CreateANewAccount.swift */; }; + 7BDC6D4422C3965900614E6B /* AnalyticManagerEvent+ImportAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDC6D4222C3964900614E6B /* AnalyticManagerEvent+ImportAccount.swift */; }; + 7BDC6D4922C396BD00614E6B /* AnalyticManagerEvent+Send.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDC6D4722C396A400614E6B /* AnalyticManagerEvent+Send.swift */; }; + 7BDC6D4A22C396C000614E6B /* AnalyticManagerEvent+SingIn.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDC6D4522C3967600614E6B /* AnalyticManagerEvent+SingIn.swift */; }; + 7BDC6D4D22C396D500614E6B /* AnalyticManagerEvent+Receive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDC6D4B22C396D200614E6B /* AnalyticManagerEvent+Receive.swift */; }; + 7BDC6D5022C396FD00614E6B /* AnalyticManagerEvent+WavesQuickAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDC6D4E22C396F200614E6B /* AnalyticManagerEvent+WavesQuickAction.swift */; }; + 7BDC6D5322C3971900614E6B /* AnalyticManagerEvent+Profile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDC6D5122C3970B00614E6B /* AnalyticManagerEvent+Profile.swift */; }; + 7BDC6D5622C3975D00614E6B /* AnalyticManagerEvent+WalletHome.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDC6D5422C3973C00614E6B /* AnalyticManagerEvent+WalletHome.swift */; }; + 7BDC6D5C22C3978400614E6B /* AnalyticManagerEvent+Alias.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDC6D5922C3978100614E6B /* AnalyticManagerEvent+Alias.swift */; }; + 7BDC6D6022C397A600614E6B /* AnalyticManagerEvent+TokenBurn.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDC6D5D22C397A300614E6B /* AnalyticManagerEvent+TokenBurn.swift */; }; + 7BDC6D6B22C397CE00614E6B /* AnalyticManagerEvent+WalletLeasing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDC6D5722C3976D00614E6B /* AnalyticManagerEvent+WalletLeasing.swift */; }; + 7BDC6D6E22C398F600614E6B /* AnalyticManagerEvent+AddressBook.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDC6D6C22C398E100614E6B /* AnalyticManagerEvent+AddressBook.swift */; }; + 7BDC6D7322C3A05B00614E6B /* AnalyticManagerEvent+Menu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDC6D6F22C3A03400614E6B /* AnalyticManagerEvent+Menu.swift */; }; + 7BDC6D7422C3A1E000614E6B /* AnalyticManagerEvent+Widgets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDC6D7122C3A03E00614E6B /* AnalyticManagerEvent+Widgets.swift */; }; + 7BDC6D7922C3CD8400614E6B /* InputScrollButtonsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDC6D7822C3CD8400614E6B /* InputScrollButtonsView.swift */; }; + 7BE09AB22313E31300A038AD /* MobileKeeperCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BE09AB12313E31300A038AD /* MobileKeeperCoordinator.swift */; }; + 7BE09AD323140F0900A038AD /* MobileKeeper.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7BE09AD223140F0900A038AD /* MobileKeeper.storyboard */; }; + 7BF50A6B22D8B95400582783 /* SeedItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF509F322D8B95300582783 /* SeedItem.swift */; }; + 7BF50A6C22D8B95400582783 /* WalletRealmFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF509F522D8B95300582783 /* WalletRealmFactory.swift */; }; + 7BF50A6D22D8B95400582783 /* LeaseTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF509F822D8B95300582783 /* LeaseTransaction.swift */; }; + 7BF50A6E22D8B95400582783 /* ScriptTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF509F922D8B95300582783 /* ScriptTransaction.swift */; }; + 7BF50A6F22D8B95400582783 /* IssueTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF509FA22D8B95300582783 /* IssueTransaction.swift */; }; + 7BF50A7022D8B95400582783 /* AssetScriptTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF509FB22D8B95300582783 /* AssetScriptTransaction.swift */; }; + 7BF50A7122D8B95400582783 /* UnrecognisedTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF509FC22D8B95300582783 /* UnrecognisedTransaction.swift */; }; + 7BF50A7222D8B95400582783 /* SponsorshipTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF509FD22D8B95300582783 /* SponsorshipTransaction.swift */; }; + 7BF50A7322D8B95400582783 /* LeaseCancelTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF509FE22D8B95300582783 /* LeaseCancelTransaction.swift */; }; + 7BF50A7422D8B95400582783 /* InvokeScriptTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF509FF22D8B95300582783 /* InvokeScriptTransaction.swift */; }; + 7BF50A7522D8B95400582783 /* BurnTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A0022D8B95300582783 /* BurnTransaction.swift */; }; + 7BF50A7622D8B95400582783 /* Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A0122D8B95300582783 /* Transaction.swift */; }; + 7BF50A7722D8B95400582783 /* TransferTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A0222D8B95300582783 /* TransferTransaction.swift */; }; + 7BF50A7822D8B95400582783 /* ExchangeTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A0322D8B95300582783 /* ExchangeTransaction.swift */; }; + 7BF50A7922D8B95400582783 /* AliasTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A0422D8B95300582783 /* AliasTransaction.swift */; }; + 7BF50A7A22D8B95400582783 /* ReissueTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A0522D8B95300582783 /* ReissueTransaction.swift */; }; + 7BF50A7B22D8B95400582783 /* MassTransferTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A0622D8B95300582783 /* MassTransferTransaction.swift */; }; + 7BF50A7C22D8B95400582783 /* AnyTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A0722D8B95300582783 /* AnyTransaction.swift */; }; + 7BF50A7D22D8B95400582783 /* DataTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A0822D8B95300582783 /* DataTransaction.swift */; }; + 7BF50A7E22D8B95400582783 /* AddressBook.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A0922D8B95300582783 /* AddressBook.swift */; }; + 7BF50A7F22D8B95400582783 /* Alias.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A0A22D8B95300582783 /* Alias.swift */; }; + 7BF50A8022D8B95400582783 /* AssetBalance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A0B22D8B95300582783 /* AssetBalance.swift */; }; + 7BF50A8122D8B95400582783 /* AssetBalanceSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A0C22D8B95300582783 /* AssetBalanceSettings.swift */; }; + 7BF50A8222D8B95400582783 /* DexAssetPair.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A0D22D8B95300582783 /* DexAssetPair.swift */; }; + 7BF50A8322D8B95400582783 /* Asset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A0E22D8B95300582783 /* Asset.swift */; }; + 7BF50A8422D8B95400582783 /* AccountEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A0F22D8B95300582783 /* AccountEnvironment.swift */; }; + 7BF50A8522D8B95400582783 /* AccountSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A1022D8B95300582783 /* AccountSettings.swift */; }; + 7BF50A8622D8B95400582783 /* WalletItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A1222D8B95300582783 /* WalletItem.swift */; }; + 7BF50A8722D8B95400582783 /* WalletEncryption.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A1422D8B95300582783 /* WalletEncryption.swift */; }; + 7BF50A8822D8B95400582783 /* DexAssetPairDomainDTO+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A1622D8B95300582783 /* DexAssetPairDomainDTO+Mapper.swift */; }; + 7BF50A8922D8B95400582783 /* DexMyOrders+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A1722D8B95300582783 /* DexMyOrders+Mapper.swift */; }; + 7BF50A8A22D8B95400582783 /* AnyTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A1922D8B95300582783 /* AnyTransaction+Mapper.swift */; }; + 7BF50A8B22D8B95400582783 /* ReissueTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A1A22D8B95300582783 /* ReissueTransaction+Mapper.swift */; }; + 7BF50A8C22D8B95400582783 /* InvokeScriptTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A1B22D8B95300582783 /* InvokeScriptTransaction+Mapper.swift */; }; + 7BF50A8D22D8B95400582783 /* AssetScriptTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A1C22D8B95300582783 /* AssetScriptTransaction+Mapper.swift */; }; + 7BF50A8E22D8B95400582783 /* AliasTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A1D22D8B95300582783 /* AliasTransaction+Mapper.swift */; }; + 7BF50A8F22D8B95400582783 /* UnrecognisedTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A1E22D8B95300582783 /* UnrecognisedTransaction+Mapper.swift */; }; + 7BF50A9022D8B95400582783 /* ScriptTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A1F22D8B95300582783 /* ScriptTransaction+Mapper.swift */; }; + 7BF50A9122D8B95400582783 /* LeaseCancelTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A2022D8B95300582783 /* LeaseCancelTransaction+Mapper.swift */; }; + 7BF50A9222D8B95400582783 /* DataTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A2122D8B95300582783 /* DataTransaction+Mapper.swift */; }; + 7BF50A9322D8B95400582783 /* SponsorshipTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A2222D8B95300582783 /* SponsorshipTransaction+Mapper.swift */; }; + 7BF50A9422D8B95400582783 /* IssueTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A2322D8B95300582783 /* IssueTransaction+Mapper.swift */; }; + 7BF50A9522D8B95400582783 /* TransferTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A2422D8B95300582783 /* TransferTransaction+Mapper.swift */; }; + 7BF50A9622D8B95400582783 /* MassTransferTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A2522D8B95300582783 /* MassTransferTransaction+Mapper.swift */; }; + 7BF50A9722D8B95400582783 /* BurnTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A2622D8B95300582783 /* BurnTransaction+Mapper.swift */; }; + 7BF50A9822D8B95400582783 /* ExchangeTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A2722D8B95300582783 /* ExchangeTransaction+Mapper.swift */; }; + 7BF50A9922D8B95400582783 /* LeaseTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A2822D8B95300582783 /* LeaseTransaction+Mapper.swift */; }; + 7BF50A9A22D8B95400582783 /* Wallet+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A2922D8B95300582783 /* Wallet+Mapper.swift */; }; + 7BF50A9B22D8B95400582783 /* AccountSettings+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A2A22D8B95400582783 /* AccountSettings+Mapper.swift */; }; + 7BF50A9C22D8B95400582783 /* Asset+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A2B22D8B95400582783 /* Asset+Mapper.swift */; }; + 7BF50A9D22D8B95400582783 /* SpamAssetsRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A2D22D8B95400582783 /* SpamAssetsRepository.swift */; }; + 7BF50A9E22D8B95400582783 /* NotificationNewsRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A2E22D8B95400582783 /* NotificationNewsRepository.swift */; }; + 7BF50A9F22D8B95400582783 /* BlockRepositoryRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A2F22D8B95400582783 /* BlockRepositoryRemote.swift */; }; + 7BF50AA022D8B95400582783 /* GatewayRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A3022D8B95400582783 /* GatewayRepository.swift */; }; + 7BF50AA122D8B95400582783 /* ApplicationVersionRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A3122D8B95400582783 /* ApplicationVersionRepository.swift */; }; + 7BF50AA222D8B95400582783 /* AccountSettingsRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A3222D8B95400582783 /* AccountSettingsRepository.swift */; }; + 7BF50AA322D8B95400582783 /* CoinomatRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A3322D8B95400582783 /* CoinomatRepository.swift */; }; + 7BF50AA422D8B95400582783 /* AuthenticationRepositoryRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A3422D8B95400582783 /* AuthenticationRepositoryRemote.swift */; }; + 7BF50AA522D8B95400582783 /* AddressRepositoryRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A3522D8B95400582783 /* AddressRepositoryRemote.swift */; }; + 7BF50AA622D8B95400582783 /* TransactionsRepositoryRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A3722D8B95400582783 /* TransactionsRepositoryRemote.swift */; }; + 7BF50AA722D8B95400582783 /* TransactionsRepositoryLocal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A3822D8B95400582783 /* TransactionsRepositoryLocal.swift */; }; + 7BF50AA822D8B95400582783 /* RepositoriesFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A3922D8B95400582783 /* RepositoriesFactory.swift */; }; + 7BF50AA922D8B95400582783 /* AddressBookRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A3B22D8B95400582783 /* AddressBookRepository.swift */; }; + 7BF50AAA22D8B95400582783 /* AccountBalanceRepositoryRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A3D22D8B95400582783 /* AccountBalanceRepositoryRemote.swift */; }; + 7BF50AAB22D8B95400582783 /* AccountBalanceRepositoryLocal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A3E22D8B95400582783 /* AccountBalanceRepositoryLocal.swift */; }; + 7BF50AAC22D8B95400582783 /* MatcherRepositoryRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A4022D8B95400582783 /* MatcherRepositoryRemote.swift */; }; + 7BF50AAD22D8B95400582783 /* LastTradesRepositoryRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A4122D8B95400582783 /* LastTradesRepositoryRemote.swift */; }; + 7BF50AAE22D8B95400582783 /* DexOrderBookRepositoryRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A4222D8B95400582783 /* DexOrderBookRepositoryRemote.swift */; }; + 7BF50AAF22D8B95400582783 /* DexRealmRepositoryLocal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A4322D8B95400582783 /* DexRealmRepositoryLocal.swift */; }; + 7BF50AB022D8B95400582783 /* CandlesRepositoryRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A4422D8B95400582783 /* CandlesRepositoryRemote.swift */; }; + 7BF50AB122D8B95400582783 /* DexPairsPriceRepositoryRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A4522D8B95400582783 /* DexPairsPriceRepositoryRemote.swift */; }; + 7BF50AB222D8B95400582783 /* WalletsRepositoryLocal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A4722D8B95400582783 /* WalletsRepositoryLocal.swift */; }; + 7BF50AB322D8B95400582783 /* WalletSeedRepositoryLocal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A4822D8B95400582783 /* WalletSeedRepositoryLocal.swift */; }; + 7BF50AB422D8B95400582783 /* AliasesRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A4A22D8B95400582783 /* AliasesRepository.swift */; }; + 7BF50AB522D8B95400582783 /* AliasesRepositoryLocal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A4B22D8B95400582783 /* AliasesRepositoryLocal.swift */; }; + 7BF50AB622D8B95400582783 /* AssetsBalanceSettingsRepositoryLocal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A4D22D8B95400582783 /* AssetsBalanceSettingsRepositoryLocal.swift */; }; + 7BF50AB722D8B95400582783 /* AssetsRepositoryLocal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A4E22D8B95400582783 /* AssetsRepositoryLocal.swift */; }; + 7BF50AB822D8B95400582783 /* AssetsRepositoryRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A4F22D8B95400582783 /* AssetsRepositoryRemote.swift */; }; + 7BF50AB922D8B95400582783 /* EnvironmentRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A5022D8B95400582783 /* EnvironmentRepository.swift */; }; + 7BF50ABA22D8B95400582783 /* SpamService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A5322D8B95400582783 /* SpamService.swift */; }; + 7BF50ABB22D8B95400582783 /* AssetsSpamService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A5422D8B95400582783 /* AssetsSpamService.swift */; }; + 7BF50ABC22D8B95400582783 /* GitHubService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A5622D8B95400582783 /* GitHubService.swift */; }; + 7BF50ABD22D8B95400582783 /* TransactionFeeRulesGitHub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A5722D8B95400582783 /* TransactionFeeRulesGitHub.swift */; }; + 7BF50ABE22D8B95400582783 /* CoinomatService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A5922D8B95400582783 /* CoinomatService.swift */; }; + 7BF50ABF22D8B95400582783 /* GatewayService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A5B22D8B95400582783 /* GatewayService.swift */; }; + 7BF50AC022D8B95400582783 /* SpamCSV+Assisstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A5D22D8B95400582783 /* SpamCSV+Assisstants.swift */; }; + 7BF50AC122D8B95400582783 /* AnalyticManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A5E22D8B95400582783 /* AnalyticManager.swift */; }; + 7BF50AC222D8B95400582783 /* TransactionSenderAssistant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A5F22D8B95400582783 /* TransactionSenderAssistant.swift */; }; + 7BF50AC322D8B95400582783 /* TimestampSignature.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A6122D8B95400582783 /* TimestampSignature.swift */; }; + 7BF50AC422D8B95400582783 /* Signature.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A6222D8B95400582783 /* Signature.swift */; }; + 7BF50AC522D8B95400582783 /* Results+Limit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A6322D8B95400582783 /* Results+Limit.swift */; }; + 7BF50AC622D8B95400582783 /* NodePlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A6422D8B95400582783 /* NodePlugin.swift */; }; + 7BF50AC722D8B95400582783 /* MoyaProvider+Helper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A6522D8B95400582783 /* MoyaProvider+Helper.swift */; }; + 7BF50AC822D8B95400582783 /* SentryNetworkLoggerPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A6622D8B95400582783 /* SentryNetworkLoggerPlugin.swift */; }; + 7BF50AC922D8B95400582783 /* SentryManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A6722D8B95400582783 /* SentryManager.swift */; }; + 7BF50ACA22D8B95400582783 /* DatabaseReference+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A6822D8B95400582783 /* DatabaseReference+Rx.swift */; }; + 7BF50ACB22D8B95400582783 /* String+NormalizeAssetId.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A6922D8B95400582783 /* String+NormalizeAssetId.swift */; }; + 7BF50ACC22D8B95400582783 /* SweetLoggerSentry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF50A6A22D8B95400582783 /* SweetLoggerSentry.swift */; }; 7BF89E9922272A5E00853F9D /* MonkeyTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF89E9822272A5E00853F9D /* MonkeyTest.swift */; }; - E1A8D6947059C03B81BC5C0B /* Pods_MonkeyTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2F182E1185D069FB9F0228C7 /* Pods_MonkeyTest.framework */; }; - E901CE592149D27000942783 /* ExchangeTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A485E9B2100A91500079B49 /* ExchangeTransaction.swift */; }; - E90223C421D53A8F0057AA45 /* DexAssetPairDomainDTO+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = E90223C321D53A8F0057AA45 /* DexAssetPairDomainDTO+Mapper.swift */; }; + 7BFB474C22FC5A41002B19F8 /* WidgetSettingsRepositoryStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFB474B22FC5A40002B19F8 /* WidgetSettingsRepositoryStorage.swift */; }; + 7BFB475722FC5AD0002B19F8 /* Sentry-io-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 7BFB474E22FC5AD0002B19F8 /* Sentry-io-Info.plist */; }; + 7BFB475822FC5AD0002B19F8 /* Appsflyer-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 7BFB474F22FC5AD0002B19F8 /* Appsflyer-Info.plist */; }; + 7BFB475922FC5AD0002B19F8 /* AppSpector-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 7BFB475022FC5AD0002B19F8 /* AppSpector-Info.plist */; }; + 7BFB475A22FC5AD0002B19F8 /* environment_testnet.json in Resources */ = {isa = PBXBuildFile; fileRef = 7BFB475122FC5AD0002B19F8 /* environment_testnet.json */; }; + 7BFB475B22FC5AD0002B19F8 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 7BFB475222FC5AD0002B19F8 /* GoogleService-Info.plist */; }; + 7BFB475C22FC5AD0002B19F8 /* Fabric-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 7BFB475322FC5AD0002B19F8 /* Fabric-Info.plist */; }; + 7BFB475D22FC5AD0002B19F8 /* Amplitude-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 7BFB475422FC5AD0002B19F8 /* Amplitude-Info.plist */; }; + 7BFB475E22FC5AD0002B19F8 /* environment_mainnet.json in Resources */ = {isa = PBXBuildFile; fileRef = 7BFB475522FC5AD0002B19F8 /* environment_mainnet.json */; }; + 7BFB475F22FC5AD0002B19F8 /* spam.csv in Resources */ = {isa = PBXBuildFile; fileRef = 7BFB475622FC5AD0002B19F8 /* spam.csv */; }; + 7BFB480022FC742F002B19F8 /* SmartTransactionDTO+EncodingToString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFB47DD22FC742C002B19F8 /* SmartTransactionDTO+EncodingToString.swift */; }; + 7BFB480222FC742F002B19F8 /* AssetsRepositoryMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFB47E022FC742D002B19F8 /* AssetsRepositoryMock.swift */; }; + 7BFB480322FC742F002B19F8 /* SmartTransactionKind+UIImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFB47E122FC742E002B19F8 /* SmartTransactionKind+UIImage.swift */; }; + 7BFB480422FC742F002B19F8 /* UIAlertController+Factory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFB47E422FC742E002B19F8 /* UIAlertController+Factory.swift */; }; + 7BFB480622FC742F002B19F8 /* BiometricType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFB47E622FC742E002B19F8 /* BiometricType.swift */; }; + 7BFB480722FC742F002B19F8 /* UITableView+Skeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFB47E822FC742E002B19F8 /* UITableView+Skeleton.swift */; }; + 7BFB480822FC742F002B19F8 /* SkeletonAnimatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFB47E922FC742E002B19F8 /* SkeletonAnimatable.swift */; }; + 7BFB480922FC742F002B19F8 /* RateApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFB47EA22FC742E002B19F8 /* RateApp.swift */; }; + 7BFB480A22FC742F002B19F8 /* DisplayError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFB47EB22FC742E002B19F8 /* DisplayError.swift */; }; + 7BFB480B22FC742F002B19F8 /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFB47EC22FC742E002B19F8 /* Notifications.swift */; }; + 7BFB480C22FC742F002B19F8 /* GlobalConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFB47ED22FC742E002B19F8 /* GlobalConstants.swift */; }; + 7BFB480D22FC742F002B19F8 /* QRCodeReader+Factory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFB47EE22FC742E002B19F8 /* QRCodeReader+Factory.swift */; }; + 7BFB480E22FC742F002B19F8 /* MailCompose+Support.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFB47EF22FC742E002B19F8 /* MailCompose+Support.swift */; }; + 7BFB480F22FC742F002B19F8 /* ModalRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFB47F122FC742E002B19F8 /* ModalRootView.swift */; }; + 7BFB481022FC742F002B19F8 /* ModalViewControllerTransitioning.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFB47F222FC742E002B19F8 /* ModalViewControllerTransitioning.swift */; }; + 7BFB481122FC742F002B19F8 /* ModalPresentationAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFB47F322FC742E002B19F8 /* ModalPresentationAnimator.swift */; }; + 7BFB481222FC742F002B19F8 /* ModalPresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFB47F422FC742E002B19F8 /* ModalPresentationController.swift */; }; + 7BFB481322FC742F002B19F8 /* ModalTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFB47F522FC742E002B19F8 /* ModalTableView.swift */; }; + 7BFB481422FC742F002B19F8 /* ModalScrollViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFB47F622FC742E002B19F8 /* ModalScrollViewController.swift */; }; + 7BFB481522FC742F002B19F8 /* ModalPresentationAnimatorContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFB47F722FC742E002B19F8 /* ModalPresentationAnimatorContext.swift */; }; + 7BFB481722FC742F002B19F8 /* NSAttributedString+Styles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFB47F922FC742E002B19F8 /* NSAttributedString+Styles.swift */; }; + 7BFB481822FC742F002B19F8 /* BiometricManager+String.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFB47FA22FC742F002B19F8 /* BiometricManager+String.swift */; }; + 7BFB481A22FC742F002B19F8 /* QRCodeParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFB47FD22FC742F002B19F8 /* QRCodeParser.swift */; }; + 7BFB481B22FC742F002B19F8 /* NewUserWithoutBackupStorageTrack.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFB47FF22FC742F002B19F8 /* NewUserWithoutBackupStorageTrack.swift */; }; + A3521B8E7F8D5AFE73837B59 /* Pods_Extensions.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F48C7630D481FB8B18C7CDD /* Pods_Extensions.framework */; }; + B5B2F5FE86DB13C5F1ABC764 /* Pods_DomainLayerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1CCD1A311B65E78F9D8E3AFB /* Pods_DomainLayerTests.framework */; }; + CE9236ADA9B30C0AE5EAC713 /* Pods_DomainLayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 41C4770FECD0D0B762C47A43 /* Pods_DomainLayer.framework */; }; + DCE90C1BC9209D8B69BA1D86 /* Pods_WavesWallet_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BC49EA63C68974786E6084B7 /* Pods_WavesWallet_iOS.framework */; }; + DEF8AC61C03932433B247FBD /* Pods_MonkeyTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 660956FE76B04B363AEC458B /* Pods_MonkeyTest.framework */; }; + E902BBD0236A664300141CF4 /* DexDeepLinkCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E902BBCF236A664300141CF4 /* DexDeepLinkCoordinator.swift */; }; E902F61520E5829B00A46335 /* ChooseAccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E902F61420E5829B00A46335 /* ChooseAccountViewController.swift */; }; E904525A20B4EF4200A490E5 /* PopupViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E904525920B4EF4200A490E5 /* PopupViewController.swift */; }; - E910B7E921C3261B00E402AB /* CoinomatRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = E910B7E821C3261B00E402AB /* CoinomatRepository.swift */; }; - E910B7EC21C3266F00E402AB /* CoinomatDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = E910B7EB21C3266F00E402AB /* CoinomatDomainDTO.swift */; }; E911300C21BC028400588430 /* AssetSelectSkeletonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E911300B21BC028400588430 /* AssetSelectSkeletonView.swift */; }; E911300E21BC029300588430 /* AssetSelectSkeletonView.xib in Resources */ = {isa = PBXBuildFile; fileRef = E911300D21BC029300588430 /* AssetSelectSkeletonView.xib */; }; E9157BEE21A4C081009F99B6 /* StartLeasingCompleteViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9157BED21A4C081009F99B6 /* StartLeasingCompleteViewController.swift */; }; @@ -576,27 +751,38 @@ E91DC0E120E0054A00BAB519 /* NetworkSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E91DC0E020E0054A00BAB519 /* NetworkSettingsViewController.swift */; }; E920372B21A5F4C10055E4D8 /* StartLeasingConfirmModuleBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = E920372A21A5F4C10055E4D8 /* StartLeasingConfirmModuleBuilder.swift */; }; E921ED04222DDA4600DE286D /* DexScriptAssetMessageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E921ED03222DDA4600DE286D /* DexScriptAssetMessageViewController.swift */; }; - E922D25F21B81BE800575955 /* CandleDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = E922D25E21B81BE800575955 /* CandleDomainDTO.swift */; }; - E922D26421B82C2100575955 /* CandlesRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E922D26321B82C2100575955 /* CandlesRepositoryProtocol.swift */; }; - E922D26821B8311F00575955 /* LastTradesRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E922D26721B8311F00575955 /* LastTradesRepositoryProtocol.swift */; }; - E922D26A21B831B600575955 /* LastTradesRepositoryRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = E922D26921B831B600575955 /* LastTradesRepositoryRemote.swift */; }; E9236F1D2216F35B00A12FD5 /* AppNewsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9236F1C2216F35B00A12FD5 /* AppNewsView.swift */; }; E9236F1F2216F37300A12FD5 /* AppNewsView.xib in Resources */ = {isa = PBXBuildFile; fileRef = E9236F1E2216F37300A12FD5 /* AppNewsView.xib */; }; E9236F212216F48A00A12FD5 /* PopupActionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9236F202216F48A00A12FD5 /* PopupActionView.swift */; }; + E9239570237518B7009C4091 /* PushNotificationsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = E923956D237518B7009C4091 /* PushNotificationsManager.swift */; }; + E9239571237518B7009C4091 /* PushNotificationsAlertView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E923956E237518B7009C4091 /* PushNotificationsAlertView.swift */; }; + E9239572237518B7009C4091 /* PushNotificationsAlertView.xib in Resources */ = {isa = PBXBuildFile; fileRef = E923956F237518B7009C4091 /* PushNotificationsAlertView.xib */; }; E923A765219D53EE000DD9F6 /* TokenBurnInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = E923A764219D53EE000DD9F6 /* TokenBurnInteractor.swift */; }; E923A768219D714E000DD9F6 /* TokenBurnLoadingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E923A767219D714E000DD9F6 /* TokenBurnLoadingViewController.swift */; }; E923A76D219D73BF000DD9F6 /* TokenBurnCompleteViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E923A76C219D73BF000DD9F6 /* TokenBurnCompleteViewController.swift */; }; E92703C6226FDD0C0022D5F0 /* WalletSortPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E92703C5226FDD0C0022D5F0 /* WalletSortPresenter.swift */; }; - E92A8DE12278ACFF0009DF27 /* TSUD+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = E92A8DE02278ACFF0009DF27 /* TSUD+Rx.swift */; }; - E92D9BFF2148740B006D6D6B /* InputScrollButtonsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E92D9BFE2148740B006D6D6B /* InputScrollButtonsView.swift */; }; + E92A11642317CE35004EC6A1 /* WidgetPairsPriceDataTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = E92A11632317CE35004EC6A1 /* WidgetPairsPriceDataTarget.swift */; }; + E92A11682317CEF6004EC6A1 /* WidgetPairsPriceDataService.swift in Sources */ = {isa = PBXBuildFile; fileRef = E92A11672317CEF6004EC6A1 /* WidgetPairsPriceDataService.swift */; }; + E92A116B2317CF9A004EC6A1 /* InternalWidgetService.swift in Sources */ = {isa = PBXBuildFile; fileRef = E92A116A2317CF9A004EC6A1 /* InternalWidgetService.swift */; }; + E92A116D2317D12F004EC6A1 /* WidgetDataServiceTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = E92A116C2317D12F004EC6A1 /* WidgetDataServiceTypes.swift */; }; + E92A11702317D1DD004EC6A1 /* WidgetPairPriceData.swift in Sources */ = {isa = PBXBuildFile; fileRef = E92A116F2317D1DD004EC6A1 /* WidgetPairPriceData.swift */; }; + E92A11722317D2E9004EC6A1 /* WidgetResponseData.swift in Sources */ = {isa = PBXBuildFile; fileRef = E92A11712317D2E9004EC6A1 /* WidgetResponseData.swift */; }; + E92A11752317D5DB004EC6A1 /* WidgetPairsPriceRepositoryRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = E92A11742317D5DB004EC6A1 /* WidgetPairsPriceRepositoryRemote.swift */; }; + E92A11772317DB2E004EC6A1 /* WidgetMatcherRepositoryRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = E92A11762317DB2E004EC6A1 /* WidgetMatcherRepositoryRemote.swift */; }; + E92A117B2317DD6F004EC6A1 /* WidgetMatcherServiceTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = E92A117A2317DD6F004EC6A1 /* WidgetMatcherServiceTypes.swift */; }; + E92A117E2317DF4B004EC6A1 /* WidgetSettingsMarcherTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = E92A117D2317DF4B004EC6A1 /* WidgetSettingsMarcherTarget.swift */; }; + E92A11812317E10C004EC6A1 /* WidgetMatcherSettingService.swift in Sources */ = {isa = PBXBuildFile; fileRef = E92A11802317E10C004EC6A1 /* WidgetMatcherSettingService.swift */; }; + E92A11832317E7A9004EC6A1 /* WidgetAssetsRepositoryRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = E92A11822317E7A9004EC6A1 /* WidgetAssetsRepositoryRemote.swift */; }; + E92A11852317E883004EC6A1 /* WidgetAssetsDataService.swift in Sources */ = {isa = PBXBuildFile; fileRef = E92A11842317E883004EC6A1 /* WidgetAssetsDataService.swift */; }; E92FAD0E226F6C050054D4AA /* WalletSortSeparatorCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E92FAD0C226F6C050054D4AA /* WalletSortSeparatorCell.swift */; }; E92FAD0F226F6C050054D4AA /* WalletSortSeparatorCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = E92FAD0D226F6C050054D4AA /* WalletSortSeparatorCell.xib */; }; E9310D0C217924D0008BF3EE /* SendConfirmationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9310D0B217924D0008BF3EE /* SendConfirmationViewController.swift */; }; E9310D1921792D01008BF3EE /* SendConfirmationRecipientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9310D1821792D01008BF3EE /* SendConfirmationRecipientView.swift */; }; E9310D1B21792D14008BF3EE /* SendConfirmationRecipientView.xib in Resources */ = {isa = PBXBuildFile; fileRef = E9310D1A21792D13008BF3EE /* SendConfirmationRecipientView.xib */; }; E9310D1D217942C8008BF3EE /* BlueBgView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9310D1C217942C8008BF3EE /* BlueBgView.swift */; }; + E936C2EA2314BF590097515B /* WidgetSettingsInizialization.swift in Sources */ = {isa = PBXBuildFile; fileRef = E936C2E92314BF590097515B /* WidgetSettingsInizialization.swift */; }; E938356F20A472B4001A2509 /* HistoryTransactionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E938356E20A472B4001A2509 /* HistoryTransactionCell.swift */; }; - E9419CCB21CFAD76004DACCA /* MarketMatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9419CCA21CFAD76004DACCA /* MarketMatcher.swift */; }; + E9413AC222FA3D9C002C4A97 /* DexChartSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9413AC122FA3D9C002C4A97 /* DexChartSettings.swift */; }; E94231F022A40FA80087F82F /* WalletSearchModuleBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = E94231EF22A40FA80087F82F /* WalletSearchModuleBuilder.swift */; }; E9443008226E62A600EB6257 /* WalletSortViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9443007226E62A600EB6257 /* WalletSortViewController.swift */; }; E944300A226E641E00EB6257 /* WalletSortTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9443009226E641E00EB6257 /* WalletSortTypes.swift */; }; @@ -605,18 +791,17 @@ E9443012226E64E900EB6257 /* WalletSortInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9443011226E64E900EB6257 /* WalletSortInteractor.swift */; }; E9443014226E64F600EB6257 /* WalletSortInteractorProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9443013226E64F600EB6257 /* WalletSortInteractorProtocol.swift */; }; E9443018226E757E00EB6257 /* WalletSort+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9443017226E757E00EB6257 /* WalletSort+Mapper.swift */; }; - E944AA6F22444B780009F494 /* Amplitude-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = E944AA6E22444B780009F494 /* Amplitude-Info.plist */; }; - E944AA74224465BE0009F494 /* AnalyticManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = E944AA73224465BE0009F494 /* AnalyticManager.swift */; }; - E944AA76224465D60009F494 /* AnalyticManager+Dex.swift in Sources */ = {isa = PBXBuildFile; fileRef = E944AA75224465D60009F494 /* AnalyticManager+Dex.swift */; }; - E944AA78224467570009F494 /* AnalyticManager+WalletAsset.swift in Sources */ = {isa = PBXBuildFile; fileRef = E944AA77224467570009F494 /* AnalyticManager+WalletAsset.swift */; }; - E944AA7A22446A530009F494 /* AnalyticManager+WalletStart.swift in Sources */ = {isa = PBXBuildFile; fileRef = E944AA7922446A530009F494 /* AnalyticManager+WalletStart.swift */; }; - E944AA822245394C0009F494 /* AnalyticAssetManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = E944AA812245394C0009F494 /* AnalyticAssetManager.swift */; }; - E94A6E9F215AD53E001814F7 /* ContactDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = E94A6E9E215AD53E001814F7 /* ContactDomainDTO.swift */; }; - E94A7004215AEA4A001814F7 /* AddressBookRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E94A7003215AEA49001814F7 /* AddressBookRepositoryProtocol.swift */; }; - E94A7007215AEB0E001814F7 /* AddressBookRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = E94A7006215AEB0E001814F7 /* AddressBookRepository.swift */; }; - E94E4E6921CF9F6D00053A49 /* CoinomatService.swift in Sources */ = {isa = PBXBuildFile; fileRef = E94E4E6821CF9F6D00053A49 /* CoinomatService.swift */; }; + E9443BA822DCCC2B00AFF151 /* TransactionCardExchangeFeeCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9443BA722DCCC2B00AFF151 /* TransactionCardExchangeFeeCell.swift */; }; + E95310B322E8507500F72809 /* MarketPulseWidgetCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E95310B222E8507500F72809 /* MarketPulseWidgetCell.swift */; }; + E95310BC22E85FEE00F72809 /* MarketPulseTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = E95310BB22E85FEE00F72809 /* MarketPulseTypes.swift */; }; + E95310BE22E8A43000F72809 /* WidgetAssets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E95310BD22E8A43000F72809 /* WidgetAssets.xcassets */; }; + E953CE3E22EB19D5001D5800 /* DomainLayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7B66860022B3F70D0029E6F1 /* DomainLayer.framework */; }; + E953CE3F22EB19D5001D5800 /* Extensions.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7B6686EE22B7C5120029E6F1 /* Extensions.framework */; }; E95438F8217F91BA001A7860 /* SendLoadingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E95438F7217F91BA001A7860 /* SendLoadingViewController.swift */; }; E9543902217FF9EC001A7860 /* SendCompleteViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9543901217FF9EC001A7860 /* SendCompleteViewController.swift */; }; + E958571322F2E73D007A0178 /* WidgetSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = E958571222F2E73D007A0178 /* WidgetSettings.swift */; }; + E958572022F3BBA0007A0178 /* MarketPulseDataBaseRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E958571E22F3BB9F007A0178 /* MarketPulseDataBaseRepositoryProtocol.swift */; }; + E958572122F3BBA0007A0178 /* MarketPulseDataBaseRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = E958571F22F3BBA0007A0178 /* MarketPulseDataBaseRepository.swift */; }; E95B47C021638A9F004D4E39 /* Hello.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E95B47A821638A9F004D4E39 /* Hello.storyboard */; }; E95B47C221638A9F004D4E39 /* HelloLanguagesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E95B47AB21638A9F004D4E39 /* HelloLanguagesViewController.swift */; }; E95B47C721638A9F004D4E39 /* LongInfoPageView.xib in Resources */ = {isa = PBXBuildFile; fileRef = E95B47B321638A9F004D4E39 /* LongInfoPageView.xib */; }; @@ -646,44 +831,43 @@ E95E151222A18C25003552B8 /* WalletSearchTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E95E151022A18C25003552B8 /* WalletSearchTableViewCell.swift */; }; E95E151322A18C25003552B8 /* WalletSearchTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = E95E151122A18C25003552B8 /* WalletSearchTableViewCell.xib */; }; E95E151522A197B8003552B8 /* WalletSearchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E95E151422A197B8003552B8 /* WalletSearchViewController.swift */; }; + E9618D1422EF933800FB7F06 /* WidgetSettingsRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9618D1322EF933800FB7F06 /* WidgetSettingsRepositoryProtocol.swift */; }; + E9618D1622EF936800FB7F06 /* MarketPulseSettingsDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9618D1522EF936800FB7F06 /* MarketPulseSettingsDomainDTO.swift */; }; + E9618D1922F0473000FB7F06 /* MarketPulseTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = E95310BB22E85FEE00F72809 /* MarketPulseTypes.swift */; }; E96358A422A73D62008A3395 /* WalletClearAssetsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E96358A322A73D62008A3395 /* WalletClearAssetsView.swift */; }; E96358A622A73D70008A3395 /* WalletClearAssetsView.xib in Resources */ = {isa = PBXBuildFile; fileRef = E96358A522A73D70008A3395 /* WalletClearAssetsView.xib */; }; - E964067E21D5299D00569963 /* DexDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = E964067D21D5299D00569963 /* DexDomainDTO.swift */; }; E9642C8F21CB32570065A1BD /* CoinomatServiceErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9642C8E21CB32570065A1BD /* CoinomatServiceErrorView.swift */; }; E9642C9121CB326A0065A1BD /* CoinomatServiceErrorView.xib in Resources */ = {isa = PBXBuildFile; fileRef = E9642C9021CB326A0065A1BD /* CoinomatServiceErrorView.xib */; }; E965702321935F2F0052F0FC /* DexCreateOrderInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = E965702221935F2F0052F0FC /* DexCreateOrderInteractor.swift */; }; E96570432193E8570052F0FC /* DexMyOrdersModuleOutput.swift in Sources */ = {isa = PBXBuildFile; fileRef = E96570422193E8570052F0FC /* DexMyOrdersModuleOutput.swift */; }; - E967786921EC491600CE56D6 /* CandlesRepositoryRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = E967786821EC491500CE56D6 /* CandlesRepositoryRemote.swift */; }; - E967786B21EC660C00CE56D6 /* DexMyOrders+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = E967786A21EC660C00CE56D6 /* DexMyOrders+Mapper.swift */; }; E96DAB71228EE643005ED12B /* WalletSortSegmentedControl.xib in Resources */ = {isa = PBXBuildFile; fileRef = E96DAB70228EE643005ED12B /* WalletSortSegmentedControl.xib */; }; E96DAB73228EEC87005ED12B /* WalletSortSegmentedControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = E96DAB72228EEC87005ED12B /* WalletSortSegmentedControl.swift */; }; - E96E29FE21D3492F00AC2FA9 /* MatcherService.swift in Sources */ = {isa = PBXBuildFile; fileRef = E96E29FD21D3492F00AC2FA9 /* MatcherService.swift */; }; - E96E2A0021D34A2100AC2FA9 /* MatcherRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E96E29FF21D34A2100AC2FA9 /* MatcherRepositoryProtocol.swift */; }; - E96E2A0221D34AA200AC2FA9 /* MatcherRepositoryRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = E96E2A0121D34AA200AC2FA9 /* MatcherRepositoryRemote.swift */; }; - E96E2A0521D3D9AA00AC2FA9 /* DomainDexQueries.swift in Sources */ = {isa = PBXBuildFile; fileRef = E96E2A0421D3D9AA00AC2FA9 /* DomainDexQueries.swift */; }; + E96DE1862317F07B005E1FD9 /* WidgetAssetsDataTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = E96DE1852317F07B005E1FD9 /* WidgetAssetsDataTarget.swift */; }; + E96DE18A2317FE66005E1FD9 /* WidgetSettingsRepositoryStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFB474B22FC5A40002B19F8 /* WidgetSettingsRepositoryStorage.swift */; }; + E96DE1912318076A005E1FD9 /* WidgetAnalyticManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = E96DE1902318076A005E1FD9 /* WidgetAnalyticManager.swift */; }; E96FEA25226E962300C0EE22 /* WalletSortEmptyAssetsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E96FEA23226E962300C0EE22 /* WalletSortEmptyAssetsCell.swift */; }; E96FEA26226E962300C0EE22 /* WalletSortEmptyAssetsCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = E96FEA24226E962300C0EE22 /* WalletSortEmptyAssetsCell.xib */; }; E96FEA29226F27BC00C0EE22 /* WalletSortCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E96FEA27226F27BC00C0EE22 /* WalletSortCell.swift */; }; E96FEA2A226F27BC00C0EE22 /* WalletSortCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = E96FEA28226F27BC00C0EE22 /* WalletSortCell.xib */; }; - E971DA5220FFF4B600616A03 /* BiometricManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = E971DA5120FFF4B600616A03 /* BiometricManager.swift */; }; - E9740E5E21D1C90F00EAD3ED /* PairsPriceApiService.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9740E5D21D1C90F00EAD3ED /* PairsPriceApiService.swift */; }; E97667CE227F0F8C0050E0D6 /* TransactionCardOrderFilledCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E97667CD227F0F8B0050E0D6 /* TransactionCardOrderFilledCell.swift */; }; - E97D450921C80233000E3C48 /* DexPairsPriceRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E97D450821C80233000E3C48 /* DexPairsPriceRepositoryProtocol.swift */; }; - E97D450B21C802AB000E3C48 /* DexPairsPriceRepositoryRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = E97D450A21C802AB000E3C48 /* DexPairsPriceRepositoryRemote.swift */; }; - E97D450D21C8127F000E3C48 /* DexOrderBookRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E97D450C21C8127F000E3C48 /* DexOrderBookRepositoryProtocol.swift */; }; - E97D451021C814C0000E3C48 /* OrderBookMatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = E97D450F21C814C0000E3C48 /* OrderBookMatcher.swift */; }; - E97D451221C817CC000E3C48 /* DexOrderBookRepositoryRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = E97D451121C817CC000E3C48 /* DexOrderBookRepositoryRemote.swift */; }; + E97A74A522D3BAA200777C39 /* OrderBookUseCaseProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E97A74A422D3BAA200777C39 /* OrderBookUseCaseProtocol.swift */; }; + E97A74A722D3BAD400777C39 /* OrderBookUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = E97A74A622D3BAD400777C39 /* OrderBookUseCase.swift */; }; E97EC83F20E67BE900AB006B /* NewAccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E97EC83E20E67BE900AB006B /* NewAccountViewController.swift */; }; E97EC84320E689A800AB006B /* ImportAccountPasswordViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E97EC84220E689A800AB006B /* ImportAccountPasswordViewController.swift */; }; E98092A922A85EE700914CF1 /* WalletViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E98092A822A85EE700914CF1 /* WalletViewController.swift */; }; E980EACE20A9F5BF001834DB /* ScannerCustomView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E980EACD20A9F5BF001834DB /* ScannerCustomView.swift */; }; E983665E21F5972300178A8A /* TransactionScriptErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E983665D21F5972300178A8A /* TransactionScriptErrorView.swift */; }; E983666121F5973900178A8A /* TransactionScriptErrorView.xib in Resources */ = {isa = PBXBuildFile; fileRef = E983666021F5973900178A8A /* TransactionScriptErrorView.xib */; }; - E98D14D12266B25500BE5481 /* CleanerWalletManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = E98D14D02266B25500BE5481 /* CleanerWalletManager.swift */; }; + E9845D3B2374645900716515 /* PushNotificationsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9845D3A2374645900716515 /* PushNotificationsCoordinator.swift */; }; + E984BB6B2318457800D60C38 /* WidgetTransactionsDataService.swift in Sources */ = {isa = PBXBuildFile; fileRef = E984BB6A2318457800D60C38 /* WidgetTransactionsDataService.swift */; }; + E984BB6D2318461A00D60C38 /* WidgetTransactionsDataTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = E984BB6C2318461A00D60C38 /* WidgetTransactionsDataTarget.swift */; }; + E984BB6F23184EE100D60C38 /* WidgetTransactionsRepositoryRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = E984BB6E23184EE100D60C38 /* WidgetTransactionsRepositoryRemote.swift */; }; + E984BB71231935DD00D60C38 /* WidgetPublicKeyMatcherTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = E984BB70231935DD00D60C38 /* WidgetPublicKeyMatcherTarget.swift */; }; + E984BB732319367400D60C38 /* WidgetPublicKeyMatcherService.swift in Sources */ = {isa = PBXBuildFile; fileRef = E984BB722319367400D60C38 /* WidgetPublicKeyMatcherService.swift */; }; + E98A1A162301A0EF00E7EAAD /* MatcherRepositoryLocal.swift in Sources */ = {isa = PBXBuildFile; fileRef = E98A1A152301A0EF00E7EAAD /* MatcherRepositoryLocal.swift */; }; + E98F0589236B1CCF0055DCCE /* DexDeepLinkLoadingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E98F0588236B1CCF0055DCCE /* DexDeepLinkLoadingViewController.swift */; }; E98F1D2D22A5E2E600B4A8C4 /* WalletUpdateAppView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E98F1D2C22A5E2E600B4A8C4 /* WalletUpdateAppView.swift */; }; E98F1D2F22A5E2F200B4A8C4 /* WalletUpdateAppView.xib in Resources */ = {isa = PBXBuildFile; fileRef = E98F1D2E22A5E2F200B4A8C4 /* WalletUpdateAppView.xib */; }; - E991BB15220189530022E27D /* AliasApiService.swift in Sources */ = {isa = PBXBuildFile; fileRef = E991BB14220189530022E27D /* AliasApiService.swift */; }; - E991BB17220197280022E27D /* AliasApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = E991BB16220197280022E27D /* AliasApi.swift */; }; E991BB1A2202CA250022E27D /* SendFeeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E991BB192202CA250022E27D /* SendFeeViewController.swift */; }; E991BB1C2202CB3C0022E27D /* SendFeeModuleBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = E991BB1B2202CB3C0022E27D /* SendFeeModuleBuilder.swift */; }; E991BB202202CE090022E27D /* SendFeeTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E991BB1F2202CE090022E27D /* SendFeeTableViewCell.swift */; }; @@ -693,17 +877,20 @@ E991BB2A2202D5E00022E27D /* SendFeeInteractorProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E991BB292202D5E00022E27D /* SendFeeInteractorProtocol.swift */; }; E991BB2C2202D6560022E27D /* SendFeeTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = E991BB2B2202D6560022E27D /* SendFeeTypes.swift */; }; E991BB2E2202DD420022E27D /* SendFeeHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E991BB2D2202DD420022E27D /* SendFeeHeaderView.swift */; }; + E991F8FF22E8CFC1008D1AE4 /* MarketPulseWidgetInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = E991F8FE22E8CFC1008D1AE4 /* MarketPulseWidgetInteractor.swift */; }; + E991F90122E8CFD3008D1AE4 /* MarketPulseWidgetPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E991F90022E8CFD3008D1AE4 /* MarketPulseWidgetPresenter.swift */; }; E9939B4522302E3800B50E67 /* InfoPageConfirmView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9939B4422302E3800B50E67 /* InfoPageConfirmView.swift */; }; E9939B4722302E6100B50E67 /* InfoPageConfirmView.xib in Resources */ = {isa = PBXBuildFile; fileRef = E9939B4622302E6100B50E67 /* InfoPageConfirmView.xib */; }; - E99DD81B21CEE7690091AFEC /* CandlesApiService.swift in Sources */ = {isa = PBXBuildFile; fileRef = E99DD81A21CEE7690091AFEC /* CandlesApiService.swift */; }; - E99DD81D21CEF09C0091AFEC /* CandleApiFilters.swift in Sources */ = {isa = PBXBuildFile; fileRef = E99DD81C21CEF09C0091AFEC /* CandleApiFilters.swift */; }; - E99DD81F21CEF7AC0091AFEC /* CandleApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = E99DD81E21CEF7AC0091AFEC /* CandleApi.swift */; }; + E999E6A62323D5C300EDDF45 /* WavesSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E999E6A52323D5C300EDDF45 /* WavesSDK.framework */; }; + E999E6A82323D5C900EDDF45 /* WavesSDKCrypto.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E999E6A72323D5C900EDDF45 /* WavesSDKCrypto.framework */; }; + E999E6AA2323D5D200EDDF45 /* WavesSDKExtensions.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E999E6A92323D5D200EDDF45 /* WavesSDKExtensions.framework */; }; + E999E6AB2323D61300EDDF45 /* MarketPulseWidget.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = E9B190A722E7CD99008220B7 /* MarketPulseWidget.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + E99A3B7522BE5CEB0070AC76 /* GatewayRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E99A3B7422BE5CEB0070AC76 /* GatewayRepositoryProtocol.swift */; }; + E99A3B7722BE5DB70070AC76 /* GatewayDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = E99A3B7622BE5DB70070AC76 /* GatewayDomainDTO.swift */; }; E9A05C5820E9264300B0E0FA /* UseTouchIDViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9A05C5720E9264300B0E0FA /* UseTouchIDViewController.swift */; }; - E9A380A721D2E1C5004377A6 /* PairPriceApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9A380A621D2E1C5004377A6 /* PairPriceApi.swift */; }; - E9A380AD21D3035B004377A6 /* OrderMatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9A380AC21D3035B004377A6 /* OrderMatcher.swift */; }; + E9A3ABBD2319EEB900EB4389 /* MatcherRepositoryLocal.swift in Sources */ = {isa = PBXBuildFile; fileRef = E98A1A152301A0EF00E7EAAD /* MatcherRepositoryLocal.swift */; }; E9A3AFAE222DEECB009FB45A /* DexScriptAssetMessageModuleBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9A3AFAD222DEECB009FB45A /* DexScriptAssetMessageModuleBuilder.swift */; }; E9A4812F20D8DDBB00272C6D /* ChangePasswordViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9A4812E20D8DDBB00272C6D /* ChangePasswordViewController.swift */; }; - E9A6A49A227661940093FC59 /* TableViewNoShadow.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9A6A499227661940093FC59 /* TableViewNoShadow.swift */; }; E9AFDBE421F32E88003130A8 /* TransactionFeeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9AFDBE321F32E88003130A8 /* TransactionFeeView.swift */; }; E9AFDBE621F32E96003130A8 /* TransactionFeeView.xib in Resources */ = {isa = PBXBuildFile; fileRef = E9AFDBE521F32E96003130A8 /* TransactionFeeView.xib */; }; E9B086AE2163883000937644 /* AddAddressBookModuleBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9B086922163882F00937644 /* AddAddressBookModuleBuilder.swift */; }; @@ -830,14 +1017,17 @@ E9B12DB6219DD6E000128EFE /* AssetBalanceSpamCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = E9B12DB4219DD6E000128EFE /* AssetBalanceSpamCell.xib */; }; E9B12DB9219E2D3900128EFE /* AssetBurnCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9B12DB7219E2D3900128EFE /* AssetBurnCell.swift */; }; E9B12DBA219E2D3900128EFE /* AssetBurnCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = E9B12DB8219E2D3900128EFE /* AssetBurnCell.xib */; }; + E9B190A922E7CD99008220B7 /* NotificationCenter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E9B190A822E7CD99008220B7 /* NotificationCenter.framework */; }; + E9B190AC22E7CD99008220B7 /* MarketPulseWidgetViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9B190AB22E7CD99008220B7 /* MarketPulseWidgetViewController.swift */; }; + E9B190AF22E7CD99008220B7 /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E9B190AD22E7CD99008220B7 /* MainInterface.storyboard */; }; + E9B387CF23690DCD001FCA60 /* SendCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9B387CE23690DCD001FCA60 /* SendCoordinator.swift */; }; E9BB2D852260DEB000366278 /* TransactionCardInvokeScriptCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9BB2D842260DEB000366278 /* TransactionCardInvokeScriptCell.swift */; }; - E9BB724821C2A94000B2AF7E /* CoinomatRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9BB724721C2A94000B2AF7E /* CoinomatRepositoryProtocol.swift */; }; - E9BCF48121636DAC00FA6502 /* ResponseType.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9BCF48021636DAC00FA6502 /* ResponseType.swift */; }; E9C0B49C2176C46E00669D1D /* SendPresenterProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9C0B49B2176C46E00669D1D /* SendPresenterProtocol.swift */; }; E9C0B49E2176C48300669D1D /* SendPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9C0B49D2176C48300669D1D /* SendPresenter.swift */; }; E9C0B4A02176C49B00669D1D /* SendInteractorProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9C0B49F2176C49B00669D1D /* SendInteractorProtocol.swift */; }; E9C0B4A42176C4BE00669D1D /* SendTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9C0B4A32176C4BE00669D1D /* SendTypes.swift */; }; - E9C1F5C6224D60B1006DBD8E /* ApplicationDebugSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9C1F5C5224D60B1006DBD8E /* ApplicationDebugSettings.swift */; }; + E9C1B90E236C6D9500F8E988 /* ForceUpdateApp.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E9C1B90D236C6D9500F8E988 /* ForceUpdateApp.storyboard */; }; + E9C1B910236C6DA900F8E988 /* ForceUpdateAppViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9C1B90F236C6DA900F8E988 /* ForceUpdateAppViewController.swift */; }; E9C4134C20E826E300AA044F /* DottedRoundView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9C4134B20E826E300AA044F /* DottedRoundView.swift */; }; E9C8F94B20F66A05004C438A /* ConfirmBackupStackListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9C8F94A20F66A05004C438A /* ConfirmBackupStackListView.swift */; }; E9C8F94D20F66D64004C438A /* ConfirmBackupStackBaseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9C8F94C20F66D64004C438A /* ConfirmBackupStackBaseView.swift */; }; @@ -846,9 +1036,6 @@ E9CD0D2E21809A5D001A99B3 /* SendMoneroPaymentIdView.xib in Resources */ = {isa = PBXBuildFile; fileRef = E9CD0D2D21809A5D001A99B3 /* SendMoneroPaymentIdView.xib */; }; E9CD0D32218137FE001A99B3 /* MainTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9CD0D30218137FE001A99B3 /* MainTabBarController.swift */; }; E9CD0D3521815849001A99B3 /* AddAddressBookTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9CD0D3421815849001A99B3 /* AddAddressBookTypes.swift */; }; - E9D0ED86225CB8400098C234 /* InvokeScriptTransactionNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9D0ED85225CB8400098C234 /* InvokeScriptTransactionNode.swift */; }; - E9D0ED88225CBDEA0098C234 /* InvokeScriptTransactionDomainDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9D0ED87225CBDEA0098C234 /* InvokeScriptTransactionDomainDTO.swift */; }; - E9D0ED8A225CBECA0098C234 /* InvokeScriptTransaction+Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9D0ED89225CBECA0098C234 /* InvokeScriptTransaction+Mapper.swift */; }; E9D36DC72175C755001E6DF0 /* ReceiveCryptocurrencyTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9D36D6D2175C754001E6DF0 /* ReceiveCryptocurrencyTypes.swift */; }; E9D36DC92175C755001E6DF0 /* ReceiveCryptocurrencyModuleBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9D36D702175C754001E6DF0 /* ReceiveCryptocurrencyModuleBuilder.swift */; }; E9D36DCA2175C755001E6DF0 /* ReceiveCryptocurrencyPresenterProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9D36D722175C754001E6DF0 /* ReceiveCryptocurrencyPresenterProtocol.swift */; }; @@ -895,21 +1082,16 @@ E9DB667521A3848900962639 /* StartLeasingCancelConfirmationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9DB667421A3848900962639 /* StartLeasingCancelConfirmationViewController.swift */; }; E9DB667B21A3938200962639 /* StartLeasingLoadingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9DB667A21A3938200962639 /* StartLeasingLoadingViewController.swift */; }; E9DC959621A3A5BD0020249F /* StartLeasingTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = E95B47E021638B11004D4E39 /* StartLeasingTypes.swift */; }; - E9DDF73A2240F52D00B83CFD /* EnvironmentRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9DDF7392240F52D00B83CFD /* EnvironmentRepository.swift */; }; - E9DDF73D2240F58900B83CFD /* UtilsNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9DDF73B2240F58800B83CFD /* UtilsNode.swift */; }; - E9DDF7402240F5FD00B83CFD /* UtilsNodeService.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9DDF73F2240F5FD00B83CFD /* UtilsNodeService.swift */; }; E9DEECE920BEF96700F28C67 /* WavesPopupViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9DEECE820BEF96700F28C67 /* WavesPopupViewController.swift */; }; E9DEECEB20BEF97E00F28C67 /* Waves.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E9DEECEA20BEF97E00F28C67 /* Waves.storyboard */; }; E9DF24F62221ED640077F2EB /* AssetDetailInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9DF24F52221ED640077F2EB /* AssetDetailInteractor.swift */; }; E9DF24F82221EE180077F2EB /* AssetDetailPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9DF24F72221EE180077F2EB /* AssetDetailPresenter.swift */; }; E9DF24FA2221EF4D0077F2EB /* AssetDetailTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9DF24F92221EF4D0077F2EB /* AssetDetailTypes.swift */; }; - E9E62D1F22678B7000D7DC95 /* SweetLoggerSentry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B951124225CD6D80030390C /* SweetLoggerSentry.swift */; }; E9EC5BAA2175F35900E5C29A /* Send.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E9EC5B362175F35800E5C29A /* Send.storyboard */; }; E9EC5BAC2175F35900E5C29A /* SendViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9EC5B3A2175F35800E5C29A /* SendViewController.swift */; }; E9EC5BAD2175F35900E5C29A /* SendModuleBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9EC5B3B2175F35800E5C29A /* SendModuleBuilder.swift */; }; E9EC5C0F2175F35900E5C29A /* AddressInputView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9EC5BA82175F35800E5C29A /* AddressInputView.swift */; }; E9EC5C102175F35900E5C29A /* AddressInputView.xib in Resources */ = {isa = PBXBuildFile; fileRef = E9EC5BA92175F35800E5C29A /* AddressInputView.xib */; }; - E9EE476D225E91ED0005176A /* InvokeScriptTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9EE476C225E91ED0005176A /* InvokeScriptTransaction.swift */; }; E9F69B9222A5217200CDBD00 /* WalletSearchTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9F69B9122A5217200CDBD00 /* WalletSearchTypes.swift */; }; E9F69B9822A522E400CDBD00 /* WalletSearchPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9F69B9722A522E400CDBD00 /* WalletSearchPresenter.swift */; }; E9F69B9C22A5333500CDBD00 /* WalletSearchHeaderCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9F69B9A22A5333500CDBD00 /* WalletSearchHeaderCell.swift */; }; @@ -919,21 +1101,72 @@ E9F984A920E526DA00D2CB4D /* Enter.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E9F984A820E526DA00D2CB4D /* Enter.storyboard */; }; E9F984AB20E52D8E00D2CB4D /* EnterStartViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9F984AA20E52D8E00D2CB4D /* EnterStartViewController.swift */; }; E9F984B220E53FE000D2CB4D /* LanguageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9F984B120E53FE000D2CB4D /* LanguageViewController.swift */; }; - E9F9A279218535A200FD68D7 /* DexAssetPair.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9F9A278218535A200FD68D7 /* DexAssetPair.swift */; }; - E9F9A27C21853E7D00FD68D7 /* DexRealmRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9F9A27B21853E7D00FD68D7 /* DexRealmRepositoryProtocol.swift */; }; - E9F9A27E218540F700FD68D7 /* DexRealmRepositoryLocal.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9F9A27D218540F700FD68D7 /* DexRealmRepositoryLocal.swift */; }; E9FB6E382178265100FA13C1 /* SendInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9C0B4A12176C4A800669D1D /* SendInteractor.swift */; }; E9FE4D7820EA767B00208F29 /* SaveBackupPhraseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9FE4D7720EA767B00208F29 /* SaveBackupPhraseViewController.swift */; }; E9FE4D7A20EA7F8500208F29 /* ConfirmBackupViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9FE4D7920EA7F8500208F29 /* ConfirmBackupViewController.swift */; }; - F74240B61EAB8D1600C3B84D /* AddressBook.swift in Sources */ = {isa = PBXBuildFile; fileRef = F74240B11EAB8D1600C3B84D /* AddressBook.swift */; }; - F74240B71EAB8D1600C3B84D /* AssetBalance.swift in Sources */ = {isa = PBXBuildFile; fileRef = F74240B21EAB8D1600C3B84D /* AssetBalance.swift */; }; - F74240B81EAB8D1600C3B84D /* Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = F74240B31EAB8D1600C3B84D /* Transaction.swift */; }; + F38A5F9B2B9C0AC51E99378B /* (null) in Frameworks */ = {isa = PBXBuildFile; }; F74240C91EAB8EC800C3B84D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F74240C81EAB8EC800C3B84D /* Main.storyboard */; }; F7C683BE1EA93C5800C87DAF /* CustomNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7C683BA1EA93C5800C87DAF /* CustomNavigationController.swift */; }; F7E954E81EA8FE0700A804DE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E954E71EA8FE0700A804DE /* AppDelegate.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ + 7B16BCDD22DBE39000540418 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F7E954DC1EA8FE0600A804DE /* Project object */; + proxyType = 1; + remoteGlobalIDString = 7B6685FF22B3F70D0029E6F1; + remoteInfo = DomainLayer; + }; + 7B16BCDF22DBE39000540418 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F7E954DC1EA8FE0600A804DE /* Project object */; + proxyType = 1; + remoteGlobalIDString = 7B6686ED22B7C5120029E6F1; + remoteInfo = Extensions; + }; + 7B16BCE122DBE39000540418 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F7E954DC1EA8FE0600A804DE /* Project object */; + proxyType = 1; + remoteGlobalIDString = 7B66872222B7E68B0029E6F1; + remoteInfo = DataLayer; + }; + 7B16BCE722DBE59B00540418 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F7E954DC1EA8FE0600A804DE /* Project object */; + proxyType = 1; + remoteGlobalIDString = 7B6685FF22B3F70D0029E6F1; + remoteInfo = DomainLayer; + }; + 7B16BCE922DBE5A900540418 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F7E954DC1EA8FE0600A804DE /* Project object */; + proxyType = 1; + remoteGlobalIDString = 7B6686ED22B7C5120029E6F1; + remoteInfo = Extensions; + }; + 7B83A7AE22D8C60E0038180D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F7E954DC1EA8FE0600A804DE /* Project object */; + proxyType = 1; + remoteGlobalIDString = F7E954E31EA8FE0700A804DE; + remoteInfo = "WavesWallet-iOS"; + }; + 7B83A7E622D8C7580038180D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F7E954DC1EA8FE0600A804DE /* Project object */; + proxyType = 1; + remoteGlobalIDString = 7B83A7CF22D8C74E0038180D; + remoteInfo = DummyForTest; + }; + 7B83A7EA22D8D8050038180D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F7E954DC1EA8FE0600A804DE /* Project object */; + proxyType = 1; + remoteGlobalIDString = 7B83A7CF22D8C74E0038180D; + remoteInfo = DummyForTest; + }; 7BF89E9B22272A5E00853F9D /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = F7E954DC1EA8FE0600A804DE /* Project object */; @@ -941,8 +1174,59 @@ remoteGlobalIDString = F7E954E31EA8FE0700A804DE; remoteInfo = "WavesWallet-iOS"; }; + E953CE3722EB19C2001D5800 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F7E954DC1EA8FE0600A804DE /* Project object */; + proxyType = 1; + remoteGlobalIDString = 7B6685FF22B3F70D0029E6F1; + remoteInfo = DomainLayer; + }; + E953CE3922EB19C2001D5800 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F7E954DC1EA8FE0600A804DE /* Project object */; + proxyType = 1; + remoteGlobalIDString = 7B6686ED22B7C5120029E6F1; + remoteInfo = Extensions; + }; + E999E6AC2323D61300EDDF45 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F7E954DC1EA8FE0600A804DE /* Project object */; + proxyType = 1; + remoteGlobalIDString = E9B190A622E7CD99008220B7; + remoteInfo = MarketPulseWidget; + }; /* End PBXContainerItemProxy section */ +/* Begin PBXCopyFilesBuildPhase section */ + 7B9393CC22DF5827006634A6 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 7B9393C922DF5827006634A6 /* WavesSDK.framework in Embed Frameworks */, + 7B9393D022DF5830006634A6 /* DataLayer.framework in Embed Frameworks */, + 7B9393D222DF5835006634A6 /* Extensions.framework in Embed Frameworks */, + 7B9393C722DF5827006634A6 /* WavesSDKExtensions.framework in Embed Frameworks */, + 7B9393CE22DF582D006634A6 /* DomainLayer.framework in Embed Frameworks */, + 7B9393CB22DF5827006634A6 /* WavesSDKCrypto.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + E9B190BB22E7CD9A008220B7 /* Embed App Extensions */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 13; + files = ( + E999E6AB2323D61300EDDF45 /* MarketPulseWidget.appex in Embed App Extensions */, + ); + name = "Embed App Extensions"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + /* Begin PBXFileReference section */ 04016DFB219420C900BA5235 /* ImportAccountViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImportAccountViewController.swift; sourceTree = ""; }; 04016DFF219499DA00BA5235 /* ImportAccountScanViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImportAccountScanViewController.swift; sourceTree = ""; }; @@ -969,24 +1253,20 @@ 04A2CFA4211213BE00784FEC /* History.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = History.storyboard; sourceTree = ""; }; 04A403212164D80200652F21 /* EnterStartTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnterStartTypes.swift; sourceTree = ""; }; 04A403232164D89700652F21 /* EnterStartBlockCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnterStartBlockCell.swift; sourceTree = ""; }; - 04D4431A21885F4F009CEB22 /* Fabric-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Fabric-Info.plist"; sourceTree = ""; }; 04D882BE21706FEF00EAAB90 /* InfoPagesCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoPagesCell.swift; sourceTree = ""; }; 04E1C3552126157000C702BA /* HeaderSkeletonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeaderSkeletonView.swift; sourceTree = ""; }; 04E1C357212615CA00C702BA /* HeaderSkeletonView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = HeaderSkeletonView.xib; sourceTree = ""; }; 04E1C3592126B21A00C702BA /* HistoryTransactionSkeletonCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryTransactionSkeletonCell.swift; sourceTree = ""; }; - 04E80A11214EF20C00D00AA4 /* SmartTransactionDomain+Assistants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SmartTransactionDomain+Assistants.swift"; sourceTree = ""; }; 04EB742521133318004A065B /* HistoryViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryViewController.swift; sourceTree = ""; }; 04EB74272113335B004A065B /* HistoryTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryTypes.swift; sourceTree = ""; }; 04EB74292113415E004A065B /* HistoryTypes+State.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HistoryTypes+State.swift"; sourceTree = ""; }; 04EFAF4C2164F8D800277CCF /* EnterStartBlockCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = EnterStartBlockCell.xib; sourceTree = ""; }; 04F2DD2D219F27AB0070AF9D /* MultilineTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultilineTextField.swift; sourceTree = ""; }; 04F9979521AA197B0036768D /* CameraAccess.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraAccess.swift; sourceTree = ""; }; - 0A00B184221AE325005A9053 /* AssetsBalanceSettingsRepositoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetsBalanceSettingsRepositoryProtocol.swift; sourceTree = ""; }; - 0A02D20621AEA1B1005DF820 /* Appsflyer-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Appsflyer-Info.plist"; sourceTree = ""; }; + 09C7B309A88856F7E5362438 /* Pods-MarketPulseWidget.release-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MarketPulseWidget.release-prod.xcconfig"; path = "Target Support Files/Pods-MarketPulseWidget/Pods-MarketPulseWidget.release-prod.xcconfig"; sourceTree = ""; }; 0A02D20821AEDD3C005DF820 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/InfoPlist.strings; sourceTree = ""; }; 0A02D20921AEDD3C005DF820 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Waves.strings; sourceTree = ""; }; 0A071E40215AEF61007D9750 /* AccountPassword.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = AccountPassword.storyboard; sourceTree = ""; }; - 0A071E42215B0A1B007D9750 /* SigningWalletsProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SigningWalletsProtocol.swift; sourceTree = ""; }; 0A071E63215C65D2007D9750 /* UseTouchID.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = UseTouchID.storyboard; sourceTree = ""; }; 0A071E76215DB07C007D9750 /* ChooseAccountTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChooseAccountTypes.swift; sourceTree = ""; }; 0A071E79215DB0A9007D9750 /* ChooseAccount.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = ChooseAccount.storyboard; sourceTree = ""; }; @@ -997,9 +1277,6 @@ 0A110CC52153F36F002A8FD7 /* SkeletonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonView.swift; sourceTree = ""; }; 0A110CC7215417DD002A8FD7 /* MultyTextField.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MultyTextField.xib; sourceTree = ""; }; 0A110CC8215417DD002A8FD7 /* MultyTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultyTextField.swift; sourceTree = ""; }; - 0A14CFC62141DA9800C3A4D5 /* SmartTransactionDomainDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SmartTransactionDomainDTO.swift; sourceTree = ""; }; - 0A14CFCE2144159300C3A4D5 /* Asset+Assistants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Asset+Assistants.swift"; sourceTree = ""; }; - 0A14CFD0214415C100C3A4D5 /* TransactionDomainDTO+Mapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TransactionDomainDTO+Mapper.swift"; sourceTree = ""; }; 0A14E3E32187184000EA7E91 /* AliasesPresenterProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AliasesPresenterProtocol.swift; sourceTree = ""; }; 0A14E3E52187185700EA7E91 /* AliasesViewModuleBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AliasesViewModuleBuilder.swift; sourceTree = ""; }; 0A14E3E721871B7700EA7E91 /* AliasesHeadCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AliasesHeadCell.swift; sourceTree = ""; }; @@ -1014,153 +1291,45 @@ 0A15081C219AE51100516037 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/Waves.strings; sourceTree = ""; }; 0A15081D219AE53600516037 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; 0A15081E219AE53700516037 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Waves.strings; sourceTree = ""; }; - 0A150821219B0D6B00516037 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; 0A16784720FD3E4F00AA5980 /* WalletTypes+DisplayState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WalletTypes+DisplayState.swift"; sourceTree = ""; }; - 0A1DAD6120F3876C004DA625 /* AssetApi.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetApi.swift; sourceTree = ""; }; - 0A1DAD6420F395F2004DA625 /* AssetsInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetsInteractor.swift; sourceTree = ""; }; - 0A1DAD6820F39AE3004DA625 /* ResponseApi.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResponseApi.swift; sourceTree = ""; }; - 0A1DAD6C20F39F94004DA625 /* NodeServiceTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeServiceTypes.swift; sourceTree = ""; }; - 0A1DAD7020F3A112004DA625 /* AddressesNodeService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressesNodeService.swift; sourceTree = ""; }; - 0A1DAD7220F3A12B004DA625 /* AssetsNodeService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetsNodeService.swift; sourceTree = ""; }; - 0A1DAD7520F3A6A6004DA625 /* ExchangeApiFilters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExchangeApiFilters.swift; sourceTree = ""; }; - 0A1DAD7920F3A9AE004DA625 /* TransactionApi.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionApi.swift; sourceTree = ""; }; - 0A2060622181C2C10048CF83 /* environment_mainnet.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = environment_mainnet.json; sourceTree = ""; }; - 0A2060632181C2C20048CF83 /* environment_testnet.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = environment_testnet.json; sourceTree = ""; }; 0A20606721822C3A0048CF83 /* AddressesKeysViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressesKeysViewController.swift; sourceTree = ""; }; - 0A218B802155180C00B989A1 /* WalletDomainDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletDomainDTO.swift; sourceTree = ""; }; - 0A218B8421551D1400B989A1 /* WalletsRepositoryLocal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletsRepositoryLocal.swift; sourceTree = ""; }; - 0A218B8621551E6600B989A1 /* WalletsRepositoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletsRepositoryProtocol.swift; sourceTree = ""; }; - 0A218B882155221F00B989A1 /* Wallet+Mapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Wallet+Mapper.swift"; sourceTree = ""; }; - 0A218B8A2155335F00B989A1 /* WalletSeedRepositoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletSeedRepositoryProtocol.swift; sourceTree = ""; }; - 0A218B8D215534E000B989A1 /* WalletSeedRepositoryLocal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletSeedRepositoryLocal.swift; sourceTree = ""; }; - 0A218B94215556F600B989A1 /* AuthenticationRepositoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationRepositoryProtocol.swift; sourceTree = ""; }; - 0A218B9621555A4B00B989A1 /* AuthenticationRepositoryRemote.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationRepositoryRemote.swift; sourceTree = ""; }; 0A2B7D32216037FD0098438D /* AssetViewHistoryCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AssetViewHistoryCell.xib; sourceTree = ""; }; 0A2B7D33216037FD0098438D /* AssetViewHistoryCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssetViewHistoryCell.swift; sourceTree = ""; }; 0A2B7D36216038540098438D /* HalfModalInteractiveTransition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HalfModalInteractiveTransition.swift; sourceTree = ""; }; - 0A2B7D38216038A80098438D /* SpamService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpamService.swift; sourceTree = ""; }; - 0A2B7D3A216038F70098438D /* AssetsSpamService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssetsSpamService.swift; sourceTree = ""; }; - 0A2CD237216D0F0000162063 /* AuthorizationInteractorProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthorizationInteractorProtocol.swift; sourceTree = ""; }; - 0A344E2E2194747E007809B1 /* MigrationInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrationInteractor.swift; sourceTree = ""; }; 0A36A37B215E493D0060F49E /* NeedBackupViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NeedBackupViewController.swift; sourceTree = ""; }; 0A3FE8A52135AC2A00DBF4E1 /* AssetTransactionsCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssetTransactionsCell.swift; sourceTree = ""; }; 0A3FE8A72135AE3600DBF4E1 /* AssetTransactionCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AssetTransactionCell.xib; sourceTree = ""; }; 0A3FE8A92135AE4000DBF4E1 /* AssetTransactionCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetTransactionCell.swift; sourceTree = ""; }; - 0A3FE8AB2136AF4B00DBF4E1 /* TransactionsRepositoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionsRepositoryProtocol.swift; sourceTree = ""; }; - 0A3FE8AD2136E51900DBF4E1 /* TransactionContainersNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionContainersNode.swift; sourceTree = ""; }; 0A4140EA2174F09C00B1310E /* ChangePassword.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = ChangePassword.storyboard; sourceTree = ""; }; 0A41410A217603F800B1310E /* ChangePasswordPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChangePasswordPresenter.swift; sourceTree = ""; }; 0A4399652150465E0032E608 /* NewAccount.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = NewAccount.storyboard; sourceTree = ""; }; 0A43996821504CF60032E608 /* SideMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SideMenu.swift; sourceTree = ""; }; 0A4508F72177970F00EBF669 /* AlertDeleteAccountViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AlertDeleteAccountViewController.swift; sourceTree = ""; }; - 0A4508F92178938C00EBF669 /* EnvironmentRepositoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnvironmentRepositoryProtocol.swift; sourceTree = ""; }; - 0A485E8620FF570000079B49 /* AssetBalanceSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetBalanceSettings.swift; sourceTree = ""; }; - 0A485E8A20FFAC6C00079B49 /* LeasingNodeService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeasingNodeService.swift; sourceTree = ""; }; - 0A485E8C20FFB02100079B49 /* LeaseTransactionNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeaseTransactionNode.swift; sourceTree = ""; }; - 0A485E942100A0D400079B49 /* DomainLayerTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomainLayerTypes.swift; sourceTree = ""; }; - 0A485E992100A8ED00079B49 /* TransferTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransferTransaction.swift; sourceTree = ""; }; - 0A485E9B2100A91500079B49 /* ExchangeTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExchangeTransaction.swift; sourceTree = ""; }; - 0A485E9D2100AE9B00079B49 /* IssueTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IssueTransaction.swift; sourceTree = ""; }; - 0A485E9F2100B0BD00079B49 /* LeaseTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeaseTransaction.swift; sourceTree = ""; }; - 0A485EA12100C4FA00079B49 /* LeaseTransaction+Mapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LeaseTransaction+Mapper.swift"; sourceTree = ""; }; 0A4C9A2720ED443C0095A417 /* WalletPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletPresenter.swift; sourceTree = ""; usesTabs = 0; }; 0A4C9A9E20EE425B0095A417 /* WalletTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletTypes.swift; sourceTree = ""; }; - 0A4C9AA020EE65800095A417 /* WalletItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = WalletItem.swift; path = ../WalletItem.swift; sourceTree = ""; }; - 0A4C9AA220EE65910095A417 /* SeedItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeedItem.swift; sourceTree = ""; }; - 0A4C9AAA20EF6BFF0095A417 /* AssetsApiService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetsApiService.swift; sourceTree = ""; }; - 0A4D221D21809E3600155A8E /* AccountEnvironmentDomainDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountEnvironmentDomainDTO.swift; sourceTree = ""; }; 0A4E71942216C6CD00A46613 /* WavesWallet-iOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "WavesWallet-iOS.entitlements"; sourceTree = ""; }; 0A4E71952216E98200A46613 /* SendFeeIndicatorCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendFeeIndicatorCell.swift; sourceTree = ""; }; - 0A4E7DE822018C5E007BBA39 /* ModalPresentationAnimatorContext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ModalPresentationAnimatorContext.swift; sourceTree = ""; }; - 0A4E7DE922018C5E007BBA39 /* ModalViewControllerTransitioning.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ModalViewControllerTransitioning.swift; sourceTree = ""; }; - 0A4E7DEA22018C5F007BBA39 /* ModalPresentationAnimator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ModalPresentationAnimator.swift; sourceTree = ""; }; - 0A4E7DEB22018C5F007BBA39 /* ModalPresentationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ModalPresentationController.swift; sourceTree = ""; }; - 0A57C38B21F74E20003B5386 /* ScriptTransaction+Mapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ScriptTransaction+Mapper.swift"; sourceTree = ""; }; - 0A57C38D21F74E2E003B5386 /* AssetScriptTransaction+Mapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AssetScriptTransaction+Mapper.swift"; sourceTree = ""; }; - 0A57C38F21F74EB0003B5386 /* ScriptTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScriptTransaction.swift; sourceTree = ""; }; - 0A57C39121F74EBA003B5386 /* AssetScriptTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetScriptTransaction.swift; sourceTree = ""; }; 0A59330B218343B00059A77A /* AddressesKeysAliacesCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressesKeysAliacesCell.swift; sourceTree = ""; }; 0A593311218344000059A77A /* AddressesKeysHiddenPrivateKeyCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressesKeysHiddenPrivateKeyCell.swift; sourceTree = ""; }; 0A59331321835C9C0059A77A /* AddressesKeysTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressesKeysTypes.swift; sourceTree = ""; }; 0A5933152183604F0059A77A /* AddressesKeysPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressesKeysPresenter.swift; sourceTree = ""; }; 0A59331721870ABB0059A77A /* AliasesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AliasesViewController.swift; sourceTree = ""; }; 0A59331A21870B130059A77A /* AliasesTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AliasesTypes.swift; sourceTree = ""; }; - 0A5B6E6E211A2B6D005A7F09 /* TransactionNodeService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionNodeService.swift; sourceTree = ""; }; - 0A5B6E70211A2F77005A7F09 /* MassTransferTransactionNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MassTransferTransactionNode.swift; sourceTree = ""; }; - 0A5B6E72211A3065005A7F09 /* IssueTransactionNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IssueTransactionNode.swift; sourceTree = ""; }; - 0A5B6E74211A3103005A7F09 /* TransferTransactionNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransferTransactionNode.swift; sourceTree = ""; }; - 0A5B6E76211A3161005A7F09 /* ReissueTransactionNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReissueTransactionNode.swift; sourceTree = ""; }; - 0A5B6E78211A319C005A7F09 /* BurnTransactionNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BurnTransactionNode.swift; sourceTree = ""; }; - 0A5B6E7A211A327C005A7F09 /* ExchangeTransactionNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExchangeTransactionNode.swift; sourceTree = ""; }; - 0A5B6E7C211A3343005A7F09 /* LeaseCancelTransactionNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeaseCancelTransactionNode.swift; sourceTree = ""; }; - 0A5B6E7E211A3373005A7F09 /* AliasTransactionNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AliasTransactionNode.swift; sourceTree = ""; }; - 0A5B6E80211A33D9005A7F09 /* DataTransactionNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataTransactionNode.swift; sourceTree = ""; }; - 0A5C3201213D916900420004 /* AnyTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyTransaction.swift; sourceTree = ""; }; - 0A5C3203213E93C700420004 /* UnrecognisedTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnrecognisedTransaction.swift; sourceTree = ""; }; - 0A5C53DC2139491C00667E34 /* UnrecognisedTransactionNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnrecognisedTransactionNode.swift; sourceTree = ""; }; - 0A5C53DE2139498800667E34 /* UnrecognisedTransactionDomainDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnrecognisedTransactionDomainDTO.swift; sourceTree = ""; }; - 0A5C53E021394A2B00667E34 /* UnrecognisedTransaction+Mapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UnrecognisedTransaction+Mapper.swift"; sourceTree = ""; }; - 0A5C53E42139609600667E34 /* TransactionsRepositoryLocal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionsRepositoryLocal.swift; sourceTree = ""; }; - 0A5C918420F3CD0500443CE6 /* ApiServiceTypes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApiServiceTypes.swift; sourceTree = ""; }; - 0A5C919720F3DB1100443CE6 /* AccountBalanceNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountBalanceNode.swift; sourceTree = ""; }; - 0A5C919920F3DB4C00443CE6 /* AccountAssetsBalanceNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountAssetsBalanceNode.swift; sourceTree = ""; }; - 0A5C919B20F3E7DD00443CE6 /* Asset.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Asset.swift; sourceTree = ""; }; 0A5D32F8215461E90009CDF3 /* ImportTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImportTypes.swift; sourceTree = ""; }; - 0A5D3301215842860009CDF3 /* AuthorizationInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthorizationInteractor.swift; sourceTree = ""; }; - 0A5E4BAE213801C400E3C3C3 /* ReissueTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReissueTransaction.swift; sourceTree = ""; }; - 0A5E4BB02138034500E3C3C3 /* LeaseCancelTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeaseCancelTransaction.swift; sourceTree = ""; }; - 0A5E4BB22138046E00E3C3C3 /* AliasTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AliasTransaction.swift; sourceTree = ""; }; - 0A5E4BB4213805B400E3C3C3 /* MassTransferTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MassTransferTransaction.swift; sourceTree = ""; }; - 0A5E4BB621380B3300E3C3C3 /* BurnTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BurnTransaction.swift; sourceTree = ""; }; - 0A5E4BB921381E3400E3C3C3 /* DataTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataTransaction.swift; sourceTree = ""; }; - 0A5E4BBC213820C500E3C3C3 /* DataTransactionDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataTransactionDomainDTO.swift; sourceTree = ""; }; - 0A5E4BBD213820C500E3C3C3 /* LeaseCancelTransactionDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LeaseCancelTransactionDomainDTO.swift; sourceTree = ""; }; - 0A5E4BBE213820C500E3C3C3 /* MassTransferTransactionDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MassTransferTransactionDomainDTO.swift; sourceTree = ""; }; - 0A5E4BC0213820C500E3C3C3 /* IssueTransactionDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IssueTransactionDomainDTO.swift; sourceTree = ""; }; - 0A5E4BC1213820C500E3C3C3 /* TransferTransactionDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransferTransactionDomainDTO.swift; sourceTree = ""; }; - 0A5E4BC2213820C500E3C3C3 /* ExchangeTransactionDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExchangeTransactionDomainDTO.swift; sourceTree = ""; }; - 0A5E4BC3213820C500E3C3C3 /* ReissueTransactionDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReissueTransactionDomainDTO.swift; sourceTree = ""; }; - 0A5E4BC4213820C500E3C3C3 /* BurnTransactionDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BurnTransactionDomainDTO.swift; sourceTree = ""; }; - 0A5E4BC5213820C500E3C3C3 /* LeaseTransactionDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LeaseTransactionDomainDTO.swift; sourceTree = ""; }; - 0A5E4BC6213820C500E3C3C3 /* AnyTransactionDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnyTransactionDomainDTO.swift; sourceTree = ""; }; - 0A5E4BC7213820C500E3C3C3 /* AliasTransactionDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AliasTransactionDomainDTO.swift; sourceTree = ""; }; - 0A5E4BD82138297000E3C3C3 /* TransactionsRepositoryRemote.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionsRepositoryRemote.swift; sourceTree = ""; }; - 0A5E4BDA21382C2200E3C3C3 /* IssueTransaction+Mapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "IssueTransaction+Mapper.swift"; sourceTree = ""; }; - 0A5E4BDC2138311C00E3C3C3 /* TransferTransaction+Mapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TransferTransaction+Mapper.swift"; sourceTree = ""; }; - 0A5E4BDE213832A000E3C3C3 /* ReissueTransaction+Mapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ReissueTransaction+Mapper.swift"; sourceTree = ""; }; - 0A5E4BE02138378500E3C3C3 /* LeaseCancelTransaction+Mapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LeaseCancelTransaction+Mapper.swift"; sourceTree = ""; }; - 0A5E4BE22138395200E3C3C3 /* AliasTransaction+Mapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AliasTransaction+Mapper.swift"; sourceTree = ""; }; - 0A5E4BE421383B3600E3C3C3 /* MassTransferTransaction+Mapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MassTransferTransaction+Mapper.swift"; sourceTree = ""; }; - 0A5E4BE621383E1600E3C3C3 /* BurnTransaction+Mapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BurnTransaction+Mapper.swift"; sourceTree = ""; }; - 0A5E4BE821383F3D00E3C3C3 /* ExchangeTransaction+Mapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ExchangeTransaction+Mapper.swift"; sourceTree = ""; }; - 0A5EC393213ED90F00659350 /* TransactionsInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionsInteractor.swift; sourceTree = ""; }; 0A5F953E2185FAD4005308AC /* AliasWithoutViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AliasWithoutViewController.swift; sourceTree = ""; }; 0A61B599214ACFD500EC60FC /* Languages.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = Languages.json; sourceTree = ""; }; 0A6AC3D821839F4E005D2525 /* AddressesKeysValueCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddressesKeysValueCell.swift; sourceTree = ""; }; 0A6AC3DD2183CEFF005D2525 /* AddressesKeysSkeletonCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressesKeysSkeletonCell.swift; sourceTree = ""; }; 0A6AC3DF21847F8D005D2525 /* AddressesKeysModuleBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressesKeysModuleBuilder.swift; sourceTree = ""; }; - 0A6AC3E321848920005D2525 /* AliasesRepositoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AliasesRepositoryProtocol.swift; sourceTree = ""; }; - 0A6AC3E7218489F5005D2525 /* AliasDomainDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AliasDomainDTO.swift; sourceTree = ""; }; - 0A6CCD3A20F4CE250023E36E /* Asset+Mapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Asset+Mapper.swift"; sourceTree = ""; }; - 0A6CCD3C20F4CF490023E36E /* AccountBalanceInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountBalanceInteractor.swift; sourceTree = ""; }; - 0A751D3122170EF60024D523 /* NotificationNewsRepositoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationNewsRepositoryProtocol.swift; sourceTree = ""; }; - 0A751D3322170F3D0024D523 /* NotificationNewsDomainDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationNewsDomainDTO.swift; sourceTree = ""; }; - 0A751D35221711380024D523 /* NotificationNewsRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationNewsRepository.swift; sourceTree = ""; }; 0A751D37221715F80024D523 /* AppNewsCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppNewsCoordinator.swift; sourceTree = ""; }; - 0A751D3922171ABA0024D523 /* Kingfisher+Rx.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Kingfisher+Rx.swift"; sourceTree = ""; }; 0A762D10214FDFA100BE9204 /* NewAccountAvatarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewAccountAvatarView.swift; sourceTree = ""; }; 0A762D12214FE23E00BE9204 /* NewAccountAvatarView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = NewAccountAvatarView.xib; sourceTree = ""; }; 0A762D14214FE3F300BE9204 /* InputTextField.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = InputTextField.xib; sourceTree = ""; }; 0A762D16214FF1CD00BE9204 /* InputTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputTextField.swift; sourceTree = ""; }; 0A762D9621639FCC0019D447 /* WavesButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WavesButton.swift; sourceTree = ""; }; 0A762D9F2163AD0F0019D447 /* Support.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Support.storyboard; sourceTree = ""; }; - 0A762DA12163AD1A0019D447 /* SupportViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SupportViewController.swift; sourceTree = ""; }; 0A762DA921661AC40019D447 /* ProfileModuleBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileModuleBuilder.swift; sourceTree = ""; }; 0A762DAB21661B000019D447 /* ProfilePresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfilePresenter.swift; sourceTree = ""; }; - 0A7643F9211874F400B633E1 /* FactoryInteractorsProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FactoryInteractorsProtocol.swift; sourceTree = ""; }; - 0A7643FB211876DF00B633E1 /* FactoryRepositoriesProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FactoryRepositoriesProtocol.swift; sourceTree = ""; }; - 0A7643FD21187DF500B633E1 /* FactoryInteractors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FactoryInteractors.swift; sourceTree = ""; }; - 0A7643FF21187E3A00B633E1 /* FactoryRepositories.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FactoryRepositories.swift; sourceTree = ""; }; 0A7BFD4D21CCEA8000B29654 /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/InfoPlist.strings"; sourceTree = ""; }; 0A7BFD4E21CCEA8100B29654 /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/Waves.strings"; sourceTree = ""; }; 0A7CCDA1218A138D005D372B /* MyAddressPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MyAddressPresenter.swift; sourceTree = ""; }; @@ -1172,18 +1341,7 @@ 0A7CCDAA218A138D005D372B /* MyAddressAliacesCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MyAddressAliacesCell.swift; sourceTree = ""; }; 0A7CCDAB218A138D005D372B /* MyAddressInfoAddressCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MyAddressInfoAddressCell.swift; sourceTree = ""; }; 0A7CCDB6218A17A9005D372B /* MyAddress.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = MyAddress.storyboard; sourceTree = ""; }; - 0A7E0CD020F2AF6C0010CA6C /* BaseTargetType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseTargetType.swift; sourceTree = ""; }; - 0A7E0CD820F2BCFF0010CA6C /* TransactionsApiService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionsApiService.swift; sourceTree = ""; }; - 0A84F00021F4BBA000C0B7DB /* AddressRepositoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressRepositoryProtocol.swift; sourceTree = ""; }; - 0A84F00221F4C68000C0B7DB /* TransactionFeeRulesGitHub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionFeeRulesGitHub.swift; sourceTree = ""; }; 0A88CBFD2177FE130083874C /* ChangePasswordTypes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChangePasswordTypes.swift; sourceTree = ""; }; - 0A88CC01217D217D0083874C /* SpamCSV+Assisstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SpamCSV+Assisstants.swift"; sourceTree = ""; }; - 0A88CC03217D27370083874C /* AccountSettingsRepositoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountSettingsRepositoryProtocol.swift; sourceTree = ""; }; - 0A88CC05217D27DF0083874C /* AccountSettingsDomainDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountSettingsDomainDTO.swift; sourceTree = ""; }; - 0A88CC07217D281F0083874C /* AccountEnvironmentRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountEnvironmentRepository.swift; sourceTree = ""; }; - 0A88CC09217E80040083874C /* WalletRealmFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletRealmFactory.swift; sourceTree = ""; }; - 0A8AFF272101F37200D0582B /* MatcherServiceTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatcherServiceTypes.swift; sourceTree = ""; }; - 0A8AFF292101F47F00D0582B /* OrderBookMatcherService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderBookMatcherService.swift; sourceTree = ""; }; 0A93FED220FCAADC0058179E /* WalletTypes+DTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WalletTypes+DTO.swift"; sourceTree = ""; }; 0A96F1CB2151B392005E148F /* Passcode.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Passcode.storyboard; sourceTree = ""; }; 0A96F1CD2151B699005E148F /* PasscodeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasscodeViewController.swift; sourceTree = ""; }; @@ -1198,8 +1356,6 @@ 0A97975B210888B600407F67 /* Localizable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Localizable.swift; sourceTree = ""; }; 0A97975F2108A11A00407F67 /* Wallet.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Wallet.storyboard; sourceTree = ""; }; 0A9797642108B18C00407F67 /* WalletModuleOutput.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletModuleOutput.swift; sourceTree = ""; }; - 0A98D1492138910600550FE0 /* DataTransaction+Mapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DataTransaction+Mapper.swift"; sourceTree = ""; }; - 0A98D14B2138A30700550FE0 /* AnyTransaction+Mapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AnyTransaction+Mapper.swift"; sourceTree = ""; }; 0A9CA14C21C16B4A003C0A1B /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/InfoPlist.strings; sourceTree = ""; }; 0A9CA14D21C16B4A003C0A1B /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Waves.strings; sourceTree = ""; }; 0A9CA15021C16E6F003C0A1B /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/InfoPlist.strings"; sourceTree = ""; }; @@ -1211,10 +1367,7 @@ 0AAB15C421655BEC00F1F7BC /* ProfileBackupPhraseCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileBackupPhraseCell.swift; sourceTree = ""; }; 0AAB15C621655C0600F1F7BC /* ProfileDisabledButtomTableCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileDisabledButtomTableCell.swift; sourceTree = ""; }; 0AAB15C821655C1800F1F7BC /* ProfileValueCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileValueCell.swift; sourceTree = ""; }; - 0AAC2810221438B200D8A404 /* UIImageView+Rx.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImageView+Rx.swift"; sourceTree = ""; }; 0AAC28122215C4C700D8A404 /* SendFeeHeaderView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SendFeeHeaderView.xib; sourceTree = ""; }; - 0AAC2A452146C65900F6EB27 /* BlockRepositoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockRepositoryProtocol.swift; sourceTree = ""; }; - 0AAC2A472146C69600F6EB27 /* BlockRepositoryRemote.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockRepositoryRemote.swift; sourceTree = ""; }; 0AACD59821A59E7000B30815 /* SweetSnackbar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SweetSnackbar.swift; sourceTree = ""; }; 0AACD59921A59E7000B30815 /* SweetSnackView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SweetSnackView.swift; sourceTree = ""; }; 0AACD59A21A59E7100B30815 /* SweetSnackView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SweetSnackView.xib; sourceTree = ""; }; @@ -1223,83 +1376,18 @@ 0AACD5A421A5C18300B30815 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; 0AACD5A521A5C18300B30815 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Waves.strings; sourceTree = ""; }; 0AACD5AA21A6CAC800B30815 /* SweetSnackBack+Factory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SweetSnackBack+Factory.swift"; sourceTree = ""; }; - 0AADFD0521F9F4AB001F5C0A /* AppSpector-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "AppSpector-Info.plist"; sourceTree = ""; }; 0AB63C2B2170EBF00056B17E /* Language.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Language.storyboard; sourceTree = ""; }; - 0ABD1BE521469CE70027A7A2 /* AddressInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressInteractor.swift; sourceTree = ""; }; - 0ABD1BE721469D2F0027A7A2 /* AddressDomainDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressDomainDTO.swift; sourceTree = ""; }; - 0ABD1BE92146BEED0027A7A2 /* BlocksNodeService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlocksNodeService.swift; sourceTree = ""; }; - 0ABD1BEB2146BFEE0027A7A2 /* BlockNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockNode.swift; sourceTree = ""; }; 0AC1251121A758BC00357C93 /* LongInfoPageView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LongInfoPageView.swift; sourceTree = ""; }; - 0AC33AEF21A826B700B66747 /* NetworkError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkError.swift; sourceTree = ""; }; 0ACC0232217E2BA1000E3EE0 /* DynamicHeaderTableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DynamicHeaderTableView.swift; sourceTree = ""; }; 0AD6323F217633C20047D467 /* ChangePasswordModuleBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChangePasswordModuleBuilder.swift; sourceTree = ""; }; - 0AD83600217A0D25004413E9 /* GitHubService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GitHubService.swift; sourceTree = ""; }; - 0AD83605217A1C14004413E9 /* AccountEnvironment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountEnvironment.swift; sourceTree = ""; }; - 0AD83607217A1C26004413E9 /* AccountSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountSettings.swift; sourceTree = ""; }; - 0AD8360D217DD34B004413E9 /* AccountSettings+Mapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AccountSettings+Mapper.swift"; sourceTree = ""; }; 0AD83611217DDD94004413E9 /* NetworkSettingsTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkSettingsTypes.swift; sourceTree = ""; }; 0AD83613217DDDAC004413E9 /* NetworkSettingsPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkSettingsPresenter.swift; sourceTree = ""; }; 0AD83615217DE071004413E9 /* NetworkSettingsModuleBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkSettingsModuleBuilder.swift; sourceTree = ""; }; - 0ADC179D2204A23000472130 /* ModalRootView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalRootView.swift; sourceTree = ""; }; - 0ADC179F2204A24C00472130 /* ModalScrollViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalScrollViewController.swift; sourceTree = ""; }; - 0ADC17A12204A34100472130 /* ModalTableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalTableView.swift; sourceTree = ""; }; 0ADD6C802167948400B06917 /* ProfileHeaderView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ProfileHeaderView.xib; sourceTree = ""; }; 0ADD6C812167948400B06917 /* ProfileHeaderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProfileHeaderView.swift; sourceTree = ""; }; 0ADD6C86216796DB00B06917 /* ProfileLanguageCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileLanguageCell.swift; sourceTree = ""; }; 0ADD6C882167980E00B06917 /* ProfileBiometricCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileBiometricCell.swift; sourceTree = ""; }; - 0ADD7F1F21F22FB60075FC59 /* CALayer+Shadow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CALayer+Shadow.swift"; sourceTree = ""; }; - 0ADD7F2021F22FB60075FC59 /* ControlEvent+ScrollView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ControlEvent+ScrollView.swift"; sourceTree = ""; }; - 0ADD7F2121F22FB60075FC59 /* UIButton+WithoutAnimation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIButton+WithoutAnimation.swift"; sourceTree = ""; }; - 0ADD7F2221F22FB60075FC59 /* UIScrollView+Pagination.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIScrollView+Pagination.swift"; sourceTree = ""; }; - 0ADD7F2421F22FB60075FC59 /* UIFeedbackGenerator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIFeedbackGenerator.swift; sourceTree = ""; }; - 0ADD7F2521F22FB60075FC59 /* UIColor+Asset.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIColor+Asset.swift"; sourceTree = ""; }; - 0ADD7F2621F22FB60075FC59 /* UIColor+Hex.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIColor+Hex.swift"; sourceTree = ""; }; - 0ADD7F2721F22FB60075FC59 /* UIView+Additionals.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Additionals.swift"; sourceTree = ""; }; - 0ADD7F2821F22FB60075FC59 /* UITableView+HeaderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UITableView+HeaderView.swift"; sourceTree = ""; }; - 0ADD7F2921F22FB60075FC59 /* UITableView+Animation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UITableView+Animation.swift"; sourceTree = ""; }; - 0ADD7F2A21F22FB60075FC59 /* UIFont+Additions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIFont+Additions.swift"; sourceTree = ""; }; - 0ADD7F2B21F22FB60075FC59 /* UIApplication+OpenURL.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIApplication+OpenURL.swift"; sourceTree = ""; }; - 0ADD7F2C21F22FB60075FC59 /* UIViewController+Additionals.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+Additionals.swift"; sourceTree = ""; }; - 0ADD7F2D21F22FB60075FC59 /* UIResponder+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIResponder+Rx.swift"; sourceTree = ""; }; - 0ADD7F2F21F22FB60075FC59 /* UIViewController+Alert.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+Alert.swift"; sourceTree = ""; }; - 0ADD7F3021F22FB60075FC59 /* RateApp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RateApp.swift; sourceTree = ""; }; - 0ADD7F3121F22FB60075FC59 /* UIColor+Colors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIColor+Colors.swift"; sourceTree = ""; }; - 0ADD7F3221F22FB60075FC59 /* ControlEvent+Signal.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ControlEvent+Signal.swift"; sourceTree = ""; }; - 0ADD7F3321F22FB60075FC59 /* Notifications.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Notifications.swift; sourceTree = ""; }; - 0ADD7F3421F22FB60075FC59 /* UIView+SafeArea.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+SafeArea.swift"; sourceTree = ""; }; - 0ADD7F3521F22FB60075FC59 /* UINavigationController+Additionals.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UINavigationController+Additionals.swift"; sourceTree = ""; }; - 0ADD7F3621F22FB60075FC59 /* UIView+TouchInset.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+TouchInset.swift"; sourceTree = ""; }; - 0ADD7F3721F22FB60075FC59 /* ActivityIndicator+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ActivityIndicator+Rx.swift"; sourceTree = ""; }; - 0ADD7F3821F22FB60075FC59 /* UIImage+Color.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Color.swift"; sourceTree = ""; }; - 0ADD7F3921F22FB60075FC59 /* UIViewController+SafeArea.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+SafeArea.swift"; sourceTree = ""; }; 0ADD7F3B21F22FB60075FC59 /* PasteboardButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasteboardButton.swift; sourceTree = ""; }; - 0ADD7F3C21F22FB60075FC59 /* UIViewController+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+Rx.swift"; sourceTree = ""; }; - 0ADD7F3D21F22FB60075FC59 /* QRCodeReader+Factory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "QRCodeReader+Factory.swift"; sourceTree = ""; }; - 0ADD7F3E21F22FB60075FC59 /* UIView+Passtrough.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Passtrough.swift"; sourceTree = ""; }; - 0ADD7F3F21F22FB60075FC59 /* MailCompose+Support.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "MailCompose+Support.swift"; sourceTree = ""; }; - 0ADD7F4021F22FB60075FC59 /* UIView+Shadow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Shadow.swift"; sourceTree = ""; }; - 0ADD7F4121F22FB60075FC59 /* UIScrollView+ContentInset.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIScrollView+ContentInset.swift"; sourceTree = ""; }; - 0ADD7F4221F22FB60075FC59 /* CALayer+RoundingCorners.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CALayer+RoundingCorners.swift"; sourceTree = ""; }; - 0ADD7F4321F22FB60075FC59 /* TimingFunction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimingFunction.swift; sourceTree = ""; }; - 0ADD7F4421F22FB60075FC59 /* UIView+Animation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Animation.swift"; sourceTree = ""; }; - 0ADD7F4A21F22FB60075FC59 /* UIAlertController+Factory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIAlertController+Factory.swift"; sourceTree = ""; }; - 0ADD7F4B21F22FB60075FC59 /* CGFloat+Min.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CGFloat+Min.swift"; sourceTree = ""; }; - 0ADD7F5021F22FB60075FC59 /* NSAttributedString+Styles.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSAttributedString+Styles.swift"; sourceTree = ""; }; - 0ADD7F5B21F22FB60075FC59 /* DisplayError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DisplayError.swift; sourceTree = ""; }; - 0ADD7F6121F22FB60075FC59 /* GlobalConstants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GlobalConstants.swift; sourceTree = ""; }; - 0ADD7F6521F22FB60075FC59 /* AssetLogo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssetLogo.swift; sourceTree = ""; }; - 0ADD7F7F21F22FB60075FC59 /* UITableView+Skeleton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UITableView+Skeleton.swift"; sourceTree = ""; }; - 0ADD7F8021F22FB60075FC59 /* SkeletonAnimatable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SkeletonAnimatable.swift; sourceTree = ""; }; - 0ADD7F8221F22FB60075FC59 /* ModuleBuilderOutput.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ModuleBuilderOutput.swift; sourceTree = ""; }; - 0ADD7F8321F22FB60075FC59 /* ModuleBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ModuleBuilder.swift; sourceTree = ""; }; - 0ADD7F8421F22FB60075FC59 /* ViewConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewConfiguration.swift; sourceTree = ""; }; - 0ADD7F8621F22FB60075FC59 /* ViewCalculate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewCalculate.swift; sourceTree = ""; }; - 0ADD7F8721F22FB60075FC59 /* SectionDisplayCollection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SectionDisplayCollection.swift; sourceTree = ""; }; - 0ADD7F8921F22FB60075FC59 /* UICollectionView+Reusable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UICollectionView+Reusable.swift"; sourceTree = ""; }; - 0ADD7F8A21F22FB60075FC59 /* Reusable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Reusable.swift; sourceTree = ""; }; - 0ADD7F8B21F22FB60075FC59 /* UITableView+Reusable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UITableView+Reusable.swift"; sourceTree = ""; }; - 0ADD7F8C21F22FB60075FC59 /* NibLoadable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NibLoadable.swift; sourceTree = ""; }; - 0ADD7F8D21F22FB60075FC59 /* NibOwnerLoadable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NibOwnerLoadable.swift; sourceTree = ""; }; 0ADD7FF821F22FFA0075FC59 /* DexCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DexCoordinator.swift; sourceTree = ""; }; 0ADD7FFA21F22FFA0075FC59 /* PresentationCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PresentationCoordinator.swift; sourceTree = ""; }; 0ADD7FFB21F22FFA0075FC59 /* RoutingCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoutingCoordinator.swift; sourceTree = ""; }; @@ -1329,38 +1417,14 @@ 0ADD801A21F22FFA0075FC59 /* BackupCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BackupCoordinator.swift; sourceTree = ""; }; 0ADD801B21F22FFA0075FC59 /* BackupTostCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BackupTostCoordinator.swift; sourceTree = ""; }; 0ADD801C21F22FFA0075FC59 /* MainTabBarCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainTabBarCoordinator.swift; sourceTree = ""; }; - 0ADD803B21F5B60D0075FC59 /* AddressScriptInfoNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressScriptInfoNode.swift; sourceTree = ""; }; - 0ADD803D21F5B7090075FC59 /* AssetDetailNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetDetailNode.swift; sourceTree = ""; }; - 0ADD803F21F5D2DD0075FC59 /* AddressRepositoryRemote.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressRepositoryRemote.swift; sourceTree = ""; }; - 0ADD804121F71FD90075FC59 /* ScriptTransactionNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScriptTransactionNode.swift; sourceTree = ""; }; - 0ADD804321F72B2C0075FC59 /* AssetScriptTransactionNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetScriptTransactionNode.swift; sourceTree = ""; }; - 0ADD804721F73C280075FC59 /* AssetScriptTransactionDomainDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetScriptTransactionDomainDTO.swift; sourceTree = ""; }; - 0ADD804921F73C360075FC59 /* ScriptTransactionDomainDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScriptTransactionDomainDTO.swift; sourceTree = ""; }; 0AE491F12107A51A009223DB /* WalletTypes+State.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "WalletTypes+State.swift"; sourceTree = ""; }; 0AE491F22107A51A009223DB /* WalletTypes+ViewModels.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "WalletTypes+ViewModels.swift"; sourceTree = ""; }; 0AE491F52107A529009223DB /* WalletInteractorProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletInteractorProtocol.swift; sourceTree = ""; }; 0AE491F72107A52D009223DB /* WalletPresenterProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletPresenterProtocol.swift; sourceTree = ""; }; 0AE491F92107A531009223DB /* WalletInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletInteractor.swift; sourceTree = ""; }; - 0AE6572E2106340A003D2DB8 /* Signature.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Signature.swift; sourceTree = ""; }; - 0AE657302106368F003D2DB8 /* BalanceMatcherService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BalanceMatcherService.swift; sourceTree = ""; }; - 0AE657332106375D003D2DB8 /* TimestampSignature.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimestampSignature.swift; sourceTree = ""; }; - 0AEB358B2115DB3C00EDD63C /* AssetsRepositoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetsRepositoryProtocol.swift; sourceTree = ""; }; - 0AEB358E2115DFF500EDD63C /* AssetDomainDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetDomainDTO.swift; sourceTree = ""; }; - 0AEB35902115E44300EDD63C /* AssetsRepositoryLocal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetsRepositoryLocal.swift; sourceTree = ""; }; - 0AEB35932115E45500EDD63C /* AssetsRepositoryRemote.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetsRepositoryRemote.swift; sourceTree = ""; }; - 0AEB359F21165CBF00EDD63C /* AssetBalanceDomainDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetBalanceDomainDTO.swift; sourceTree = ""; }; - 0AEB35A121165D2100EDD63C /* AccountBalanceRepositoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountBalanceRepositoryProtocol.swift; sourceTree = ""; }; - 0AEB35A321165E1300EDD63C /* AccountBalanceRepositoryRemote.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountBalanceRepositoryRemote.swift; sourceTree = ""; usesTabs = 0; }; - 0AEB35A521165E1D00EDD63C /* AccountBalanceRepositoryLocal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountBalanceRepositoryLocal.swift; sourceTree = ""; }; 0AED6BB9216620F000481B42 /* ProfileTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileTypes.swift; sourceTree = ""; }; - 0AF0C67121A97C4700602197 /* AliasesInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AliasesInteractor.swift; sourceTree = ""; }; - 0AF0C67321A97D3500602197 /* AliasesRepositoryLocal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AliasesRepositoryLocal.swift; sourceTree = ""; }; - 0AF0C67621A97E1400602197 /* Alias.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Alias.swift; sourceTree = ""; }; - 0AF0C67821AA25B200602197 /* AliasesRepository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AliasesRepository.swift; sourceTree = ""; }; 0AF0C67A21AACA4F00602197 /* GlobalErrorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlobalErrorView.swift; sourceTree = ""; }; 0AF0C67C21AACB3700602197 /* GlobalErrorView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = GlobalErrorView.xib; sourceTree = ""; }; - 0AF2536221B0351A00B8F7DF /* AssetsBalanceSettingsInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetsBalanceSettingsInteractor.swift; sourceTree = ""; }; - 0AF2536421B6C2F900B8F7DF /* AssetsBalanceSettingsRepositoryLocal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AssetsBalanceSettingsRepositoryLocal.swift; path = Assets/AssetsBalanceSettingsRepositoryLocal.swift; sourceTree = ""; }; 0AF58F8F2191BC9300C8A4B3 /* PasscodePresenterProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasscodePresenterProtocol.swift; sourceTree = ""; }; 0AF58F932191C1D300C8A4B3 /* PasscodeRegistationPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasscodeRegistationPresenter.swift; sourceTree = ""; }; 0AF58F952191C95A00C8A4B3 /* PasscodeLogInPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasscodeLogInPresenter.swift; sourceTree = ""; }; @@ -1368,7 +1432,6 @@ 0AF58F9A2191D6D000C8A4B3 /* PasscodeChangePasscodeByPasswordPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasscodeChangePasscodeByPasswordPresenter.swift; sourceTree = ""; }; 0AF58F9C2191DEA300C8A4B3 /* PasscodeEnableBiometricPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasscodeEnableBiometricPresenter.swift; sourceTree = ""; }; 0AF58F9E2192056300C8A4B3 /* PasscodeChangePasswordPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasscodeChangePasswordPresenter.swift; sourceTree = ""; }; - 0AF58FA021931AD400C8A4B3 /* WalletEncryption.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletEncryption.swift; sourceTree = ""; }; 0AF6AD24218A54840004F107 /* CopyableImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CopyableImageView.swift; sourceTree = ""; }; 0AF921C1212E07B2003BA067 /* AssetDetailPresenterProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssetDetailPresenterProtocol.swift; sourceTree = ""; }; 0AF921C4212E07B2003BA067 /* Asset.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Asset.storyboard; sourceTree = ""; }; @@ -1434,11 +1497,6 @@ 0AF92304212E142A003BA067 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Waves.strings; sourceTree = ""; }; 0AFA0C742174A2300003FE3B /* BrowserViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BrowserViewController.swift; sourceTree = ""; }; 0AFB593F2209AD56001F0DD8 /* TestViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestViewController.swift; sourceTree = ""; }; - 0AFB59412209B2BD001F0DD8 /* SponsorshipTransactionNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SponsorshipTransactionNode.swift; sourceTree = ""; }; - 0AFB59432209B5F3001F0DD8 /* SponsorshipTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SponsorshipTransaction.swift; sourceTree = ""; }; - 0AFB59452209C20E001F0DD8 /* SponsorshipTransaction+Mapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SponsorshipTransaction+Mapper.swift"; sourceTree = ""; }; - 0AFB59472209C2F8001F0DD8 /* SponsorshipTransactionDomainDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SponsorshipTransactionDomainDTO.swift; sourceTree = ""; }; - 0AFB59492209F167001F0DD8 /* Sentry-io-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Sentry-io-Info.plist"; sourceTree = ""; }; 0AFBCA7F211306F600285BCB /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; 0AFBCA862113188A00285BCB /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 0AFBCA872113188B00285BCB /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; @@ -1449,13 +1507,63 @@ 0AFF5C7E215BD08E00B82940 /* AccountPasswordInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountPasswordInteractor.swift; sourceTree = ""; }; 0AFF5C80215BD09500B82940 /* AccountPasswordPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountPasswordPresenter.swift; sourceTree = ""; }; 0AFF5C8C215CE2D000B82940 /* UseTouchIDModuleBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UseTouchIDModuleBuilder.swift; sourceTree = ""; }; - 2A5A5CDBE4190D8A1A1C4124 /* Pods-WavesWallet-iOS.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WavesWallet-iOS.test.xcconfig"; path = "Pods/Target Support Files/Pods-WavesWallet-iOS/Pods-WavesWallet-iOS.test.xcconfig"; sourceTree = ""; }; - 2F182E1185D069FB9F0228C7 /* Pods_MonkeyTest.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MonkeyTest.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 3780CE9B95DA4BD90D83FC04 /* Pods-WavesWallet-iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WavesWallet-iOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-WavesWallet-iOS/Pods-WavesWallet-iOS.release.xcconfig"; sourceTree = ""; }; - 39E7B5DDD0BC308CCE651F05 /* Pods-MonkeyTest.test-adhoc.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MonkeyTest.test-adhoc.xcconfig"; path = "Pods/Target Support Files/Pods-MonkeyTest/Pods-MonkeyTest.test-adhoc.xcconfig"; sourceTree = ""; }; - 621D6D45B8A2773F670A4883 /* Pods-WavesWallet-iOS.adhoc.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WavesWallet-iOS.adhoc.xcconfig"; path = "Pods/Target Support Files/Pods-WavesWallet-iOS/Pods-WavesWallet-iOS.adhoc.xcconfig"; sourceTree = ""; }; + 0F5A04DF94D5267FF54BF4A9 /* Pods-MonkeyTest.test-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MonkeyTest.test-prod.xcconfig"; path = "Target Support Files/Pods-MonkeyTest/Pods-MonkeyTest.test-prod.xcconfig"; sourceTree = ""; }; + 14D96B733AE3D2EDCB81A40F /* Pods-DataLayerTests.dev-adhoc.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DataLayerTests.dev-adhoc.xcconfig"; path = "Target Support Files/Pods-DataLayerTests/Pods-DataLayerTests.dev-adhoc.xcconfig"; sourceTree = ""; }; + 15AE893AD1EB53FBCDA161D5 /* Pods-Extensions.release-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Extensions.release-prod.xcconfig"; path = "Target Support Files/Pods-Extensions/Pods-Extensions.release-prod.xcconfig"; sourceTree = ""; }; + 16E2A809803D77F7ACA94D8C /* Pods-WavesWallet-iOS.dev-debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WavesWallet-iOS.dev-debug.xcconfig"; path = "Target Support Files/Pods-WavesWallet-iOS/Pods-WavesWallet-iOS.dev-debug.xcconfig"; sourceTree = ""; }; + 1CCD1A311B65E78F9D8E3AFB /* Pods_DomainLayerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_DomainLayerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 1E821BB79863BE6E2DFD41B1 /* Pods-MarketPulseWidget.release-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MarketPulseWidget.release-dev.xcconfig"; path = "Target Support Files/Pods-MarketPulseWidget/Pods-MarketPulseWidget.release-dev.xcconfig"; sourceTree = ""; }; + 20735B3922DF223C5F8F7C79 /* Pods_MarketPulseWidget.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MarketPulseWidget.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 30B16B6ED15D84C95E9C0700 /* Pods-DataLayer.release-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DataLayer.release-dev.xcconfig"; path = "Target Support Files/Pods-DataLayer/Pods-DataLayer.release-dev.xcconfig"; sourceTree = ""; }; + 32D0AB8E233A565D00E6C26A /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/WavesMarketPulse.strings; sourceTree = ""; }; + 330A6CFEA80C3C564AC3C090 /* Pods-Extensions.dev-debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Extensions.dev-debug.xcconfig"; path = "Target Support Files/Pods-Extensions/Pods-Extensions.dev-debug.xcconfig"; sourceTree = ""; }; + 344A99254C39E6D45BA6BFEE /* Pods-WavesWallet-iOS.release-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WavesWallet-iOS.release-prod.xcconfig"; path = "Target Support Files/Pods-WavesWallet-iOS/Pods-WavesWallet-iOS.release-prod.xcconfig"; sourceTree = ""; }; + 358F7A355EB990FE9BE8A2BE /* Pods-DomainLayer.dev-adhoc.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DomainLayer.dev-adhoc.xcconfig"; path = "Target Support Files/Pods-DomainLayer/Pods-DomainLayer.dev-adhoc.xcconfig"; sourceTree = ""; }; + 39D072CCF146C6CC2C64586F /* Pods-MarketPulseWidget.dev-debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MarketPulseWidget.dev-debug.xcconfig"; path = "Target Support Files/Pods-MarketPulseWidget/Pods-MarketPulseWidget.dev-debug.xcconfig"; sourceTree = ""; }; + 4002342AE27E8283A7330127 /* Pods-DataLayer.dev-adhoc.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DataLayer.dev-adhoc.xcconfig"; path = "Target Support Files/Pods-DataLayer/Pods-DataLayer.dev-adhoc.xcconfig"; sourceTree = ""; }; + 41C4770FECD0D0B762C47A43 /* Pods_DomainLayer.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_DomainLayer.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 42540834023E32A59FAD0948 /* Pods-MonkeyTest.release-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MonkeyTest.release-prod.xcconfig"; path = "Target Support Files/Pods-MonkeyTest/Pods-MonkeyTest.release-prod.xcconfig"; sourceTree = ""; }; + 42BA6C1489543A7B9FBD6970 /* Pods-WavesWallet-iOS.test-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WavesWallet-iOS.test-prod.xcconfig"; path = "Target Support Files/Pods-WavesWallet-iOS/Pods-WavesWallet-iOS.test-prod.xcconfig"; sourceTree = ""; }; + 45AA58BA32AC1AF6D19F9EEF /* Pods-DomainLayer.dev-debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DomainLayer.dev-debug.xcconfig"; path = "Target Support Files/Pods-DomainLayer/Pods-DomainLayer.dev-debug.xcconfig"; sourceTree = ""; }; + 4A5FEAF1E09BD85095F7190B /* Pods-MarketPulseWidget.test-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MarketPulseWidget.test-prod.xcconfig"; path = "Target Support Files/Pods-MarketPulseWidget/Pods-MarketPulseWidget.test-prod.xcconfig"; sourceTree = ""; }; + 4F48C7630D481FB8B18C7CDD /* Pods_Extensions.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Extensions.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 5B93090B2CB93A36B3FC8D0F /* Pods-Extensions.test-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Extensions.test-prod.xcconfig"; path = "Target Support Files/Pods-Extensions/Pods-Extensions.test-prod.xcconfig"; sourceTree = ""; }; + 5BB158FA7ECE6E5227A7AF0B /* Pods_DataLayer.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_DataLayer.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 5E9E95698304826A9178CFEB /* Pods-WavesWallet-iOS.test-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WavesWallet-iOS.test-dev.xcconfig"; path = "Target Support Files/Pods-WavesWallet-iOS/Pods-WavesWallet-iOS.test-dev.xcconfig"; sourceTree = ""; }; + 5F1A2C7157881DA75A52C4BA /* Pods_DataLayerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_DataLayerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 613D35B159856DDD30F86C98 /* Pods-DomainLayer.test-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DomainLayer.test-dev.xcconfig"; path = "Target Support Files/Pods-DomainLayer/Pods-DomainLayer.test-dev.xcconfig"; sourceTree = ""; }; + 660956FE76B04B363AEC458B /* Pods_MonkeyTest.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MonkeyTest.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 664726FDDF58367CA0C7AEFA /* Pods-MonkeyTest.test-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MonkeyTest.test-dev.xcconfig"; path = "Target Support Files/Pods-MonkeyTest/Pods-MonkeyTest.test-dev.xcconfig"; sourceTree = ""; }; + 79716E63B228F54DC963B57A /* Pods-DomainLayer.release-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DomainLayer.release-prod.xcconfig"; path = "Target Support Files/Pods-DomainLayer/Pods-DomainLayer.release-prod.xcconfig"; sourceTree = ""; }; + 7A79F97385011A8CE0363A70 /* Pods-WavesWallet-iOS.release-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WavesWallet-iOS.release-dev.xcconfig"; path = "Target Support Files/Pods-WavesWallet-iOS/Pods-WavesWallet-iOS.release-dev.xcconfig"; sourceTree = ""; }; + 7AE17C6CE90449256074E98F /* Pods-MonkeyTest.dev-debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MonkeyTest.dev-debug.xcconfig"; path = "Target Support Files/Pods-MonkeyTest/Pods-MonkeyTest.dev-debug.xcconfig"; sourceTree = ""; }; + 7B0FD984231952740004B52B /* ConfirmRequestLoadingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfirmRequestLoadingViewController.swift; sourceTree = ""; }; + 7B0FD98623195D6A0004B52B /* ConfirmRequestCompleteViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfirmRequestCompleteViewController.swift; sourceTree = ""; }; + 7B0FD98823196A3F0004B52B /* ConfirmRequestDTOTransaction+Mapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ConfirmRequestDTOTransaction+Mapper.swift"; sourceTree = ""; }; + 7B0FD98A23196C430004B52B /* ConfirmRequestDTORequest+Mapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ConfirmRequestDTORequest+Mapper.swift"; sourceTree = ""; }; + 7B0FD98E2319C0EA0004B52B /* MobileKeeperRepositoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MobileKeeperRepositoryProtocol.swift; sourceTree = ""; }; + 7B2407FF2317F26100D35F59 /* ConfirmRequestButtonsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfirmRequestButtonsCell.swift; sourceTree = ""; }; + 7B26A87C22ED129300E7B024 /* WidgetSettings.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = WidgetSettings.storyboard; sourceTree = ""; }; + 7B26A87E22ED13F300E7B024 /* WidgetSettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetSettingsViewController.swift; sourceTree = ""; }; + 7B26A88022ED140000E7B024 /* WidgetSettingsType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetSettingsType.swift; sourceTree = ""; }; + 7B26A88222ED14DA00E7B024 /* WidgetSettingsSystem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetSettingsSystem.swift; sourceTree = ""; }; + 7B26A88922ED180A00E7B024 /* UIDeveloperCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIDeveloperCoordinator.swift; sourceTree = ""; }; + 7B26A88B22ED191900E7B024 /* WidgetSettingsModuleBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetSettingsModuleBuilder.swift; sourceTree = ""; }; + 7B26A88D22EEEA7000E7B024 /* WidgetSettingsModuleOutput.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetSettingsModuleOutput.swift; sourceTree = ""; }; + 7B26A88F22EEECC200E7B024 /* WidgetSettingsAssetCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetSettingsAssetCell.swift; sourceTree = ""; }; 7B32A903229EEFB0004789E7 /* fr-FR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "fr-FR"; path = "fr-FR.lproj/InfoPlist.strings"; sourceTree = ""; }; 7B32A904229EEFB1004789E7 /* fr-FR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "fr-FR"; path = "fr-FR.lproj/Waves.strings"; sourceTree = ""; }; + 7B3681972314260C000D5592 /* ConfirmRequestViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfirmRequestViewController.swift; sourceTree = ""; }; + 7B36819923142625000D5592 /* ConfirmRequestType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfirmRequestType.swift; sourceTree = ""; }; + 7B36819C23142639000D5592 /* ConfirmRequestSystem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfirmRequestSystem.swift; sourceTree = ""; }; + 7B36819E23142A0F000D5592 /* ConfirmRequestModuleBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfirmRequestModuleBuilder.swift; sourceTree = ""; }; + 7B3681A023142A33000D5592 /* ConfirmRequestModuleOutput.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfirmRequestModuleOutput.swift; sourceTree = ""; }; + 7B3681A62315534E000D5592 /* ConfirmRequestTransactionKindCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfirmRequestTransactionKindCell.swift; sourceTree = ""; }; + 7B3681A823155499000D5592 /* ConfirmRequestFromToCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfirmRequestFromToCell.swift; sourceTree = ""; }; + 7B3681AA231555B8000D5592 /* ConfirmRequestKeyValueCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfirmRequestKeyValueCell.swift; sourceTree = ""; }; + 7B3681AC231556B4000D5592 /* ConfirmRequestFeeAndTimestampCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfirmRequestFeeAndTimestampCell.swift; sourceTree = ""; }; + 7B3681AE23155805000D5592 /* ConfirmRequestBalanceCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfirmRequestBalanceCell.swift; sourceTree = ""; }; + 7B3681B02315612C000D5592 /* ConfirmRequestSkeletonCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfirmRequestSkeletonCell.swift; sourceTree = ""; }; 7B39029422366B8E00AAFDB8 /* TransactionCardAddressCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionCardAddressCell.swift; sourceTree = ""; }; 7B39029622366D0100AAFDB8 /* AddressBookButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressBookButton.swift; sourceTree = ""; }; 7B390298223698D300AAFDB8 /* TransactionCardKeyValueCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionCardKeyValueCell.swift; sourceTree = ""; }; @@ -1471,6 +1579,29 @@ 7B3902AC2237D31900AAFDB8 /* TransactionCardShowAllCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionCardShowAllCell.swift; sourceTree = ""; }; 7B3902AF2237D8FA00AAFDB8 /* TransactionCardExchangeCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionCardExchangeCell.swift; sourceTree = ""; }; 7B3A51A7223AA08F00C3BF38 /* TransactionCardAssetCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionCardAssetCell.swift; sourceTree = ""; }; + 7B3A9AB3231BE3900025CDCA /* MobileKeeperRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MobileKeeperRepository.swift; sourceTree = ""; }; + 7B3A9AB5231D66B80025CDCA /* NetworkError+Title.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NetworkError+Title.swift"; sourceTree = ""; }; + 7B431A7C22BCFE8A00DE73B9 /* AssetsUseCaseProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetsUseCaseProtocol.swift; sourceTree = ""; }; + 7B431A7F22BCFF5700DE73B9 /* AssetsBalanceSettingsUseCaseProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetsBalanceSettingsUseCaseProtocol.swift; sourceTree = ""; }; + 7B431A8222BCFFA900DE73B9 /* TransactionsUseCaseProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionsUseCaseProtocol.swift; sourceTree = ""; }; + 7B431A8422BD02E700DE73B9 /* AddressUseCaseProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressUseCaseProtocol.swift; sourceTree = ""; }; + 7B431A8C22BD176D00DE73B9 /* DomainLayerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DomainLayerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 7B431A8E22BD176D00DE73B9 /* DomainLayerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomainLayerTests.swift; sourceTree = ""; }; + 7B431A9022BD176D00DE73B9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 7B431A9C22BD185A00DE73B9 /* DataLayerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DataLayerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 7B431A9E22BD185B00DE73B9 /* DataLayerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataLayerTests.swift; sourceTree = ""; }; + 7B431AA022BD185B00DE73B9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 7B48F35E2330F7BF00923E9E /* environment_stagenet.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = environment_stagenet.json; sourceTree = ""; }; + 7B49911622F874B0005B7123 /* AssetsSearchViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetsSearchViewController.swift; sourceTree = ""; }; + 7B49911922F874DD005B7123 /* AssetsSearchAssetCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetsSearchAssetCell.swift; sourceTree = ""; }; + 7B49911B22F8754A005B7123 /* AssetsSearch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetsSearch.swift; sourceTree = ""; }; + 7B49911D22F875A1005B7123 /* AssetsSearchViewBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetsSearchViewBuilder.swift; sourceTree = ""; }; + 7B49911F22F875D4005B7123 /* AssetsSearch.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = AssetsSearch.storyboard; sourceTree = ""; }; + 7B49912122F876AA005B7123 /* AssetsSearchHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetsSearchHeaderView.swift; sourceTree = ""; }; + 7B49912522F876E1005B7123 /* AssetsSearchHeaderView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AssetsSearchHeaderView.xib; sourceTree = ""; }; + 7B49912722F87C7A005B7123 /* AssetsSearchSystem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetsSearchSystem.swift; sourceTree = ""; }; + 7B49912B22F99B76005B7123 /* AssetsSearchEmptyCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetsSearchEmptyCell.swift; sourceTree = ""; }; + 7B49912D22F9B470005B7123 /* AssetsSearchModuleOutput.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetsSearchModuleOutput.swift; sourceTree = ""; }; 7B5E7464223907AA00746ADD /* TransactionCardHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionCardHeaderView.swift; sourceTree = ""; }; 7B5E74662239088800746ADD /* TransactionCardHeaderView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TransactionCardHeaderView.xib; sourceTree = ""; }; 7B5E746822390B8200746ADD /* TransactionCardBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionCardBuilder.swift; sourceTree = ""; }; @@ -1478,39 +1609,242 @@ 7B5EDEC122522837009C2B3B /* TransactionCardSystemOrder+Mapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TransactionCardSystemOrder+Mapper.swift"; sourceTree = ""; }; 7B5EDEC32253618C009C2B3B /* AccessibilityIdentifiers.strings */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; path = AccessibilityIdentifiers.strings; sourceTree = ""; }; 7B5EDEC522536268009C2B3B /* AccessibilityIdentifiers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccessibilityIdentifiers.swift; sourceTree = ""; }; - 7B601B292240C4B80040975C /* SmartTransactionDTO+EncodingToString.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SmartTransactionDTO+EncodingToString.swift"; sourceTree = ""; }; + 7B5FAA0522BBE3EB00621A44 /* UseCasesFactoryProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UseCasesFactoryProtocol.swift; sourceTree = ""; }; + 7B5FAA0622BBE3EB00621A44 /* RepositoriesFactoryProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RepositoriesFactoryProtocol.swift; sourceTree = ""; }; + 7B5FAA0822BBE3EB00621A44 /* TransactionDomainDTO+Mapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "TransactionDomainDTO+Mapper.swift"; sourceTree = ""; }; + 7B5FAA0922BBE3EB00621A44 /* Asset+Assistants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Asset+Assistants.swift"; sourceTree = ""; }; + 7B5FAA0B22BBE3EB00621A44 /* DomainDexQueries.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DomainDexQueries.swift; sourceTree = ""; }; + 7B5FAA0D22BBE3EB00621A44 /* WalletsRepositoryProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletsRepositoryProtocol.swift; sourceTree = ""; }; + 7B5FAA0E22BBE3EB00621A44 /* AccountSettingsRepositoryProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountSettingsRepositoryProtocol.swift; sourceTree = ""; }; + 7B5FAA0F22BBE3EB00621A44 /* CoinomatRepositoryProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoinomatRepositoryProtocol.swift; sourceTree = ""; }; + 7B5FAA1022BBE3EB00621A44 /* AddressRepositoryProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddressRepositoryProtocol.swift; sourceTree = ""; }; + 7B5FAA1122BBE3EB00621A44 /* AssetsBalanceSettingsRepositoryProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssetsBalanceSettingsRepositoryProtocol.swift; sourceTree = ""; }; + 7B5FAA1222BBE3EB00621A44 /* MatcherRepositoryProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MatcherRepositoryProtocol.swift; sourceTree = ""; }; + 7B5FAA1322BBE3EB00621A44 /* DexRealmRepositoryProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DexRealmRepositoryProtocol.swift; sourceTree = ""; }; + 7B5FAA1422BBE3EB00621A44 /* NotificationNewsRepositoryProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationNewsRepositoryProtocol.swift; sourceTree = ""; }; + 7B5FAA1522BBE3EB00621A44 /* ApplicationVersionRepositoryProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApplicationVersionRepositoryProtocol.swift; sourceTree = ""; }; + 7B5FAA1622BBE3EB00621A44 /* DexPairsPriceRepositoryProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DexPairsPriceRepositoryProtocol.swift; sourceTree = ""; }; + 7B5FAA1722BBE3EB00621A44 /* AddressBookRepositoryProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddressBookRepositoryProtocol.swift; sourceTree = ""; }; + 7B5FAA1822BBE3EB00621A44 /* WalletSeedRepositoryProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletSeedRepositoryProtocol.swift; sourceTree = ""; }; + 7B5FAA1922BBE3EB00621A44 /* CandlesRepositoryProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CandlesRepositoryProtocol.swift; sourceTree = ""; }; + 7B5FAA1A22BBE3EB00621A44 /* TransactionsRepositoryProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionsRepositoryProtocol.swift; sourceTree = ""; }; + 7B5FAA1B22BBE3EB00621A44 /* LastTradesRepositoryProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LastTradesRepositoryProtocol.swift; sourceTree = ""; }; + 7B5FAA1C22BBE3EB00621A44 /* AssetsRepositoryProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssetsRepositoryProtocol.swift; sourceTree = ""; }; + 7B5FAA1D22BBE3EB00621A44 /* BlockRepositoryProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlockRepositoryProtocol.swift; sourceTree = ""; }; + 7B5FAA1E22BBE3EB00621A44 /* AliasesRepositoryProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AliasesRepositoryProtocol.swift; sourceTree = ""; }; + 7B5FAA1F22BBE3EB00621A44 /* AccountBalanceRepositoryProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountBalanceRepositoryProtocol.swift; sourceTree = ""; }; + 7B5FAA2022BBE3EB00621A44 /* DexOrderBookRepositoryProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DexOrderBookRepositoryProtocol.swift; sourceTree = ""; }; + 7B5FAA2122BBE3EB00621A44 /* AuthenticationRepositoryProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthenticationRepositoryProtocol.swift; sourceTree = ""; }; + 7B5FAA2222BBE3EB00621A44 /* EnvironmentRepositoryProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnvironmentRepositoryProtocol.swift; sourceTree = ""; }; + 7B5FAA2322BBE3EB00621A44 /* UtilsRepositoryProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UtilsRepositoryProtocol.swift; sourceTree = ""; }; + 7B5FAA2422BBE3EB00621A44 /* DomainLayerTypes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DomainLayerTypes.swift; sourceTree = ""; }; + 7B5FAA2722BBE3EC00621A44 /* AccountEnvironmentDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountEnvironmentDomainDTO.swift; sourceTree = ""; }; + 7B5FAA2822BBE3EC00621A44 /* CandleDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CandleDomainDTO.swift; sourceTree = ""; }; + 7B5FAA2922BBE3EC00621A44 /* AssetBalanceDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssetBalanceDomainDTO.swift; sourceTree = ""; }; + 7B5FAA2A22BBE3EC00621A44 /* DexDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DexDomainDTO.swift; sourceTree = ""; }; + 7B5FAA2B22BBE3EC00621A44 /* WalletDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletDomainDTO.swift; sourceTree = ""; }; + 7B5FAA2C22BBE3EC00621A44 /* AliasDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AliasDomainDTO.swift; sourceTree = ""; }; + 7B5FAA2E22BBE3EC00621A44 /* SponsorshipTransactionDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SponsorshipTransactionDomainDTO.swift; sourceTree = ""; }; + 7B5FAA2F22BBE3EC00621A44 /* AddressDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddressDomainDTO.swift; sourceTree = ""; }; + 7B5FAA3022BBE3EC00621A44 /* InvokeScriptTransactionDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InvokeScriptTransactionDomainDTO.swift; sourceTree = ""; }; + 7B5FAA3122BBE3EC00621A44 /* DataTransactionDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataTransactionDomainDTO.swift; sourceTree = ""; }; + 7B5FAA3222BBE3EC00621A44 /* AssetScriptTransactionDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssetScriptTransactionDomainDTO.swift; sourceTree = ""; }; + 7B5FAA3322BBE3EC00621A44 /* SmartTransactionDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SmartTransactionDomainDTO.swift; sourceTree = ""; }; + 7B5FAA3422BBE3EC00621A44 /* LeaseCancelTransactionDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LeaseCancelTransactionDomainDTO.swift; sourceTree = ""; }; + 7B5FAA3522BBE3EC00621A44 /* MassTransferTransactionDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MassTransferTransactionDomainDTO.swift; sourceTree = ""; }; + 7B5FAA3622BBE3EC00621A44 /* ScriptTransactionDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScriptTransactionDomainDTO.swift; sourceTree = ""; }; + 7B5FAA3722BBE3EC00621A44 /* AnyTransactionDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnyTransactionDomainDTO.swift; sourceTree = ""; }; + 7B5FAA3822BBE3EC00621A44 /* UnrecognisedTransactionDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnrecognisedTransactionDomainDTO.swift; sourceTree = ""; }; + 7B5FAA3922BBE3EC00621A44 /* IssueTransactionDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IssueTransactionDomainDTO.swift; sourceTree = ""; }; + 7B5FAA3A22BBE3EC00621A44 /* TransferTransactionDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransferTransactionDomainDTO.swift; sourceTree = ""; }; + 7B5FAA3B22BBE3EC00621A44 /* ExchangeTransactionDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExchangeTransactionDomainDTO.swift; sourceTree = ""; }; + 7B5FAA3C22BBE3EC00621A44 /* ReissueTransactionDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReissueTransactionDomainDTO.swift; sourceTree = ""; }; + 7B5FAA3D22BBE3EC00621A44 /* BurnTransactionDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BurnTransactionDomainDTO.swift; sourceTree = ""; }; + 7B5FAA3E22BBE3EC00621A44 /* LeaseTransactionDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LeaseTransactionDomainDTO.swift; sourceTree = ""; }; + 7B5FAA3F22BBE3EC00621A44 /* AliasTransactionDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AliasTransactionDomainDTO.swift; sourceTree = ""; }; + 7B5FAA4022BBE3EC00621A44 /* NotificationNewsDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationNewsDomainDTO.swift; sourceTree = ""; }; + 7B5FAA4122BBE3EC00621A44 /* AssetDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssetDomainDTO.swift; sourceTree = ""; }; + 7B5FAA4222BBE3EC00621A44 /* CoinomatDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoinomatDomainDTO.swift; sourceTree = ""; }; + 7B5FAA4322BBE3EC00621A44 /* ContactDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContactDomainDTO.swift; sourceTree = ""; }; + 7B5FAA4422BBE3EC00621A44 /* AccountSettingsDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountSettingsDomainDTO.swift; sourceTree = ""; }; + 7B5FAA4522BBE3EC00621A44 /* ResponseType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ResponseType.swift; sourceTree = ""; }; + 7B5FAA4622BBE3EC00621A44 /* WalletEnvironment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletEnvironment.swift; sourceTree = ""; }; + 7B5FAA4722BBE3EC00621A44 /* UseCasesFactory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UseCasesFactory.swift; sourceTree = ""; }; + 7B5FAA4A22BBE3EC00621A44 /* AnalyticManagerProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnalyticManagerProtocol.swift; sourceTree = ""; }; + 7B5FAA4B22BBE3EC00621A44 /* AnalyticAssetManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnalyticAssetManager.swift; sourceTree = ""; }; + 7B5FAA4E22BBE3EC00621A44 /* AnalyticManager+Dex.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AnalyticManager+Dex.swift"; sourceTree = ""; }; + 7B5FAA5022BBE3EC00621A44 /* AccountBalanceUseCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountBalanceUseCase.swift; sourceTree = ""; }; + 7B5FAA5122BBE3EC00621A44 /* AuthorizationUseCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthorizationUseCase.swift; sourceTree = ""; }; + 7B5FAA5222BBE3EC00621A44 /* AuthorizationUseCaseProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthorizationUseCaseProtocol.swift; sourceTree = ""; }; + 7B5FAA5322BBE3EC00621A44 /* AliasesUseCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AliasesUseCase.swift; sourceTree = ""; }; + 7B5FAA5422BBE3EC00621A44 /* MigrationUseCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MigrationUseCase.swift; sourceTree = ""; }; + 7B5FAA5522BBE3EC00621A44 /* AddressUseCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddressUseCase.swift; sourceTree = ""; }; + 7B5FAA5622BBE3EC00621A44 /* AssetsUseCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssetsUseCase.swift; sourceTree = ""; }; + 7B5FAA5722BBE3EC00621A44 /* ApplicationVersionUseCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApplicationVersionUseCase.swift; sourceTree = ""; }; + 7B5FAA5822BBE3EC00621A44 /* TransactionsUseCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionsUseCase.swift; sourceTree = ""; }; + 7B5FAA5922BBE3EC00621A44 /* AssetsBalanceSettingsUseCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssetsBalanceSettingsUseCase.swift; sourceTree = ""; }; + 7B5FAA5B22BBE3EC00621A44 /* ApplicationDebugSettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApplicationDebugSettings.swift; sourceTree = ""; }; + 7B5FAA5C22BBE3EC00621A44 /* CleanerWalletManagerBanner.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CleanerWalletManagerBanner.swift; sourceTree = ""; }; + 7B5FAA5D22BBE3EC00621A44 /* SmartTransactionDomain+Assistants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SmartTransactionDomain+Assistants.swift"; sourceTree = ""; }; + 7B5FAA5E22BBE3EC00621A44 /* CleanerWalletManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CleanerWalletManager.swift; sourceTree = ""; }; + 7B5FAA5F22BBE3EC00621A44 /* SigningWalletsProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SigningWalletsProtocol.swift; sourceTree = ""; }; + 7B5FAA6122BBE3EC00621A44 /* WordList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WordList.swift; sourceTree = ""; }; + 7B5FAA6222BBE3EC00621A44 /* Hash.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Hash.swift; sourceTree = ""; }; + 7B5FAA6322BBE3EC00621A44 /* Address.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Address.swift; sourceTree = ""; }; + 7B5FAA6422BBE3EC00621A44 /* PublicKeyAccount.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PublicKeyAccount.swift; sourceTree = ""; }; + 7B5FAA6522BBE3EC00621A44 /* PrivateKeyAccount.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PrivateKeyAccount.swift; sourceTree = ""; }; + 7B5FAA6622BBE3EC00621A44 /* RXCrypto+SHA.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "RXCrypto+SHA.swift"; sourceTree = ""; }; + 7B5FAA6722BBE3EC00621A44 /* Data+AES.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Data+AES.swift"; sourceTree = ""; }; + 7B5FAA6822BBE3EC00621A44 /* BiometricManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BiometricManager.swift; sourceTree = ""; }; + 7B5FAAC922BCE71400621A44 /* AccountBalanceUseCaseProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountBalanceUseCaseProtocol.swift; sourceTree = ""; }; + 7B5FAACB22BCE8D800621A44 /* AliasesUseCaseProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AliasesUseCaseProtocol.swift; sourceTree = ""; }; + 7B5FAACD22BCE98F00621A44 /* MigrationUseCaseProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrationUseCaseProtocol.swift; sourceTree = ""; }; + 7B60E2BB2316CBEA00113C38 /* ConfirmRequestTransactionKindView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfirmRequestTransactionKindView.swift; sourceTree = ""; }; + 7B60E2BD2316CC0400113C38 /* ConfirmRequestTransactionKindView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ConfirmRequestTransactionKindView.xib; sourceTree = ""; }; + 7B65B6F222F9D03E007D5C53 /* WidgetSettingsSkeletonCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetSettingsSkeletonCell.swift; sourceTree = ""; }; + 7B65B6F422F9D63D007D5C53 /* KeyboardControl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyboardControl.swift; sourceTree = ""; }; + 7B65B6F622F9D647007D5C53 /* KeyboardControl.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = KeyboardControl.xib; sourceTree = ""; }; + 7B66860022B3F70D0029E6F1 /* DomainLayer.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DomainLayer.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7B66860222B3F70E0029E6F1 /* DomainLayer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DomainLayer.h; sourceTree = ""; }; + 7B66860322B3F70E0029E6F1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 7B6686EE22B7C5120029E6F1 /* Extensions.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Extensions.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7B6686F022B7C5120029E6F1 /* Extensions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Extensions.h; sourceTree = ""; }; + 7B6686F122B7C5120029E6F1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 7B66872322B7E68B0029E6F1 /* DataLayer.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DataLayer.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7B66872522B7E68B0029E6F1 /* DataLayer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DataLayer.h; sourceTree = ""; }; + 7B66872622B7E68B0029E6F1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 7B6922C5223BA1730056DA67 /* TransactionCardSystemTransaction+Mapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TransactionCardSystemTransaction+Mapper.swift"; sourceTree = ""; }; + 7B7422E3237ACC9D00E5910D /* WavesWallet-iOS-Dev.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "WavesWallet-iOS-Dev.entitlements"; sourceTree = ""; }; + 7B7422E4237ACC9D00E5910D /* WavesWallet-iOS-Test.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "WavesWallet-iOS-Test.entitlements"; sourceTree = ""; }; + 7B7A4B7B22D6258C00E0A8CD /* DexCreateOrderInvalidPriceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DexCreateOrderInvalidPriceView.swift; sourceTree = ""; }; + 7B7A4B7D22D625B300E0A8CD /* DexCreateOrderInvalidPriceView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DexCreateOrderInvalidPriceView.xib; sourceTree = ""; }; + 7B83A7D022D8C74E0038180D /* DummyForTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DummyForTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 7B83A7D222D8C74F0038180D /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7B83A7D422D8C74F0038180D /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 7B83A7D722D8C74F0038180D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 7B83A7D922D8C7500038180D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 7B83A7DC22D8C7500038180D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 7B83A7DE22D8C7500038180D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 7B83A7E822D8D72F0038180D /* Extensions.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Extensions.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7B848A52230075920092AD18 /* Sentry-io-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Sentry-io-Info.plist"; sourceTree = ""; }; + 7B848A53230075920092AD18 /* Appsflyer-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Appsflyer-Info.plist"; sourceTree = ""; }; + 7B848A54230075920092AD18 /* AppSpector-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "AppSpector-Info.plist"; sourceTree = ""; }; + 7B848A55230075920092AD18 /* environment_testnet.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = environment_testnet.json; sourceTree = ""; }; + 7B848A56230075920092AD18 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; + 7B848A57230075920092AD18 /* Fabric-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Fabric-Info.plist"; sourceTree = ""; }; + 7B848A58230075920092AD18 /* Amplitude-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Amplitude-Info.plist"; sourceTree = ""; }; + 7B848A59230075920092AD18 /* environment_mainnet.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = environment_mainnet.json; sourceTree = ""; }; + 7B848A5A230075920092AD18 /* spam.csv */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = spam.csv; sourceTree = ""; }; + 7B848A68230076AE0092AD18 /* Localizable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Localizable.swift; sourceTree = ""; }; + 7B848A6A230077540092AD18 /* Images.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Images.swift; sourceTree = ""; }; + 7B848A6C2301784B0092AD18 /* WidgetSettingsUseCaseProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetSettingsUseCaseProtocol.swift; sourceTree = ""; }; + 7B848A6E230178B70092AD18 /* WidgetSettingsUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetSettingsUseCase.swift; sourceTree = ""; }; + 7B848A7023018C0E0092AD18 /* WidgetSettingsInizializationUseCaseProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetSettingsInizializationUseCaseProtocol.swift; sourceTree = ""; }; + 7B848A732301AD0D0092AD18 /* WalletsRealmFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletsRealmFactory.swift; sourceTree = ""; }; + 7B848A792301C0950092AD18 /* WidgetSettingsInizializationUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetSettingsInizializationUseCase.swift; sourceTree = ""; }; + 7B848A7B2301C95A0092AD18 /* PairsPathUseCaseProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PairsPathUseCaseProtocol.swift; sourceTree = ""; }; + 7B848A7D2301CB0F0092AD18 /* CorrectionPairsUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CorrectionPairsUseCase.swift; sourceTree = ""; }; + 7B848A922304073B0092AD18 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/WavesMarketPulse.strings; sourceTree = ""; }; + 7B848A932304073B0092AD18 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/WavesMarketPulse.strings; sourceTree = ""; }; + 7B848A942304073B0092AD18 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/WavesMarketPulse.strings; sourceTree = ""; }; + 7B848A952304073B0092AD18 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/WavesMarketPulse.strings; sourceTree = ""; }; + 7B848A962304073B0092AD18 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/WavesMarketPulse.strings; sourceTree = ""; }; + 7B848A972304073B0092AD18 /* fr-FR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "fr-FR"; path = "fr-FR.lproj/WavesMarketPulse.strings"; sourceTree = ""; }; + 7B848A982304073B0092AD18 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/WavesMarketPulse.strings; sourceTree = ""; }; + 7B848A992304073B0092AD18 /* hi-IN */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "hi-IN"; path = "hi-IN.lproj/WavesMarketPulse.strings"; sourceTree = ""; }; + 7B848A9A2304073B0092AD18 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/WavesMarketPulse.strings; sourceTree = ""; }; + 7B848A9B2304073B0092AD18 /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/WavesMarketPulse.strings"; sourceTree = ""; }; + 7B848A9C2304073B0092AD18 /* nl-NL */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "nl-NL"; path = "nl-NL.lproj/WavesMarketPulse.strings"; sourceTree = ""; }; + 7B848A9D2304073B0092AD18 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/WavesMarketPulse.strings; sourceTree = ""; }; + 7B848A9E2304073B0092AD18 /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = id; path = id.lproj/WavesMarketPulse.strings; sourceTree = ""; }; + 7B848A9F2304073B0092AD18 /* zh-Hans-CN */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans-CN"; path = "zh-Hans-CN.lproj/WavesMarketPulse.strings"; sourceTree = ""; }; + 7B848AA02304073B0092AD18 /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/WavesMarketPulse.strings"; sourceTree = ""; }; + 7B88186123044B7F00AB0549 /* Language+List.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Language+List.swift"; sourceTree = ""; }; + 7B88186323044FCC00AB0549 /* Languages.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = Languages.json; sourceTree = ""; }; + 7B8818662305639600AB0549 /* ActionSheetViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetViewController.swift; sourceTree = ""; }; + 7B8818672305639600AB0549 /* ActionSheet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheet.swift; sourceTree = ""; }; + 7B8818692305639600AB0549 /* ActionSheetElementCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetElementCell.swift; sourceTree = ""; }; + 7B88186A2305639600AB0549 /* ActionSheetHeaderView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ActionSheetHeaderView.xib; sourceTree = ""; }; + 7B88186B2305639600AB0549 /* ActionSheetHeaderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetHeaderView.swift; sourceTree = ""; }; + 7B88186C2305639600AB0549 /* ActionSheetViewBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetViewBuilder.swift; sourceTree = ""; }; + 7B88186D2305639600AB0549 /* ActionSheet.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = ActionSheet.storyboard; sourceTree = ""; }; + 7B881875230590BB00AB0549 /* DeepLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepLink.swift; sourceTree = ""; }; + 7B8818772305926E00AB0549 /* WidgetSettingsCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WidgetSettingsCoordinator.swift; sourceTree = ""; }; 7B95110E225CC2CF0030390C /* nl-NL */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "nl-NL"; path = "nl-NL.lproj/InfoPlist.strings"; sourceTree = ""; }; 7B95110F225CC2CF0030390C /* nl-NL */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "nl-NL"; path = "nl-NL.lproj/Waves.strings"; sourceTree = ""; }; 7B951110225CC2E60030390C /* hi-IN */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "hi-IN"; path = "hi-IN.lproj/InfoPlist.strings"; sourceTree = ""; }; 7B951111225CC2E60030390C /* hi-IN */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "hi-IN"; path = "hi-IN.lproj/Waves.strings"; sourceTree = ""; }; 7B951112225CC32B0030390C /* zh-Hans-CN */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans-CN"; path = "zh-Hans-CN.lproj/InfoPlist.strings"; sourceTree = ""; }; 7B951113225CC32C0030390C /* zh-Hans-CN */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans-CN"; path = "zh-Hans-CN.lproj/Waves.strings"; sourceTree = ""; }; - 7B951115225CD55F0030390C /* Mutating.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Mutating.swift; sourceTree = ""; }; - 7B951117225CD5850030390C /* DatabaseReference+Rx.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DatabaseReference+Rx.swift"; sourceTree = ""; }; - 7B951119225CD5B70030390C /* BiometricType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BiometricType.swift; sourceTree = ""; }; - 7B95111B225CD5EE0030390C /* Results+Limit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Results+Limit.swift"; sourceTree = ""; }; - 7B95111D225CD6140030390C /* RunLoopThreadScheduler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunLoopThreadScheduler.swift; sourceTree = ""; }; - 7B951120225CD6790030390C /* Language.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Language.swift; sourceTree = ""; }; - 7B951122225CD6AD0030390C /* SentryNetworkLoggerPlugin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryNetworkLoggerPlugin.swift; sourceTree = ""; }; - 7B951124225CD6D80030390C /* SweetLoggerSentry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SweetLoggerSentry.swift; sourceTree = ""; }; - 7B951126225CD7160030390C /* QRCodeParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCodeParser.swift; sourceTree = ""; }; - 7B951128225CD7350030390C /* AppSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppSettings.swift; sourceTree = ""; }; - 7B95112A225CDA860030390C /* Balance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Balance.swift; sourceTree = ""; }; - 7B95112B225CDA870030390C /* Money.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Money.swift; sourceTree = ""; }; - 7B95112C225CDA870030390C /* MoneyUtil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoneyUtil.swift; sourceTree = ""; }; - 7B95112D225CDA880030390C /* Sync.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Sync.swift; sourceTree = ""; }; - 7B951132225CDA9F0030390C /* Decimal+Assisstants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Decimal+Assisstants.swift"; sourceTree = ""; }; - 7B951134225CDAA80030390C /* CGSize+Hashable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CGSize+Hashable.swift"; sourceTree = ""; }; - 7B951136225CF7A00030390C /* Reachability+Shared.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Reachability+Shared.swift"; sourceTree = ""; }; - 7B95115E225F7BA80030390C /* DateFormatter+UI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DateFormatter+UI.swift"; sourceTree = ""; }; - 7BAA9F7A22A032DE003B6D01 /* ApplicationVersionUseCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApplicationVersionUseCase.swift; sourceTree = ""; }; - 7BAA9F7C22A03329003B6D01 /* ApplicationVersionRepository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApplicationVersionRepository.swift; sourceTree = ""; }; - 7BAA9F7E22A03361003B6D01 /* ApplicationVersionRepositoryProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApplicationVersionRepositoryProtocol.swift; sourceTree = ""; }; - 7BBDA0B52226CA5C00A83411 /* NodePlugin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodePlugin.swift; sourceTree = ""; }; + 7B97B03822FC784F008BA3F4 /* CALayer+Shadow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CALayer+Shadow.swift"; sourceTree = ""; }; + 7B97B03922FC784F008BA3F4 /* ControlEvent+ScrollView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ControlEvent+ScrollView.swift"; sourceTree = ""; }; + 7B97B03A22FC784F008BA3F4 /* CGFloat+Min.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CGFloat+Min.swift"; sourceTree = ""; }; + 7B97B03B22FC784F008BA3F4 /* UIButton+WithoutAnimation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIButton+WithoutAnimation.swift"; sourceTree = ""; }; + 7B97B03C22FC784F008BA3F4 /* UIImageView+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImageView+Rx.swift"; sourceTree = ""; }; + 7B97B03D22FC784F008BA3F4 /* UIScrollView+Pagination.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIScrollView+Pagination.swift"; sourceTree = ""; }; + 7B97B03E22FC784F008BA3F4 /* UIFeedbackGenerator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIFeedbackGenerator.swift; sourceTree = ""; }; + 7B97B03F22FC784F008BA3F4 /* UIColor+Asset.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIColor+Asset.swift"; sourceTree = ""; }; + 7B97B04022FC784F008BA3F4 /* UIColor+Hex.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIColor+Hex.swift"; sourceTree = ""; }; + 7B97B04122FC784F008BA3F4 /* UIView+Additionals.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Additionals.swift"; sourceTree = ""; }; + 7B97B04222FC784F008BA3F4 /* UITableView+HeaderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UITableView+HeaderView.swift"; sourceTree = ""; }; + 7B97B04322FC784F008BA3F4 /* UITableView+Animation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UITableView+Animation.swift"; sourceTree = ""; }; + 7B97B04422FC784F008BA3F4 /* UIFont+Additions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIFont+Additions.swift"; sourceTree = ""; }; + 7B97B04522FC784F008BA3F4 /* String+Size.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+Size.swift"; sourceTree = ""; }; + 7B97B04622FC784F008BA3F4 /* UIApplication+OpenURL.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIApplication+OpenURL.swift"; sourceTree = ""; }; + 7B97B04722FC784F008BA3F4 /* UIViewController+Additionals.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+Additionals.swift"; sourceTree = ""; }; + 7B97B04822FC784F008BA3F4 /* UIColor+Colors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIColor+Colors.swift"; sourceTree = ""; }; + 7B97B04A22FC784F008BA3F4 /* UIView+SafeArea.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+SafeArea.swift"; sourceTree = ""; }; + 7B97B04B22FC784F008BA3F4 /* UINavigationController+Additionals.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UINavigationController+Additionals.swift"; sourceTree = ""; }; + 7B97B04C22FC784F008BA3F4 /* TableViewNoShadow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableViewNoShadow.swift; sourceTree = ""; }; + 7B97B04D22FC784F008BA3F4 /* UIView+TouchInset.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+TouchInset.swift"; sourceTree = ""; }; + 7B97B04F22FC784F008BA3F4 /* UIImage+Color.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Color.swift"; sourceTree = ""; }; + 7B97B05022FC784F008BA3F4 /* UIViewController+SafeArea.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+SafeArea.swift"; sourceTree = ""; }; + 7B97B05122FC784F008BA3F4 /* CGSize+Hashable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CGSize+Hashable.swift"; sourceTree = ""; }; + 7B97B05222FC784F008BA3F4 /* UIViewController+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+Rx.swift"; sourceTree = ""; }; + 7B97B05322FC784F008BA3F4 /* UIView+Passtrough.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Passtrough.swift"; sourceTree = ""; }; + 7B97B05422FC784F008BA3F4 /* DateFormatter+UI.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DateFormatter+UI.swift"; sourceTree = ""; }; + 7B97B05522FC784F008BA3F4 /* UIView+Shadow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Shadow.swift"; sourceTree = ""; }; + 7B97B05622FC784F008BA3F4 /* UIScrollView+ContentInset.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIScrollView+ContentInset.swift"; sourceTree = ""; }; + 7B97B05722FC784F008BA3F4 /* CALayer+RoundingCorners.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CALayer+RoundingCorners.swift"; sourceTree = ""; }; + 7B97B05822FC784F008BA3F4 /* TimingFunction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimingFunction.swift; sourceTree = ""; }; + 7B97B05B22FC784F008BA3F4 /* ModuleBuilderOutput.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ModuleBuilderOutput.swift; sourceTree = ""; }; + 7B97B05C22FC784F008BA3F4 /* ModuleBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ModuleBuilder.swift; sourceTree = ""; }; + 7B97B05D22FC784F008BA3F4 /* ViewConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewConfiguration.swift; sourceTree = ""; }; + 7B97B05E22FC784F008BA3F4 /* ViewCalculate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewCalculate.swift; sourceTree = ""; }; + 7B97B05F22FC784F008BA3F4 /* SectionDisplayCollection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SectionDisplayCollection.swift; sourceTree = ""; }; + 7B97B06122FC784F008BA3F4 /* UICollectionView+Reusable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UICollectionView+Reusable.swift"; sourceTree = ""; }; + 7B97B06222FC784F008BA3F4 /* Reusable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Reusable.swift; sourceTree = ""; }; + 7B97B06322FC784F008BA3F4 /* UITableView+Reusable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UITableView+Reusable.swift"; sourceTree = ""; }; + 7B97B06422FC784F008BA3F4 /* NibLoadable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NibLoadable.swift; sourceTree = ""; }; + 7B97B06522FC784F008BA3F4 /* NibOwnerLoadable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NibOwnerLoadable.swift; sourceTree = ""; }; + 7B97B06622FC784F008BA3F4 /* UIView+Animation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Animation.swift"; sourceTree = ""; }; + 7B97B06822FC784F008BA3F4 /* MoneyUtil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoneyUtil.swift; sourceTree = ""; }; + 7B97B06922FC784F008BA3F4 /* Sync.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Sync.swift; sourceTree = ""; }; + 7B97B06A22FC784F008BA3F4 /* Decimal+Assisstants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Decimal+Assisstants.swift"; sourceTree = ""; }; + 7B97B06B22FC784F008BA3F4 /* Balance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Balance.swift; sourceTree = ""; }; + 7B97B06C22FC784F008BA3F4 /* Money.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Money.swift; sourceTree = ""; }; + 7B97B06D22FC784F008BA3F4 /* TSUD+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "TSUD+Rx.swift"; sourceTree = ""; }; + 7B97B06E22FC784F008BA3F4 /* RunLoopThreadScheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RunLoopThreadScheduler.swift; sourceTree = ""; }; + 7B97B06F22FC784F008BA3F4 /* Mutating.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Mutating.swift; sourceTree = ""; }; + 7B97B07022FC784F008BA3F4 /* System.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = System.swift; sourceTree = ""; }; + 7B97B07122FC784F008BA3F4 /* Platform.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Platform.swift; sourceTree = ""; }; + 7B97B0AC22FCB2BD008BA3F4 /* Reachability+Shared.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Reachability+Shared.swift"; sourceTree = ""; }; + 7B97B0B122FCB5D9008BA3F4 /* Localizable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Localizable.swift; sourceTree = ""; }; + 7B97B0B522FCBD59008BA3F4 /* AssetLogo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssetLogo.swift; sourceTree = ""; }; + 7B97B0BB22FD92AC008BA3F4 /* AssetLogo+Styles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AssetLogo+Styles.swift"; sourceTree = ""; }; + 7B9B326022E6004700DB1C59 /* DebugRootView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugRootView.swift; sourceTree = ""; }; + 7BB03E4922EF2C84008F179D /* WidgetSettingsHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetSettingsHeaderView.swift; sourceTree = ""; }; + 7BB03E4B22EF2DAB008F179D /* WidgetSettingsHeaderView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = WidgetSettingsHeaderView.xib; sourceTree = ""; }; 7BD2313A224E55090074C3BF /* TransactionCardOrderCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionCardOrderCell.swift; sourceTree = ""; }; 7BD2FD34223C5E1F0098CFB9 /* TransactionCardCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionCardCoordinator.swift; sourceTree = ""; }; - 7BDA6AD4222D8C81001DE71C /* System.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = System.swift; sourceTree = ""; }; + 7BD6E0FD22E228DC00BAAFC8 /* DebugView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugView.swift; sourceTree = ""; }; + 7BD6E0FF22E228F000BAAFC8 /* DebugView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DebugView.xib; sourceTree = ""; }; + 7BD6E10122E50EB200BAAFC8 /* DebugViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugViewController.swift; sourceTree = ""; }; + 7BD6E10422E5AE0200BAAFC8 /* DebugHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugHeaderView.swift; sourceTree = ""; }; + 7BD6E10722E5AE7000BAAFC8 /* DebugInfoCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugInfoCell.swift; sourceTree = ""; }; + 7BD6E10922E5AEEB00BAAFC8 /* DebugHeaderView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DebugHeaderView.xib; sourceTree = ""; }; + 7BD6E10B22E5B6D700BAAFC8 /* DebugSwitchCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugSwitchCell.swift; sourceTree = ""; }; + 7BD6E10D22E5CD5E00BAAFC8 /* DebugEnviromentsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugEnviromentsCell.swift; sourceTree = ""; }; 7BDA6AD6222D8CA1001DE71C /* TransactionCardViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionCardViewController.swift; sourceTree = ""; }; 7BDA6AD8222D8D0A001DE71C /* TransactionCardSystem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionCardSystem.swift; sourceTree = ""; }; 7BDA6ADA222D8D16001DE71C /* TransactionCardType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionCardType.swift; sourceTree = ""; }; @@ -1521,26 +1855,209 @@ 7BDA6AE5223028DC001DE71C /* BalanceLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BalanceLabel.swift; sourceTree = ""; }; 7BDA6AE722313E59001DE71C /* TransactionImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionImageView.swift; sourceTree = ""; }; 7BDA6AE922313E85001DE71C /* TransactionImageView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TransactionImageView.xib; sourceTree = ""; }; - 7BDA6AEF2231405D001DE71C /* SmartTransactionKind+UIImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SmartTransactionKind+UIImage.swift"; sourceTree = ""; }; 7BDA6AF122315024001DE71C /* ContactDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactDetailView.swift; sourceTree = ""; }; 7BDA6AF322315466001DE71C /* ContactDetailView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ContactDetailView.xib; sourceTree = ""; }; 7BDA6AF522316078001DE71C /* TransactionCardMassSentRecipientCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionCardMassSentRecipientCell.swift; sourceTree = ""; }; - 7BF89E882226E00800853F9D /* SentryManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SentryManager.swift; path = Type/SentryManager.swift; sourceTree = ""; }; + 7BDC623522DC78BF0029DA37 /* WavesSDK.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = WavesSDK.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7BDC623722DC78BF0029DA37 /* WavesSDKCrypto.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = WavesSDKCrypto.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7BDC623922DC78BF0029DA37 /* WavesSDKExtensions.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = WavesSDKExtensions.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7BDC623B22DC970F0029DA37 /* WavesSDK.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = WavesSDK.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7BDC623D22DC970F0029DA37 /* WavesSDKCrypto.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = WavesSDKCrypto.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7BDC623F22DC970F0029DA37 /* WavesSDKExtensions.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = WavesSDKExtensions.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7BDC624122DC972E0029DA37 /* WavesSDK.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = WavesSDK.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7BDC624322DC972E0029DA37 /* WavesSDKCrypto.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = WavesSDKCrypto.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7BDC624522DC972E0029DA37 /* WavesSDKExtensions.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = WavesSDKExtensions.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7BDC624722DC973E0029DA37 /* WavesSDK.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = WavesSDK.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7BDC624922DC973E0029DA37 /* WavesSDKCrypto.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = WavesSDKCrypto.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7BDC624B22DC973E0029DA37 /* WavesSDKExtensions.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = WavesSDKExtensions.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7BDC624F22DCB04F0029DA37 /* WavesSDKExtensions.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = WavesSDKExtensions.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7BDC625122DCB06D0029DA37 /* RxSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = RxSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7BDC6D3D22C2522F00614E6B /* SpamAssetsRepositoryProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpamAssetsRepositoryProtocol.swift; sourceTree = ""; }; + 7BDC6D3F22C395F500614E6B /* AnalyticManagerEvent+CreateANewAccount.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AnalyticManagerEvent+CreateANewAccount.swift"; sourceTree = ""; }; + 7BDC6D4222C3964900614E6B /* AnalyticManagerEvent+ImportAccount.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AnalyticManagerEvent+ImportAccount.swift"; sourceTree = ""; }; + 7BDC6D4522C3967600614E6B /* AnalyticManagerEvent+SingIn.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AnalyticManagerEvent+SingIn.swift"; sourceTree = ""; }; + 7BDC6D4722C396A400614E6B /* AnalyticManagerEvent+Send.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AnalyticManagerEvent+Send.swift"; sourceTree = ""; }; + 7BDC6D4B22C396D200614E6B /* AnalyticManagerEvent+Receive.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AnalyticManagerEvent+Receive.swift"; sourceTree = ""; }; + 7BDC6D4E22C396F200614E6B /* AnalyticManagerEvent+WavesQuickAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AnalyticManagerEvent+WavesQuickAction.swift"; sourceTree = ""; }; + 7BDC6D5122C3970B00614E6B /* AnalyticManagerEvent+Profile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AnalyticManagerEvent+Profile.swift"; sourceTree = ""; }; + 7BDC6D5422C3973C00614E6B /* AnalyticManagerEvent+WalletHome.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AnalyticManagerEvent+WalletHome.swift"; sourceTree = ""; }; + 7BDC6D5722C3976D00614E6B /* AnalyticManagerEvent+WalletLeasing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AnalyticManagerEvent+WalletLeasing.swift"; sourceTree = ""; }; + 7BDC6D5922C3978100614E6B /* AnalyticManagerEvent+Alias.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AnalyticManagerEvent+Alias.swift"; sourceTree = ""; }; + 7BDC6D5D22C397A300614E6B /* AnalyticManagerEvent+TokenBurn.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AnalyticManagerEvent+TokenBurn.swift"; sourceTree = ""; }; + 7BDC6D6C22C398E100614E6B /* AnalyticManagerEvent+AddressBook.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AnalyticManagerEvent+AddressBook.swift"; sourceTree = ""; }; + 7BDC6D6F22C3A03400614E6B /* AnalyticManagerEvent+Menu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AnalyticManagerEvent+Menu.swift"; sourceTree = ""; }; + 7BDC6D7122C3A03E00614E6B /* AnalyticManagerEvent+Widgets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AnalyticManagerEvent+Widgets.swift"; sourceTree = ""; }; + 7BDC6D7822C3CD8400614E6B /* InputScrollButtonsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputScrollButtonsView.swift; sourceTree = ""; }; + 7BDD7F47C7597E6AD76837FD /* Pods-MarketPulseWidget.dev-adhoc.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MarketPulseWidget.dev-adhoc.xcconfig"; path = "Target Support Files/Pods-MarketPulseWidget/Pods-MarketPulseWidget.dev-adhoc.xcconfig"; sourceTree = ""; }; + 7BE09AB12313E31300A038AD /* MobileKeeperCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MobileKeeperCoordinator.swift; sourceTree = ""; }; + 7BE09AD223140F0900A038AD /* MobileKeeper.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = MobileKeeper.storyboard; sourceTree = ""; }; + 7BF509F322D8B95300582783 /* SeedItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SeedItem.swift; sourceTree = ""; }; + 7BF509F522D8B95300582783 /* WalletRealmFactory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletRealmFactory.swift; sourceTree = ""; }; + 7BF509F822D8B95300582783 /* LeaseTransaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LeaseTransaction.swift; sourceTree = ""; }; + 7BF509F922D8B95300582783 /* ScriptTransaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScriptTransaction.swift; sourceTree = ""; }; + 7BF509FA22D8B95300582783 /* IssueTransaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IssueTransaction.swift; sourceTree = ""; }; + 7BF509FB22D8B95300582783 /* AssetScriptTransaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssetScriptTransaction.swift; sourceTree = ""; }; + 7BF509FC22D8B95300582783 /* UnrecognisedTransaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnrecognisedTransaction.swift; sourceTree = ""; }; + 7BF509FD22D8B95300582783 /* SponsorshipTransaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SponsorshipTransaction.swift; sourceTree = ""; }; + 7BF509FE22D8B95300582783 /* LeaseCancelTransaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LeaseCancelTransaction.swift; sourceTree = ""; }; + 7BF509FF22D8B95300582783 /* InvokeScriptTransaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InvokeScriptTransaction.swift; sourceTree = ""; }; + 7BF50A0022D8B95300582783 /* BurnTransaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BurnTransaction.swift; sourceTree = ""; }; + 7BF50A0122D8B95300582783 /* Transaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Transaction.swift; sourceTree = ""; }; + 7BF50A0222D8B95300582783 /* TransferTransaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransferTransaction.swift; sourceTree = ""; }; + 7BF50A0322D8B95300582783 /* ExchangeTransaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExchangeTransaction.swift; sourceTree = ""; }; + 7BF50A0422D8B95300582783 /* AliasTransaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AliasTransaction.swift; sourceTree = ""; }; + 7BF50A0522D8B95300582783 /* ReissueTransaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReissueTransaction.swift; sourceTree = ""; }; + 7BF50A0622D8B95300582783 /* MassTransferTransaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MassTransferTransaction.swift; sourceTree = ""; }; + 7BF50A0722D8B95300582783 /* AnyTransaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnyTransaction.swift; sourceTree = ""; }; + 7BF50A0822D8B95300582783 /* DataTransaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataTransaction.swift; sourceTree = ""; }; + 7BF50A0922D8B95300582783 /* AddressBook.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddressBook.swift; sourceTree = ""; }; + 7BF50A0A22D8B95300582783 /* Alias.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Alias.swift; sourceTree = ""; }; + 7BF50A0B22D8B95300582783 /* AssetBalance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssetBalance.swift; sourceTree = ""; }; + 7BF50A0C22D8B95300582783 /* AssetBalanceSettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssetBalanceSettings.swift; sourceTree = ""; }; + 7BF50A0D22D8B95300582783 /* DexAssetPair.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DexAssetPair.swift; sourceTree = ""; }; + 7BF50A0E22D8B95300582783 /* Asset.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Asset.swift; sourceTree = ""; }; + 7BF50A0F22D8B95300582783 /* AccountEnvironment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountEnvironment.swift; sourceTree = ""; }; + 7BF50A1022D8B95300582783 /* AccountSettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountSettings.swift; sourceTree = ""; }; + 7BF50A1222D8B95300582783 /* WalletItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletItem.swift; sourceTree = ""; }; + 7BF50A1422D8B95300582783 /* WalletEncryption.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletEncryption.swift; sourceTree = ""; }; + 7BF50A1622D8B95300582783 /* DexAssetPairDomainDTO+Mapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DexAssetPairDomainDTO+Mapper.swift"; sourceTree = ""; }; + 7BF50A1722D8B95300582783 /* DexMyOrders+Mapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DexMyOrders+Mapper.swift"; sourceTree = ""; }; + 7BF50A1922D8B95300582783 /* AnyTransaction+Mapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AnyTransaction+Mapper.swift"; sourceTree = ""; }; + 7BF50A1A22D8B95300582783 /* ReissueTransaction+Mapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ReissueTransaction+Mapper.swift"; sourceTree = ""; }; + 7BF50A1B22D8B95300582783 /* InvokeScriptTransaction+Mapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "InvokeScriptTransaction+Mapper.swift"; sourceTree = ""; }; + 7BF50A1C22D8B95300582783 /* AssetScriptTransaction+Mapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AssetScriptTransaction+Mapper.swift"; sourceTree = ""; }; + 7BF50A1D22D8B95300582783 /* AliasTransaction+Mapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AliasTransaction+Mapper.swift"; sourceTree = ""; }; + 7BF50A1E22D8B95300582783 /* UnrecognisedTransaction+Mapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UnrecognisedTransaction+Mapper.swift"; sourceTree = ""; }; + 7BF50A1F22D8B95300582783 /* ScriptTransaction+Mapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ScriptTransaction+Mapper.swift"; sourceTree = ""; }; + 7BF50A2022D8B95300582783 /* LeaseCancelTransaction+Mapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LeaseCancelTransaction+Mapper.swift"; sourceTree = ""; }; + 7BF50A2122D8B95300582783 /* DataTransaction+Mapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DataTransaction+Mapper.swift"; sourceTree = ""; }; + 7BF50A2222D8B95300582783 /* SponsorshipTransaction+Mapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SponsorshipTransaction+Mapper.swift"; sourceTree = ""; }; + 7BF50A2322D8B95300582783 /* IssueTransaction+Mapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "IssueTransaction+Mapper.swift"; sourceTree = ""; }; + 7BF50A2422D8B95300582783 /* TransferTransaction+Mapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "TransferTransaction+Mapper.swift"; sourceTree = ""; }; + 7BF50A2522D8B95300582783 /* MassTransferTransaction+Mapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "MassTransferTransaction+Mapper.swift"; sourceTree = ""; }; + 7BF50A2622D8B95300582783 /* BurnTransaction+Mapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BurnTransaction+Mapper.swift"; sourceTree = ""; }; + 7BF50A2722D8B95300582783 /* ExchangeTransaction+Mapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ExchangeTransaction+Mapper.swift"; sourceTree = ""; }; + 7BF50A2822D8B95300582783 /* LeaseTransaction+Mapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LeaseTransaction+Mapper.swift"; sourceTree = ""; }; + 7BF50A2922D8B95300582783 /* Wallet+Mapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Wallet+Mapper.swift"; sourceTree = ""; }; + 7BF50A2A22D8B95400582783 /* AccountSettings+Mapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AccountSettings+Mapper.swift"; sourceTree = ""; }; + 7BF50A2B22D8B95400582783 /* Asset+Mapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Asset+Mapper.swift"; sourceTree = ""; }; + 7BF50A2D22D8B95400582783 /* SpamAssetsRepository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpamAssetsRepository.swift; sourceTree = ""; }; + 7BF50A2E22D8B95400582783 /* NotificationNewsRepository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationNewsRepository.swift; sourceTree = ""; }; + 7BF50A2F22D8B95400582783 /* BlockRepositoryRemote.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlockRepositoryRemote.swift; sourceTree = ""; }; + 7BF50A3022D8B95400582783 /* GatewayRepository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GatewayRepository.swift; sourceTree = ""; }; + 7BF50A3122D8B95400582783 /* ApplicationVersionRepository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApplicationVersionRepository.swift; sourceTree = ""; }; + 7BF50A3222D8B95400582783 /* AccountSettingsRepository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountSettingsRepository.swift; sourceTree = ""; }; + 7BF50A3322D8B95400582783 /* CoinomatRepository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoinomatRepository.swift; sourceTree = ""; }; + 7BF50A3422D8B95400582783 /* AuthenticationRepositoryRemote.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthenticationRepositoryRemote.swift; sourceTree = ""; }; + 7BF50A3522D8B95400582783 /* AddressRepositoryRemote.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddressRepositoryRemote.swift; sourceTree = ""; }; + 7BF50A3722D8B95400582783 /* TransactionsRepositoryRemote.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionsRepositoryRemote.swift; sourceTree = ""; }; + 7BF50A3822D8B95400582783 /* TransactionsRepositoryLocal.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionsRepositoryLocal.swift; sourceTree = ""; }; + 7BF50A3922D8B95400582783 /* RepositoriesFactory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RepositoriesFactory.swift; sourceTree = ""; }; + 7BF50A3B22D8B95400582783 /* AddressBookRepository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddressBookRepository.swift; sourceTree = ""; }; + 7BF50A3D22D8B95400582783 /* AccountBalanceRepositoryRemote.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountBalanceRepositoryRemote.swift; sourceTree = ""; }; + 7BF50A3E22D8B95400582783 /* AccountBalanceRepositoryLocal.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountBalanceRepositoryLocal.swift; sourceTree = ""; }; + 7BF50A4022D8B95400582783 /* MatcherRepositoryRemote.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MatcherRepositoryRemote.swift; sourceTree = ""; }; + 7BF50A4122D8B95400582783 /* LastTradesRepositoryRemote.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LastTradesRepositoryRemote.swift; sourceTree = ""; }; + 7BF50A4222D8B95400582783 /* DexOrderBookRepositoryRemote.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DexOrderBookRepositoryRemote.swift; sourceTree = ""; }; + 7BF50A4322D8B95400582783 /* DexRealmRepositoryLocal.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DexRealmRepositoryLocal.swift; sourceTree = ""; }; + 7BF50A4422D8B95400582783 /* CandlesRepositoryRemote.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CandlesRepositoryRemote.swift; sourceTree = ""; }; + 7BF50A4522D8B95400582783 /* DexPairsPriceRepositoryRemote.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DexPairsPriceRepositoryRemote.swift; sourceTree = ""; }; + 7BF50A4722D8B95400582783 /* WalletsRepositoryLocal.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletsRepositoryLocal.swift; sourceTree = ""; }; + 7BF50A4822D8B95400582783 /* WalletSeedRepositoryLocal.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletSeedRepositoryLocal.swift; sourceTree = ""; }; + 7BF50A4A22D8B95400582783 /* AliasesRepository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AliasesRepository.swift; sourceTree = ""; }; + 7BF50A4B22D8B95400582783 /* AliasesRepositoryLocal.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AliasesRepositoryLocal.swift; sourceTree = ""; }; + 7BF50A4D22D8B95400582783 /* AssetsBalanceSettingsRepositoryLocal.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssetsBalanceSettingsRepositoryLocal.swift; sourceTree = ""; }; + 7BF50A4E22D8B95400582783 /* AssetsRepositoryLocal.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssetsRepositoryLocal.swift; sourceTree = ""; }; + 7BF50A4F22D8B95400582783 /* AssetsRepositoryRemote.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssetsRepositoryRemote.swift; sourceTree = ""; }; + 7BF50A5022D8B95400582783 /* EnvironmentRepository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnvironmentRepository.swift; sourceTree = ""; }; + 7BF50A5322D8B95400582783 /* SpamService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpamService.swift; sourceTree = ""; }; + 7BF50A5422D8B95400582783 /* AssetsSpamService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssetsSpamService.swift; sourceTree = ""; }; + 7BF50A5622D8B95400582783 /* GitHubService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GitHubService.swift; sourceTree = ""; }; + 7BF50A5722D8B95400582783 /* TransactionFeeRulesGitHub.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionFeeRulesGitHub.swift; sourceTree = ""; }; + 7BF50A5922D8B95400582783 /* CoinomatService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoinomatService.swift; sourceTree = ""; }; + 7BF50A5B22D8B95400582783 /* GatewayService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GatewayService.swift; sourceTree = ""; }; + 7BF50A5D22D8B95400582783 /* SpamCSV+Assisstants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SpamCSV+Assisstants.swift"; sourceTree = ""; }; + 7BF50A5E22D8B95400582783 /* AnalyticManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnalyticManager.swift; sourceTree = ""; }; + 7BF50A5F22D8B95400582783 /* TransactionSenderAssistant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionSenderAssistant.swift; sourceTree = ""; }; + 7BF50A6122D8B95400582783 /* TimestampSignature.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimestampSignature.swift; sourceTree = ""; }; + 7BF50A6222D8B95400582783 /* Signature.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Signature.swift; sourceTree = ""; }; + 7BF50A6322D8B95400582783 /* Results+Limit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Results+Limit.swift"; sourceTree = ""; }; + 7BF50A6422D8B95400582783 /* NodePlugin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NodePlugin.swift; sourceTree = ""; }; + 7BF50A6522D8B95400582783 /* MoyaProvider+Helper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "MoyaProvider+Helper.swift"; sourceTree = ""; }; + 7BF50A6622D8B95400582783 /* SentryNetworkLoggerPlugin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SentryNetworkLoggerPlugin.swift; sourceTree = ""; }; + 7BF50A6722D8B95400582783 /* SentryManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SentryManager.swift; sourceTree = ""; }; + 7BF50A6822D8B95400582783 /* DatabaseReference+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DatabaseReference+Rx.swift"; sourceTree = ""; }; + 7BF50A6922D8B95400582783 /* String+NormalizeAssetId.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+NormalizeAssetId.swift"; sourceTree = ""; }; + 7BF50A6A22D8B95400582783 /* SweetLoggerSentry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SweetLoggerSentry.swift; sourceTree = ""; }; + 7BF50ACF22D8BAF300582783 /* DomainLayer.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = DomainLayer.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7BF50AD122D8BAF800582783 /* Extensions.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Extensions.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7BF50AD322D8BB0100582783 /* DataLayer.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = DataLayer.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7BF50AD522D8BB0800582783 /* Extensions.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Extensions.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7BF50AD722D8BB0C00582783 /* DomainLayer.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = DomainLayer.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 7BF89E9622272A5E00853F9D /* MonkeyTest.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MonkeyTest.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 7BF89E9822272A5E00853F9D /* MonkeyTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MonkeyTest.swift; sourceTree = ""; }; - 7BF89E9A22272A5E00853F9D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 8929E19527D7945D5DC03230 /* Pods-MonkeyTest.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MonkeyTest.release.xcconfig"; path = "Pods/Target Support Files/Pods-MonkeyTest/Pods-MonkeyTest.release.xcconfig"; sourceTree = ""; }; - 965E90884D099176A23D5038 /* Pods-WavesWallet-iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WavesWallet-iOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-WavesWallet-iOS/Pods-WavesWallet-iOS.debug.xcconfig"; sourceTree = ""; }; - A1E804B3D4295816120F6042 /* Pods-MonkeyTest.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MonkeyTest.test.xcconfig"; path = "Pods/Target Support Files/Pods-MonkeyTest/Pods-MonkeyTest.test.xcconfig"; sourceTree = ""; }; - AFB68EB998D497670C5F75E3 /* Pods-WavesWallet-iOS.test-build.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WavesWallet-iOS.test-build.xcconfig"; path = "Pods/Target Support Files/Pods-WavesWallet-iOS/Pods-WavesWallet-iOS.test-build.xcconfig"; sourceTree = ""; }; - B2F04F55A260735DF3584D3E /* Pods_WavesWallet_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_WavesWallet_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - D0E2547DB09713AC51E70B93 /* Pods-MonkeyTest.test-build.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MonkeyTest.test-build.xcconfig"; path = "Pods/Target Support Files/Pods-MonkeyTest/Pods-MonkeyTest.test-build.xcconfig"; sourceTree = ""; }; - E0E99F201DFCDD4280DDB64C /* Pods-WavesWallet-iOS.test-adhoc.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WavesWallet-iOS.test-adhoc.xcconfig"; path = "Pods/Target Support Files/Pods-WavesWallet-iOS/Pods-WavesWallet-iOS.test-adhoc.xcconfig"; sourceTree = ""; }; - E90223C321D53A8F0057AA45 /* DexAssetPairDomainDTO+Mapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DexAssetPairDomainDTO+Mapper.swift"; sourceTree = ""; }; + 7BFB474B22FC5A40002B19F8 /* WidgetSettingsRepositoryStorage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WidgetSettingsRepositoryStorage.swift; sourceTree = ""; }; + 7BFB474E22FC5AD0002B19F8 /* Sentry-io-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Sentry-io-Info.plist"; sourceTree = ""; }; + 7BFB474F22FC5AD0002B19F8 /* Appsflyer-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Appsflyer-Info.plist"; sourceTree = ""; }; + 7BFB475022FC5AD0002B19F8 /* AppSpector-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "AppSpector-Info.plist"; sourceTree = ""; }; + 7BFB475122FC5AD0002B19F8 /* environment_testnet.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = environment_testnet.json; sourceTree = ""; }; + 7BFB475222FC5AD0002B19F8 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; + 7BFB475322FC5AD0002B19F8 /* Fabric-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Fabric-Info.plist"; sourceTree = ""; }; + 7BFB475422FC5AD0002B19F8 /* Amplitude-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Amplitude-Info.plist"; sourceTree = ""; }; + 7BFB475522FC5AD0002B19F8 /* environment_mainnet.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = environment_mainnet.json; sourceTree = ""; }; + 7BFB475622FC5AD0002B19F8 /* spam.csv */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = spam.csv; sourceTree = ""; }; + 7BFB47DD22FC742C002B19F8 /* SmartTransactionDTO+EncodingToString.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SmartTransactionDTO+EncodingToString.swift"; sourceTree = ""; }; + 7BFB47DE22FC742D002B19F8 /* Kingfisher+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Kingfisher+Rx.swift"; sourceTree = ""; }; + 7BFB47E022FC742D002B19F8 /* AssetsRepositoryMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssetsRepositoryMock.swift; sourceTree = ""; }; + 7BFB47E122FC742E002B19F8 /* SmartTransactionKind+UIImage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SmartTransactionKind+UIImage.swift"; sourceTree = ""; }; + 7BFB47E422FC742E002B19F8 /* UIAlertController+Factory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIAlertController+Factory.swift"; sourceTree = ""; }; + 7BFB47E622FC742E002B19F8 /* BiometricType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BiometricType.swift; sourceTree = ""; }; + 7BFB47E822FC742E002B19F8 /* UITableView+Skeleton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UITableView+Skeleton.swift"; sourceTree = ""; }; + 7BFB47E922FC742E002B19F8 /* SkeletonAnimatable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SkeletonAnimatable.swift; sourceTree = ""; }; + 7BFB47EA22FC742E002B19F8 /* RateApp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RateApp.swift; sourceTree = ""; }; + 7BFB47EB22FC742E002B19F8 /* DisplayError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DisplayError.swift; sourceTree = ""; }; + 7BFB47EC22FC742E002B19F8 /* Notifications.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Notifications.swift; sourceTree = ""; }; + 7BFB47ED22FC742E002B19F8 /* GlobalConstants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GlobalConstants.swift; sourceTree = ""; }; + 7BFB47EE22FC742E002B19F8 /* QRCodeReader+Factory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "QRCodeReader+Factory.swift"; sourceTree = ""; }; + 7BFB47EF22FC742E002B19F8 /* MailCompose+Support.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "MailCompose+Support.swift"; sourceTree = ""; }; + 7BFB47F122FC742E002B19F8 /* ModalRootView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ModalRootView.swift; sourceTree = ""; }; + 7BFB47F222FC742E002B19F8 /* ModalViewControllerTransitioning.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ModalViewControllerTransitioning.swift; sourceTree = ""; }; + 7BFB47F322FC742E002B19F8 /* ModalPresentationAnimator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ModalPresentationAnimator.swift; sourceTree = ""; }; + 7BFB47F422FC742E002B19F8 /* ModalPresentationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ModalPresentationController.swift; sourceTree = ""; }; + 7BFB47F522FC742E002B19F8 /* ModalTableView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ModalTableView.swift; sourceTree = ""; }; + 7BFB47F622FC742E002B19F8 /* ModalScrollViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ModalScrollViewController.swift; sourceTree = ""; }; + 7BFB47F722FC742E002B19F8 /* ModalPresentationAnimatorContext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ModalPresentationAnimatorContext.swift; sourceTree = ""; }; + 7BFB47F822FC742E002B19F8 /* AuthorizationInteractorLocalizableImp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthorizationInteractorLocalizableImp.swift; sourceTree = ""; }; + 7BFB47F922FC742E002B19F8 /* NSAttributedString+Styles.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSAttributedString+Styles.swift"; sourceTree = ""; }; + 7BFB47FA22FC742F002B19F8 /* BiometricManager+String.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BiometricManager+String.swift"; sourceTree = ""; }; + 7BFB47FC22FC742F002B19F8 /* Language.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Language.swift; sourceTree = ""; }; + 7BFB47FD22FC742F002B19F8 /* QRCodeParser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QRCodeParser.swift; sourceTree = ""; }; + 7BFB47FF22FC742F002B19F8 /* NewUserWithoutBackupStorageTrack.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NewUserWithoutBackupStorageTrack.swift; sourceTree = ""; }; + 8A551BA048F9720698C5BF39 /* Pods-Extensions.release-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Extensions.release-dev.xcconfig"; path = "Target Support Files/Pods-Extensions/Pods-Extensions.release-dev.xcconfig"; sourceTree = ""; }; + 8B03F78A9DF177D8D9723E8D /* Pods-MonkeyTest.release-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MonkeyTest.release-dev.xcconfig"; path = "Target Support Files/Pods-MonkeyTest/Pods-MonkeyTest.release-dev.xcconfig"; sourceTree = ""; }; + 8C9A1159470FED7057790330 /* Pods-DataLayer.release-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DataLayer.release-prod.xcconfig"; path = "Target Support Files/Pods-DataLayer/Pods-DataLayer.release-prod.xcconfig"; sourceTree = ""; }; + 8E83213560285F82F0869981 /* Pods-Extensions.dev-adhoc.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Extensions.dev-adhoc.xcconfig"; path = "Target Support Files/Pods-Extensions/Pods-Extensions.dev-adhoc.xcconfig"; sourceTree = ""; }; + 95576FFA8929D9E05D7BF2BE /* Pods-DataLayer.test-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DataLayer.test-prod.xcconfig"; path = "Target Support Files/Pods-DataLayer/Pods-DataLayer.test-prod.xcconfig"; sourceTree = ""; }; + A79335F0C0282C9BC73BC68E /* Pods-DataLayerTests.dev-debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DataLayerTests.dev-debug.xcconfig"; path = "Target Support Files/Pods-DataLayerTests/Pods-DataLayerTests.dev-debug.xcconfig"; sourceTree = ""; }; + A9E634B5E087D00A1F31D61E /* Pods-MonkeyTest.dev-adhoc.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MonkeyTest.dev-adhoc.xcconfig"; path = "Target Support Files/Pods-MonkeyTest/Pods-MonkeyTest.dev-adhoc.xcconfig"; sourceTree = ""; }; + AAE0DD42A072FF6782D8699E /* Pods-DomainLayerTests.test-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DomainLayerTests.test-prod.xcconfig"; path = "Target Support Files/Pods-DomainLayerTests/Pods-DomainLayerTests.test-prod.xcconfig"; sourceTree = ""; }; + ABBE8EE95A2EDD196C036A99 /* Pods-MarketPulseWidget.test-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MarketPulseWidget.test-dev.xcconfig"; path = "Target Support Files/Pods-MarketPulseWidget/Pods-MarketPulseWidget.test-dev.xcconfig"; sourceTree = ""; }; + AD61D54FAF8C35F7FE42B48C /* Pods-DataLayer.dev-debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DataLayer.dev-debug.xcconfig"; path = "Target Support Files/Pods-DataLayer/Pods-DataLayer.dev-debug.xcconfig"; sourceTree = ""; }; + B7A25F7D6E4B1692329D7BF7 /* Pods-Extensions.test-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Extensions.test-dev.xcconfig"; path = "Target Support Files/Pods-Extensions/Pods-Extensions.test-dev.xcconfig"; sourceTree = ""; }; + BAA94A74B517FBB13852F114 /* Pods-DataLayerTests.test-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DataLayerTests.test-prod.xcconfig"; path = "Target Support Files/Pods-DataLayerTests/Pods-DataLayerTests.test-prod.xcconfig"; sourceTree = ""; }; + BC49EA63C68974786E6084B7 /* Pods_WavesWallet_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_WavesWallet_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + BDE6D164A37B938C860EDF5F /* Pods-DomainLayer.test-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DomainLayer.test-prod.xcconfig"; path = "Target Support Files/Pods-DomainLayer/Pods-DomainLayer.test-prod.xcconfig"; sourceTree = ""; }; + C880B220C9E5499780C35467 /* Pods-DataLayerTests.release-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DataLayerTests.release-dev.xcconfig"; path = "Target Support Files/Pods-DataLayerTests/Pods-DataLayerTests.release-dev.xcconfig"; sourceTree = ""; }; + CEB61763B0920D458B8C82AE /* Pods-DomainLayer.release-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DomainLayer.release-dev.xcconfig"; path = "Target Support Files/Pods-DomainLayer/Pods-DomainLayer.release-dev.xcconfig"; sourceTree = ""; }; + D0CCB8B5087EC114938067B4 /* Pods-DomainLayerTests.dev-debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DomainLayerTests.dev-debug.xcconfig"; path = "Target Support Files/Pods-DomainLayerTests/Pods-DomainLayerTests.dev-debug.xcconfig"; sourceTree = ""; }; + D206585280B732B56334628E /* Pods-WavesWallet-iOS.dev-adhoc.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WavesWallet-iOS.dev-adhoc.xcconfig"; path = "Target Support Files/Pods-WavesWallet-iOS/Pods-WavesWallet-iOS.dev-adhoc.xcconfig"; sourceTree = ""; }; + DAD260D2DDC7E839EDD12EA6 /* Pods-DomainLayerTests.dev-adhoc.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DomainLayerTests.dev-adhoc.xcconfig"; path = "Target Support Files/Pods-DomainLayerTests/Pods-DomainLayerTests.dev-adhoc.xcconfig"; sourceTree = ""; }; + DD32EC8514D2E93CE1593C7F /* Pods-DataLayerTests.test-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DataLayerTests.test-dev.xcconfig"; path = "Target Support Files/Pods-DataLayerTests/Pods-DataLayerTests.test-dev.xcconfig"; sourceTree = ""; }; + DF56F95985E2EA4D53A570EC /* Pods-DomainLayerTests.test-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DomainLayerTests.test-dev.xcconfig"; path = "Target Support Files/Pods-DomainLayerTests/Pods-DomainLayerTests.test-dev.xcconfig"; sourceTree = ""; }; + E750B898EC2D32D49A39F690 /* Pods-DomainLayerTests.release-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DomainLayerTests.release-prod.xcconfig"; path = "Target Support Files/Pods-DomainLayerTests/Pods-DomainLayerTests.release-prod.xcconfig"; sourceTree = ""; }; + E902BBCF236A664300141CF4 /* DexDeepLinkCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DexDeepLinkCoordinator.swift; sourceTree = ""; }; E902F61420E5829B00A46335 /* ChooseAccountViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChooseAccountViewController.swift; sourceTree = ""; }; E904525920B4EF4200A490E5 /* PopupViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PopupViewController.swift; sourceTree = ""; }; - E910B7E821C3261B00E402AB /* CoinomatRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoinomatRepository.swift; sourceTree = ""; }; - E910B7EB21C3266F00E402AB /* CoinomatDomainDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoinomatDomainDTO.swift; sourceTree = ""; }; E911300B21BC028400588430 /* AssetSelectSkeletonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetSelectSkeletonView.swift; sourceTree = ""; }; E911300D21BC029300588430 /* AssetSelectSkeletonView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AssetSelectSkeletonView.xib; sourceTree = ""; }; E9157BED21A4C081009F99B6 /* StartLeasingCompleteViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StartLeasingCompleteViewController.swift; sourceTree = ""; }; @@ -1551,27 +2068,38 @@ E91DC0E020E0054A00BAB519 /* NetworkSettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkSettingsViewController.swift; sourceTree = ""; }; E920372A21A5F4C10055E4D8 /* StartLeasingConfirmModuleBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StartLeasingConfirmModuleBuilder.swift; sourceTree = ""; }; E921ED03222DDA4600DE286D /* DexScriptAssetMessageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DexScriptAssetMessageViewController.swift; sourceTree = ""; }; - E922D25E21B81BE800575955 /* CandleDomainDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CandleDomainDTO.swift; sourceTree = ""; }; - E922D26321B82C2100575955 /* CandlesRepositoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CandlesRepositoryProtocol.swift; sourceTree = ""; }; - E922D26721B8311F00575955 /* LastTradesRepositoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LastTradesRepositoryProtocol.swift; sourceTree = ""; }; - E922D26921B831B600575955 /* LastTradesRepositoryRemote.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LastTradesRepositoryRemote.swift; sourceTree = ""; }; E9236F1C2216F35B00A12FD5 /* AppNewsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppNewsView.swift; sourceTree = ""; }; E9236F1E2216F37300A12FD5 /* AppNewsView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AppNewsView.xib; sourceTree = ""; }; E9236F202216F48A00A12FD5 /* PopupActionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PopupActionView.swift; sourceTree = ""; }; + E923956D237518B7009C4091 /* PushNotificationsManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PushNotificationsManager.swift; sourceTree = ""; }; + E923956E237518B7009C4091 /* PushNotificationsAlertView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PushNotificationsAlertView.swift; sourceTree = ""; }; + E923956F237518B7009C4091 /* PushNotificationsAlertView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PushNotificationsAlertView.xib; sourceTree = ""; }; E923A764219D53EE000DD9F6 /* TokenBurnInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokenBurnInteractor.swift; sourceTree = ""; }; E923A767219D714E000DD9F6 /* TokenBurnLoadingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokenBurnLoadingViewController.swift; sourceTree = ""; }; E923A76C219D73BF000DD9F6 /* TokenBurnCompleteViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokenBurnCompleteViewController.swift; sourceTree = ""; }; E92703C5226FDD0C0022D5F0 /* WalletSortPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletSortPresenter.swift; sourceTree = ""; }; - E92A8DE02278ACFF0009DF27 /* TSUD+Rx.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSUD+Rx.swift"; sourceTree = ""; }; - E92D9BFE2148740B006D6D6B /* InputScrollButtonsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = InputScrollButtonsView.swift; path = "WavesWallet-iOS/PresentationLayer/CustomViews/InputScrollButtonsView.swift"; sourceTree = SOURCE_ROOT; }; + E92A11632317CE35004EC6A1 /* WidgetPairsPriceDataTarget.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WidgetPairsPriceDataTarget.swift; sourceTree = ""; }; + E92A11672317CEF6004EC6A1 /* WidgetPairsPriceDataService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WidgetPairsPriceDataService.swift; sourceTree = ""; }; + E92A116A2317CF9A004EC6A1 /* InternalWidgetService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InternalWidgetService.swift; sourceTree = ""; }; + E92A116C2317D12F004EC6A1 /* WidgetDataServiceTypes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WidgetDataServiceTypes.swift; sourceTree = ""; }; + E92A116F2317D1DD004EC6A1 /* WidgetPairPriceData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WidgetPairPriceData.swift; sourceTree = ""; }; + E92A11712317D2E9004EC6A1 /* WidgetResponseData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WidgetResponseData.swift; sourceTree = ""; }; + E92A11742317D5DB004EC6A1 /* WidgetPairsPriceRepositoryRemote.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetPairsPriceRepositoryRemote.swift; sourceTree = ""; }; + E92A11762317DB2E004EC6A1 /* WidgetMatcherRepositoryRemote.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetMatcherRepositoryRemote.swift; sourceTree = ""; }; + E92A117A2317DD6F004EC6A1 /* WidgetMatcherServiceTypes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WidgetMatcherServiceTypes.swift; sourceTree = ""; }; + E92A117D2317DF4B004EC6A1 /* WidgetSettingsMarcherTarget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetSettingsMarcherTarget.swift; sourceTree = ""; }; + E92A11802317E10C004EC6A1 /* WidgetMatcherSettingService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetMatcherSettingService.swift; sourceTree = ""; }; + E92A11822317E7A9004EC6A1 /* WidgetAssetsRepositoryRemote.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetAssetsRepositoryRemote.swift; sourceTree = ""; }; + E92A11842317E883004EC6A1 /* WidgetAssetsDataService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetAssetsDataService.swift; sourceTree = ""; }; E92FAD0C226F6C050054D4AA /* WalletSortSeparatorCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletSortSeparatorCell.swift; sourceTree = ""; }; E92FAD0D226F6C050054D4AA /* WalletSortSeparatorCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = WalletSortSeparatorCell.xib; sourceTree = ""; }; E9310D0B217924D0008BF3EE /* SendConfirmationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendConfirmationViewController.swift; sourceTree = ""; }; E9310D1821792D01008BF3EE /* SendConfirmationRecipientView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendConfirmationRecipientView.swift; sourceTree = ""; }; E9310D1A21792D13008BF3EE /* SendConfirmationRecipientView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SendConfirmationRecipientView.xib; sourceTree = ""; }; E9310D1C217942C8008BF3EE /* BlueBgView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlueBgView.swift; sourceTree = ""; }; + E936C2E92314BF590097515B /* WidgetSettingsInizialization.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetSettingsInizialization.swift; sourceTree = ""; }; E938356E20A472B4001A2509 /* HistoryTransactionCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryTransactionCell.swift; sourceTree = ""; }; - E9419CCA21CFAD76004DACCA /* MarketMatcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarketMatcher.swift; sourceTree = ""; }; + E9413AC122FA3D9C002C4A97 /* DexChartSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DexChartSettings.swift; sourceTree = ""; }; E94231EF22A40FA80087F82F /* WalletSearchModuleBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletSearchModuleBuilder.swift; sourceTree = ""; }; E9443007226E62A600EB6257 /* WalletSortViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletSortViewController.swift; sourceTree = ""; }; E9443009226E641E00EB6257 /* WalletSortTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletSortTypes.swift; sourceTree = ""; }; @@ -1580,19 +2108,16 @@ E9443011226E64E900EB6257 /* WalletSortInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletSortInteractor.swift; sourceTree = ""; }; E9443013226E64F600EB6257 /* WalletSortInteractorProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletSortInteractorProtocol.swift; sourceTree = ""; }; E9443017226E757E00EB6257 /* WalletSort+Mapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WalletSort+Mapper.swift"; sourceTree = ""; }; - E944AA6E22444B780009F494 /* Amplitude-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Amplitude-Info.plist"; sourceTree = ""; }; - E944AA73224465BE0009F494 /* AnalyticManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnalyticManager.swift; sourceTree = ""; }; - E944AA75224465D60009F494 /* AnalyticManager+Dex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AnalyticManager+Dex.swift"; sourceTree = ""; }; - E944AA77224467570009F494 /* AnalyticManager+WalletAsset.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AnalyticManager+WalletAsset.swift"; sourceTree = ""; }; - E944AA7922446A530009F494 /* AnalyticManager+WalletStart.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AnalyticManager+WalletStart.swift"; sourceTree = ""; }; - E944AA812245394C0009F494 /* AnalyticAssetManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticAssetManager.swift; sourceTree = ""; }; + E9443BA722DCCC2B00AFF151 /* TransactionCardExchangeFeeCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionCardExchangeFeeCell.swift; sourceTree = ""; }; E945B19E20F75B420081F4D2 /* ConfirmBackupStackInputView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfirmBackupStackInputView.swift; sourceTree = ""; }; - E94A6E9E215AD53E001814F7 /* ContactDomainDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactDomainDTO.swift; sourceTree = ""; }; - E94A7003215AEA49001814F7 /* AddressBookRepositoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressBookRepositoryProtocol.swift; sourceTree = ""; }; - E94A7006215AEB0E001814F7 /* AddressBookRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressBookRepository.swift; sourceTree = ""; }; - E94E4E6821CF9F6D00053A49 /* CoinomatService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoinomatService.swift; sourceTree = ""; }; + E95310B222E8507500F72809 /* MarketPulseWidgetCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarketPulseWidgetCell.swift; sourceTree = ""; }; + E95310BB22E85FEE00F72809 /* MarketPulseTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarketPulseTypes.swift; sourceTree = ""; }; + E95310BD22E8A43000F72809 /* WidgetAssets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = WidgetAssets.xcassets; sourceTree = ""; }; E95438F7217F91BA001A7860 /* SendLoadingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendLoadingViewController.swift; sourceTree = ""; }; E9543901217FF9EC001A7860 /* SendCompleteViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendCompleteViewController.swift; sourceTree = ""; }; + E958571222F2E73D007A0178 /* WidgetSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetSettings.swift; sourceTree = ""; }; + E958571E22F3BB9F007A0178 /* MarketPulseDataBaseRepositoryProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MarketPulseDataBaseRepositoryProtocol.swift; sourceTree = ""; }; + E958571F22F3BBA0007A0178 /* MarketPulseDataBaseRepository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MarketPulseDataBaseRepository.swift; sourceTree = ""; }; E95B47A821638A9F004D4E39 /* Hello.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Hello.storyboard; sourceTree = ""; }; E95B47AB21638A9F004D4E39 /* HelloLanguagesViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HelloLanguagesViewController.swift; sourceTree = ""; }; E95B47B321638A9F004D4E39 /* LongInfoPageView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LongInfoPageView.xib; sourceTree = ""; }; @@ -1623,48 +2148,45 @@ E95E151022A18C25003552B8 /* WalletSearchTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletSearchTableViewCell.swift; sourceTree = ""; }; E95E151122A18C25003552B8 /* WalletSearchTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = WalletSearchTableViewCell.xib; sourceTree = ""; }; E95E151422A197B8003552B8 /* WalletSearchViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletSearchViewController.swift; sourceTree = ""; }; + E9618D1322EF933800FB7F06 /* WidgetSettingsRepositoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetSettingsRepositoryProtocol.swift; sourceTree = ""; }; + E9618D1522EF936800FB7F06 /* MarketPulseSettingsDomainDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarketPulseSettingsDomainDTO.swift; sourceTree = ""; }; E96358A322A73D62008A3395 /* WalletClearAssetsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletClearAssetsView.swift; sourceTree = ""; }; E96358A522A73D70008A3395 /* WalletClearAssetsView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = WalletClearAssetsView.xib; sourceTree = ""; }; - E964067D21D5299D00569963 /* DexDomainDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DexDomainDTO.swift; sourceTree = ""; }; E9642C8E21CB32570065A1BD /* CoinomatServiceErrorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoinomatServiceErrorView.swift; sourceTree = ""; }; E9642C9021CB326A0065A1BD /* CoinomatServiceErrorView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CoinomatServiceErrorView.xib; sourceTree = ""; }; E965702221935F2F0052F0FC /* DexCreateOrderInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DexCreateOrderInteractor.swift; sourceTree = ""; }; E96570422193E8570052F0FC /* DexMyOrdersModuleOutput.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DexMyOrdersModuleOutput.swift; sourceTree = ""; }; - E967786821EC491500CE56D6 /* CandlesRepositoryRemote.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CandlesRepositoryRemote.swift; sourceTree = ""; }; - E967786A21EC660C00CE56D6 /* DexMyOrders+Mapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DexMyOrders+Mapper.swift"; sourceTree = ""; }; E96D1B912249922F00D31D17 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = ""; }; E96D1B922249923000D31D17 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Waves.strings; sourceTree = ""; }; E96D1B932249956E00D31D17 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; E96D1B942249956F00D31D17 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Waves.strings; sourceTree = ""; }; E96DAB70228EE643005ED12B /* WalletSortSegmentedControl.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = WalletSortSegmentedControl.xib; sourceTree = ""; }; E96DAB72228EEC87005ED12B /* WalletSortSegmentedControl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletSortSegmentedControl.swift; sourceTree = ""; }; - E96E29FD21D3492F00AC2FA9 /* MatcherService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatcherService.swift; sourceTree = ""; }; - E96E29FF21D34A2100AC2FA9 /* MatcherRepositoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatcherRepositoryProtocol.swift; sourceTree = ""; }; - E96E2A0121D34AA200AC2FA9 /* MatcherRepositoryRemote.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatcherRepositoryRemote.swift; sourceTree = ""; }; - E96E2A0421D3D9AA00AC2FA9 /* DomainDexQueries.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomainDexQueries.swift; sourceTree = ""; }; + E96DE1852317F07B005E1FD9 /* WidgetAssetsDataTarget.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WidgetAssetsDataTarget.swift; sourceTree = ""; }; + E96DE1902318076A005E1FD9 /* WidgetAnalyticManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetAnalyticManager.swift; sourceTree = ""; }; E96FEA23226E962300C0EE22 /* WalletSortEmptyAssetsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletSortEmptyAssetsCell.swift; sourceTree = ""; }; E96FEA24226E962300C0EE22 /* WalletSortEmptyAssetsCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = WalletSortEmptyAssetsCell.xib; sourceTree = ""; }; E96FEA27226F27BC00C0EE22 /* WalletSortCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletSortCell.swift; sourceTree = ""; }; E96FEA28226F27BC00C0EE22 /* WalletSortCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = WalletSortCell.xib; sourceTree = ""; }; - E971DA5120FFF4B600616A03 /* BiometricManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BiometricManager.swift; sourceTree = ""; }; - E9740E5D21D1C90F00EAD3ED /* PairsPriceApiService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PairsPriceApiService.swift; sourceTree = ""; }; E97667CD227F0F8B0050E0D6 /* TransactionCardOrderFilledCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionCardOrderFilledCell.swift; sourceTree = ""; }; - E97D450821C80233000E3C48 /* DexPairsPriceRepositoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DexPairsPriceRepositoryProtocol.swift; sourceTree = ""; }; - E97D450A21C802AB000E3C48 /* DexPairsPriceRepositoryRemote.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DexPairsPriceRepositoryRemote.swift; sourceTree = ""; }; - E97D450C21C8127F000E3C48 /* DexOrderBookRepositoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DexOrderBookRepositoryProtocol.swift; sourceTree = ""; }; - E97D450F21C814C0000E3C48 /* OrderBookMatcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderBookMatcher.swift; sourceTree = ""; }; - E97D451121C817CC000E3C48 /* DexOrderBookRepositoryRemote.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DexOrderBookRepositoryRemote.swift; sourceTree = ""; }; + E97A74A422D3BAA200777C39 /* OrderBookUseCaseProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderBookUseCaseProtocol.swift; sourceTree = ""; }; + E97A74A622D3BAD400777C39 /* OrderBookUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderBookUseCase.swift; sourceTree = ""; }; E97EC83E20E67BE900AB006B /* NewAccountViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewAccountViewController.swift; sourceTree = ""; }; E97EC84220E689A800AB006B /* ImportAccountPasswordViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImportAccountPasswordViewController.swift; sourceTree = ""; }; E98092A822A85EE700914CF1 /* WalletViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletViewController.swift; sourceTree = ""; }; E980EACD20A9F5BF001834DB /* ScannerCustomView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScannerCustomView.swift; sourceTree = ""; }; E983665D21F5972300178A8A /* TransactionScriptErrorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionScriptErrorView.swift; sourceTree = ""; }; E983666021F5973900178A8A /* TransactionScriptErrorView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TransactionScriptErrorView.xib; sourceTree = ""; }; - E98D14D02266B25500BE5481 /* CleanerWalletManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CleanerWalletManager.swift; sourceTree = ""; }; + E9845D3A2374645900716515 /* PushNotificationsCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushNotificationsCoordinator.swift; sourceTree = ""; }; + E984BB6A2318457800D60C38 /* WidgetTransactionsDataService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetTransactionsDataService.swift; sourceTree = ""; }; + E984BB6C2318461A00D60C38 /* WidgetTransactionsDataTarget.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WidgetTransactionsDataTarget.swift; sourceTree = ""; }; + E984BB6E23184EE100D60C38 /* WidgetTransactionsRepositoryRemote.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetTransactionsRepositoryRemote.swift; sourceTree = ""; }; + E984BB70231935DD00D60C38 /* WidgetPublicKeyMatcherTarget.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WidgetPublicKeyMatcherTarget.swift; sourceTree = ""; }; + E984BB722319367400D60C38 /* WidgetPublicKeyMatcherService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WidgetPublicKeyMatcherService.swift; sourceTree = ""; }; + E98A1A152301A0EF00E7EAAD /* MatcherRepositoryLocal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatcherRepositoryLocal.swift; sourceTree = ""; }; + E98F0588236B1CCF0055DCCE /* DexDeepLinkLoadingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DexDeepLinkLoadingViewController.swift; sourceTree = ""; }; E98F1D2C22A5E2E600B4A8C4 /* WalletUpdateAppView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletUpdateAppView.swift; sourceTree = ""; }; E98F1D2E22A5E2F200B4A8C4 /* WalletUpdateAppView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = WalletUpdateAppView.xib; sourceTree = ""; }; - E991BB14220189530022E27D /* AliasApiService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AliasApiService.swift; sourceTree = ""; }; - E991BB16220197280022E27D /* AliasApi.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AliasApi.swift; sourceTree = ""; }; E991BB192202CA250022E27D /* SendFeeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendFeeViewController.swift; sourceTree = ""; }; E991BB1B2202CB3C0022E27D /* SendFeeModuleBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendFeeModuleBuilder.swift; sourceTree = ""; }; E991BB1F2202CE090022E27D /* SendFeeTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendFeeTableViewCell.swift; sourceTree = ""; }; @@ -1674,17 +2196,19 @@ E991BB292202D5E00022E27D /* SendFeeInteractorProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendFeeInteractorProtocol.swift; sourceTree = ""; }; E991BB2B2202D6560022E27D /* SendFeeTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendFeeTypes.swift; sourceTree = ""; }; E991BB2D2202DD420022E27D /* SendFeeHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendFeeHeaderView.swift; sourceTree = ""; }; + E991F8FB22E8BC41008D1AE4 /* MarketPulseWidget.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MarketPulseWidget.entitlements; sourceTree = ""; }; + E991F8FE22E8CFC1008D1AE4 /* MarketPulseWidgetInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarketPulseWidgetInteractor.swift; sourceTree = ""; }; + E991F90022E8CFD3008D1AE4 /* MarketPulseWidgetPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarketPulseWidgetPresenter.swift; sourceTree = ""; }; E9939B4422302E3800B50E67 /* InfoPageConfirmView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoPageConfirmView.swift; sourceTree = ""; }; E9939B4622302E6100B50E67 /* InfoPageConfirmView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = InfoPageConfirmView.xib; sourceTree = ""; }; - E99DD81A21CEE7690091AFEC /* CandlesApiService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CandlesApiService.swift; sourceTree = ""; }; - E99DD81C21CEF09C0091AFEC /* CandleApiFilters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CandleApiFilters.swift; sourceTree = ""; }; - E99DD81E21CEF7AC0091AFEC /* CandleApi.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CandleApi.swift; sourceTree = ""; }; + E999E6A52323D5C300EDDF45 /* WavesSDK.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = WavesSDK.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + E999E6A72323D5C900EDDF45 /* WavesSDKCrypto.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = WavesSDKCrypto.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + E999E6A92323D5D200EDDF45 /* WavesSDKExtensions.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = WavesSDKExtensions.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + E99A3B7422BE5CEB0070AC76 /* GatewayRepositoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GatewayRepositoryProtocol.swift; sourceTree = ""; }; + E99A3B7622BE5DB70070AC76 /* GatewayDomainDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GatewayDomainDTO.swift; sourceTree = ""; }; E9A05C5720E9264300B0E0FA /* UseTouchIDViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UseTouchIDViewController.swift; sourceTree = ""; }; - E9A380A621D2E1C5004377A6 /* PairPriceApi.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PairPriceApi.swift; sourceTree = ""; }; - E9A380AC21D3035B004377A6 /* OrderMatcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderMatcher.swift; sourceTree = ""; }; E9A3AFAD222DEECB009FB45A /* DexScriptAssetMessageModuleBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DexScriptAssetMessageModuleBuilder.swift; sourceTree = ""; }; E9A4812E20D8DDBB00272C6D /* ChangePasswordViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChangePasswordViewController.swift; sourceTree = ""; }; - E9A6A499227661940093FC59 /* TableViewNoShadow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewNoShadow.swift; sourceTree = ""; }; E9AFDBE321F32E88003130A8 /* TransactionFeeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionFeeView.swift; sourceTree = ""; }; E9AFDBE521F32E96003130A8 /* TransactionFeeView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TransactionFeeView.xib; sourceTree = ""; }; E9B086922163882F00937644 /* AddAddressBookModuleBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddAddressBookModuleBuilder.swift; sourceTree = ""; }; @@ -1812,15 +2336,20 @@ E9B12DB4219DD6E000128EFE /* AssetBalanceSpamCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AssetBalanceSpamCell.xib; sourceTree = ""; }; E9B12DB7219E2D3900128EFE /* AssetBurnCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetBurnCell.swift; sourceTree = ""; }; E9B12DB8219E2D3900128EFE /* AssetBurnCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AssetBurnCell.xib; sourceTree = ""; }; + E9B190A722E7CD99008220B7 /* MarketPulseWidget.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = MarketPulseWidget.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + E9B190A822E7CD99008220B7 /* NotificationCenter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NotificationCenter.framework; path = System/Library/Frameworks/NotificationCenter.framework; sourceTree = SDKROOT; }; + E9B190AB22E7CD99008220B7 /* MarketPulseWidgetViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarketPulseWidgetViewController.swift; sourceTree = ""; }; + E9B190AE22E7CD99008220B7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = ""; }; + E9B190B022E7CD99008220B7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + E9B387CE23690DCD001FCA60 /* SendCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendCoordinator.swift; sourceTree = ""; }; E9BB2D842260DEB000366278 /* TransactionCardInvokeScriptCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionCardInvokeScriptCell.swift; sourceTree = ""; }; - E9BB724721C2A94000B2AF7E /* CoinomatRepositoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoinomatRepositoryProtocol.swift; sourceTree = ""; }; - E9BCF48021636DAC00FA6502 /* ResponseType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResponseType.swift; sourceTree = ""; }; E9C0B49B2176C46E00669D1D /* SendPresenterProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendPresenterProtocol.swift; sourceTree = ""; }; E9C0B49D2176C48300669D1D /* SendPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendPresenter.swift; sourceTree = ""; }; E9C0B49F2176C49B00669D1D /* SendInteractorProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendInteractorProtocol.swift; sourceTree = ""; }; E9C0B4A12176C4A800669D1D /* SendInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendInteractor.swift; sourceTree = ""; }; E9C0B4A32176C4BE00669D1D /* SendTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendTypes.swift; sourceTree = ""; }; - E9C1F5C5224D60B1006DBD8E /* ApplicationDebugSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationDebugSettings.swift; sourceTree = ""; }; + E9C1B90D236C6D9500F8E988 /* ForceUpdateApp.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = ForceUpdateApp.storyboard; sourceTree = ""; }; + E9C1B90F236C6DA900F8E988 /* ForceUpdateAppViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForceUpdateAppViewController.swift; sourceTree = ""; }; E9C4134B20E826E300AA044F /* DottedRoundView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DottedRoundView.swift; sourceTree = ""; }; E9C8F94A20F66A05004C438A /* ConfirmBackupStackListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfirmBackupStackListView.swift; sourceTree = ""; }; E9C8F94C20F66D64004C438A /* ConfirmBackupStackBaseView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfirmBackupStackBaseView.swift; sourceTree = ""; }; @@ -1829,9 +2358,6 @@ E9CD0D2D21809A5D001A99B3 /* SendMoneroPaymentIdView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SendMoneroPaymentIdView.xib; sourceTree = ""; }; E9CD0D30218137FE001A99B3 /* MainTabBarController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainTabBarController.swift; sourceTree = ""; }; E9CD0D3421815849001A99B3 /* AddAddressBookTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddAddressBookTypes.swift; sourceTree = ""; }; - E9D0ED85225CB8400098C234 /* InvokeScriptTransactionNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvokeScriptTransactionNode.swift; sourceTree = ""; }; - E9D0ED87225CBDEA0098C234 /* InvokeScriptTransactionDomainDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvokeScriptTransactionDomainDTO.swift; sourceTree = ""; }; - E9D0ED89225CBECA0098C234 /* InvokeScriptTransaction+Mapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "InvokeScriptTransaction+Mapper.swift"; sourceTree = ""; }; E9D36D6D2175C754001E6DF0 /* ReceiveCryptocurrencyTypes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReceiveCryptocurrencyTypes.swift; sourceTree = ""; }; E9D36D702175C754001E6DF0 /* ReceiveCryptocurrencyModuleBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReceiveCryptocurrencyModuleBuilder.swift; sourceTree = ""; }; E9D36D722175C754001E6DF0 /* ReceiveCryptocurrencyPresenterProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReceiveCryptocurrencyPresenterProtocol.swift; sourceTree = ""; }; @@ -1877,9 +2403,6 @@ E9DB667221A3846A00962639 /* StartLeasingConfirmationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StartLeasingConfirmationViewController.swift; sourceTree = ""; }; E9DB667421A3848900962639 /* StartLeasingCancelConfirmationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StartLeasingCancelConfirmationViewController.swift; sourceTree = ""; }; E9DB667A21A3938200962639 /* StartLeasingLoadingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StartLeasingLoadingViewController.swift; sourceTree = ""; }; - E9DDF7392240F52D00B83CFD /* EnvironmentRepository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnvironmentRepository.swift; sourceTree = ""; }; - E9DDF73B2240F58800B83CFD /* UtilsNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UtilsNode.swift; sourceTree = ""; }; - E9DDF73F2240F5FD00B83CFD /* UtilsNodeService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UtilsNodeService.swift; sourceTree = ""; }; E9DEECE820BEF96700F28C67 /* WavesPopupViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WavesPopupViewController.swift; sourceTree = ""; }; E9DEECEA20BEF97E00F28C67 /* Waves.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Waves.storyboard; sourceTree = ""; }; E9DF24F52221ED640077F2EB /* AssetDetailInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssetDetailInteractor.swift; sourceTree = ""; }; @@ -1890,7 +2413,6 @@ E9EC5B3B2175F35800E5C29A /* SendModuleBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SendModuleBuilder.swift; sourceTree = ""; }; E9EC5BA82175F35800E5C29A /* AddressInputView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddressInputView.swift; sourceTree = ""; }; E9EC5BA92175F35800E5C29A /* AddressInputView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AddressInputView.xib; sourceTree = ""; }; - E9EE476C225E91ED0005176A /* InvokeScriptTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvokeScriptTransaction.swift; sourceTree = ""; }; E9F69B9122A5217200CDBD00 /* WalletSearchTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletSearchTypes.swift; sourceTree = ""; }; E9F69B9722A522E400CDBD00 /* WalletSearchPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletSearchPresenter.swift; sourceTree = ""; }; E9F69B9A22A5333500CDBD00 /* WalletSearchHeaderCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletSearchHeaderCell.swift; sourceTree = ""; }; @@ -1900,15 +2422,9 @@ E9F984A820E526DA00D2CB4D /* Enter.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Enter.storyboard; sourceTree = ""; }; E9F984AA20E52D8E00D2CB4D /* EnterStartViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnterStartViewController.swift; sourceTree = ""; }; E9F984B120E53FE000D2CB4D /* LanguageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LanguageViewController.swift; sourceTree = ""; }; - E9F9A278218535A200FD68D7 /* DexAssetPair.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DexAssetPair.swift; sourceTree = ""; }; - E9F9A27B21853E7D00FD68D7 /* DexRealmRepositoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DexRealmRepositoryProtocol.swift; sourceTree = ""; }; - E9F9A27D218540F700FD68D7 /* DexRealmRepositoryLocal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DexRealmRepositoryLocal.swift; sourceTree = ""; }; E9FE4D7720EA767B00208F29 /* SaveBackupPhraseViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SaveBackupPhraseViewController.swift; sourceTree = ""; }; E9FE4D7920EA7F8500208F29 /* ConfirmBackupViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfirmBackupViewController.swift; sourceTree = ""; }; - F7361C3F79C88A0896BACB0C /* Pods-MonkeyTest.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MonkeyTest.debug.xcconfig"; path = "Pods/Target Support Files/Pods-MonkeyTest/Pods-MonkeyTest.debug.xcconfig"; sourceTree = ""; }; - F74240B11EAB8D1600C3B84D /* AddressBook.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddressBook.swift; sourceTree = ""; }; - F74240B21EAB8D1600C3B84D /* AssetBalance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssetBalance.swift; sourceTree = ""; }; - F74240B31EAB8D1600C3B84D /* Transaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Transaction.swift; sourceTree = ""; }; + F65361A881CC9B52F2835293 /* Pods-DomainLayerTests.release-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DomainLayerTests.release-dev.xcconfig"; path = "Target Support Files/Pods-DomainLayerTests/Pods-DomainLayerTests.release-dev.xcconfig"; sourceTree = ""; }; F74240C81EAB8EC800C3B84D /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; }; F76AF1E81EBB43E00081A8BD /* SwiftBase58.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftBase58.framework; path = Carthage/Build/iOS/SwiftBase58.framework; sourceTree = ""; }; F76AF1E91EBB43E00081A8BD /* SwiftBase58.framework.dSYM */ = {isa = PBXFileReference; lastKnownFileType = wrapper.dsym; name = SwiftBase58.framework.dSYM; path = Carthage/Build/iOS/SwiftBase58.framework.dSYM; sourceTree = ""; }; @@ -1920,14 +2436,90 @@ F7E954E71EA8FE0700A804DE /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; F7E954F01EA8FE0700A804DE /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; F7E954F51EA8FE0700A804DE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + FBF207267CD94C94CF647176 /* Pods-DataLayer.test-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DataLayer.test-dev.xcconfig"; path = "Target Support Files/Pods-DataLayer/Pods-DataLayer.test-dev.xcconfig"; sourceTree = ""; }; + FD35BB6367E2BF6D13D33388 /* Pods-DataLayerTests.release-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DataLayerTests.release-prod.xcconfig"; path = "Target Support Files/Pods-DataLayerTests/Pods-DataLayerTests.release-prod.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 7B431A8922BD176D00DE73B9 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + B5B2F5FE86DB13C5F1ABC764 /* Pods_DomainLayerTests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7B431A9922BD185A00DE73B9 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 53E8DAD5791F388085BF04A3 /* (null) in Frameworks */, + 3EC73C513F8BB9C83B92E17B /* Pods_DataLayerTests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7B6685FD22B3F70D0029E6F1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 7BDC624222DC972E0029DA37 /* WavesSDK.framework in Frameworks */, + 7BDC624422DC972E0029DA37 /* WavesSDKCrypto.framework in Frameworks */, + 7BDC624622DC972E0029DA37 /* WavesSDKExtensions.framework in Frameworks */, + 7B83A7E922D8D72F0038180D /* Extensions.framework in Frameworks */, + F38A5F9B2B9C0AC51E99378B /* (null) in Frameworks */, + CE9236ADA9B30C0AE5EAC713 /* Pods_DomainLayer.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7B6686EB22B7C5120029E6F1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 7BDC625022DCB04F0029DA37 /* WavesSDKExtensions.framework in Frameworks */, + 1BAB29B6B58AFE20D3FD1998 /* (null) in Frameworks */, + A3521B8E7F8D5AFE73837B59 /* Pods_Extensions.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7B66872022B7E68B0029E6F1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 7BDC624822DC973E0029DA37 /* WavesSDK.framework in Frameworks */, + 7BDC624A22DC973E0029DA37 /* WavesSDKCrypto.framework in Frameworks */, + 7BDC624C22DC973E0029DA37 /* WavesSDKExtensions.framework in Frameworks */, + 7B16BCE622DBE49A00540418 /* DomainLayer.framework in Frameworks */, + 2D5B6193C022056CD73DEFBE /* Pods_DataLayer.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7B83A7CD22D8C74E0038180D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 7BF89E9322272A5E00853F9D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - E1A8D6947059C03B81BC5C0B /* Pods_MonkeyTest.framework in Frameworks */, + 6B2551D9571ABC864B16A7EE /* (null) in Frameworks */, + DEF8AC61C03932433B247FBD /* Pods_MonkeyTest.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E9B190A422E7CD99008220B7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + E999E6AA2323D5D200EDDF45 /* WavesSDKExtensions.framework in Frameworks */, + E999E6A82323D5C900EDDF45 /* WavesSDKCrypto.framework in Frameworks */, + E999E6A62323D5C300EDDF45 /* WavesSDK.framework in Frameworks */, + E953CE3E22EB19D5001D5800 /* DomainLayer.framework in Frameworks */, + E953CE3F22EB19D5001D5800 /* Extensions.framework in Frameworks */, + E9B190A922E7CD99008220B7 /* NotificationCenter.framework in Frameworks */, + 4BEC9D5887FACABD00BD4154 /* Pods_MarketPulseWidget.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1935,7 +2527,13 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 53AA2F7E1F0FB6ED983FDF2F /* Pods_WavesWallet_iOS.framework in Frameworks */, + 7B9393CD22DF582D006634A6 /* DomainLayer.framework in Frameworks */, + 7B9393D122DF5835006634A6 /* Extensions.framework in Frameworks */, + 7B9393C622DF5827006634A6 /* WavesSDKExtensions.framework in Frameworks */, + 7B9393CF22DF5830006634A6 /* DataLayer.framework in Frameworks */, + 7B9393CA22DF5827006634A6 /* WavesSDKCrypto.framework in Frameworks */, + 7B9393C822DF5827006634A6 /* WavesSDK.framework in Frameworks */, + DCE90C1BC9209D8B69BA1D86 /* Pods_WavesWallet_iOS.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2047,25 +2645,6 @@ path = Views; sourceTree = ""; }; - 0A00B188221AE708005A9053 /* DTO */ = { - isa = PBXGroup; - children = ( - 0A4D221D21809E3600155A8E /* AccountEnvironmentDomainDTO.swift */, - 0A88CC05217D27DF0083874C /* AccountSettingsDomainDTO.swift */, - 0A6AC3E7218489F5005D2525 /* AliasDomainDTO.swift */, - 0AEB359F21165CBF00EDD63C /* AssetBalanceDomainDTO.swift */, - 0AEB358E2115DFF500EDD63C /* AssetDomainDTO.swift */, - E922D25E21B81BE800575955 /* CandleDomainDTO.swift */, - E910B7EB21C3266F00E402AB /* CoinomatDomainDTO.swift */, - E94A6E9E215AD53E001814F7 /* ContactDomainDTO.swift */, - E964067D21D5299D00569963 /* DexDomainDTO.swift */, - 0A751D3322170F3D0024D523 /* NotificationNewsDomainDTO.swift */, - 0A218B802155180C00B989A1 /* WalletDomainDTO.swift */, - 0A5E4BBB213820C500E3C3C3 /* Transactions */, - ); - path = DTO; - sourceTree = ""; - }; 0A071E3D215AEF03007D9750 /* AccountPassword */ = { isa = PBXGroup; children = ( @@ -2110,15 +2689,6 @@ path = Views; sourceTree = ""; }; - 0A14CFCD2144157A00C3A4D5 /* Mapper */ = { - isa = PBXGroup; - children = ( - 0A14CFCE2144159300C3A4D5 /* Asset+Assistants.swift */, - 0A14CFD0214415C100C3A4D5 /* TransactionDomainDTO+Mapper.swift */, - ); - path = Mapper; - sourceTree = ""; - }; 0A14CFDC214B3EBE00C3A4D5 /* NewAccount */ = { isa = PBXGroup; children = ( @@ -2152,68 +2722,6 @@ path = CreateAlias; sourceTree = ""; }; - 0A1DAD6020F37BA2004DA625 /* Models */ = { - isa = PBXGroup; - children = ( - 0A1DAD6820F39AE3004DA625 /* ResponseApi.swift */, - 0A1DAD6120F3876C004DA625 /* AssetApi.swift */, - 0A1DAD7920F3A9AE004DA625 /* TransactionApi.swift */, - E99DD81E21CEF7AC0091AFEC /* CandleApi.swift */, - E9A380A621D2E1C5004377A6 /* PairPriceApi.swift */, - E991BB16220197280022E27D /* AliasApi.swift */, - ); - path = Models; - sourceTree = ""; - }; - 0A1DAD6320F395E7004DA625 /* Interactor */ = { - isa = PBXGroup; - children = ( - 7BAA9F7A22A032DE003B6D01 /* ApplicationVersionUseCase.swift */, - 0A6CCD3C20F4CF490023E36E /* AccountBalanceInteractor.swift */, - 0ABD1BE521469CE70027A7A2 /* AddressInteractor.swift */, - 0AF0C67121A97C4700602197 /* AliasesInteractor.swift */, - 0AF2536221B0351A00B8F7DF /* AssetsBalanceSettingsInteractor.swift */, - 0A1DAD6420F395F2004DA625 /* AssetsInteractor.swift */, - 0A5D3301215842860009CDF3 /* AuthorizationInteractor.swift */, - 0A2CD237216D0F0000162063 /* AuthorizationInteractorProtocol.swift */, - 0A344E2E2194747E007809B1 /* MigrationInteractor.swift */, - 0A5EC393213ED90F00659350 /* TransactionsInteractor.swift */, - ); - path = Interactor; - sourceTree = ""; - }; - 0A1DAD6620F396F4004DA625 /* Service */ = { - isa = PBXGroup; - children = ( - E94E4E6721CF9F6D00053A49 /* Coinomat */, - 0AD835FF217A0D10004413E9 /* GitHub */, - 0A8AFF262101EEEB00D0582B /* Matcher */, - 0A4C9AA920EF6B270095A417 /* Node */, - 0A93FECC20FCA7B80058179E /* Spam */, - 0A4C9AA820EF6B190095A417 /* Api */, - ); - path = Service; - sourceTree = ""; - }; - 0A1DAD6720F3971B004DA625 /* DataBase */ = { - isa = PBXGroup; - children = ( - 0AD8360C217A1DB2004413E9 /* WalletSeed */, - 0AD8360B217A1DA4004413E9 /* Wallet */, - 0AD83609217A1D7B004413E9 /* Wallets */, - ); - path = DataBase; - sourceTree = ""; - }; - 0A1DAD7420F3A696004DA625 /* Queries */ = { - isa = PBXGroup; - children = ( - 0A1DAD7520F3A6A6004DA625 /* ExchangeApiFilters.swift */, - E99DD81C21CEF09C0091AFEC /* CandleApiFilters.swift */, - ); - path = Queries; - sourceTree = ""; - }; 0A20606621822C1A0048CF83 /* AddressesKeys */ = { isa = PBXGroup; children = ( @@ -2226,52 +2734,6 @@ path = AddressesKeys; sourceTree = ""; }; - 0A218B7F215517E300B989A1 /* Wallets */ = { - isa = PBXGroup; - children = ( - 0A218B8421551D1400B989A1 /* WalletsRepositoryLocal.swift */, - 0A218B8D215534E000B989A1 /* WalletSeedRepositoryLocal.swift */, - ); - path = Wallets; - sourceTree = ""; - }; - 0A381EEF2106892700D250F1 /* Assisstants */ = { - isa = PBXGroup; - children = ( - E971DA5120FFF4B600616A03 /* BiometricManager.swift */, - 0A071E42215B0A1B007D9750 /* SigningWalletsProtocol.swift */, - 04E80A11214EF20C00D00AA4 /* SmartTransactionDomain+Assistants.swift */, - 7BF89E882226E00800853F9D /* SentryManager.swift */, - E9C1F5C5224D60B1006DBD8E /* ApplicationDebugSettings.swift */, - E98D14D02266B25500BE5481 /* CleanerWalletManager.swift */, - E944AA72224465BE0009F494 /* AnalyticManager */, - ); - path = Assisstants; - sourceTree = ""; - }; - 0A3FE8AF2136FE9B00DBF4E1 /* Transactions */ = { - isa = PBXGroup; - children = ( - 0A3FE8AD2136E51900DBF4E1 /* TransactionContainersNode.swift */, - 0A5B6E72211A3065005A7F09 /* IssueTransactionNode.swift */, - 0A5B6E74211A3103005A7F09 /* TransferTransactionNode.swift */, - 0A5B6E76211A3161005A7F09 /* ReissueTransactionNode.swift */, - 0A485E8C20FFB02100079B49 /* LeaseTransactionNode.swift */, - 0A5B6E7C211A3343005A7F09 /* LeaseCancelTransactionNode.swift */, - 0A5B6E7E211A3373005A7F09 /* AliasTransactionNode.swift */, - 0A5B6E70211A2F77005A7F09 /* MassTransferTransactionNode.swift */, - 0A5B6E78211A319C005A7F09 /* BurnTransactionNode.swift */, - 0A5B6E7A211A327C005A7F09 /* ExchangeTransactionNode.swift */, - 0A5B6E80211A33D9005A7F09 /* DataTransactionNode.swift */, - 0A5C53DC2139491C00667E34 /* UnrecognisedTransactionNode.swift */, - 0ADD804121F71FD90075FC59 /* ScriptTransactionNode.swift */, - 0ADD804321F72B2C0075FC59 /* AssetScriptTransactionNode.swift */, - 0AFB59412209B2BD001F0DD8 /* SponsorshipTransactionNode.swift */, - E9D0ED85225CB8400098C234 /* InvokeScriptTransactionNode.swift */, - ); - path = Transactions; - sourceTree = ""; - }; 0A4140E62174DFCD00B1310E /* AlertDeleteAccount */ = { isa = PBXGroup; children = ( @@ -2304,30 +2766,6 @@ path = Backup; sourceTree = ""; }; - 0A485E962100A89400079B49 /* Transaction */ = { - isa = PBXGroup; - children = ( - F74240B31EAB8D1600C3B84D /* Transaction.swift */, - 0A485E9D2100AE9B00079B49 /* IssueTransaction.swift */, - 0A485E992100A8ED00079B49 /* TransferTransaction.swift */, - 0A5E4BAE213801C400E3C3C3 /* ReissueTransaction.swift */, - 0A485E9F2100B0BD00079B49 /* LeaseTransaction.swift */, - 0A5E4BB02138034500E3C3C3 /* LeaseCancelTransaction.swift */, - 0A5E4BB22138046E00E3C3C3 /* AliasTransaction.swift */, - 0A5E4BB4213805B400E3C3C3 /* MassTransferTransaction.swift */, - 0A5E4BB621380B3300E3C3C3 /* BurnTransaction.swift */, - 0A485E9B2100A91500079B49 /* ExchangeTransaction.swift */, - 0A5E4BB921381E3400E3C3C3 /* DataTransaction.swift */, - 0A5C3201213D916900420004 /* AnyTransaction.swift */, - 0A5C3203213E93C700420004 /* UnrecognisedTransaction.swift */, - 0A57C38F21F74EB0003B5386 /* ScriptTransaction.swift */, - 0A57C39121F74EBA003B5386 /* AssetScriptTransaction.swift */, - 0AFB59432209B5F3001F0DD8 /* SponsorshipTransaction.swift */, - E9EE476C225E91ED0005176A /* InvokeScriptTransaction.swift */, - ); - path = Transaction; - sourceTree = ""; - }; 0A4B175F20FC028500F996F2 /* Presenter */ = { isa = PBXGroup; children = ( @@ -2365,58 +2803,6 @@ path = Wallet; sourceTree = ""; }; - 0A4C9AA820EF6B190095A417 /* Api */ = { - isa = PBXGroup; - children = ( - 0A5C918420F3CD0500443CE6 /* ApiServiceTypes.swift */, - 0A5C919D20F4B0B700443CE6 /* Services */, - 0A1DAD7420F3A696004DA625 /* Queries */, - 0A1DAD6020F37BA2004DA625 /* Models */, - ); - path = Api; - sourceTree = ""; - }; - 0A4C9AA920EF6B270095A417 /* Node */ = { - isa = PBXGroup; - children = ( - 0A1DAD6C20F39F94004DA625 /* NodeServiceTypes.swift */, - 0A5C919E20F4B0D000443CE6 /* Services */, - 0A5C919620F3DAEC00443CE6 /* Models */, - ); - path = Node; - sourceTree = ""; - }; - 0A4E7DE622018132007BBA39 /* Type */ = { - isa = PBXGroup; - children = ( - 7B951119225CD5B70030390C /* BiometricType.swift */, - 0ADD7F6521F22FB60075FC59 /* AssetLogo.swift */, - 0ADD7F5B21F22FB60075FC59 /* DisplayError.swift */, - 0ADD7F6121F22FB60075FC59 /* GlobalConstants.swift */, - 0ADD7F3F21F22FB60075FC59 /* MailCompose+Support.swift */, - 0ADD7F3321F22FB60075FC59 /* Notifications.swift */, - 0ADD7F3D21F22FB60075FC59 /* QRCodeReader+Factory.swift */, - 0ADD7F3021F22FB60075FC59 /* RateApp.swift */, - 0ADD7F4A21F22FB60075FC59 /* UIAlertController+Factory.swift */, - 0A4E7DE722018C3B007BBA39 /* Modal */, - ); - path = Type; - sourceTree = ""; - }; - 0A4E7DE722018C3B007BBA39 /* Modal */ = { - isa = PBXGroup; - children = ( - 0A4E7DE822018C5E007BBA39 /* ModalPresentationAnimatorContext.swift */, - 0A4E7DEB22018C5F007BBA39 /* ModalPresentationController.swift */, - 0A4E7DE922018C5E007BBA39 /* ModalViewControllerTransitioning.swift */, - 0A4E7DEA22018C5F007BBA39 /* ModalPresentationAnimator.swift */, - 0ADC179D2204A23000472130 /* ModalRootView.swift */, - 0ADC179F2204A24C00472130 /* ModalScrollViewController.swift */, - 0ADC17A12204A34100472130 /* ModalTableView.swift */, - ); - path = Modal; - sourceTree = ""; - }; 0A59331921870AC60059A77A /* Aliases */ = { isa = PBXGroup; children = ( @@ -2429,142 +2815,6 @@ path = Aliases; sourceTree = ""; }; - 0A5ABB9C21171A4F006A10A7 /* Assets */ = { - isa = PBXGroup; - children = ( - 0AEB35902115E44300EDD63C /* AssetsRepositoryLocal.swift */, - 0AEB35932115E45500EDD63C /* AssetsRepositoryRemote.swift */, - ); - path = Assets; - sourceTree = ""; - }; - 0A5ABB9F21171A75006A10A7 /* AccountBalance */ = { - isa = PBXGroup; - children = ( - 0AEB35A521165E1D00EDD63C /* AccountBalanceRepositoryLocal.swift */, - 0AEB35A321165E1300EDD63C /* AccountBalanceRepositoryRemote.swift */, - ); - path = AccountBalance; - sourceTree = ""; - }; - 0A5C919120F3D00D00443CE6 /* Assisstants */ = { - isa = PBXGroup; - children = ( - 7BBDA0B52226CA5C00A83411 /* NodePlugin.swift */, - 0A88CC01217D217D0083874C /* SpamCSV+Assisstants.swift */, - 0A5C919220F3D01500443CE6 /* Protocols */, - 0AE657322106374E003D2DB8 /* Types */, - ); - path = Assisstants; - sourceTree = ""; - }; - 0A5C919220F3D01500443CE6 /* Protocols */ = { - isa = PBXGroup; - children = ( - 0A7E0CD020F2AF6C0010CA6C /* BaseTargetType.swift */, - ); - path = Protocols; - sourceTree = ""; - }; - 0A5C919520F3D7D700443CE6 /* DomainLayer */ = { - isa = PBXGroup; - children = ( - 0A485E942100A0D400079B49 /* DomainLayerTypes.swift */, - 0A7643FD21187DF500B633E1 /* FactoryInteractors.swift */, - 0A7643F9211874F400B633E1 /* FactoryInteractorsProtocol.swift */, - 0A7643FF21187E3A00B633E1 /* FactoryRepositories.swift */, - 0A7643FB211876DF00B633E1 /* FactoryRepositoriesProtocol.swift */, - 0A381EEF2106892700D250F1 /* Assisstants */, - 0A1DAD6320F395E7004DA625 /* Interactor */, - 0A14CFCD2144157A00C3A4D5 /* Mapper */, - 0AEB358D2115DF8300EDD63C /* Models */, - E967786C21ECE12D00CE56D6 /* Queries */, - 0AEB358A2115DB1D00EDD63C /* Repositories */, - ); - path = DomainLayer; - sourceTree = ""; - }; - 0A5C919620F3DAEC00443CE6 /* Models */ = { - isa = PBXGroup; - children = ( - 0A5C919720F3DB1100443CE6 /* AccountBalanceNode.swift */, - 0A5C919920F3DB4C00443CE6 /* AccountAssetsBalanceNode.swift */, - 0A3FE8AF2136FE9B00DBF4E1 /* Transactions */, - 0ABD1BEB2146BFEE0027A7A2 /* BlockNode.swift */, - 0ADD803B21F5B60D0075FC59 /* AddressScriptInfoNode.swift */, - 0ADD803D21F5B7090075FC59 /* AssetDetailNode.swift */, - E9DDF73B2240F58800B83CFD /* UtilsNode.swift */, - ); - path = Models; - sourceTree = ""; - }; - 0A5C919D20F4B0B700443CE6 /* Services */ = { - isa = PBXGroup; - children = ( - 0A7E0CD820F2BCFF0010CA6C /* TransactionsApiService.swift */, - 0A4C9AAA20EF6BFF0095A417 /* AssetsApiService.swift */, - E99DD81A21CEE7690091AFEC /* CandlesApiService.swift */, - E9740E5D21D1C90F00EAD3ED /* PairsPriceApiService.swift */, - E991BB14220189530022E27D /* AliasApiService.swift */, - ); - path = Services; - sourceTree = ""; - }; - 0A5C919E20F4B0D000443CE6 /* Services */ = { - isa = PBXGroup; - children = ( - 0A1DAD7020F3A112004DA625 /* AddressesNodeService.swift */, - 0A1DAD7220F3A12B004DA625 /* AssetsNodeService.swift */, - 0A485E8A20FFAC6C00079B49 /* LeasingNodeService.swift */, - 0A5B6E6E211A2B6D005A7F09 /* TransactionNodeService.swift */, - 0ABD1BE92146BEED0027A7A2 /* BlocksNodeService.swift */, - E9DDF73F2240F5FD00B83CFD /* UtilsNodeService.swift */, - ); - path = Services; - sourceTree = ""; - }; - 0A5E4BBB213820C500E3C3C3 /* Transactions */ = { - isa = PBXGroup; - children = ( - 0ABD1BE721469D2F0027A7A2 /* AddressDomainDTO.swift */, - 0A5E4BC7213820C500E3C3C3 /* AliasTransactionDomainDTO.swift */, - 0A5E4BC6213820C500E3C3C3 /* AnyTransactionDomainDTO.swift */, - 0A5E4BC4213820C500E3C3C3 /* BurnTransactionDomainDTO.swift */, - 0A5E4BBC213820C500E3C3C3 /* DataTransactionDomainDTO.swift */, - 0A5E4BC2213820C500E3C3C3 /* ExchangeTransactionDomainDTO.swift */, - 0A5E4BC0213820C500E3C3C3 /* IssueTransactionDomainDTO.swift */, - 0A5E4BBD213820C500E3C3C3 /* LeaseCancelTransactionDomainDTO.swift */, - 0A5E4BC5213820C500E3C3C3 /* LeaseTransactionDomainDTO.swift */, - 0A5E4BBE213820C500E3C3C3 /* MassTransferTransactionDomainDTO.swift */, - 0A5E4BC3213820C500E3C3C3 /* ReissueTransactionDomainDTO.swift */, - 0A14CFC62141DA9800C3A4D5 /* SmartTransactionDomainDTO.swift */, - 0A5E4BC1213820C500E3C3C3 /* TransferTransactionDomainDTO.swift */, - 0A5C53DE2139498800667E34 /* UnrecognisedTransactionDomainDTO.swift */, - 0ADD804721F73C280075FC59 /* AssetScriptTransactionDomainDTO.swift */, - 0ADD804921F73C360075FC59 /* ScriptTransactionDomainDTO.swift */, - 0AFB59472209C2F8001F0DD8 /* SponsorshipTransactionDomainDTO.swift */, - E9D0ED87225CBDEA0098C234 /* InvokeScriptTransactionDomainDTO.swift */, - ); - path = Transactions; - sourceTree = ""; - }; - 0A5E4BD62138242C00E3C3C3 /* Transactions */ = { - isa = PBXGroup; - children = ( - 0A3FE8AB2136AF4B00DBF4E1 /* TransactionsRepositoryProtocol.swift */, - ); - path = Transactions; - sourceTree = ""; - }; - 0A5E4BD72138274A00E3C3C3 /* Transactions */ = { - isa = PBXGroup; - children = ( - 0A5C53E42139609600667E34 /* TransactionsRepositoryLocal.swift */, - 0A5E4BD82138297000E3C3C3 /* TransactionsRepositoryRemote.swift */, - ); - path = Transactions; - sourceTree = ""; - }; 0A5F953D2185FAB5005308AC /* AliasWithout */ = { isa = PBXGroup; children = ( @@ -2584,19 +2834,6 @@ path = Views; sourceTree = ""; }; - 0A6CCD3920F4BC730023E36E /* Mapper */ = { - isa = PBXGroup; - children = ( - 0AD8360D217DD34B004413E9 /* AccountSettings+Mapper.swift */, - 0A6CCD3A20F4CE250023E36E /* Asset+Mapper.swift */, - E90223C321D53A8F0057AA45 /* DexAssetPairDomainDTO+Mapper.swift */, - E967786A21EC660C00CE56D6 /* DexMyOrders+Mapper.swift */, - 0A218B882155221F00B989A1 /* Wallet+Mapper.swift */, - 0ADD804521F73ACE0075FC59 /* Transactions */, - ); - path = Mapper; - sourceTree = ""; - }; 0A6E2C8521CBBCBE006F4073 /* WavesPopup */ = { isa = PBXGroup; children = ( @@ -2639,14 +2876,15 @@ path = Views; sourceTree = ""; }; - 0A762D9E2163ACE80019D447 /* Support */ = { + 0A762D9E2163ACE80019D447 /* Debug */ = { isa = PBXGroup; children = ( + 7BD6E10322E5ACE000BAAFC8 /* View */, 0AFB593F2209AD56001F0DD8 /* TestViewController.swift */, 0A762D9F2163AD0F0019D447 /* Support.storyboard */, - 0A762DA12163AD1A0019D447 /* SupportViewController.swift */, + 7BD6E10122E50EB200BAAFC8 /* DebugViewController.swift */, ); - path = Support; + path = Debug; sourceTree = ""; }; 0A762DA321650DA80019D447 /* Profile */ = { @@ -2703,37 +2941,6 @@ path = Views; sourceTree = ""; }; - 0A8AFF262101EEEB00D0582B /* Matcher */ = { - isa = PBXGroup; - children = ( - 0A8AFF272101F37200D0582B /* MatcherServiceTypes.swift */, - 0A8AFF292101F47F00D0582B /* OrderBookMatcherService.swift */, - 0AE657302106368F003D2DB8 /* BalanceMatcherService.swift */, - E96E29FD21D3492F00AC2FA9 /* MatcherService.swift */, - E97D450E21C814A0000E3C48 /* Models */, - ); - path = Matcher; - sourceTree = ""; - }; - 0A93FECC20FCA7B80058179E /* Spam */ = { - isa = PBXGroup; - children = ( - 0A2B7D3A216038F70098438D /* AssetsSpamService.swift */, - 0A2B7D38216038A80098438D /* SpamService.swift */, - ); - path = Spam; - sourceTree = ""; - }; - 0A93FED120FCAAA30058179E /* PresentationLayer */ = { - isa = PBXGroup; - children = ( - 0ADD7FF721F22FFA0075FC59 /* Coordinators */, - 0AF92281212E1234003BA067 /* CustomViews */, - 0AF58F8B2191909200C8A4B3 /* Modules */, - ); - path = PresentationLayer; - sourceTree = ""; - }; 0A96F1C921519965005E148F /* View */ = { isa = PBXGroup; children = ( @@ -2782,17 +2989,9 @@ 0A979752210885B500407F67 /* Resources */ = { isa = PBXGroup; children = ( + 7BFB474D22FC5AD0002B19F8 /* CommonResources */, 7B5EDEC32253618C009C2B3B /* AccessibilityIdentifiers.strings */, F7C683BC1EA93C5800C87DAF /* ObjCBridgingHeader.h */, - 0A2060622181C2C10048CF83 /* environment_mainnet.json */, - 0A2060632181C2C20048CF83 /* environment_testnet.json */, - 0A61B599214ACFD500EC60FC /* Languages.json */, - 0A02D20621AEA1B1005DF820 /* Appsflyer-Info.plist */, - 0AADFD0521F9F4AB001F5C0A /* AppSpector-Info.plist */, - 04D4431A21885F4F009CEB22 /* Fabric-Info.plist */, - 0A150821219B0D6B00516037 /* GoogleService-Info.plist */, - 0AFB59492209F167001F0DD8 /* Sentry-io-Info.plist */, - E944AA6E22444B780009F494 /* Amplitude-Info.plist */, F7E954F01EA8FE0700A804DE /* Assets.xcassets */, 0AEFC74F21BAA4380085D6D1 /* Localization */, ); @@ -2810,29 +3009,6 @@ path = Wallet; sourceTree = ""; }; - 0A979775210A19B400407F67 /* Repositories */ = { - isa = PBXGroup; - children = ( - 7BAA9F7C22A03329003B6D01 /* ApplicationVersionRepository.swift */, - 0A88CC07217D281F0083874C /* AccountEnvironmentRepository.swift */, - 0ADD803F21F5D2DD0075FC59 /* AddressRepositoryRemote.swift */, - 0AF2536421B6C2F900B8F7DF /* AssetsBalanceSettingsRepositoryLocal.swift */, - 0A218B9621555A4B00B989A1 /* AuthenticationRepositoryRemote.swift */, - 0AAC2A472146C69600F6EB27 /* BlockRepositoryRemote.swift */, - E910B7E821C3261B00E402AB /* CoinomatRepository.swift */, - 0A751D35221711380024D523 /* NotificationNewsRepository.swift */, - E9DDF7392240F52D00B83CFD /* EnvironmentRepository.swift */, - 0A5ABB9F21171A75006A10A7 /* AccountBalance */, - E94A7005215AEAFB001814F7 /* AddressBook */, - 0AF0C67521A97D3900602197 /* Aliases */, - 0A5ABB9C21171A4F006A10A7 /* Assets */, - E97D450621C801C4000E3C48 /* Dex */, - 0A5E4BD72138274A00E3C3C3 /* Transactions */, - 0A218B7F215517E300B989A1 /* Wallets */, - ); - path = Repositories; - sourceTree = ""; - }; 0AACD59721A59E6300B30815 /* SweetSnackbar */ = { isa = PBXGroup; children = ( @@ -2856,49 +3032,6 @@ path = Profile; sourceTree = ""; }; - 0AD835FF217A0D10004413E9 /* GitHub */ = { - isa = PBXGroup; - children = ( - 0AD83600217A0D25004413E9 /* GitHubService.swift */, - 0A84F00221F4C68000C0B7DB /* TransactionFeeRulesGitHub.swift */, - ); - path = GitHub; - sourceTree = ""; - }; - 0AD83609217A1D7B004413E9 /* Wallets */ = { - isa = PBXGroup; - children = ( - 0AD8360A217A1D95004413E9 /* Model */, - ); - path = Wallets; - sourceTree = ""; - }; - 0AD8360A217A1D95004413E9 /* Model */ = { - isa = PBXGroup; - children = ( - 0A4C9AA020EE65800095A417 /* WalletItem.swift */, - 0AF58FA021931AD400C8A4B3 /* WalletEncryption.swift */, - ); - path = Model; - sourceTree = ""; - }; - 0AD8360B217A1DA4004413E9 /* Wallet */ = { - isa = PBXGroup; - children = ( - 0A88CC09217E80040083874C /* WalletRealmFactory.swift */, - F74240B01EAB8D1600C3B84D /* Model */, - ); - path = Wallet; - sourceTree = ""; - }; - 0AD8360C217A1DB2004413E9 /* WalletSeed */ = { - isa = PBXGroup; - children = ( - 0A4C9AA220EE65910095A417 /* SeedItem.swift */, - ); - path = WalletSeed; - sourceTree = ""; - }; 0AD8360F217DD77F004413E9 /* Network */ = { isa = PBXGroup; children = ( @@ -2925,85 +3058,46 @@ 0ADD7F1E21F22FB60075FC59 /* Extensions */ = { isa = PBXGroup; children = ( - 7B951136225CF7A00030390C /* Reachability+Shared.swift */, - 7BDA6AD4222D8C81001DE71C /* System.swift */, - 7B951134225CDAA80030390C /* CGSize+Hashable.swift */, - 7B951132225CDA9F0030390C /* Decimal+Assisstants.swift */, - 7B95112A225CDA860030390C /* Balance.swift */, - 7B95112B225CDA870030390C /* Money.swift */, - 7B95112C225CDA870030390C /* MoneyUtil.swift */, - 7B95112D225CDA880030390C /* Sync.swift */, - 7B95111F225CD6710030390C /* Type */, - 7B951114225CD4EC0030390C /* UIKit */, - 7B951115225CD55F0030390C /* Mutating.swift */, - 7B951117225CD5850030390C /* DatabaseReference+Rx.swift */, - 7B95111B225CD5EE0030390C /* Results+Limit.swift */, - 7B95111D225CD6140030390C /* RunLoopThreadScheduler.swift */, - 7B95115E225F7BA80030390C /* DateFormatter+UI.swift */, - E92A8DE02278ACFF0009DF27 /* TSUD+Rx.swift */, + 7BFB47F822FC742E002B19F8 /* AuthorizationInteractorLocalizableImp.swift */, + 7B97B0BB22FD92AC008BA3F4 /* AssetLogo+Styles.swift */, + 7BFB47FA22FC742F002B19F8 /* BiometricManager+String.swift */, + 7B97B05422FC784F008BA3F4 /* DateFormatter+UI.swift */, + 7BFB47F922FC742E002B19F8 /* NSAttributedString+Styles.swift */, + 7BFB47DD22FC742C002B19F8 /* SmartTransactionDTO+EncodingToString.swift */, + 7BFB47E122FC742E002B19F8 /* SmartTransactionKind+UIImage.swift */, + 7B97B04722FC784F008BA3F4 /* UIViewController+Additionals.swift */, + 7BFB47FE22FC742F002B19F8 /* Analytics */, + 7BFB47DF22FC742D002B19F8 /* Mock */, + 7BFB47FB22FC742F002B19F8 /* Type */, + 7BFB47E222FC742E002B19F8 /* UIKit */, + 7B88186123044B7F00AB0549 /* Language+List.swift */, + 7B3A9AB5231D66B80025CDCA /* NetworkError+Title.swift */, ); path = Extensions; sourceTree = ""; }; - 0ADD7F7D21F22FB60075FC59 /* Protocols */ = { - isa = PBXGroup; - children = ( - 0ADD7F8721F22FB60075FC59 /* SectionDisplayCollection.swift */, - 0ADD7F8621F22FB60075FC59 /* ViewCalculate.swift */, - 0ADD7F8421F22FB60075FC59 /* ViewConfiguration.swift */, - 0ADD7F8121F22FB60075FC59 /* Module */, - 0ADD7F8821F22FB60075FC59 /* Reusable */, - 0ADD7F7E21F22FB60075FC59 /* Skeleton */, - ); - path = Protocols; - sourceTree = ""; - }; - 0ADD7F7E21F22FB60075FC59 /* Skeleton */ = { - isa = PBXGroup; - children = ( - 0ADD7F7F21F22FB60075FC59 /* UITableView+Skeleton.swift */, - 0ADD7F8021F22FB60075FC59 /* SkeletonAnimatable.swift */, - ); - path = Skeleton; - sourceTree = ""; - }; - 0ADD7F8121F22FB60075FC59 /* Module */ = { - isa = PBXGroup; - children = ( - 0ADD7F8221F22FB60075FC59 /* ModuleBuilderOutput.swift */, - 0ADD7F8321F22FB60075FC59 /* ModuleBuilder.swift */, - ); - path = Module; - sourceTree = ""; - }; - 0ADD7F8821F22FB60075FC59 /* Reusable */ = { - isa = PBXGroup; - children = ( - 0ADD7F8921F22FB60075FC59 /* UICollectionView+Reusable.swift */, - 0ADD7F8A21F22FB60075FC59 /* Reusable.swift */, - 0ADD7F8B21F22FB60075FC59 /* UITableView+Reusable.swift */, - 0ADD7F8C21F22FB60075FC59 /* NibLoadable.swift */, - 0ADD7F8D21F22FB60075FC59 /* NibOwnerLoadable.swift */, - ); - path = Reusable; - sourceTree = ""; - }; 0ADD7FF721F22FFA0075FC59 /* Coordinators */ = { isa = PBXGroup; children = ( + E9B387CE23690DCD001FCA60 /* SendCoordinator.swift */, + 7BE09AB12313E31300A038AD /* MobileKeeperCoordinator.swift */, 0ADD800321F22FFA0075FC59 /* AppCoordinator.swift */, + 0A751D37221715F80024D523 /* AppNewsCoordinator.swift */, + E9845D3A2374645900716515 /* PushNotificationsCoordinator.swift */, 0ADD7FF821F22FFA0075FC59 /* DexCoordinator.swift */, + E902BBCF236A664300141CF4 /* DexDeepLinkCoordinator.swift */, 0ADD801C21F22FFA0075FC59 /* MainTabBarCoordinator.swift */, 0ADD800E21F22FFA0075FC59 /* QRCodeReaderControllerCoordinator.swift */, 0ADD801821F22FFA0075FC59 /* SlideCoordinator.swift */, 0ADD800421F22FFA0075FC59 /* WalletCoordinator.swift */, + 7B8818772305926E00AB0549 /* WidgetSettingsCoordinator.swift */, 0ADD801921F22FFA0075FC59 /* Backup */, 0ADD7FF921F22FFA0075FC59 /* CoordinatorKit */, 0ADD800621F22FFA0075FC59 /* Enter */, 0ADD801221F22FFA0075FC59 /* History */, 0ADD801521F22FFA0075FC59 /* Passcode */, 0ADD800F21F22FFA0075FC59 /* Profile */, - 0A751D37221715F80024D523 /* AppNewsCoordinator.swift */, + 7B26A88822ED17EC00E7B024 /* UITest */, ); path = Coordinators; sourceTree = ""; @@ -3027,6 +3121,7 @@ 0ADD800021F22FFA0075FC59 /* Router.swift */, 0ADD800121F22FFA0075FC59 /* TabBarRouter.swift */, 0ADD800221F22FFA0075FC59 /* SlideMenuRouter.swift */, + 7B9B326022E6004700DB1C59 /* DebugRootView.swift */, ); path = Router; sourceTree = ""; @@ -3082,88 +3177,6 @@ path = Backup; sourceTree = ""; }; - 0ADD804521F73ACE0075FC59 /* Transactions */ = { - isa = PBXGroup; - children = ( - 0A485EA12100C4FA00079B49 /* LeaseTransaction+Mapper.swift */, - 0A5E4BDA21382C2200E3C3C3 /* IssueTransaction+Mapper.swift */, - 0A5E4BDC2138311C00E3C3C3 /* TransferTransaction+Mapper.swift */, - 0A5E4BDE213832A000E3C3C3 /* ReissueTransaction+Mapper.swift */, - 0A5E4BE02138378500E3C3C3 /* LeaseCancelTransaction+Mapper.swift */, - 0A5E4BE22138395200E3C3C3 /* AliasTransaction+Mapper.swift */, - 0A5E4BE421383B3600E3C3C3 /* MassTransferTransaction+Mapper.swift */, - 0A5E4BE621383E1600E3C3C3 /* BurnTransaction+Mapper.swift */, - 0A5E4BE821383F3D00E3C3C3 /* ExchangeTransaction+Mapper.swift */, - 0A98D1492138910600550FE0 /* DataTransaction+Mapper.swift */, - 0A5C53E021394A2B00667E34 /* UnrecognisedTransaction+Mapper.swift */, - 0A98D14B2138A30700550FE0 /* AnyTransaction+Mapper.swift */, - 0A57C38B21F74E20003B5386 /* ScriptTransaction+Mapper.swift */, - 0A57C38D21F74E2E003B5386 /* AssetScriptTransaction+Mapper.swift */, - 0AFB59452209C20E001F0DD8 /* SponsorshipTransaction+Mapper.swift */, - E9D0ED89225CBECA0098C234 /* InvokeScriptTransaction+Mapper.swift */, - ); - path = Transactions; - sourceTree = ""; - }; - 0AE657322106374E003D2DB8 /* Types */ = { - isa = PBXGroup; - children = ( - 0AE6572E2106340A003D2DB8 /* Signature.swift */, - 0AE657332106375D003D2DB8 /* TimestampSignature.swift */, - ); - path = Types; - sourceTree = ""; - }; - 0AEB358A2115DB1D00EDD63C /* Repositories */ = { - isa = PBXGroup; - children = ( - 7BAA9F7E22A03361003B6D01 /* ApplicationVersionRepositoryProtocol.swift */, - 0A00B184221AE325005A9053 /* AssetsBalanceSettingsRepositoryProtocol.swift */, - 0A88CC03217D27370083874C /* AccountSettingsRepositoryProtocol.swift */, - 0A84F00021F4BBA000C0B7DB /* AddressRepositoryProtocol.swift */, - 0A6AC3E321848920005D2525 /* AliasesRepositoryProtocol.swift */, - 0A218B94215556F600B989A1 /* AuthenticationRepositoryProtocol.swift */, - 0AAC2A452146C65900F6EB27 /* BlockRepositoryProtocol.swift */, - E9BB724721C2A94000B2AF7E /* CoinomatRepositoryProtocol.swift */, - 0A4508F92178938C00EBF669 /* EnvironmentRepositoryProtocol.swift */, - 0A751D3122170EF60024D523 /* NotificationNewsRepositoryProtocol.swift */, - 0A218B8A2155335F00B989A1 /* WalletSeedRepositoryProtocol.swift */, - 0A218B8621551E6600B989A1 /* WalletsRepositoryProtocol.swift */, - 0AEB359521160E1700EDD63C /* AccountBalance */, - E94A7002215AEA2A001814F7 /* AddressBook */, - 0AEB35922115E44A00EDD63C /* Assets */, - E97D450721C8020F000E3C48 /* Dex */, - 0A5E4BD62138242C00E3C3C3 /* Transactions */, - ); - path = Repositories; - sourceTree = ""; - }; - 0AEB358D2115DF8300EDD63C /* Models */ = { - isa = PBXGroup; - children = ( - 0AC33AEF21A826B700B66747 /* NetworkError.swift */, - E9BCF48021636DAC00FA6502 /* ResponseType.swift */, - 0A00B188221AE708005A9053 /* DTO */, - ); - path = Models; - sourceTree = ""; - }; - 0AEB35922115E44A00EDD63C /* Assets */ = { - isa = PBXGroup; - children = ( - 0AEB358B2115DB3C00EDD63C /* AssetsRepositoryProtocol.swift */, - ); - path = Assets; - sourceTree = ""; - }; - 0AEB359521160E1700EDD63C /* AccountBalance */ = { - isa = PBXGroup; - children = ( - 0AEB35A121165D2100EDD63C /* AccountBalanceRepositoryProtocol.swift */, - ); - path = AccountBalance; - sourceTree = ""; - }; 0AEFC74E21BAA4220085D6D1 /* InfoPlist */ = { isa = PBXGroup; children = ( @@ -3189,27 +3202,23 @@ path = Waves; sourceTree = ""; }; - 0AF0C67521A97D3900602197 /* Aliases */ = { - isa = PBXGroup; - children = ( - 0AF0C67821AA25B200602197 /* AliasesRepository.swift */, - 0AF0C67321A97D3500602197 /* AliasesRepositoryLocal.swift */, - ); - path = Aliases; - sourceTree = ""; - }; 0AF58F8B2191909200C8A4B3 /* Modules */ = { isa = PBXGroup; children = ( - 7BDA6AD3222D8AEA001DE71C /* TransactionCard */, + E923956C237518B7009C4091 /* PushNotifictions */, + E9C1B90C236C6D7400F8E988 /* ForceUpdateApp */, + 7BE09AD123140EF800A038AD /* MobileKeeper */, 0A071E3D215AEF03007D9750 /* AccountPassword */, + 7B8818652305639600AB0549 /* ActionSheet */, E9B086902163882F00937644 /* AddressBook */, E9236F192216F2FE00A12FD5 /* AppNews */, 0AF921BE212E07B2003BA067 /* Asset */, E9D36DB52175C754001E6DF0 /* AssetList */, + 7B26A88422ED16A400E7B024 /* AssetsSearch */, 0A4399672150470E0032E608 /* Backup */, 0A4140E72174F08600B1310E /* ChangePassword */, 0A071E78215DB084007D9750 /* ChooseAccount */, + 0A762D9E2163ACE80019D447 /* Debug */, E9B086BF2163886800937644 /* Dex */, E9F984A720E5266800D2CB4D /* Enter */, E95B47A521638A9F004D4E39 /* Hello */, @@ -3225,12 +3234,13 @@ E9D36D6B2175C754001E6DF0 /* Receive */, E9EC5B352175F35800E5C29A /* Send */, E95B47D421638B11004D4E39 /* StartLeasing */, - 0A762D9E2163ACE80019D447 /* Support */, E95B6B08219B3ADF00A85B5D /* TokenBurn */, + 7BDA6AD3222D8AEA001DE71C /* TransactionCard */, 0A071E62215C65BC007D9750 /* UseTouchID */, 0A97975E2108A10400407F67 /* Wallet */, 0A6E2C8521CBBCBE006F4073 /* WavesPopup */, 0AFA0C732174A2300003FE3B /* WebView */, + 7B26A87B22ED127600E7B024 /* WidgetSettings */, ); path = Modules; sourceTree = ""; @@ -3384,50 +3394,52 @@ 0AF92281212E1234003BA067 /* CustomViews */ = { isa = PBXGroup; children = ( - E9F78A3E229E990D0065324B /* ScrolledContainerView.swift */, - E9F78A3C229E98B40065324B /* NewSegmentedControl.swift */, - 7BDA6AE722313E59001DE71C /* TransactionImageView.swift */, - 7BDA6AE922313E85001DE71C /* TransactionImageView.xib */, - 7BDA6AF122315024001DE71C /* ContactDetailView.swift */, - 7BDA6AF322315466001DE71C /* ContactDetailView.xib */, - 7B39029622366D0100AAFDB8 /* AddressBookButton.swift */, 7B3902A62237A74900AAFDB8 /* ActionsControl.swift */, 7B3902A82237A75600AAFDB8 /* ActionsControl.xib */, + 7B39029622366D0100AAFDB8 /* AddressBookButton.swift */, + 0AF9228D212E1234003BA067 /* AssetSegmented */, + 7BDA6AE5223028DC001DE71C /* BalanceLabel.swift */, + 7BDA6AE1223025AD001DE71C /* BalanceLabel.xib */, E9310D1C217942C8008BF3EE /* BlueBgView.swift */, 0AF922A2212E1234003BA067 /* BorderButtView.swift */, 0AF922A1212E1234003BA067 /* CenteringContentButton.swift */, + 7BDA6AF122315024001DE71C /* ContactDetailView.swift */, + 7BDA6AF322315466001DE71C /* ContactDetailView.xib */, 0AF6AD24218A54840004F107 /* CopyableImageView.swift */, 0AF92295212E1234003BA067 /* CopyableLabel.swift */, 04831F8321697A4F006D1ED6 /* CustomGradientView.swift */, - F7C683BA1EA93C5800C87DAF /* CustomNavigationController.swift */, E95E150E22A18B66003552B8 /* CustomNavigationBar.swift */, + F7C683BA1EA93C5800C87DAF /* CustomNavigationController.swift */, + 7BD6E0FD22E228DC00BAAFC8 /* DebugView.swift */, + 7BD6E0FF22E228F000BAAFC8 /* DebugView.xib */, 0AF9228C212E1234003BA067 /* DottedLineView.swift */, E9C4134B20E826E300AA044F /* DottedRoundView.swift */, 0ACC0232217E2BA1000E3EE0 /* DynamicHeaderTableView.swift */, 0AF92288212E1234003BA067 /* EmptyCell.swift */, + 0AF9228A212E1234003BA067 /* EmptyCell.xib */, 0AF0C67A21AACA4F00602197 /* GlobalErrorView.swift */, + 0AF0C67C21AACB3700602197 /* GlobalErrorView.xib */, 0AF922A3212E1234003BA067 /* GradientView.swift */, - E92D9BFE2148740B006D6D6B /* InputScrollButtonsView.swift */, + 0AF92283212E1234003BA067 /* HalfModalPresentationController */, + 7BDC6D7822C3CD8400614E6B /* InputScrollButtonsView.swift */, 0AF922A5212E1234003BA067 /* NavigationAccessoryView.swift */, + E9F78A3C229E98B40065324B /* NewSegmentedControl.swift */, + 0A96F1CF2151B6A9005E148F /* Passcode */, 0ADD7F3B21F22FB60075FC59 /* PasteboardButton.swift */, E904525920B4EF4200A490E5 /* PopupViewController.swift */, E980EACD20A9F5BF001834DB /* ScannerCustomView.swift */, + E9F78A3E229E990D0065324B /* ScrolledContainerView.swift */, + 0AF92298212E1234003BA067 /* SegmentedControl */, 0AF92296212E1234003BA067 /* SeparatorView.swift */, 0A43996821504CF60032E608 /* SideMenu.swift */, - 0AF92297212E1234003BA067 /* TickerView.swift */, - 0A762D9621639FCC0019D447 /* WavesButton.swift */, - 7BDA6AE5223028DC001DE71C /* BalanceLabel.swift */, - 7BDA6AE1223025AD001DE71C /* BalanceLabel.xib */, - 0AF9228A212E1234003BA067 /* EmptyCell.xib */, - 0AF0C67C21AACB3700602197 /* GlobalErrorView.xib */, - 0AF92282212E1234003BA067 /* TickerView.xib */, - 0AF9228D212E1234003BA067 /* AssetSegmented */, - 0AF92283212E1234003BA067 /* HalfModalPresentationController */, - 0A96F1CF2151B6A9005E148F /* Passcode */, - 0AF92298212E1234003BA067 /* SegmentedControl */, 0AF92292212E1234003BA067 /* Skeleton */, 0AACD59721A59E6300B30815 /* SweetSnackbar */, + 0AF92297212E1234003BA067 /* TickerView.swift */, + 0AF92282212E1234003BA067 /* TickerView.xib */, + 7BDA6AE722313E59001DE71C /* TransactionImageView.swift */, + 7BDA6AE922313E85001DE71C /* TransactionImageView.xib */, E9A2268B2159666E006E0CE1 /* UIKit */, + 0A762D9621639FCC0019D447 /* WavesButton.swift */, ); path = CustomViews; sourceTree = ""; @@ -3489,10 +3501,142 @@ F76AF1E91EBB43E00081A8BD /* SwiftBase58.framework.dSYM */, F7C683DC1EA94ECA00C87DAF /* SwiftGMP.framework */, F7C683DD1EA94ECA00C87DAF /* SwiftGMP.framework.dSYM */, - B2F04F55A260735DF3584D3E /* Pods_WavesWallet_iOS.framework */, - 2F182E1185D069FB9F0228C7 /* Pods_MonkeyTest.framework */, ); name = Frameworks; + path = ..; + sourceTree = ""; + }; + 34D3652B38B4C48A2B987569 /* Pods */ = { + isa = PBXGroup; + children = ( + AD61D54FAF8C35F7FE42B48C /* Pods-DataLayer.dev-debug.xcconfig */, + 4002342AE27E8283A7330127 /* Pods-DataLayer.dev-adhoc.xcconfig */, + 8C9A1159470FED7057790330 /* Pods-DataLayer.release-prod.xcconfig */, + 30B16B6ED15D84C95E9C0700 /* Pods-DataLayer.release-dev.xcconfig */, + FBF207267CD94C94CF647176 /* Pods-DataLayer.test-dev.xcconfig */, + 95576FFA8929D9E05D7BF2BE /* Pods-DataLayer.test-prod.xcconfig */, + A79335F0C0282C9BC73BC68E /* Pods-DataLayerTests.dev-debug.xcconfig */, + 14D96B733AE3D2EDCB81A40F /* Pods-DataLayerTests.dev-adhoc.xcconfig */, + FD35BB6367E2BF6D13D33388 /* Pods-DataLayerTests.release-prod.xcconfig */, + C880B220C9E5499780C35467 /* Pods-DataLayerTests.release-dev.xcconfig */, + DD32EC8514D2E93CE1593C7F /* Pods-DataLayerTests.test-dev.xcconfig */, + BAA94A74B517FBB13852F114 /* Pods-DataLayerTests.test-prod.xcconfig */, + 45AA58BA32AC1AF6D19F9EEF /* Pods-DomainLayer.dev-debug.xcconfig */, + 358F7A355EB990FE9BE8A2BE /* Pods-DomainLayer.dev-adhoc.xcconfig */, + 79716E63B228F54DC963B57A /* Pods-DomainLayer.release-prod.xcconfig */, + CEB61763B0920D458B8C82AE /* Pods-DomainLayer.release-dev.xcconfig */, + 613D35B159856DDD30F86C98 /* Pods-DomainLayer.test-dev.xcconfig */, + BDE6D164A37B938C860EDF5F /* Pods-DomainLayer.test-prod.xcconfig */, + D0CCB8B5087EC114938067B4 /* Pods-DomainLayerTests.dev-debug.xcconfig */, + DAD260D2DDC7E839EDD12EA6 /* Pods-DomainLayerTests.dev-adhoc.xcconfig */, + E750B898EC2D32D49A39F690 /* Pods-DomainLayerTests.release-prod.xcconfig */, + F65361A881CC9B52F2835293 /* Pods-DomainLayerTests.release-dev.xcconfig */, + DF56F95985E2EA4D53A570EC /* Pods-DomainLayerTests.test-dev.xcconfig */, + AAE0DD42A072FF6782D8699E /* Pods-DomainLayerTests.test-prod.xcconfig */, + 330A6CFEA80C3C564AC3C090 /* Pods-Extensions.dev-debug.xcconfig */, + 8E83213560285F82F0869981 /* Pods-Extensions.dev-adhoc.xcconfig */, + 15AE893AD1EB53FBCDA161D5 /* Pods-Extensions.release-prod.xcconfig */, + 8A551BA048F9720698C5BF39 /* Pods-Extensions.release-dev.xcconfig */, + B7A25F7D6E4B1692329D7BF7 /* Pods-Extensions.test-dev.xcconfig */, + 5B93090B2CB93A36B3FC8D0F /* Pods-Extensions.test-prod.xcconfig */, + 39D072CCF146C6CC2C64586F /* Pods-MarketPulseWidget.dev-debug.xcconfig */, + 7BDD7F47C7597E6AD76837FD /* Pods-MarketPulseWidget.dev-adhoc.xcconfig */, + 09C7B309A88856F7E5362438 /* Pods-MarketPulseWidget.release-prod.xcconfig */, + 1E821BB79863BE6E2DFD41B1 /* Pods-MarketPulseWidget.release-dev.xcconfig */, + ABBE8EE95A2EDD196C036A99 /* Pods-MarketPulseWidget.test-dev.xcconfig */, + 4A5FEAF1E09BD85095F7190B /* Pods-MarketPulseWidget.test-prod.xcconfig */, + 7AE17C6CE90449256074E98F /* Pods-MonkeyTest.dev-debug.xcconfig */, + A9E634B5E087D00A1F31D61E /* Pods-MonkeyTest.dev-adhoc.xcconfig */, + 42540834023E32A59FAD0948 /* Pods-MonkeyTest.release-prod.xcconfig */, + 8B03F78A9DF177D8D9723E8D /* Pods-MonkeyTest.release-dev.xcconfig */, + 664726FDDF58367CA0C7AEFA /* Pods-MonkeyTest.test-dev.xcconfig */, + 0F5A04DF94D5267FF54BF4A9 /* Pods-MonkeyTest.test-prod.xcconfig */, + 16E2A809803D77F7ACA94D8C /* Pods-WavesWallet-iOS.dev-debug.xcconfig */, + D206585280B732B56334628E /* Pods-WavesWallet-iOS.dev-adhoc.xcconfig */, + 344A99254C39E6D45BA6BFEE /* Pods-WavesWallet-iOS.release-prod.xcconfig */, + 7A79F97385011A8CE0363A70 /* Pods-WavesWallet-iOS.release-dev.xcconfig */, + 5E9E95698304826A9178CFEB /* Pods-WavesWallet-iOS.test-dev.xcconfig */, + 42BA6C1489543A7B9FBD6970 /* Pods-WavesWallet-iOS.test-prod.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; + 7B26A87B22ED127600E7B024 /* WidgetSettings */ = { + isa = PBXGroup; + children = ( + 7BB03E4822EF2C6D008F179D /* Views */, + 7B26A87C22ED129300E7B024 /* WidgetSettings.storyboard */, + 7B26A87E22ED13F300E7B024 /* WidgetSettingsViewController.swift */, + 7B26A88022ED140000E7B024 /* WidgetSettingsType.swift */, + 7B26A88222ED14DA00E7B024 /* WidgetSettingsSystem.swift */, + 7B26A88B22ED191900E7B024 /* WidgetSettingsModuleBuilder.swift */, + 7B26A88D22EEEA7000E7B024 /* WidgetSettingsModuleOutput.swift */, + ); + path = WidgetSettings; + sourceTree = ""; + }; + 7B26A88422ED16A400E7B024 /* AssetsSearch */ = { + isa = PBXGroup; + children = ( + 7B49911822F874CC005B7123 /* View */, + 7B49912722F87C7A005B7123 /* AssetsSearchSystem.swift */, + 7B49911622F874B0005B7123 /* AssetsSearchViewController.swift */, + 7B49911D22F875A1005B7123 /* AssetsSearchViewBuilder.swift */, + 7B49911B22F8754A005B7123 /* AssetsSearch.swift */, + 7B49911F22F875D4005B7123 /* AssetsSearch.storyboard */, + 7B49912D22F9B470005B7123 /* AssetsSearchModuleOutput.swift */, + ); + path = AssetsSearch; + sourceTree = ""; + }; + 7B26A88722ED16DF00E7B024 /* Cells */ = { + isa = PBXGroup; + children = ( + 7B26A88F22EEECC200E7B024 /* WidgetSettingsAssetCell.swift */, + 7B65B6F222F9D03E007D5C53 /* WidgetSettingsSkeletonCell.swift */, + ); + path = Cells; + sourceTree = ""; + }; + 7B26A88822ED17EC00E7B024 /* UITest */ = { + isa = PBXGroup; + children = ( + 7B26A88922ED180A00E7B024 /* UIDeveloperCoordinator.swift */, + ); + path = UITest; + sourceTree = ""; + }; + 7B368196231425ED000D5592 /* ConfirmRequest */ = { + isa = PBXGroup; + children = ( + 7B0FD98A23196C430004B52B /* ConfirmRequestDTORequest+Mapper.swift */, + 7B0FD98623195D6A0004B52B /* ConfirmRequestCompleteViewController.swift */, + 7B0FD98823196A3F0004B52B /* ConfirmRequestDTOTransaction+Mapper.swift */, + 7B0FD984231952740004B52B /* ConfirmRequestLoadingViewController.swift */, + 7B36819E23142A0F000D5592 /* ConfirmRequestModuleBuilder.swift */, + 7B3681A023142A33000D5592 /* ConfirmRequestModuleOutput.swift */, + 7B36819C23142639000D5592 /* ConfirmRequestSystem.swift */, + 7B36819923142625000D5592 /* ConfirmRequestType.swift */, + 7B3681972314260C000D5592 /* ConfirmRequestViewController.swift */, + 7B3681A52315531B000D5592 /* Views */, + ); + path = ConfirmRequest; + sourceTree = ""; + }; + 7B3681A52315531B000D5592 /* Views */ = { + isa = PBXGroup; + children = ( + 7B60E2BD2316CC0400113C38 /* ConfirmRequestTransactionKindView.xib */, + 7B60E2BB2316CBEA00113C38 /* ConfirmRequestTransactionKindView.swift */, + 7B3681A62315534E000D5592 /* ConfirmRequestTransactionKindCell.swift */, + 7B3681A823155499000D5592 /* ConfirmRequestFromToCell.swift */, + 7B3681AA231555B8000D5592 /* ConfirmRequestKeyValueCell.swift */, + 7B3681AC231556B4000D5592 /* ConfirmRequestFeeAndTimestampCell.swift */, + 7B3681AE23155805000D5592 /* ConfirmRequestBalanceCell.swift */, + 7B3681B02315612C000D5592 /* ConfirmRequestSkeletonCell.swift */, + 7B2407FF2317F26100D35F59 /* ConfirmRequestButtonsCell.swift */, + ); + path = Views; sourceTree = ""; }; 7B3902AE2237D74400AAFDB8 /* Cell */ = { @@ -3516,2132 +3660,3678 @@ 7B39029C2236ABFF00AAFDB8 /* TransactionCardStatusCell.swift */, E9BB2D842260DEB000366278 /* TransactionCardInvokeScriptCell.swift */, E97667CD227F0F8B0050E0D6 /* TransactionCardOrderFilledCell.swift */, + E9443BA722DCCC2B00AFF151 /* TransactionCardExchangeFeeCell.swift */, ); path = Cell; sourceTree = ""; }; - 7B951114225CD4EC0030390C /* UIKit */ = { - isa = PBXGroup; - children = ( - 0ADD7F3721F22FB60075FC59 /* ActivityIndicator+Rx.swift */, - 0ADD7F4221F22FB60075FC59 /* CALayer+RoundingCorners.swift */, - 0ADD7F1F21F22FB60075FC59 /* CALayer+Shadow.swift */, - 0ADD7F4B21F22FB60075FC59 /* CGFloat+Min.swift */, - 0ADD7F2021F22FB60075FC59 /* ControlEvent+ScrollView.swift */, - 0ADD7F3221F22FB60075FC59 /* ControlEvent+Signal.swift */, - 0ADD7F5021F22FB60075FC59 /* NSAttributedString+Styles.swift */, - 0ADD7F4321F22FB60075FC59 /* TimingFunction.swift */, - 0ADD7F2B21F22FB60075FC59 /* UIApplication+OpenURL.swift */, - 0ADD7F2121F22FB60075FC59 /* UIButton+WithoutAnimation.swift */, - 0ADD7F2521F22FB60075FC59 /* UIColor+Asset.swift */, - 0ADD7F3121F22FB60075FC59 /* UIColor+Colors.swift */, - 0ADD7F2621F22FB60075FC59 /* UIColor+Hex.swift */, - 0ADD7F2421F22FB60075FC59 /* UIFeedbackGenerator.swift */, - 0ADD7F2A21F22FB60075FC59 /* UIFont+Additions.swift */, - 0ADD7F3821F22FB60075FC59 /* UIImage+Color.swift */, - 0AAC2810221438B200D8A404 /* UIImageView+Rx.swift */, - 0ADD7F3521F22FB60075FC59 /* UINavigationController+Additionals.swift */, - 0ADD7F2D21F22FB60075FC59 /* UIResponder+Rx.swift */, - 0ADD7F4121F22FB60075FC59 /* UIScrollView+ContentInset.swift */, - 0ADD7F2221F22FB60075FC59 /* UIScrollView+Pagination.swift */, - 0ADD7F2921F22FB60075FC59 /* UITableView+Animation.swift */, - 0ADD7F2821F22FB60075FC59 /* UITableView+HeaderView.swift */, - 0ADD7F2721F22FB60075FC59 /* UIView+Additionals.swift */, - 0ADD7F4421F22FB60075FC59 /* UIView+Animation.swift */, - 0ADD7F3E21F22FB60075FC59 /* UIView+Passtrough.swift */, - 0ADD7F3421F22FB60075FC59 /* UIView+SafeArea.swift */, - 0ADD7F4021F22FB60075FC59 /* UIView+Shadow.swift */, - 0ADD7F3621F22FB60075FC59 /* UIView+TouchInset.swift */, - 0ADD7F2C21F22FB60075FC59 /* UIViewController+Additionals.swift */, - 0ADD7F2F21F22FB60075FC59 /* UIViewController+Alert.swift */, - 0ADD7F3C21F22FB60075FC59 /* UIViewController+Rx.swift */, - 0ADD7F3921F22FB60075FC59 /* UIViewController+SafeArea.swift */, - E9A6A499227661940093FC59 /* TableViewNoShadow.swift */, - 0ADD7F7D21F22FB60075FC59 /* Protocols */, - 0A4E7DE622018132007BBA39 /* Type */, - 0A751D3922171ABA0024D523 /* Kingfisher+Rx.swift */, - 7BDA6AEF2231405D001DE71C /* SmartTransactionKind+UIImage.swift */, - 7B601B292240C4B80040975C /* SmartTransactionDTO+EncodingToString.swift */, + 7B431A8722BD037C00DE73B9 /* Protocol */ = { + isa = PBXGroup; + children = ( + 7B5FAAC922BCE71400621A44 /* AccountBalanceUseCaseProtocol.swift */, + 7B431A8422BD02E700DE73B9 /* AddressUseCaseProtocol.swift */, + 7B5FAACB22BCE8D800621A44 /* AliasesUseCaseProtocol.swift */, + 7B431A7F22BCFF5700DE73B9 /* AssetsBalanceSettingsUseCaseProtocol.swift */, + 7B431A7C22BCFE8A00DE73B9 /* AssetsUseCaseProtocol.swift */, + 7B5FAA5222BBE3EC00621A44 /* AuthorizationUseCaseProtocol.swift */, + 7B5FAACD22BCE98F00621A44 /* MigrationUseCaseProtocol.swift */, + E97A74A422D3BAA200777C39 /* OrderBookUseCaseProtocol.swift */, + 7B431A8222BCFFA900DE73B9 /* TransactionsUseCaseProtocol.swift */, + 7B848A7023018C0E0092AD18 /* WidgetSettingsInizializationUseCaseProtocol.swift */, + 7B848A6C2301784B0092AD18 /* WidgetSettingsUseCaseProtocol.swift */, + 7B848A7B2301C95A0092AD18 /* PairsPathUseCaseProtocol.swift */, ); - path = UIKit; + path = Protocol; sourceTree = ""; }; - 7B95111F225CD6710030390C /* Type */ = { + 7B431A8D22BD176D00DE73B9 /* DomainLayerTests */ = { isa = PBXGroup; children = ( - 7B951120225CD6790030390C /* Language.swift */, - 7B951122225CD6AD0030390C /* SentryNetworkLoggerPlugin.swift */, - 7B951124225CD6D80030390C /* SweetLoggerSentry.swift */, - 7B951126225CD7160030390C /* QRCodeParser.swift */, - 7B951128225CD7350030390C /* AppSettings.swift */, + 7B431A8E22BD176D00DE73B9 /* DomainLayerTests.swift */, + 7B431A9022BD176D00DE73B9 /* Info.plist */, ); - path = Type; + path = DomainLayerTests; sourceTree = ""; }; - 7BDA6AD3222D8AEA001DE71C /* TransactionCard */ = { + 7B431A9D22BD185B00DE73B9 /* DataLayerTests */ = { isa = PBXGroup; children = ( - 7BDA6AE0222FDCFA001DE71C /* View */, - 7BDA6AD6222D8CA1001DE71C /* TransactionCardViewController.swift */, - 7BDA6AD8222D8D0A001DE71C /* TransactionCardSystem.swift */, - 7B6922C5223BA1730056DA67 /* TransactionCardSystemTransaction+Mapper.swift */, - 7B5EDEC122522837009C2B3B /* TransactionCardSystemOrder+Mapper.swift */, - 7BDA6ADA222D8D16001DE71C /* TransactionCardType.swift */, - 7BDA6ADE222E9664001DE71C /* TransactionCard.storyboard */, - 7B5E746822390B8200746ADD /* TransactionCardBuilder.swift */, + 7B431A9E22BD185B00DE73B9 /* DataLayerTests.swift */, + 7B431AA022BD185B00DE73B9 /* Info.plist */, ); - path = TransactionCard; + path = DataLayerTests; sourceTree = ""; }; - 7BDA6AE0222FDCFA001DE71C /* View */ = { + 7B49911822F874CC005B7123 /* View */ = { isa = PBXGroup; children = ( - 7B5E7464223907AA00746ADD /* TransactionCardHeaderView.swift */, - 7BDA6ADC222E95C8001DE71C /* TransactionCardView.swift */, - 7B5E74662239088800746ADD /* TransactionCardHeaderView.xib */, - 7B3902AE2237D74400AAFDB8 /* Cell */, + 7B65B6F622F9D647007D5C53 /* KeyboardControl.xib */, + 7B65B6F422F9D63D007D5C53 /* KeyboardControl.swift */, + 7B49911922F874DD005B7123 /* AssetsSearchAssetCell.swift */, + 7B49912122F876AA005B7123 /* AssetsSearchHeaderView.swift */, + 7B49912522F876E1005B7123 /* AssetsSearchHeaderView.xib */, + 7B49912B22F99B76005B7123 /* AssetsSearchEmptyCell.swift */, ); path = View; sourceTree = ""; }; - 7BF89E9722272A5E00853F9D /* MonkeyTest */ = { + 7B5FAA0422BBE3EB00621A44 /* Sources */ = { isa = PBXGroup; children = ( - 7BF89E9822272A5E00853F9D /* MonkeyTest.swift */, - 7BF89E9A22272A5E00853F9D /* Info.plist */, + 7B5FAA2422BBE3EB00621A44 /* DomainLayerTypes.swift */, + 7B5FAA0622BBE3EB00621A44 /* RepositoriesFactoryProtocol.swift */, + 7B5FAA4722BBE3EC00621A44 /* UseCasesFactory.swift */, + 7B5FAA0522BBE3EB00621A44 /* UseCasesFactoryProtocol.swift */, + 7B5FAA4822BBE3EC00621A44 /* AnalyticManager */, + 7B5FAA5A22BBE3EC00621A44 /* Assisstants */, + 7B97B0B022FCB5D9008BA3F4 /* Generated */, + 7B5FAA0722BBE3EB00621A44 /* Mapper */, + 7B5FAA2522BBE3EB00621A44 /* Models */, + 7B5FAA0A22BBE3EB00621A44 /* Queries */, + 7B5FAA0C22BBE3EB00621A44 /* Repositories */, + 7B5FAA4F22BBE3EC00621A44 /* UseCases */, ); - path = MonkeyTest; + path = Sources; sourceTree = ""; }; - D6029DF045FAF50274C41646 /* Pods */ = { + 7B5FAA0722BBE3EB00621A44 /* Mapper */ = { isa = PBXGroup; children = ( - 965E90884D099176A23D5038 /* Pods-WavesWallet-iOS.debug.xcconfig */, - 3780CE9B95DA4BD90D83FC04 /* Pods-WavesWallet-iOS.release.xcconfig */, - 2A5A5CDBE4190D8A1A1C4124 /* Pods-WavesWallet-iOS.test.xcconfig */, - 621D6D45B8A2773F670A4883 /* Pods-WavesWallet-iOS.adhoc.xcconfig */, - E0E99F201DFCDD4280DDB64C /* Pods-WavesWallet-iOS.test-adhoc.xcconfig */, - F7361C3F79C88A0896BACB0C /* Pods-MonkeyTest.debug.xcconfig */, - 8929E19527D7945D5DC03230 /* Pods-MonkeyTest.release.xcconfig */, - 39E7B5DDD0BC308CCE651F05 /* Pods-MonkeyTest.test-adhoc.xcconfig */, - A1E804B3D4295816120F6042 /* Pods-MonkeyTest.test.xcconfig */, - D0E2547DB09713AC51E70B93 /* Pods-MonkeyTest.test-build.xcconfig */, - AFB68EB998D497670C5F75E3 /* Pods-WavesWallet-iOS.test-build.xcconfig */, + 7B5FAA0822BBE3EB00621A44 /* TransactionDomainDTO+Mapper.swift */, + 7B5FAA0922BBE3EB00621A44 /* Asset+Assistants.swift */, ); - name = Pods; + path = Mapper; sourceTree = ""; }; - E921ED02222DDA2B00DE286D /* DexScriptAssetMessage */ = { + 7B5FAA0A22BBE3EB00621A44 /* Queries */ = { isa = PBXGroup; children = ( - E921ED03222DDA4600DE286D /* DexScriptAssetMessageViewController.swift */, - E9A3AFAD222DEECB009FB45A /* DexScriptAssetMessageModuleBuilder.swift */, + 7B5FAA0B22BBE3EB00621A44 /* DomainDexQueries.swift */, ); - path = DexScriptAssetMessage; + path = Queries; sourceTree = ""; }; - E9236F192216F2FE00A12FD5 /* AppNews */ = { - isa = PBXGroup; - children = ( - E9236F1C2216F35B00A12FD5 /* AppNewsView.swift */, - E9236F1E2216F37300A12FD5 /* AppNewsView.xib */, + 7B5FAA0C22BBE3EB00621A44 /* Repositories */ = { + isa = PBXGroup; + children = ( + 7B5FAA1F22BBE3EB00621A44 /* AccountBalanceRepositoryProtocol.swift */, + 7B5FAA0E22BBE3EB00621A44 /* AccountSettingsRepositoryProtocol.swift */, + 7B5FAA1722BBE3EB00621A44 /* AddressBookRepositoryProtocol.swift */, + 7B5FAA1022BBE3EB00621A44 /* AddressRepositoryProtocol.swift */, + 7B5FAA1E22BBE3EB00621A44 /* AliasesRepositoryProtocol.swift */, + 7B5FAA1522BBE3EB00621A44 /* ApplicationVersionRepositoryProtocol.swift */, + 7B5FAA1122BBE3EB00621A44 /* AssetsBalanceSettingsRepositoryProtocol.swift */, + 7B5FAA1C22BBE3EB00621A44 /* AssetsRepositoryProtocol.swift */, + 7B5FAA2122BBE3EB00621A44 /* AuthenticationRepositoryProtocol.swift */, + 7B5FAA1D22BBE3EB00621A44 /* BlockRepositoryProtocol.swift */, + 7B5FAA1922BBE3EB00621A44 /* CandlesRepositoryProtocol.swift */, + 7B5FAA0F22BBE3EB00621A44 /* CoinomatRepositoryProtocol.swift */, + 7B5FAA2022BBE3EB00621A44 /* DexOrderBookRepositoryProtocol.swift */, + 7B5FAA1622BBE3EB00621A44 /* DexPairsPriceRepositoryProtocol.swift */, + 7B5FAA1322BBE3EB00621A44 /* DexRealmRepositoryProtocol.swift */, + 7B5FAA2222BBE3EB00621A44 /* EnvironmentRepositoryProtocol.swift */, + E99A3B7422BE5CEB0070AC76 /* GatewayRepositoryProtocol.swift */, + 7B5FAA1B22BBE3EB00621A44 /* LastTradesRepositoryProtocol.swift */, + 7B5FAA1222BBE3EB00621A44 /* MatcherRepositoryProtocol.swift */, + 7B0FD98E2319C0EA0004B52B /* MobileKeeperRepositoryProtocol.swift */, + 7B5FAA1422BBE3EB00621A44 /* NotificationNewsRepositoryProtocol.swift */, + 7BDC6D3D22C2522F00614E6B /* SpamAssetsRepositoryProtocol.swift */, + 7B5FAA1A22BBE3EB00621A44 /* TransactionsRepositoryProtocol.swift */, + 7B5FAA2322BBE3EB00621A44 /* UtilsRepositoryProtocol.swift */, + 7B5FAA1822BBE3EB00621A44 /* WalletSeedRepositoryProtocol.swift */, + 7B5FAA0D22BBE3EB00621A44 /* WalletsRepositoryProtocol.swift */, + E9618D1322EF933800FB7F06 /* WidgetSettingsRepositoryProtocol.swift */, ); - path = AppNews; + path = Repositories; sourceTree = ""; }; - E923A766219D713A000DD9F6 /* Loading */ = { + 7B5FAA2522BBE3EB00621A44 /* Models */ = { isa = PBXGroup; children = ( - E923A767219D714E000DD9F6 /* TokenBurnLoadingViewController.swift */, + 7B5FAA2622BBE3EB00621A44 /* DTO */, + 7B5FAA4522BBE3EC00621A44 /* ResponseType.swift */, + 7B5FAA4622BBE3EC00621A44 /* WalletEnvironment.swift */, ); - path = Loading; + path = Models; sourceTree = ""; }; - E923A76B219D73AE000DD9F6 /* Complete */ = { + 7B5FAA2622BBE3EB00621A44 /* DTO */ = { isa = PBXGroup; children = ( - E923A76C219D73BF000DD9F6 /* TokenBurnCompleteViewController.swift */, + 7B5FAA2722BBE3EC00621A44 /* AccountEnvironmentDomainDTO.swift */, + 7B5FAA2822BBE3EC00621A44 /* CandleDomainDTO.swift */, + 7B5FAA2922BBE3EC00621A44 /* AssetBalanceDomainDTO.swift */, + 7B5FAA2A22BBE3EC00621A44 /* DexDomainDTO.swift */, + 7B5FAA2B22BBE3EC00621A44 /* WalletDomainDTO.swift */, + 7B5FAA2C22BBE3EC00621A44 /* AliasDomainDTO.swift */, + 7B5FAA2D22BBE3EC00621A44 /* Transactions */, + 7B5FAA4022BBE3EC00621A44 /* NotificationNewsDomainDTO.swift */, + 7B5FAA4122BBE3EC00621A44 /* AssetDomainDTO.swift */, + 7B5FAA4222BBE3EC00621A44 /* CoinomatDomainDTO.swift */, + 7B5FAA4322BBE3EC00621A44 /* ContactDomainDTO.swift */, + 7B5FAA4422BBE3EC00621A44 /* AccountSettingsDomainDTO.swift */, + E99A3B7622BE5DB70070AC76 /* GatewayDomainDTO.swift */, + E9618D1522EF936800FB7F06 /* MarketPulseSettingsDomainDTO.swift */, ); - path = Complete; + path = DTO; sourceTree = ""; }; - E92FF25121A43B3B00CBFF07 /* Complete */ = { - isa = PBXGroup; - children = ( - E9157BED21A4C081009F99B6 /* StartLeasingCompleteViewController.swift */, + 7B5FAA2D22BBE3EC00621A44 /* Transactions */ = { + isa = PBXGroup; + children = ( + 7B5FAA2E22BBE3EC00621A44 /* SponsorshipTransactionDomainDTO.swift */, + 7B5FAA2F22BBE3EC00621A44 /* AddressDomainDTO.swift */, + 7B5FAA3022BBE3EC00621A44 /* InvokeScriptTransactionDomainDTO.swift */, + 7B5FAA3122BBE3EC00621A44 /* DataTransactionDomainDTO.swift */, + 7B5FAA3222BBE3EC00621A44 /* AssetScriptTransactionDomainDTO.swift */, + 7B5FAA3322BBE3EC00621A44 /* SmartTransactionDomainDTO.swift */, + 7B5FAA3422BBE3EC00621A44 /* LeaseCancelTransactionDomainDTO.swift */, + 7B5FAA3522BBE3EC00621A44 /* MassTransferTransactionDomainDTO.swift */, + 7B5FAA3622BBE3EC00621A44 /* ScriptTransactionDomainDTO.swift */, + 7B5FAA3722BBE3EC00621A44 /* AnyTransactionDomainDTO.swift */, + 7B5FAA3822BBE3EC00621A44 /* UnrecognisedTransactionDomainDTO.swift */, + 7B5FAA3922BBE3EC00621A44 /* IssueTransactionDomainDTO.swift */, + 7B5FAA3A22BBE3EC00621A44 /* TransferTransactionDomainDTO.swift */, + 7B5FAA3B22BBE3EC00621A44 /* ExchangeTransactionDomainDTO.swift */, + 7B5FAA3C22BBE3EC00621A44 /* ReissueTransactionDomainDTO.swift */, + 7B5FAA3D22BBE3EC00621A44 /* BurnTransactionDomainDTO.swift */, + 7B5FAA3E22BBE3EC00621A44 /* LeaseTransactionDomainDTO.swift */, + 7B5FAA3F22BBE3EC00621A44 /* AliasTransactionDomainDTO.swift */, ); - path = Complete; + path = Transactions; sourceTree = ""; }; - E9310D0A217924B7008BF3EE /* Confirmaion */ = { + 7B5FAA4822BBE3EC00621A44 /* AnalyticManager */ = { isa = PBXGroup; children = ( - E9310D1721792CD0008BF3EE /* Views */, - E9310D0B217924D0008BF3EE /* SendConfirmationViewController.swift */, + 7B5FAA4A22BBE3EC00621A44 /* AnalyticManagerProtocol.swift */, + 7B5FAA4B22BBE3EC00621A44 /* AnalyticAssetManager.swift */, + 7B5FAA4E22BBE3EC00621A44 /* AnalyticManager+Dex.swift */, + 7BDC6D3F22C395F500614E6B /* AnalyticManagerEvent+CreateANewAccount.swift */, + 7BDC6D4222C3964900614E6B /* AnalyticManagerEvent+ImportAccount.swift */, + 7BDC6D4522C3967600614E6B /* AnalyticManagerEvent+SingIn.swift */, + 7BDC6D4722C396A400614E6B /* AnalyticManagerEvent+Send.swift */, + 7BDC6D4B22C396D200614E6B /* AnalyticManagerEvent+Receive.swift */, + 7BDC6D4E22C396F200614E6B /* AnalyticManagerEvent+WavesQuickAction.swift */, + 7BDC6D5122C3970B00614E6B /* AnalyticManagerEvent+Profile.swift */, + 7BDC6D5722C3976D00614E6B /* AnalyticManagerEvent+WalletLeasing.swift */, + 7BDC6D5422C3973C00614E6B /* AnalyticManagerEvent+WalletHome.swift */, + 7BDC6D5922C3978100614E6B /* AnalyticManagerEvent+Alias.swift */, + 7BDC6D5D22C397A300614E6B /* AnalyticManagerEvent+TokenBurn.swift */, + 7BDC6D6C22C398E100614E6B /* AnalyticManagerEvent+AddressBook.swift */, + 7BDC6D6F22C3A03400614E6B /* AnalyticManagerEvent+Menu.swift */, + 7BDC6D7122C3A03E00614E6B /* AnalyticManagerEvent+Widgets.swift */, ); - path = Confirmaion; + path = AnalyticManager; sourceTree = ""; }; - E9310D1721792CD0008BF3EE /* Views */ = { + 7B5FAA4F22BBE3EC00621A44 /* UseCases */ = { isa = PBXGroup; children = ( - E9310D1821792D01008BF3EE /* SendConfirmationRecipientView.swift */, - E9310D1A21792D13008BF3EE /* SendConfirmationRecipientView.xib */, + 7B5FAA5022BBE3EC00621A44 /* AccountBalanceUseCase.swift */, + 7B5FAA5522BBE3EC00621A44 /* AddressUseCase.swift */, + 7B5FAA5322BBE3EC00621A44 /* AliasesUseCase.swift */, + 7B5FAA5722BBE3EC00621A44 /* ApplicationVersionUseCase.swift */, + 7B5FAA5922BBE3EC00621A44 /* AssetsBalanceSettingsUseCase.swift */, + 7B5FAA5622BBE3EC00621A44 /* AssetsUseCase.swift */, + 7B5FAA5122BBE3EC00621A44 /* AuthorizationUseCase.swift */, + 7B848A7D2301CB0F0092AD18 /* CorrectionPairsUseCase.swift */, + 7B5FAA5422BBE3EC00621A44 /* MigrationUseCase.swift */, + E97A74A622D3BAD400777C39 /* OrderBookUseCase.swift */, + 7B5FAA5822BBE3EC00621A44 /* TransactionsUseCase.swift */, + 7B848A792301C0950092AD18 /* WidgetSettingsInizializationUseCase.swift */, + 7B848A6E230178B70092AD18 /* WidgetSettingsUseCase.swift */, + 7B431A8722BD037C00DE73B9 /* Protocol */, ); - path = Views; + path = UseCases; sourceTree = ""; }; - E94231EE22A40A010087F82F /* WalletSearch */ = { + 7B5FAA5A22BBE3EC00621A44 /* Assisstants */ = { isa = PBXGroup; children = ( - E9F69B9922A5331B00CDBD00 /* Views */, - E9F69B9422A522BC00CDBD00 /* Presenter */, - E95E151422A197B8003552B8 /* WalletSearchViewController.swift */, - E94231EF22A40FA80087F82F /* WalletSearchModuleBuilder.swift */, - E9F69B9122A5217200CDBD00 /* WalletSearchTypes.swift */, + 7B5FAA5B22BBE3EC00621A44 /* ApplicationDebugSettings.swift */, + 7B5FAA5C22BBE3EC00621A44 /* CleanerWalletManagerBanner.swift */, + 7B5FAA5D22BBE3EC00621A44 /* SmartTransactionDomain+Assistants.swift */, + 7B5FAA5E22BBE3EC00621A44 /* CleanerWalletManager.swift */, + 7B5FAA5F22BBE3EC00621A44 /* SigningWalletsProtocol.swift */, + 7B5FAA6022BBE3EC00621A44 /* ClientCrypto */, + 7B5FAA6822BBE3EC00621A44 /* BiometricManager.swift */, ); - path = WalletSearch; + path = Assisstants; sourceTree = ""; }; - E944AA72224465BE0009F494 /* AnalyticManager */ = { + 7B5FAA6022BBE3EC00621A44 /* ClientCrypto */ = { isa = PBXGroup; children = ( - E944AA73224465BE0009F494 /* AnalyticManager.swift */, - E944AA812245394C0009F494 /* AnalyticAssetManager.swift */, - E944AA75224465D60009F494 /* AnalyticManager+Dex.swift */, - E944AA77224467570009F494 /* AnalyticManager+WalletAsset.swift */, - E944AA7922446A530009F494 /* AnalyticManager+WalletStart.swift */, + 7B5FAA6122BBE3EC00621A44 /* WordList.swift */, + 7B5FAA6222BBE3EC00621A44 /* Hash.swift */, + 7B5FAA6322BBE3EC00621A44 /* Address.swift */, + 7B5FAA6422BBE3EC00621A44 /* PublicKeyAccount.swift */, + 7B5FAA6522BBE3EC00621A44 /* PrivateKeyAccount.swift */, + 7B5FAA6622BBE3EC00621A44 /* RXCrypto+SHA.swift */, + 7B5FAA6722BBE3EC00621A44 /* Data+AES.swift */, ); - path = AnalyticManager; + path = ClientCrypto; sourceTree = ""; }; - E94A7002215AEA2A001814F7 /* AddressBook */ = { + 7B66860122B3F70E0029E6F1 /* DomainLayer */ = { isa = PBXGroup; children = ( - E94A7003215AEA49001814F7 /* AddressBookRepositoryProtocol.swift */, + 7B5FAA0422BBE3EB00621A44 /* Sources */, + 7B66860222B3F70E0029E6F1 /* DomainLayer.h */, + 18CFECE732E67CAF8666D2C9 /* Frameworks */, + 7B66860322B3F70E0029E6F1 /* Info.plist */, ); - path = AddressBook; + path = DomainLayer; sourceTree = ""; }; - E94A7005215AEAFB001814F7 /* AddressBook */ = { + 7B6686EF22B7C5120029E6F1 /* Extensions */ = { isa = PBXGroup; children = ( - E94A7006215AEB0E001814F7 /* AddressBookRepository.swift */, + 7B97B06B22FC784F008BA3F4 /* Balance.swift */, + 7B6686F022B7C5120029E6F1 /* Extensions.h */, + 7B6686F122B7C5120029E6F1 /* Info.plist */, + 7B66871D22B7E6550029E6F1 /* Sources */, ); - path = AddressBook; + path = Extensions; sourceTree = ""; }; - E94E4E6721CF9F6D00053A49 /* Coinomat */ = { + 7B66871D22B7E6550029E6F1 /* Sources */ = { isa = PBXGroup; children = ( - E94E4E6821CF9F6D00053A49 /* CoinomatService.swift */, + 7B97B06722FC784F008BA3F4 /* Common */, + 7B97B03722FC784F008BA3F4 /* UI */, ); - path = Coinomat; + path = Sources; sourceTree = ""; }; - E95438F6217F919B001A7860 /* Loading */ = { + 7B66872422B7E68B0029E6F1 /* DataLayer */ = { isa = PBXGroup; children = ( - E95438F7217F91BA001A7860 /* SendLoadingViewController.swift */, + 7BF509F022D8B95300582783 /* Sources */, + 7B66872522B7E68B0029E6F1 /* DataLayer.h */, + 7B66872622B7E68B0029E6F1 /* Info.plist */, ); - path = Loading; + path = DataLayer; sourceTree = ""; }; - E9543900217FF9C8001A7860 /* Complete */ = { - isa = PBXGroup; - children = ( - E9543901217FF9EC001A7860 /* SendCompleteViewController.swift */, + 7B66873122B7E6950029E6F1 /* Frameworks */ = { + isa = PBXGroup; + children = ( + E999E6A92323D5D200EDDF45 /* WavesSDKExtensions.framework */, + E999E6A72323D5C900EDDF45 /* WavesSDKCrypto.framework */, + E999E6A52323D5C300EDDF45 /* WavesSDK.framework */, + 7BDC625122DCB06D0029DA37 /* RxSwift.framework */, + 7BDC624F22DCB04F0029DA37 /* WavesSDKExtensions.framework */, + 7BDC624722DC973E0029DA37 /* WavesSDK.framework */, + 7BDC624922DC973E0029DA37 /* WavesSDKCrypto.framework */, + 7BDC624B22DC973E0029DA37 /* WavesSDKExtensions.framework */, + 7BDC624122DC972E0029DA37 /* WavesSDK.framework */, + 7BDC624322DC972E0029DA37 /* WavesSDKCrypto.framework */, + 7BDC624522DC972E0029DA37 /* WavesSDKExtensions.framework */, + 7BDC623B22DC970F0029DA37 /* WavesSDK.framework */, + 7BDC623D22DC970F0029DA37 /* WavesSDKCrypto.framework */, + 7BDC623F22DC970F0029DA37 /* WavesSDKExtensions.framework */, + 7BDC623522DC78BF0029DA37 /* WavesSDK.framework */, + 7BDC623722DC78BF0029DA37 /* WavesSDKCrypto.framework */, + 7BDC623922DC78BF0029DA37 /* WavesSDKExtensions.framework */, + 7B83A7E822D8D72F0038180D /* Extensions.framework */, + 7BF50AD722D8BB0C00582783 /* DomainLayer.framework */, + 7BF50AD522D8BB0800582783 /* Extensions.framework */, + 7BF50AD322D8BB0100582783 /* DataLayer.framework */, + 7BF50AD122D8BAF800582783 /* Extensions.framework */, + 7BF50ACF22D8BAF300582783 /* DomainLayer.framework */, + E9B190A822E7CD99008220B7 /* NotificationCenter.framework */, + 5BB158FA7ECE6E5227A7AF0B /* Pods_DataLayer.framework */, + 5F1A2C7157881DA75A52C4BA /* Pods_DataLayerTests.framework */, + 41C4770FECD0D0B762C47A43 /* Pods_DomainLayer.framework */, + 1CCD1A311B65E78F9D8E3AFB /* Pods_DomainLayerTests.framework */, + 4F48C7630D481FB8B18C7CDD /* Pods_Extensions.framework */, + 20735B3922DF223C5F8F7C79 /* Pods_MarketPulseWidget.framework */, + 660956FE76B04B363AEC458B /* Pods_MonkeyTest.framework */, + BC49EA63C68974786E6084B7 /* Pods_WavesWallet_iOS.framework */, ); - path = Complete; + name = Frameworks; sourceTree = ""; }; - E95B47A521638A9F004D4E39 /* Hello */ = { + 7B83A7D122D8C74F0038180D /* DummyForTest */ = { isa = PBXGroup; children = ( - E95B47A821638A9F004D4E39 /* Hello.storyboard */, - E95B47AA21638A9F004D4E39 /* Languages */, - E95B47AD21638A9F004D4E39 /* InfoPages */, + 7B83A7D222D8C74F0038180D /* AppDelegate.swift */, + 7B83A7D422D8C74F0038180D /* ViewController.swift */, + 7B83A7D622D8C74F0038180D /* Main.storyboard */, + 7B83A7D922D8C7500038180D /* Assets.xcassets */, + 7B83A7DB22D8C7500038180D /* LaunchScreen.storyboard */, + 7B83A7DE22D8C7500038180D /* Info.plist */, ); - path = Hello; + path = DummyForTest; sourceTree = ""; }; - E95B47AA21638A9F004D4E39 /* Languages */ = { + 7B848A51230075920092AD18 /* CommonResources */ = { isa = PBXGroup; children = ( - E95B47AB21638A9F004D4E39 /* HelloLanguagesViewController.swift */, + 7B88186323044FCC00AB0549 /* Languages.json */, + 7B848A52230075920092AD18 /* Sentry-io-Info.plist */, + 7B848A53230075920092AD18 /* Appsflyer-Info.plist */, + 7B848A54230075920092AD18 /* AppSpector-Info.plist */, + 7B848A55230075920092AD18 /* environment_testnet.json */, + 7B848A56230075920092AD18 /* GoogleService-Info.plist */, + 7B848A57230075920092AD18 /* Fabric-Info.plist */, + 7B848A58230075920092AD18 /* Amplitude-Info.plist */, + 7B848A59230075920092AD18 /* environment_mainnet.json */, + 7B848A5A230075920092AD18 /* spam.csv */, ); - path = Languages; - sourceTree = ""; + path = CommonResources; + sourceTree = SOURCE_ROOT; }; - E95B47AD21638A9F004D4E39 /* InfoPages */ = { + 7B848A67230076AE0092AD18 /* Generated */ = { isa = PBXGroup; children = ( - E95B47AE21638A9F004D4E39 /* View */, - E95B47BD21638A9F004D4E39 /* InfoPagesViewController.swift */, + 7B848A6A230077540092AD18 /* Images.swift */, + 7B848A68230076AE0092AD18 /* Localizable.swift */, ); - path = InfoPages; + path = Generated; sourceTree = ""; }; - E95B47AE21638A9F004D4E39 /* View */ = { + 7B848A902304073B0092AD18 /* Localization */ = { isa = PBXGroup; children = ( - 0AC1251121A758BC00357C93 /* LongInfoPageView.swift */, - E95B47B321638A9F004D4E39 /* LongInfoPageView.xib */, - E95B47B921638A9F004D4E39 /* ShortInfoPageView.swift */, - E95B47BA21638A9F004D4E39 /* ShortInfoPageView.xib */, - 04D882BE21706FEF00EAAB90 /* InfoPagesCell.swift */, - E9939B4422302E3800B50E67 /* InfoPageConfirmView.swift */, - E9939B4622302E6100B50E67 /* InfoPageConfirmView.xib */, + 7B848A912304073B0092AD18 /* WavesMarketPulse.strings */, ); - path = View; + path = Localization; sourceTree = ""; }; - E95B47D421638B11004D4E39 /* StartLeasing */ = { + 7B8818652305639600AB0549 /* ActionSheet */ = { isa = PBXGroup; children = ( - E95B47DD21638B11004D4E39 /* StartLeasing.storyboard */, - E95B47E021638B11004D4E39 /* StartLeasingTypes.swift */, - E92FF25121A43B3B00CBFF07 /* Complete */, - E9DB667921A3937300962639 /* Loading */, - E9DB667821A38D7300962639 /* CancelConfirmation */, - E9DB666F21A383E900962639 /* Confirmation */, - E9DB667021A383F300962639 /* StartLeasing */, + 7B8818662305639600AB0549 /* ActionSheetViewController.swift */, + 7B8818672305639600AB0549 /* ActionSheet.swift */, + 7B8818682305639600AB0549 /* View */, + 7B88186C2305639600AB0549 /* ActionSheetViewBuilder.swift */, + 7B88186D2305639600AB0549 /* ActionSheet.storyboard */, ); - path = StartLeasing; + path = ActionSheet; sourceTree = ""; }; - E95B47E121638B11004D4E39 /* Views */ = { + 7B8818682305639600AB0549 /* View */ = { isa = PBXGroup; children = ( - E917B3AC21BD685800CC849A /* AmountSkeletonView.swift */, - E917B3AE21BD688500CC849A /* AmountSkeletonView.xib */, - E95B47E521638B11004D4E39 /* AmountInputView.xib */, - E95B47E221638B11004D4E39 /* AmountInputView.swift */, + 7B8818692305639600AB0549 /* ActionSheetElementCell.swift */, + 7B88186A2305639600AB0549 /* ActionSheetHeaderView.xib */, + 7B88186B2305639600AB0549 /* ActionSheetHeaderView.swift */, ); - path = Views; + path = View; sourceTree = ""; }; - E95B47E621638B11004D4E39 /* Interactor */ = { - isa = PBXGroup; - children = ( - E95B47E721638B11004D4E39 /* StartLeasingInteractorProtocol.swift */, - E95B47E921638B11004D4E39 /* StartLeasingInteractor.swift */, + 7B97B03722FC784F008BA3F4 /* UI */ = { + isa = PBXGroup; + children = ( + 7B97B0B522FCBD59008BA3F4 /* AssetLogo.swift */, + 7B97B05722FC784F008BA3F4 /* CALayer+RoundingCorners.swift */, + 7B97B03822FC784F008BA3F4 /* CALayer+Shadow.swift */, + 7B97B03A22FC784F008BA3F4 /* CGFloat+Min.swift */, + 7B97B05122FC784F008BA3F4 /* CGSize+Hashable.swift */, + 7B97B03922FC784F008BA3F4 /* ControlEvent+ScrollView.swift */, + 7B97B04522FC784F008BA3F4 /* String+Size.swift */, + 7B97B04C22FC784F008BA3F4 /* TableViewNoShadow.swift */, + 7B97B05822FC784F008BA3F4 /* TimingFunction.swift */, + 7B97B04622FC784F008BA3F4 /* UIApplication+OpenURL.swift */, + 7B97B03B22FC784F008BA3F4 /* UIButton+WithoutAnimation.swift */, + 7B97B03F22FC784F008BA3F4 /* UIColor+Asset.swift */, + 7B97B04822FC784F008BA3F4 /* UIColor+Colors.swift */, + 7B97B04022FC784F008BA3F4 /* UIColor+Hex.swift */, + 7B97B03E22FC784F008BA3F4 /* UIFeedbackGenerator.swift */, + 7B97B04422FC784F008BA3F4 /* UIFont+Additions.swift */, + 7B97B04F22FC784F008BA3F4 /* UIImage+Color.swift */, + 7B97B03C22FC784F008BA3F4 /* UIImageView+Rx.swift */, + 7B97B04B22FC784F008BA3F4 /* UINavigationController+Additionals.swift */, + 7B97B05622FC784F008BA3F4 /* UIScrollView+ContentInset.swift */, + 7B97B03D22FC784F008BA3F4 /* UIScrollView+Pagination.swift */, + 7B97B04322FC784F008BA3F4 /* UITableView+Animation.swift */, + 7B97B04222FC784F008BA3F4 /* UITableView+HeaderView.swift */, + 7B97B04122FC784F008BA3F4 /* UIView+Additionals.swift */, + 7B97B06622FC784F008BA3F4 /* UIView+Animation.swift */, + 7B97B05322FC784F008BA3F4 /* UIView+Passtrough.swift */, + 7B97B04A22FC784F008BA3F4 /* UIView+SafeArea.swift */, + 7B97B05522FC784F008BA3F4 /* UIView+Shadow.swift */, + 7B97B04D22FC784F008BA3F4 /* UIView+TouchInset.swift */, + 7B97B05222FC784F008BA3F4 /* UIViewController+Rx.swift */, + 7B97B05022FC784F008BA3F4 /* UIViewController+SafeArea.swift */, + 7B97B05922FC784F008BA3F4 /* Protocols */, + ); + path = UI; + sourceTree = ""; + }; + 7B97B05922FC784F008BA3F4 /* Protocols */ = { + isa = PBXGroup; + children = ( + 7B97B05F22FC784F008BA3F4 /* SectionDisplayCollection.swift */, + 7B97B05E22FC784F008BA3F4 /* ViewCalculate.swift */, + 7B97B05D22FC784F008BA3F4 /* ViewConfiguration.swift */, + 7B97B05A22FC784F008BA3F4 /* Module */, + 7B97B06022FC784F008BA3F4 /* Reusable */, ); - path = Interactor; + path = Protocols; sourceTree = ""; }; - E95B6B08219B3ADF00A85B5D /* TokenBurn */ = { + 7B97B05A22FC784F008BA3F4 /* Module */ = { isa = PBXGroup; children = ( - E9B12DB0219DCFDC00128EFE /* Interactor */, - E9B12DAE219DCDD300128EFE /* TokenBurnTypes.swift */, - E923A76B219D73AE000DD9F6 /* Complete */, - E923A766219D713A000DD9F6 /* Loading */, - E95B6B0D219C22CA00A85B5D /* Confirmation */, - E95B6B0C219C22BB00A85B5D /* TokenBurn */, + 7B97B05C22FC784F008BA3F4 /* ModuleBuilder.swift */, + 7B97B05B22FC784F008BA3F4 /* ModuleBuilderOutput.swift */, ); - path = TokenBurn; + path = Module; sourceTree = ""; }; - E95B6B0C219C22BB00A85B5D /* TokenBurn */ = { + 7B97B06022FC784F008BA3F4 /* Reusable */ = { isa = PBXGroup; children = ( - E95B6B09219B3B0100A85B5D /* TokenBurnViewController.swift */, + 7B97B06422FC784F008BA3F4 /* NibLoadable.swift */, + 7B97B06522FC784F008BA3F4 /* NibOwnerLoadable.swift */, + 7B97B06222FC784F008BA3F4 /* Reusable.swift */, + 7B97B06122FC784F008BA3F4 /* UICollectionView+Reusable.swift */, + 7B97B06322FC784F008BA3F4 /* UITableView+Reusable.swift */, ); - path = TokenBurn; + path = Reusable; sourceTree = ""; }; - E95B6B0D219C22CA00A85B5D /* Confirmation */ = { + 7B97B06722FC784F008BA3F4 /* Common */ = { isa = PBXGroup; children = ( - E95B6B11219C341E00A85B5D /* Views */, - E95B6B10219C22F500A85B5D /* Interactor */, - E95B6B0E219C22E400A85B5D /* TokenBurnConfirmationViewController.swift */, + 7B97B06A22FC784F008BA3F4 /* Decimal+Assisstants.swift */, + 7B881875230590BB00AB0549 /* DeepLink.swift */, + 7BFB47DE22FC742D002B19F8 /* Kingfisher+Rx.swift */, + 7BFB47FC22FC742F002B19F8 /* Language.swift */, + 7B97B06C22FC784F008BA3F4 /* Money.swift */, + 7B97B06822FC784F008BA3F4 /* MoneyUtil.swift */, + 7B97B06F22FC784F008BA3F4 /* Mutating.swift */, + 7B97B07122FC784F008BA3F4 /* Platform.swift */, + 7B97B0AC22FCB2BD008BA3F4 /* Reachability+Shared.swift */, + 7B97B06E22FC784F008BA3F4 /* RunLoopThreadScheduler.swift */, + 7B97B06922FC784F008BA3F4 /* Sync.swift */, + 7B97B07022FC784F008BA3F4 /* System.swift */, + 7B97B06D22FC784F008BA3F4 /* TSUD+Rx.swift */, ); - path = Confirmation; + path = Common; sourceTree = ""; }; - E95B6B10219C22F500A85B5D /* Interactor */ = { + 7B97B0B022FCB5D9008BA3F4 /* Generated */ = { isa = PBXGroup; children = ( - E923A764219D53EE000DD9F6 /* TokenBurnInteractor.swift */, + 7B97B0B122FCB5D9008BA3F4 /* Localizable.swift */, ); - path = Interactor; + path = Generated; sourceTree = ""; }; - E95B6B11219C341E00A85B5D /* Views */ = { + 7BB03E4822EF2C6D008F179D /* Views */ = { isa = PBXGroup; children = ( - E95B6B12219C345B00A85B5D /* TokenBurnConfirmationIDView.swift */, - E95B6B14219C347200A85B5D /* TokenBurnConfirmationIDView.xib */, + 7B26A88722ED16DF00E7B024 /* Cells */, + 7BB03E4922EF2C84008F179D /* WidgetSettingsHeaderView.swift */, + 7BB03E4B22EF2DAB008F179D /* WidgetSettingsHeaderView.xib */, ); path = Views; sourceTree = ""; }; - E9657026219360770052F0FC /* WalletSort */ = { + 7BD6E10322E5ACE000BAAFC8 /* View */ = { isa = PBXGroup; children = ( - E9657027219360770052F0FC /* Presenter */, - E944300B226E643A00EB6257 /* WalletSortModuleBuilder.swift */, - E9443009226E641E00EB6257 /* WalletSortTypes.swift */, - E9443017226E757E00EB6257 /* WalletSort+Mapper.swift */, - E965702D219360770052F0FC /* Views */, - E9443007226E62A600EB6257 /* WalletSortViewController.swift */, - E9657033219360770052F0FC /* Interactor */, + 7BD6E10422E5AE0200BAAFC8 /* DebugHeaderView.swift */, + 7BD6E10722E5AE7000BAAFC8 /* DebugInfoCell.swift */, + 7BD6E10922E5AEEB00BAAFC8 /* DebugHeaderView.xib */, + 7BD6E10B22E5B6D700BAAFC8 /* DebugSwitchCell.swift */, + 7BD6E10D22E5CD5E00BAAFC8 /* DebugEnviromentsCell.swift */, ); - path = WalletSort; + path = View; sourceTree = ""; }; - E9657027219360770052F0FC /* Presenter */ = { + 7BDA6AD3222D8AEA001DE71C /* TransactionCard */ = { isa = PBXGroup; children = ( - E944300D226E645300EB6257 /* WalletSortPresenterProtocol.swift */, - E92703C5226FDD0C0022D5F0 /* WalletSortPresenter.swift */, + 7BDA6AE0222FDCFA001DE71C /* View */, + 7BDA6AD6222D8CA1001DE71C /* TransactionCardViewController.swift */, + 7BDA6AD8222D8D0A001DE71C /* TransactionCardSystem.swift */, + 7B6922C5223BA1730056DA67 /* TransactionCardSystemTransaction+Mapper.swift */, + 7B5EDEC122522837009C2B3B /* TransactionCardSystemOrder+Mapper.swift */, + 7BDA6ADA222D8D16001DE71C /* TransactionCardType.swift */, + 7BDA6ADE222E9664001DE71C /* TransactionCard.storyboard */, + 7B5E746822390B8200746ADD /* TransactionCardBuilder.swift */, ); - path = Presenter; + path = TransactionCard; sourceTree = ""; }; - E965702D219360770052F0FC /* Views */ = { + 7BDA6AE0222FDCFA001DE71C /* View */ = { isa = PBXGroup; children = ( - E96FEA23226E962300C0EE22 /* WalletSortEmptyAssetsCell.swift */, - E96FEA24226E962300C0EE22 /* WalletSortEmptyAssetsCell.xib */, - E96FEA27226F27BC00C0EE22 /* WalletSortCell.swift */, - E96FEA28226F27BC00C0EE22 /* WalletSortCell.xib */, - E92FAD0C226F6C050054D4AA /* WalletSortSeparatorCell.swift */, - E92FAD0D226F6C050054D4AA /* WalletSortSeparatorCell.xib */, - E96DAB72228EEC87005ED12B /* WalletSortSegmentedControl.swift */, - E96DAB70228EE643005ED12B /* WalletSortSegmentedControl.xib */, + 7B5E7464223907AA00746ADD /* TransactionCardHeaderView.swift */, + 7BDA6ADC222E95C8001DE71C /* TransactionCardView.swift */, + 7B5E74662239088800746ADD /* TransactionCardHeaderView.xib */, + 7B3902AE2237D74400AAFDB8 /* Cell */, ); - path = Views; + path = View; sourceTree = ""; }; - E9657033219360770052F0FC /* Interactor */ = { + 7BDDFA74230B2E75007A179B /* Recovered References */ = { isa = PBXGroup; children = ( - E9443013226E64F600EB6257 /* WalletSortInteractorProtocol.swift */, - E9443011226E64E900EB6257 /* WalletSortInteractor.swift */, + 7BF89E9822272A5E00853F9D /* MonkeyTest.swift */, ); - path = Interactor; + name = "Recovered References"; sourceTree = ""; }; - E967786C21ECE12D00CE56D6 /* Queries */ = { + 7BE09AD123140EF800A038AD /* MobileKeeper */ = { isa = PBXGroup; children = ( - E96E2A0421D3D9AA00AC2FA9 /* DomainDexQueries.swift */, + 7B368196231425ED000D5592 /* ConfirmRequest */, + 7BE09AD223140F0900A038AD /* MobileKeeper.storyboard */, ); - path = Queries; + path = MobileKeeper; sourceTree = ""; }; - E97D450621C801C4000E3C48 /* Dex */ = { + 7BF509F022D8B95300582783 /* Sources */ = { isa = PBXGroup; children = ( - E9F9A27D218540F700FD68D7 /* DexRealmRepositoryLocal.swift */, - E967786821EC491500CE56D6 /* CandlesRepositoryRemote.swift */, - E922D26921B831B600575955 /* LastTradesRepositoryRemote.swift */, - E97D450A21C802AB000E3C48 /* DexPairsPriceRepositoryRemote.swift */, - E97D451121C817CC000E3C48 /* DexOrderBookRepositoryRemote.swift */, - E96E2A0121D34AA200AC2FA9 /* MatcherRepositoryRemote.swift */, + 7BF50A5C22D8B95400582783 /* Assisstants */, + 7BF509F122D8B95300582783 /* DataBase */, + 7BF50A1522D8B95300582783 /* Mapper */, + 7BF50A2C22D8B95400582783 /* Repositories */, + 7BF50A5122D8B95400582783 /* Service */, ); - path = Dex; + path = Sources; sourceTree = ""; }; - E97D450721C8020F000E3C48 /* Dex */ = { + 7BF509F122D8B95300582783 /* DataBase */ = { isa = PBXGroup; children = ( - E9F9A27B21853E7D00FD68D7 /* DexRealmRepositoryProtocol.swift */, - E922D26321B82C2100575955 /* CandlesRepositoryProtocol.swift */, - E922D26721B8311F00575955 /* LastTradesRepositoryProtocol.swift */, - E97D450821C80233000E3C48 /* DexPairsPriceRepositoryProtocol.swift */, - E97D450C21C8127F000E3C48 /* DexOrderBookRepositoryProtocol.swift */, - E96E29FF21D34A2100AC2FA9 /* MatcherRepositoryProtocol.swift */, + 7BF509F222D8B95300582783 /* WalletSeed */, + 7BF509F422D8B95300582783 /* Wallet */, + 7BF50A1122D8B95300582783 /* Wallets */, ); - path = Dex; + path = DataBase; sourceTree = ""; }; - E97D450E21C814A0000E3C48 /* Models */ = { + 7BF509F222D8B95300582783 /* WalletSeed */ = { isa = PBXGroup; children = ( - E97D450F21C814C0000E3C48 /* OrderBookMatcher.swift */, - E9419CCA21CFAD76004DACCA /* MarketMatcher.swift */, - E9A380AC21D3035B004377A6 /* OrderMatcher.swift */, + 7BF509F322D8B95300582783 /* SeedItem.swift */, ); - path = Models; + path = WalletSeed; sourceTree = ""; }; - E991BB182202C9E10022E27D /* SendFee */ = { + 7BF509F422D8B95300582783 /* Wallet */ = { isa = PBXGroup; children = ( - E991BB222202D5490022E27D /* Presenter */, - E991BB212202D5420022E27D /* Interactor */, - E991BB1D2202CDDF0022E27D /* Views */, - E991BB192202CA250022E27D /* SendFeeViewController.swift */, - E991BB1B2202CB3C0022E27D /* SendFeeModuleBuilder.swift */, - E991BB2B2202D6560022E27D /* SendFeeTypes.swift */, + 7BF509F522D8B95300582783 /* WalletRealmFactory.swift */, + 7BF509F622D8B95300582783 /* Model */, ); - path = SendFee; + path = Wallet; sourceTree = ""; }; - E991BB1D2202CDDF0022E27D /* Views */ = { + 7BF509F622D8B95300582783 /* Model */ = { isa = PBXGroup; children = ( - E991BB1F2202CE090022E27D /* SendFeeTableViewCell.swift */, - E991BB2D2202DD420022E27D /* SendFeeHeaderView.swift */, - 0AAC28122215C4C700D8A404 /* SendFeeHeaderView.xib */, - 0A4E71952216E98200A46613 /* SendFeeIndicatorCell.swift */, + 7BF509F722D8B95300582783 /* Transaction */, + 7BF50A0922D8B95300582783 /* AddressBook.swift */, + 7BF50A0A22D8B95300582783 /* Alias.swift */, + 7BF50A0B22D8B95300582783 /* AssetBalance.swift */, + 7BF50A0C22D8B95300582783 /* AssetBalanceSettings.swift */, + 7BF50A0D22D8B95300582783 /* DexAssetPair.swift */, + 7BF50A0E22D8B95300582783 /* Asset.swift */, + 7BF50A0F22D8B95300582783 /* AccountEnvironment.swift */, + 7BF50A1022D8B95300582783 /* AccountSettings.swift */, ); - path = Views; + path = Model; sourceTree = ""; }; - E991BB212202D5420022E27D /* Interactor */ = { + 7BF509F722D8B95300582783 /* Transaction */ = { isa = PBXGroup; children = ( - E991BB292202D5E00022E27D /* SendFeeInteractorProtocol.swift */, - E991BB232202D5740022E27D /* SendFeeInteractor.swift */, + 7BF509F822D8B95300582783 /* LeaseTransaction.swift */, + 7BF509F922D8B95300582783 /* ScriptTransaction.swift */, + 7BF509FA22D8B95300582783 /* IssueTransaction.swift */, + 7BF509FB22D8B95300582783 /* AssetScriptTransaction.swift */, + 7BF509FC22D8B95300582783 /* UnrecognisedTransaction.swift */, + 7BF509FD22D8B95300582783 /* SponsorshipTransaction.swift */, + 7BF509FE22D8B95300582783 /* LeaseCancelTransaction.swift */, + 7BF509FF22D8B95300582783 /* InvokeScriptTransaction.swift */, + 7BF50A0022D8B95300582783 /* BurnTransaction.swift */, + 7BF50A0122D8B95300582783 /* Transaction.swift */, + 7BF50A0222D8B95300582783 /* TransferTransaction.swift */, + 7BF50A0322D8B95300582783 /* ExchangeTransaction.swift */, + 7BF50A0422D8B95300582783 /* AliasTransaction.swift */, + 7BF50A0522D8B95300582783 /* ReissueTransaction.swift */, + 7BF50A0622D8B95300582783 /* MassTransferTransaction.swift */, + 7BF50A0722D8B95300582783 /* AnyTransaction.swift */, + 7BF50A0822D8B95300582783 /* DataTransaction.swift */, ); - path = Interactor; + path = Transaction; sourceTree = ""; }; - E991BB222202D5490022E27D /* Presenter */ = { + 7BF50A1122D8B95300582783 /* Wallets */ = { isa = PBXGroup; children = ( - E991BB272202D5AA0022E27D /* SendFeePresenterProtocol.swift */, - E991BB252202D58C0022E27D /* SendFeePresenter.swift */, + 7B848A732301AD0D0092AD18 /* WalletsRealmFactory.swift */, + 7BF50A1222D8B95300582783 /* WalletItem.swift */, + 7BF50A1322D8B95300582783 /* Model */, ); - path = Presenter; + path = Wallets; sourceTree = ""; }; - E9A2268B2159666E006E0CE1 /* UIKit */ = { + 7BF50A1322D8B95300582783 /* Model */ = { isa = PBXGroup; children = ( - 0AD83619217DE830004413E9 /* TextFields */, - 04831F5F21691428006D1ED6 /* HighlightedView.swift */, - 04831F6021691428006D1ED6 /* MoneyTextField.swift */, - 04831F6121691429006D1ED6 /* SuccessSystemMessageView.swift */, - E9B08821216388B100937644 /* HighlightedButton.swift */, + 7BF50A1422D8B95300582783 /* WalletEncryption.swift */, ); - path = UIKit; + path = Model; sourceTree = ""; }; - E9B086902163882F00937644 /* AddressBook */ = { + 7BF50A1522D8B95300582783 /* Mapper */ = { isa = PBXGroup; children = ( - E9B086912163882F00937644 /* AddAddressBook */, - E9B0869C2163883000937644 /* AddressBook */, - E9B086AD2163883000937644 /* AddressBook.storyboard */, + 7BF50A1622D8B95300582783 /* DexAssetPairDomainDTO+Mapper.swift */, + 7BF50A1722D8B95300582783 /* DexMyOrders+Mapper.swift */, + 7BF50A1822D8B95300582783 /* Transactions */, + 7BF50A2922D8B95300582783 /* Wallet+Mapper.swift */, + 7BF50A2A22D8B95400582783 /* AccountSettings+Mapper.swift */, + 7BF50A2B22D8B95400582783 /* Asset+Mapper.swift */, ); - path = AddressBook; + path = Mapper; sourceTree = ""; }; - E9B086912163882F00937644 /* AddAddressBook */ = { + 7BF50A1822D8B95300582783 /* Transactions */ = { isa = PBXGroup; children = ( - E9B086922163882F00937644 /* AddAddressBookModuleBuilder.swift */, - E9CD0D3421815849001A99B3 /* AddAddressBookTypes.swift */, - E9B086972163883000937644 /* Views */, - E9B0869A2163883000937644 /* AddAddressBookModuleOutput.swift */, - E9B0869B2163883000937644 /* AddAddressBookViewController.swift */, + 7BF50A1922D8B95300582783 /* AnyTransaction+Mapper.swift */, + 7BF50A1A22D8B95300582783 /* ReissueTransaction+Mapper.swift */, + 7BF50A1B22D8B95300582783 /* InvokeScriptTransaction+Mapper.swift */, + 7BF50A1C22D8B95300582783 /* AssetScriptTransaction+Mapper.swift */, + 7BF50A1D22D8B95300582783 /* AliasTransaction+Mapper.swift */, + 7BF50A1E22D8B95300582783 /* UnrecognisedTransaction+Mapper.swift */, + 7BF50A1F22D8B95300582783 /* ScriptTransaction+Mapper.swift */, + 7BF50A2022D8B95300582783 /* LeaseCancelTransaction+Mapper.swift */, + 7BF50A2122D8B95300582783 /* DataTransaction+Mapper.swift */, + 7BF50A2222D8B95300582783 /* SponsorshipTransaction+Mapper.swift */, + 7BF50A2322D8B95300582783 /* IssueTransaction+Mapper.swift */, + 7BF50A2422D8B95300582783 /* TransferTransaction+Mapper.swift */, + 7BF50A2522D8B95300582783 /* MassTransferTransaction+Mapper.swift */, + 7BF50A2622D8B95300582783 /* BurnTransaction+Mapper.swift */, + 7BF50A2722D8B95300582783 /* ExchangeTransaction+Mapper.swift */, + 7BF50A2822D8B95300582783 /* LeaseTransaction+Mapper.swift */, ); - path = AddAddressBook; + path = Transactions; sourceTree = ""; }; - E9B086972163883000937644 /* Views */ = { + 7BF50A2C22D8B95400582783 /* Repositories */ = { + isa = PBXGroup; + children = ( + 7BF50A3222D8B95400582783 /* AccountSettingsRepository.swift */, + 7BF50A3522D8B95400582783 /* AddressRepositoryRemote.swift */, + 7BF50A3122D8B95400582783 /* ApplicationVersionRepository.swift */, + 7BF50A3422D8B95400582783 /* AuthenticationRepositoryRemote.swift */, + 7BF50A2F22D8B95400582783 /* BlockRepositoryRemote.swift */, + 7BF50A3322D8B95400582783 /* CoinomatRepository.swift */, + 7BF50A5022D8B95400582783 /* EnvironmentRepository.swift */, + 7BF50A3022D8B95400582783 /* GatewayRepository.swift */, + 7BF50A2E22D8B95400582783 /* NotificationNewsRepository.swift */, + 7BF50A3922D8B95400582783 /* RepositoriesFactory.swift */, + 7BF50A2D22D8B95400582783 /* SpamAssetsRepository.swift */, + 7BFB474B22FC5A40002B19F8 /* WidgetSettingsRepositoryStorage.swift */, + 7BF50A3C22D8B95400582783 /* AccountBalance */, + 7BF50A3A22D8B95400582783 /* AddressBook */, + 7BF50A4922D8B95400582783 /* Aliases */, + 7BF50A4C22D8B95400582783 /* Assets */, + 7BF50A3F22D8B95400582783 /* Dex */, + 7BF50A3622D8B95400582783 /* Transactions */, + 7BF50A4622D8B95400582783 /* Wallets */, + 7B3A9AB3231BE3900025CDCA /* MobileKeeperRepository.swift */, + ); + path = Repositories; + sourceTree = ""; + }; + 7BF50A3622D8B95400582783 /* Transactions */ = { isa = PBXGroup; children = ( - E9B086982163883000937644 /* AddAddressTextField.xib */, - E9B086992163883000937644 /* AddAddressTextField.swift */, + 7BF50A3722D8B95400582783 /* TransactionsRepositoryRemote.swift */, + 7BF50A3822D8B95400582783 /* TransactionsRepositoryLocal.swift */, ); - path = Views; + path = Transactions; sourceTree = ""; }; - E9B0869C2163883000937644 /* AddressBook */ = { + 7BF50A3A22D8B95400582783 /* AddressBook */ = { isa = PBXGroup; children = ( - E9B0869D2163883000937644 /* AddressBookModuleOutput.swift */, - E9B086A42163883000937644 /* AddressBookModuleBuilder.swift */, - E9B086A52163883000937644 /* AddressBookTypes.swift */, - E9B086A92163883000937644 /* AddressBookViewController.swift */, - E9B086A02163883000937644 /* Presenter */, - E9B086A72163883000937644 /* Views */, - E9B086AA2163883000937644 /* Interactor */, + 7BF50A3B22D8B95400582783 /* AddressBookRepository.swift */, ); path = AddressBook; sourceTree = ""; }; - E9B086A02163883000937644 /* Presenter */ = { + 7BF50A3C22D8B95400582783 /* AccountBalance */ = { isa = PBXGroup; children = ( - E9B086A12163883000937644 /* AddressBookPresenter.swift */, - E9B086A22163883000937644 /* AddressBookPresenterProtocol.swift */, + 7BF50A3D22D8B95400582783 /* AccountBalanceRepositoryRemote.swift */, + 7BF50A3E22D8B95400582783 /* AccountBalanceRepositoryLocal.swift */, ); - path = Presenter; + path = AccountBalance; sourceTree = ""; }; - E9B086A72163883000937644 /* Views */ = { + 7BF50A3F22D8B95400582783 /* Dex */ = { isa = PBXGroup; children = ( - E9B086A82163883000937644 /* AddressBookCell.swift */, + 7BF50A4022D8B95400582783 /* MatcherRepositoryRemote.swift */, + 7BF50A4122D8B95400582783 /* LastTradesRepositoryRemote.swift */, + 7BF50A4222D8B95400582783 /* DexOrderBookRepositoryRemote.swift */, + 7BF50A4322D8B95400582783 /* DexRealmRepositoryLocal.swift */, + 7BF50A4422D8B95400582783 /* CandlesRepositoryRemote.swift */, + 7BF50A4522D8B95400582783 /* DexPairsPriceRepositoryRemote.swift */, + E98A1A152301A0EF00E7EAAD /* MatcherRepositoryLocal.swift */, ); - path = Views; + path = Dex; sourceTree = ""; }; - E9B086AA2163883000937644 /* Interactor */ = { + 7BF50A4622D8B95400582783 /* Wallets */ = { isa = PBXGroup; children = ( - E9B086AB2163883000937644 /* AddressBookInteractorProtocol.swift */, - E9B086AC2163883000937644 /* AddressBookInteractor.swift */, + 7BF50A4722D8B95400582783 /* WalletsRepositoryLocal.swift */, + 7BF50A4822D8B95400582783 /* WalletSeedRepositoryLocal.swift */, ); - path = Interactor; + path = Wallets; sourceTree = ""; }; - E9B086BF2163886800937644 /* Dex */ = { + 7BF50A4922D8B95400582783 /* Aliases */ = { isa = PBXGroup; children = ( - E9B086F32163886800937644 /* Dex.storyboard */, - E921ED02222DDA2B00DE286D /* DexScriptAssetMessage */, - E9B086C02163886800937644 /* DexChart */, - E9B086D92163886800937644 /* DexOrderBook */, - E9B086F42163886800937644 /* DexInfo */, - E9B086FF2163886800937644 /* DexTraderContainer */, - E9B0870F2163886800937644 /* DexList */, - E9B087282163886800937644 /* DexCreateOrder */, - E9B0873D2163886800937644 /* DexLastTrades */, - E9B087512163886800937644 /* DexMyOrders */, - E9B087662163886800937644 /* DexCompleteOrder */, - E9B0876E2163886800937644 /* DexMarket */, - E9B087842163886800937644 /* DexSort */, + 7BF50A4A22D8B95400582783 /* AliasesRepository.swift */, + 7BF50A4B22D8B95400582783 /* AliasesRepositoryLocal.swift */, ); - path = Dex; + path = Aliases; sourceTree = ""; }; - E9B086C02163886800937644 /* DexChart */ = { + 7BF50A4C22D8B95400582783 /* Assets */ = { isa = PBXGroup; children = ( - E9B086C32163886800937644 /* DexChartTypes.swift */, - E9B086C42163886800937644 /* DexChartConstants.swift */, - E9B086C52163886800937644 /* Presenter */, - E9B086C82163886800937644 /* DexChartHelper.swift */, - E9B086C92163886800937644 /* Models */, - E9B086CC2163886800937644 /* DexChartModuleBuilder.swift */, - E9B086CE2163886800937644 /* DexChartViewController.swift */, - E9B086CF2163886800937644 /* Views */, - E9B086D42163886800937644 /* Interactor */, + 7BF50A4D22D8B95400582783 /* AssetsBalanceSettingsRepositoryLocal.swift */, + 7BF50A4E22D8B95400582783 /* AssetsRepositoryLocal.swift */, + 7BF50A4F22D8B95400582783 /* AssetsRepositoryRemote.swift */, ); - path = DexChart; + path = Assets; sourceTree = ""; }; - E9B086C52163886800937644 /* Presenter */ = { + 7BF50A5122D8B95400582783 /* Service */ = { isa = PBXGroup; children = ( - E9B086C62163886800937644 /* DexChartPresenterProtocol.swift */, - E9B086C72163886800937644 /* DexChartPresenter.swift */, + 7BF50A5222D8B95400582783 /* Spam */, + 7BF50A5522D8B95400582783 /* GitHub */, + 7BF50A5822D8B95400582783 /* Coinomat */, + 7BF50A5A22D8B95400582783 /* Gateway */, ); - path = Presenter; + path = Service; sourceTree = ""; }; - E9B086C92163886800937644 /* Models */ = { + 7BF50A5222D8B95400582783 /* Spam */ = { isa = PBXGroup; children = ( - E9B086CA2163886800937644 /* DexChartAxisFormatters.swift */, + 7BF50A5322D8B95400582783 /* SpamService.swift */, + 7BF50A5422D8B95400582783 /* AssetsSpamService.swift */, ); - path = Models; + path = Spam; sourceTree = ""; }; - E9B086CF2163886800937644 /* Views */ = { + 7BF50A5522D8B95400582783 /* GitHub */ = { isa = PBXGroup; children = ( - E9B086D02163886800937644 /* DexChartCandlePriceView.xib */, - E9B086D12163886800937644 /* DexChartCandlePriceView.swift */, - E9B086D22163886800937644 /* DexChartHeaderView.swift */, - E9B086D32163886800937644 /* DexChartHeaderView.xib */, + 7BF50A5622D8B95400582783 /* GitHubService.swift */, + 7BF50A5722D8B95400582783 /* TransactionFeeRulesGitHub.swift */, ); - path = Views; + path = GitHub; sourceTree = ""; }; - E9B086D42163886800937644 /* Interactor */ = { + 7BF50A5822D8B95400582783 /* Coinomat */ = { isa = PBXGroup; children = ( - E9B086D52163886800937644 /* DexChartInteractor.swift */, - E9B086D72163886800937644 /* DexChartInteractorProtocol.swift */, + 7BF50A5922D8B95400582783 /* CoinomatService.swift */, ); - path = Interactor; + path = Coinomat; sourceTree = ""; }; - E9B086D92163886800937644 /* DexOrderBook */ = { + 7BF50A5A22D8B95400582783 /* Gateway */ = { isa = PBXGroup; children = ( - E9B086DC2163886800937644 /* DexOrderBookTypes.swift */, - E9B086DD2163886800937644 /* DexOrderBookViewController.swift */, - E9B086DE2163886800937644 /* Presenter */, - E9B086E12163886800937644 /* DexOrderBookModuleOutput.swift */, - E9B086E42163886800937644 /* DexOrderBookModuleBuilder.swift */, - E9B086E52163886800937644 /* Views */, - E9B086EA2163886800937644 /* Interactor */, + 7BF50A5B22D8B95400582783 /* GatewayService.swift */, ); - path = DexOrderBook; + path = Gateway; sourceTree = ""; }; - E9B086DE2163886800937644 /* Presenter */ = { + 7BF50A5C22D8B95400582783 /* Assisstants */ = { isa = PBXGroup; children = ( - E9B086DF2163886800937644 /* DexOrderBookPresenterProtocol.swift */, - E9B086E02163886800937644 /* DexOrderBookPresenter.swift */, + 7BF50A5E22D8B95400582783 /* AnalyticManager.swift */, + 7BF50A6822D8B95400582783 /* DatabaseReference+Rx.swift */, + 7BF50A6522D8B95400582783 /* MoyaProvider+Helper.swift */, + 7BF50A6422D8B95400582783 /* NodePlugin.swift */, + 7BF50A6322D8B95400582783 /* Results+Limit.swift */, + 7BF50A6722D8B95400582783 /* SentryManager.swift */, + 7BF50A6622D8B95400582783 /* SentryNetworkLoggerPlugin.swift */, + 7BF50A5D22D8B95400582783 /* SpamCSV+Assisstants.swift */, + 7BF50A6922D8B95400582783 /* String+NormalizeAssetId.swift */, + 7BF50A6A22D8B95400582783 /* SweetLoggerSentry.swift */, + 7BF50A5F22D8B95400582783 /* TransactionSenderAssistant.swift */, + 7BF50A6022D8B95400582783 /* Types */, ); - path = Presenter; + path = Assisstants; sourceTree = ""; }; - E9B086E52163886800937644 /* Views */ = { + 7BF50A6022D8B95400582783 /* Types */ = { isa = PBXGroup; children = ( - E9B086E62163886800937644 /* DexOrderBookLastPriceCell.swift */, - E9B086E72163886800937644 /* DexOrderBookCell.swift */, - E9B086E82163886800937644 /* DexOrderBookHeaderView.swift */, - E9B086E92163886800937644 /* DexOrderBookHeaderView.xib */, + 7BF50A6222D8B95400582783 /* Signature.swift */, + 7BF50A6122D8B95400582783 /* TimestampSignature.swift */, ); - path = Views; + path = Types; sourceTree = ""; }; - E9B086EA2163886800937644 /* Interactor */ = { + 7BF89E9722272A5E00853F9D /* Analytics */ = { isa = PBXGroup; children = ( - E9B086EC2163886800937644 /* DexOrderBookInteractorProtocol.swift */, - E9B086ED2163886800937644 /* DexOrderBookInteractor.swift */, ); - path = Interactor; + path = Analytics; sourceTree = ""; }; - E9B086F42163886800937644 /* DexInfo */ = { + 7BFB474D22FC5AD0002B19F8 /* CommonResources */ = { isa = PBXGroup; children = ( - E9B086F72163886800937644 /* DexInfoModuleBuilder.swift */, - E9B086F82163886800937644 /* DexInfoViewController.swift */, - E9B086FB2163886800937644 /* DexInfoTypes.swift */, - E9B086FC2163886800937644 /* Views */, + 7B48F35E2330F7BF00923E9E /* environment_stagenet.json */, + 0A61B599214ACFD500EC60FC /* Languages.json */, + 7BFB474E22FC5AD0002B19F8 /* Sentry-io-Info.plist */, + 7BFB474F22FC5AD0002B19F8 /* Appsflyer-Info.plist */, + 7BFB475022FC5AD0002B19F8 /* AppSpector-Info.plist */, + 7BFB475122FC5AD0002B19F8 /* environment_testnet.json */, + 7BFB475222FC5AD0002B19F8 /* GoogleService-Info.plist */, + 7BFB475322FC5AD0002B19F8 /* Fabric-Info.plist */, + 7BFB475422FC5AD0002B19F8 /* Amplitude-Info.plist */, + 7BFB475522FC5AD0002B19F8 /* environment_mainnet.json */, + 7BFB475622FC5AD0002B19F8 /* spam.csv */, ); - path = DexInfo; - sourceTree = ""; + path = CommonResources; + sourceTree = SOURCE_ROOT; }; - E9B086FC2163886800937644 /* Views */ = { + 7BFB47DF22FC742D002B19F8 /* Mock */ = { isa = PBXGroup; children = ( - E9B086FD2163886800937644 /* SearchBarView.swift */, - E9B086FE2163886800937644 /* SearchBarView.xib */, + 7BFB47E022FC742D002B19F8 /* AssetsRepositoryMock.swift */, ); - path = Views; + path = Mock; sourceTree = ""; }; - E9B086FF2163886800937644 /* DexTraderContainer */ = { + 7BFB47E222FC742E002B19F8 /* UIKit */ = { isa = PBXGroup; children = ( - E9B087022163886800937644 /* DexTraderContainerTypes.swift */, - E9B087032163886800937644 /* DexTraderContainerViewController.swift */, - E9B087062163886800937644 /* Modules */, - E9B0870A2163886800937644 /* Views */, + 7BFB47E622FC742E002B19F8 /* BiometricType.swift */, + 7BFB47EB22FC742E002B19F8 /* DisplayError.swift */, + 7BFB47ED22FC742E002B19F8 /* GlobalConstants.swift */, + 7BFB47EF22FC742E002B19F8 /* MailCompose+Support.swift */, + 7BFB47EC22FC742E002B19F8 /* Notifications.swift */, + 7BFB47EE22FC742E002B19F8 /* QRCodeReader+Factory.swift */, + 7BFB47EA22FC742E002B19F8 /* RateApp.swift */, + 7BFB47E422FC742E002B19F8 /* UIAlertController+Factory.swift */, + 7BFB47F022FC742E002B19F8 /* Modal */, + 7BFB47E722FC742E002B19F8 /* Skeleton */, ); - path = DexTraderContainer; + path = UIKit; sourceTree = ""; }; - E9B087062163886800937644 /* Modules */ = { + 7BFB47E722FC742E002B19F8 /* Skeleton */ = { isa = PBXGroup; children = ( - E9B087072163886800937644 /* DexTraderContainerModuleOutput.swift */, - E9B087082163886800937644 /* DexTraderContainerModuleBuilder.swift */, - E9B087092163886800937644 /* DexTraderContainerInputProtocol.swift */, + 7BFB47E822FC742E002B19F8 /* UITableView+Skeleton.swift */, + 7BFB47E922FC742E002B19F8 /* SkeletonAnimatable.swift */, ); - path = Modules; + path = Skeleton; sourceTree = ""; }; - E9B0870A2163886800937644 /* Views */ = { + 7BFB47F022FC742E002B19F8 /* Modal */ = { isa = PBXGroup; children = ( - E9B0870B2163886800937644 /* DexTraderContainerSegmentedControl.xib */, - E9B0870C2163886800937644 /* DexTraderContainerBaseHeaderView.swift */, - E9B0870D2163886800937644 /* DexTraderContainerButton.swift */, - E9B0870E2163886800937644 /* DexTraderContainerSegmentedControl.swift */, + 7BFB47F122FC742E002B19F8 /* ModalRootView.swift */, + 7BFB47F222FC742E002B19F8 /* ModalViewControllerTransitioning.swift */, + 7BFB47F322FC742E002B19F8 /* ModalPresentationAnimator.swift */, + 7BFB47F422FC742E002B19F8 /* ModalPresentationController.swift */, + 7BFB47F522FC742E002B19F8 /* ModalTableView.swift */, + 7BFB47F622FC742E002B19F8 /* ModalScrollViewController.swift */, + 7BFB47F722FC742E002B19F8 /* ModalPresentationAnimatorContext.swift */, ); - path = Views; + path = Modal; sourceTree = ""; }; - E9B0870F2163886800937644 /* DexList */ = { + 7BFB47FB22FC742F002B19F8 /* Type */ = { isa = PBXGroup; children = ( - E9B087102163886800937644 /* DexListModuleOutput.swift */, - E9B087132163886800937644 /* Presenter */, - E9B087162163886800937644 /* DexListTypes.swift */, - E9B087192163886800937644 /* Views */, - E9B0871D2163886800937644 /* DexListViewController.swift */, - E9B0871E2163886800937644 /* DexListModuleBuilder.swift */, - E9B0871F2163886800937644 /* Interactor */, + 7BFB47FD22FC742F002B19F8 /* QRCodeParser.swift */, ); - path = DexList; + path = Type; sourceTree = ""; }; - E9B087132163886800937644 /* Presenter */ = { + 7BFB47FE22FC742F002B19F8 /* Analytics */ = { isa = PBXGroup; children = ( - E9B087142163886800937644 /* DexListPresenterProtocol.swift */, - E9B087152163886800937644 /* DexListPresenter.swift */, + 7BFB47FF22FC742F002B19F8 /* NewUserWithoutBackupStorageTrack.swift */, ); - path = Presenter; + path = Analytics; sourceTree = ""; }; - E9B087192163886800937644 /* Views */ = { + E921ED02222DDA2B00DE286D /* DexScriptAssetMessage */ = { isa = PBXGroup; children = ( - E9B0871A2163886800937644 /* DexListHeaderCell.swift */, - E9B0871B2163886800937644 /* DexListCell.swift */, - E9B0871C2163886800937644 /* DexListSkeletonCell.swift */, + E921ED03222DDA4600DE286D /* DexScriptAssetMessageViewController.swift */, + E9A3AFAD222DEECB009FB45A /* DexScriptAssetMessageModuleBuilder.swift */, ); - path = Views; + path = DexScriptAssetMessage; sourceTree = ""; }; - E9B0871F2163886800937644 /* Interactor */ = { + E9236F192216F2FE00A12FD5 /* AppNews */ = { isa = PBXGroup; children = ( - E9B087212163886800937644 /* DexListInteractorProtocol.swift */, - E9B087222163886800937644 /* DexListInteractor.swift */, + E9236F1C2216F35B00A12FD5 /* AppNewsView.swift */, + E9236F1E2216F37300A12FD5 /* AppNewsView.xib */, ); - path = Interactor; + path = AppNews; sourceTree = ""; }; - E9B087282163886800937644 /* DexCreateOrder */ = { + E923956C237518B7009C4091 /* PushNotifictions */ = { isa = PBXGroup; children = ( - E9B087292163886800937644 /* DexCreateOrderModuleOutput.swift */, - E9B0872C2163886800937644 /* DexCreateOrderViewController.swift */, - E9B0872D2163886800937644 /* Presenter */, - E9B087302163886800937644 /* DexCreateOrderTypes.swift */, - E9B087332163886800937644 /* DexCreateOrderModuleBuilder.swift */, - E9B087342163886800937644 /* Views */, - E9B0873A2163886800937644 /* Interactor */, + E923956D237518B7009C4091 /* PushNotificationsManager.swift */, + E923956E237518B7009C4091 /* PushNotificationsAlertView.swift */, + E923956F237518B7009C4091 /* PushNotificationsAlertView.xib */, ); - path = DexCreateOrder; + path = PushNotifictions; sourceTree = ""; }; - E9B0872D2163886800937644 /* Presenter */ = { + E923A766219D713A000DD9F6 /* Loading */ = { isa = PBXGroup; children = ( - E9B0872E2163886800937644 /* DexCreateOrderPresenterProtocol.swift */, - E9B0872F2163886800937644 /* DexCreateOrderPresenter.swift */, + E923A767219D714E000DD9F6 /* TokenBurnLoadingViewController.swift */, ); - path = Presenter; + path = Loading; sourceTree = ""; }; - E9B087342163886800937644 /* Views */ = { + E923A76B219D73AE000DD9F6 /* Complete */ = { isa = PBXGroup; children = ( - E9B087352163886800937644 /* DexCreateOrderInputView.xib */, - E9B087362163886800937644 /* DexCreateOrderSegmentedControl.swift */, - E9B087372163886800937644 /* DexCreateOrderInputView.swift */, - E9B087382163886800937644 /* DexCreateOrderAmountButton.swift */, - E9B087392163886800937644 /* DexCreateOrderSegmentedControl.xib */, + E923A76C219D73BF000DD9F6 /* TokenBurnCompleteViewController.swift */, ); - path = Views; + path = Complete; sourceTree = ""; }; - E9B0873A2163886800937644 /* Interactor */ = { + E92A115F2317CD06004EC6A1 /* Services */ = { isa = PBXGroup; children = ( - E9B0873B2163886800937644 /* DexCreateOrderInteractorProtocol.swift */, - E965702221935F2F0052F0FC /* DexCreateOrderInteractor.swift */, + E92A116A2317CF9A004EC6A1 /* InternalWidgetService.swift */, + E92A11792317DCDA004EC6A1 /* Matcher */, + E92A11652317CEC5004EC6A1 /* Data */, ); - path = Interactor; + path = Services; sourceTree = ""; }; - E9B0873D2163886800937644 /* DexLastTrades */ = { + E92A11622317CE08004EC6A1 /* Targets */ = { isa = PBXGroup; children = ( - E9B087402163886800937644 /* DexLastTradesModuleOutput.swift */, - E9B087412163886800937644 /* DexLastTradesModuleBuilder.swift */, - E9B087422163886800937644 /* Presenter */, - E9B087452163886800937644 /* DexLastTradesTypes.swift */, - E9B087472163886800937644 /* DexLastTradesViewController.swift */, - E9B087492163886800937644 /* Views */, - E9B0874D2163886800937644 /* Interactor */, + E96DE1852317F07B005E1FD9 /* WidgetAssetsDataTarget.swift */, + E92A11632317CE35004EC6A1 /* WidgetPairsPriceDataTarget.swift */, + E984BB6C2318461A00D60C38 /* WidgetTransactionsDataTarget.swift */, ); - path = DexLastTrades; + path = Targets; sourceTree = ""; }; - E9B087422163886800937644 /* Presenter */ = { + E92A11652317CEC5004EC6A1 /* Data */ = { isa = PBXGroup; children = ( - E9B087432163886800937644 /* DexLastTradesPresenterProtocol.swift */, - E9B087442163886800937644 /* DexLastTradesPresenter.swift */, + E92A116C2317D12F004EC6A1 /* WidgetDataServiceTypes.swift */, + E92A116E2317D1D2004EC6A1 /* Models */, + E92A11662317CED3004EC6A1 /* Services */, + E92A11622317CE08004EC6A1 /* Targets */, ); - path = Presenter; + path = Data; sourceTree = ""; }; - E9B087492163886800937644 /* Views */ = { + E92A11662317CED3004EC6A1 /* Services */ = { isa = PBXGroup; children = ( - E9B0874A2163886800937644 /* DexLastTradesHeaderView.xib */, - E9B0874B2163886800937644 /* DexLastTradesCell.swift */, - E9B0874C2163886800937644 /* DexLastTradesHeaderView.swift */, + E92A11672317CEF6004EC6A1 /* WidgetPairsPriceDataService.swift */, + E92A11842317E883004EC6A1 /* WidgetAssetsDataService.swift */, + E984BB6A2318457800D60C38 /* WidgetTransactionsDataService.swift */, ); - path = Views; + path = Services; sourceTree = ""; }; - E9B0874D2163886800937644 /* Interactor */ = { + E92A116E2317D1D2004EC6A1 /* Models */ = { isa = PBXGroup; children = ( - E9B0874F2163886800937644 /* DexLastTradesInteractor.swift */, - E9B087502163886800937644 /* DexLastTradesInteractorProtocol.swift */, + E92A11712317D2E9004EC6A1 /* WidgetResponseData.swift */, + E92A116F2317D1DD004EC6A1 /* WidgetPairPriceData.swift */, ); - path = Interactor; + path = Models; sourceTree = ""; }; - E9B087512163886800937644 /* DexMyOrders */ = { + E92A11782317DB37004EC6A1 /* Network */ = { isa = PBXGroup; children = ( - E9B087522163886800937644 /* DexMyOrdersViewController.swift */, - E9B087552163886800937644 /* Presenter */, - E9B087582163886800937644 /* DexMyOrdersModuleBuilder.swift */, - E96570422193E8570052F0FC /* DexMyOrdersModuleOutput.swift */, - E9B0875B2163886800937644 /* Views */, - E9B0875F2163886800937644 /* Interactor */, - E9B087632163886800937644 /* DexMyOrdersTypes.swift */, + E92A11742317D5DB004EC6A1 /* WidgetPairsPriceRepositoryRemote.swift */, + E92A11762317DB2E004EC6A1 /* WidgetMatcherRepositoryRemote.swift */, + E92A11822317E7A9004EC6A1 /* WidgetAssetsRepositoryRemote.swift */, + E984BB6E23184EE100D60C38 /* WidgetTransactionsRepositoryRemote.swift */, ); - path = DexMyOrders; + path = Network; sourceTree = ""; }; - E9B087552163886800937644 /* Presenter */ = { + E92A11792317DCDA004EC6A1 /* Matcher */ = { isa = PBXGroup; children = ( - E9B087562163886800937644 /* DexMyOrdersPresenterProtocol.swift */, - E9B087572163886800937644 /* DexMyOrdersPresenter.swift */, + E92A117A2317DD6F004EC6A1 /* WidgetMatcherServiceTypes.swift */, + E92A117F2317E0E2004EC6A1 /* Services */, + E92A117C2317DF2D004EC6A1 /* Targets */, ); - path = Presenter; + path = Matcher; sourceTree = ""; }; - E9B0875B2163886800937644 /* Views */ = { + E92A117C2317DF2D004EC6A1 /* Targets */ = { isa = PBXGroup; children = ( - E9B0875E2163886800937644 /* DexMyOrdersCell.swift */, + E92A117D2317DF4B004EC6A1 /* WidgetSettingsMarcherTarget.swift */, + E984BB70231935DD00D60C38 /* WidgetPublicKeyMatcherTarget.swift */, ); - path = Views; + path = Targets; sourceTree = ""; }; - E9B0875F2163886800937644 /* Interactor */ = { + E92A117F2317E0E2004EC6A1 /* Services */ = { isa = PBXGroup; children = ( - E9B087602163886800937644 /* DexMyOrdersInteractor.swift */, - E9B087612163886800937644 /* DexMyOrdersInteractorProtocol.swift */, + E92A11802317E10C004EC6A1 /* WidgetMatcherSettingService.swift */, + E984BB722319367400D60C38 /* WidgetPublicKeyMatcherService.swift */, ); - path = Interactor; + path = Services; sourceTree = ""; }; - E9B087662163886800937644 /* DexCompleteOrder */ = { + E92FF25121A43B3B00CBFF07 /* Complete */ = { isa = PBXGroup; children = ( - E9B087692163886800937644 /* DexCompleteOrderViewController.swift */, - E9B0876C2163886800937644 /* DexCompleteOrderModuleBuilder.swift */, + E9157BED21A4C081009F99B6 /* StartLeasingCompleteViewController.swift */, ); - path = DexCompleteOrder; + path = Complete; sourceTree = ""; }; - E9B0876E2163886800937644 /* DexMarket */ = { + E9310D0A217924B7008BF3EE /* Confirmaion */ = { isa = PBXGroup; children = ( - E9B087742163886800937644 /* Presenter */, - E9B087772163886800937644 /* DexMarketViewController.swift */, - E9B087782163886800937644 /* DexMarketModuleOutput.swift */, - E9B087792163886800937644 /* DexMarketModuleBuilder.swift */, - E9B0877B2163886800937644 /* DexMarketTypes.swift */, - E9B0877D2163886800937644 /* Views */, - E9B0877F2163886800937644 /* Interactor */, + E9310D1721792CD0008BF3EE /* Views */, + E9310D0B217924D0008BF3EE /* SendConfirmationViewController.swift */, ); - path = DexMarket; + path = Confirmaion; sourceTree = ""; }; - E9B087742163886800937644 /* Presenter */ = { + E9310D1721792CD0008BF3EE /* Views */ = { isa = PBXGroup; children = ( - E9B087752163886800937644 /* DexMarketPresenter.swift */, - E9B087762163886800937644 /* DexMarketPresenterProtocol.swift */, + E9310D1821792D01008BF3EE /* SendConfirmationRecipientView.swift */, + E9310D1A21792D13008BF3EE /* SendConfirmationRecipientView.xib */, ); - path = Presenter; + path = Views; sourceTree = ""; }; - E9B0877D2163886800937644 /* Views */ = { + E94231EE22A40A010087F82F /* WalletSearch */ = { isa = PBXGroup; children = ( - E9B0877E2163886800937644 /* DexMarketCell.swift */, + E9F69B9922A5331B00CDBD00 /* Views */, + E9F69B9422A522BC00CDBD00 /* Presenter */, + E95E151422A197B8003552B8 /* WalletSearchViewController.swift */, + E94231EF22A40FA80087F82F /* WalletSearchModuleBuilder.swift */, + E9F69B9122A5217200CDBD00 /* WalletSearchTypes.swift */, ); - path = Views; + path = WalletSearch; sourceTree = ""; }; - E9B0877F2163886800937644 /* Interactor */ = { + E95310B122E8502F00F72809 /* Views */ = { isa = PBXGroup; children = ( - E9B087802163886800937644 /* DexMarketInteractor.swift */, - E9B087812163886800937644 /* DexMarketInteractorProtocol.swift */, + E95310B222E8507500F72809 /* MarketPulseWidgetCell.swift */, ); - path = Interactor; + path = Views; sourceTree = ""; }; - E9B087842163886800937644 /* DexSort */ = { + E95438F6217F919B001A7860 /* Loading */ = { isa = PBXGroup; children = ( - E9B087852163886800937644 /* DexSortViewController.swift */, - E9B087882163886800937644 /* Presenter */, - E9B0878B2163886800937644 /* DexSortModuleBuilder.swift */, - E9B0878D2163886800937644 /* DexSortTypes.swift */, - E9B0878F2163886800937644 /* Views */, - E9B087912163886800937644 /* Interactor */, + E95438F7217F91BA001A7860 /* SendLoadingViewController.swift */, ); - path = DexSort; + path = Loading; sourceTree = ""; }; - E9B087882163886800937644 /* Presenter */ = { + E9543900217FF9C8001A7860 /* Complete */ = { isa = PBXGroup; children = ( - E9B087892163886800937644 /* DexSortPresenter.swift */, - E9B0878A2163886800937644 /* DexSortPresenterProtocol.swift */, + E9543901217FF9EC001A7860 /* SendCompleteViewController.swift */, ); - path = Presenter; + path = Complete; sourceTree = ""; }; - E9B0878F2163886800937644 /* Views */ = { + E958571422F35BBD007A0178 /* Sources */ = { isa = PBXGroup; children = ( - E9B087902163886800937644 /* DexSortCell.swift */, + E92A115F2317CD06004EC6A1 /* Services */, + 7B848A67230076AE0092AD18 /* Generated */, + E958571822F35C87007A0178 /* Repositories */, + E991F8FD22E8CF9D008D1AE4 /* Presenter */, + E991F8FC22E8CF94008D1AE4 /* Interactor */, + E95310B122E8502F00F72809 /* Views */, + E9B190AB22E7CD99008220B7 /* MarketPulseWidgetViewController.swift */, + E95310BB22E85FEE00F72809 /* MarketPulseTypes.swift */, + E958571222F2E73D007A0178 /* WidgetSettings.swift */, + E936C2E92314BF590097515B /* WidgetSettingsInizialization.swift */, + E96DE1902318076A005E1FD9 /* WidgetAnalyticManager.swift */, ); - path = Views; + path = Sources; sourceTree = ""; }; - E9B087912163886800937644 /* Interactor */ = { + E958571522F35BCB007A0178 /* Resources */ = { isa = PBXGroup; children = ( - E9B087922163886800937644 /* DexSortInteractor.swift */, - E9B087932163886800937644 /* DexSortInteractorProtocol.swift */, + 7B848A902304073B0092AD18 /* Localization */, + E95310BD22E8A43000F72809 /* WidgetAssets.xcassets */, ); - path = Interactor; + path = Resources; sourceTree = ""; }; - E9B12DB0219DCFDC00128EFE /* Interactor */ = { + E958571822F35C87007A0178 /* Repositories */ = { isa = PBXGroup; children = ( - E9B12DAA219DCCDB00128EFE /* TokenBurnSendInteractorProtocol.swift */, - E9B12DAC219DCD1800128EFE /* TokenBurnSendInteractor.swift */, + E92A11782317DB37004EC6A1 /* Network */, + E958571F22F3BBA0007A0178 /* MarketPulseDataBaseRepository.swift */, + E958571E22F3BB9F007A0178 /* MarketPulseDataBaseRepositoryProtocol.swift */, ); - path = Interactor; + path = Repositories; sourceTree = ""; }; - E9CD0D2F218137FE001A99B3 /* MainTabBar */ = { + E95B47A521638A9F004D4E39 /* Hello */ = { isa = PBXGroup; children = ( - E9CD0D30218137FE001A99B3 /* MainTabBarController.swift */, + E95B47A821638A9F004D4E39 /* Hello.storyboard */, + E95B47AA21638A9F004D4E39 /* Languages */, + E95B47AD21638A9F004D4E39 /* InfoPages */, ); - path = MainTabBar; + path = Hello; sourceTree = ""; }; - E9D36D6B2175C754001E6DF0 /* Receive */ = { + E95B47AA21638A9F004D4E39 /* Languages */ = { isa = PBXGroup; children = ( - E9D36D6C2175C754001E6DF0 /* Сryptocurrency */, - E9D36D7D2175C754001E6DF0 /* Card */, - E9D36D8C2175C754001E6DF0 /* ReceiveTypes.swift */, - E9D36D8D2175C754001E6DF0 /* CardComplete */, - E9D36D932175C754001E6DF0 /* Receive.storyboard */, - E9D36D942175C754001E6DF0 /* ReceiveContainerViewController.swift */, - E9D36D952175C754001E6DF0 /* ReceiveContainerModuleBuilder.swift */, - E9D36D972175C754001E6DF0 /* Address */, - E9D36DA02175C754001E6DF0 /* Generate */, - E9D36DA82175C754001E6DF0 /* Views */, - E9D36DAB2175C754001E6DF0 /* Invoice */, + E95B47AB21638A9F004D4E39 /* HelloLanguagesViewController.swift */, ); - path = Receive; + path = Languages; sourceTree = ""; }; - E9D36D6C2175C754001E6DF0 /* Сryptocurrency */ = { + E95B47AD21638A9F004D4E39 /* InfoPages */ = { isa = PBXGroup; children = ( - E9D36D6D2175C754001E6DF0 /* ReceiveCryptocurrencyTypes.swift */, - E9D36D702175C754001E6DF0 /* ReceiveCryptocurrencyModuleBuilder.swift */, - E9D36D712175C754001E6DF0 /* Presenter */, - E9D36D762175C754001E6DF0 /* Interactor */, - E9D36D7A2175C754001E6DF0 /* ReceiveCryptocurrencyViewController.swift */, + E95B47AE21638A9F004D4E39 /* View */, + E95B47BD21638A9F004D4E39 /* InfoPagesViewController.swift */, ); - path = "Сryptocurrency"; + path = InfoPages; sourceTree = ""; }; - E9D36D712175C754001E6DF0 /* Presenter */ = { + E95B47AE21638A9F004D4E39 /* View */ = { isa = PBXGroup; children = ( - E9D36D722175C754001E6DF0 /* ReceiveCryptocurrencyPresenterProtocol.swift */, - E9D36D732175C754001E6DF0 /* ReceiveCryptocurrencyPresenter.swift */, + 0AC1251121A758BC00357C93 /* LongInfoPageView.swift */, + E95B47B321638A9F004D4E39 /* LongInfoPageView.xib */, + E95B47B921638A9F004D4E39 /* ShortInfoPageView.swift */, + E95B47BA21638A9F004D4E39 /* ShortInfoPageView.xib */, + 04D882BE21706FEF00EAAB90 /* InfoPagesCell.swift */, + E9939B4422302E3800B50E67 /* InfoPageConfirmView.swift */, + E9939B4622302E6100B50E67 /* InfoPageConfirmView.xib */, ); - path = Presenter; + path = View; sourceTree = ""; }; - E9D36D762175C754001E6DF0 /* Interactor */ = { + E95B47D421638B11004D4E39 /* StartLeasing */ = { isa = PBXGroup; children = ( - E9D36D782175C754001E6DF0 /* ReceiveCryptocurrencyInteractorProtocol.swift */, - E9D36D792175C754001E6DF0 /* ReceiveCryptocurrencyInteractor.swift */, + E95B47DD21638B11004D4E39 /* StartLeasing.storyboard */, + E95B47E021638B11004D4E39 /* StartLeasingTypes.swift */, + E92FF25121A43B3B00CBFF07 /* Complete */, + E9DB667921A3937300962639 /* Loading */, + E9DB667821A38D7300962639 /* CancelConfirmation */, + E9DB666F21A383E900962639 /* Confirmation */, + E9DB667021A383F300962639 /* StartLeasing */, ); - path = Interactor; + path = StartLeasing; sourceTree = ""; }; - E9D36D7D2175C754001E6DF0 /* Card */ = { + E95B47E121638B11004D4E39 /* Views */ = { isa = PBXGroup; children = ( - E9D36D7E2175C754001E6DF0 /* ReceiveCardTypes.swift */, - E9D36D812175C754001E6DF0 /* Presenter */, - E9D36D842175C754001E6DF0 /* ReceiveCardViewController.swift */, - E9D36D852175C754001E6DF0 /* ReceiveCardModuleBuilder.swift */, - E9D36D882175C754001E6DF0 /* Interactor */, + E917B3AC21BD685800CC849A /* AmountSkeletonView.swift */, + E917B3AE21BD688500CC849A /* AmountSkeletonView.xib */, + E95B47E521638B11004D4E39 /* AmountInputView.xib */, + E95B47E221638B11004D4E39 /* AmountInputView.swift */, ); - path = Card; + path = Views; sourceTree = ""; }; - E9D36D812175C754001E6DF0 /* Presenter */ = { + E95B47E621638B11004D4E39 /* Interactor */ = { isa = PBXGroup; children = ( - E9D36D822175C754001E6DF0 /* ReceiveCardPresenter.swift */, - E9D36D832175C754001E6DF0 /* ReceiveCardPresenterProtocol.swift */, + E95B47E721638B11004D4E39 /* StartLeasingInteractorProtocol.swift */, + E95B47E921638B11004D4E39 /* StartLeasingInteractor.swift */, ); - path = Presenter; + path = Interactor; sourceTree = ""; }; - E9D36D882175C754001E6DF0 /* Interactor */ = { + E95B6B08219B3ADF00A85B5D /* TokenBurn */ = { isa = PBXGroup; children = ( - E9D36D892175C754001E6DF0 /* ReceiveCardInteractorProtocol.swift */, - E9D36D8A2175C754001E6DF0 /* ReceiveCardInteractor.swift */, + E9B12DB0219DCFDC00128EFE /* Interactor */, + E9B12DAE219DCDD300128EFE /* TokenBurnTypes.swift */, + E923A76B219D73AE000DD9F6 /* Complete */, + E923A766219D713A000DD9F6 /* Loading */, + E95B6B0D219C22CA00A85B5D /* Confirmation */, + E95B6B0C219C22BB00A85B5D /* TokenBurn */, ); - path = Interactor; + path = TokenBurn; sourceTree = ""; }; - E9D36D8D2175C754001E6DF0 /* CardComplete */ = { + E95B6B0C219C22BB00A85B5D /* TokenBurn */ = { isa = PBXGroup; children = ( - E9D36D922175C754001E6DF0 /* ReceiveCardCompleteViewController.swift */, + E95B6B09219B3B0100A85B5D /* TokenBurnViewController.swift */, ); - path = CardComplete; + path = TokenBurn; sourceTree = ""; }; - E9D36D972175C754001E6DF0 /* Address */ = { + E95B6B0D219C22CA00A85B5D /* Confirmation */ = { isa = PBXGroup; children = ( - E9D36D982175C754001E6DF0 /* ReceiveAddressViewController.swift */, - E9D36D9B2175C754001E6DF0 /* ReceiveAddressModuleBuilder.swift */, - E9D36D9E2175C754001E6DF0 /* ReceiveAddressTypes.swift */, + E95B6B11219C341E00A85B5D /* Views */, + E95B6B10219C22F500A85B5D /* Interactor */, + E95B6B0E219C22E400A85B5D /* TokenBurnConfirmationViewController.swift */, ); - path = Address; + path = Confirmation; sourceTree = ""; }; - E9D36DA02175C754001E6DF0 /* Generate */ = { + E95B6B10219C22F500A85B5D /* Interactor */ = { isa = PBXGroup; children = ( - E9D36DA32175C754001E6DF0 /* ReceiveGenerateAddressModuleBuilder.swift */, - E9D36DA52175C754001E6DF0 /* ReceiveGenerateTypes.swift */, - E9D36DA72175C754001E6DF0 /* ReceiveGenerateAddressViewController.swift */, + E923A764219D53EE000DD9F6 /* TokenBurnInteractor.swift */, ); - path = Generate; + path = Interactor; sourceTree = ""; }; - E9D36DA82175C754001E6DF0 /* Views */ = { + E95B6B11219C341E00A85B5D /* Views */ = { isa = PBXGroup; children = ( - E9D36DA92175C754001E6DF0 /* AssetSelectView.swift */, - E9D36DAA2175C754001E6DF0 /* AssetSelectView.xib */, - E911300B21BC028400588430 /* AssetSelectSkeletonView.swift */, - E911300D21BC029300588430 /* AssetSelectSkeletonView.xib */, + E95B6B12219C345B00A85B5D /* TokenBurnConfirmationIDView.swift */, + E95B6B14219C347200A85B5D /* TokenBurnConfirmationIDView.xib */, ); path = Views; sourceTree = ""; }; - E9D36DAB2175C754001E6DF0 /* Invoice */ = { + E9657026219360770052F0FC /* WalletSort */ = { isa = PBXGroup; children = ( - E9D36DAE2175C754001E6DF0 /* ReceiveInvoiceViewController.swift */, - E9D36DAF2175C754001E6DF0 /* ReceiveInvoiceModuleBuilder.swift */, - E9D36DB12175C754001E6DF0 /* ReceiveInvoiveTypes.swift */, - E9D36DB22175C754001E6DF0 /* Interactor */, + E9657027219360770052F0FC /* Presenter */, + E944300B226E643A00EB6257 /* WalletSortModuleBuilder.swift */, + E9443009226E641E00EB6257 /* WalletSortTypes.swift */, + E9443017226E757E00EB6257 /* WalletSort+Mapper.swift */, + E965702D219360770052F0FC /* Views */, + E9443007226E62A600EB6257 /* WalletSortViewController.swift */, + E9657033219360770052F0FC /* Interactor */, ); - path = Invoice; + path = WalletSort; sourceTree = ""; }; - E9D36DB22175C754001E6DF0 /* Interactor */ = { + E9657027219360770052F0FC /* Presenter */ = { isa = PBXGroup; children = ( - E9D36DB32175C754001E6DF0 /* ReceiveInvoiceInteractorProtocol.swift */, - E9D36DB42175C754001E6DF0 /* ReceiveInvoiceInteractor.swift */, + E944300D226E645300EB6257 /* WalletSortPresenterProtocol.swift */, + E92703C5226FDD0C0022D5F0 /* WalletSortPresenter.swift */, ); - path = Interactor; + path = Presenter; sourceTree = ""; }; - E9D36DB52175C754001E6DF0 /* AssetList */ = { + E965702D219360770052F0FC /* Views */ = { isa = PBXGroup; children = ( - E9D36DB82175C755001E6DF0 /* AssetListModuleBuilder.swift */, - E9D36DB92175C755001E6DF0 /* Presenter */, - E9D36DBC2175C755001E6DF0 /* AssetListViewController.swift */, - E9D36DBD2175C755001E6DF0 /* AssetListTypes.swift */, - E9D36DC02175C755001E6DF0 /* Views */, - E9D36DC22175C755001E6DF0 /* Interactor */, - E9D36DC52175C755001E6DF0 /* AssetListModuleOutput.swift */, - E9D36DC62175C755001E6DF0 /* AssetList.storyboard */, + E96FEA23226E962300C0EE22 /* WalletSortEmptyAssetsCell.swift */, + E96FEA24226E962300C0EE22 /* WalletSortEmptyAssetsCell.xib */, + E96FEA27226F27BC00C0EE22 /* WalletSortCell.swift */, + E96FEA28226F27BC00C0EE22 /* WalletSortCell.xib */, + E92FAD0C226F6C050054D4AA /* WalletSortSeparatorCell.swift */, + E92FAD0D226F6C050054D4AA /* WalletSortSeparatorCell.xib */, + E96DAB72228EEC87005ED12B /* WalletSortSegmentedControl.swift */, + E96DAB70228EE643005ED12B /* WalletSortSegmentedControl.xib */, ); - path = AssetList; + path = Views; sourceTree = ""; }; - E9D36DB92175C755001E6DF0 /* Presenter */ = { + E9657033219360770052F0FC /* Interactor */ = { isa = PBXGroup; children = ( - E9D36DBA2175C755001E6DF0 /* AssetListPresenterProtocol.swift */, - E9D36DBB2175C755001E6DF0 /* AssetListPresenter.swift */, + E9443013226E64F600EB6257 /* WalletSortInteractorProtocol.swift */, + E9443011226E64E900EB6257 /* WalletSortInteractor.swift */, ); - path = Presenter; + path = Interactor; sourceTree = ""; }; - E9D36DC02175C755001E6DF0 /* Views */ = { + E98F0587236B1CB00055DCCE /* DexDeepLinkLoading */ = { isa = PBXGroup; children = ( - E9D36DC12175C755001E6DF0 /* AssetListTableViewCell.swift */, + E98F0588236B1CCF0055DCCE /* DexDeepLinkLoadingViewController.swift */, ); - path = Views; + path = DexDeepLinkLoading; sourceTree = ""; }; - E9D36DC22175C755001E6DF0 /* Interactor */ = { + E991BB182202C9E10022E27D /* SendFee */ = { isa = PBXGroup; children = ( - E9D36DC32175C755001E6DF0 /* AssetListInteractor.swift */, - E9D36DC42175C755001E6DF0 /* AssetListInteractorProtocol.swift */, + E991BB222202D5490022E27D /* Presenter */, + E991BB212202D5420022E27D /* Interactor */, + E991BB1D2202CDDF0022E27D /* Views */, + E991BB192202CA250022E27D /* SendFeeViewController.swift */, + E991BB1B2202CB3C0022E27D /* SendFeeModuleBuilder.swift */, + E991BB2B2202D6560022E27D /* SendFeeTypes.swift */, ); - path = Interactor; + path = SendFee; sourceTree = ""; }; - E9DB666F21A383E900962639 /* Confirmation */ = { + E991BB1D2202CDDF0022E27D /* Views */ = { isa = PBXGroup; children = ( - E9DB667221A3846A00962639 /* StartLeasingConfirmationViewController.swift */, + E991BB1F2202CE090022E27D /* SendFeeTableViewCell.swift */, + E991BB2D2202DD420022E27D /* SendFeeHeaderView.swift */, + 0AAC28122215C4C700D8A404 /* SendFeeHeaderView.xib */, + 0A4E71952216E98200A46613 /* SendFeeIndicatorCell.swift */, ); - path = Confirmation; + path = Views; sourceTree = ""; }; - E9DB667021A383F300962639 /* StartLeasing */ = { + E991BB212202D5420022E27D /* Interactor */ = { isa = PBXGroup; children = ( - E95B47D721638B11004D4E39 /* StartLeasingModuleBuilder.swift */, - E95B47DE21638B11004D4E39 /* StartLeasingViewController.swift */, - E920372A21A5F4C10055E4D8 /* StartLeasingConfirmModuleBuilder.swift */, - E95B47E121638B11004D4E39 /* Views */, - E95B47E621638B11004D4E39 /* Interactor */, + E991BB292202D5E00022E27D /* SendFeeInteractorProtocol.swift */, + E991BB232202D5740022E27D /* SendFeeInteractor.swift */, ); - path = StartLeasing; + path = Interactor; sourceTree = ""; }; - E9DB667821A38D7300962639 /* CancelConfirmation */ = { + E991BB222202D5490022E27D /* Presenter */ = { isa = PBXGroup; children = ( - E9DB667421A3848900962639 /* StartLeasingCancelConfirmationViewController.swift */, + E991BB272202D5AA0022E27D /* SendFeePresenterProtocol.swift */, + E991BB252202D58C0022E27D /* SendFeePresenter.swift */, ); - path = CancelConfirmation; + path = Presenter; sourceTree = ""; }; - E9DB667921A3937300962639 /* Loading */ = { + E991F8FC22E8CF94008D1AE4 /* Interactor */ = { isa = PBXGroup; children = ( - E9DB667A21A3938200962639 /* StartLeasingLoadingViewController.swift */, + E991F8FE22E8CFC1008D1AE4 /* MarketPulseWidgetInteractor.swift */, ); - path = Loading; + path = Interactor; sourceTree = ""; }; - E9EC5B352175F35800E5C29A /* Send */ = { + E991F8FD22E8CF9D008D1AE4 /* Presenter */ = { isa = PBXGroup; children = ( - E9EC5B362175F35800E5C29A /* Send.storyboard */, - E991BB182202C9E10022E27D /* SendFee */, - E9543900217FF9C8001A7860 /* Complete */, - E95438F6217F919B001A7860 /* Loading */, - E9310D0A217924B7008BF3EE /* Confirmaion */, - E9EC5B372175F35800E5C29A /* Send */, + E991F90022E8CFD3008D1AE4 /* MarketPulseWidgetPresenter.swift */, ); - path = Send; + path = Presenter; sourceTree = ""; }; - E9EC5B372175F35800E5C29A /* Send */ = { + E9A2268B2159666E006E0CE1 /* UIKit */ = { isa = PBXGroup; children = ( - E9EC5C122176B2D700E5C29A /* Interactor */, - E9EC5C112176B2CD00E5C29A /* Presenter */, - E9EC5BA72175F35800E5C29A /* Views */, - E9EC5B3A2175F35800E5C29A /* SendViewController.swift */, - E9EC5B3B2175F35800E5C29A /* SendModuleBuilder.swift */, - E9C0B4A32176C4BE00669D1D /* SendTypes.swift */, + 0AD83619217DE830004413E9 /* TextFields */, + 04831F5F21691428006D1ED6 /* HighlightedView.swift */, + 04831F6021691428006D1ED6 /* MoneyTextField.swift */, + 04831F6121691429006D1ED6 /* SuccessSystemMessageView.swift */, + E9B08821216388B100937644 /* HighlightedButton.swift */, ); - path = Send; + path = UIKit; sourceTree = ""; }; - E9EC5BA72175F35800E5C29A /* Views */ = { + E9B086902163882F00937644 /* AddressBook */ = { isa = PBXGroup; children = ( - E9642C8E21CB32570065A1BD /* CoinomatServiceErrorView.swift */, - E9642C9021CB326A0065A1BD /* CoinomatServiceErrorView.xib */, - E9EC5BA82175F35800E5C29A /* AddressInputView.swift */, - E9EC5BA92175F35800E5C29A /* AddressInputView.xib */, - E9CD0D2B218099FB001A99B3 /* SendMoneroPaymentIdView.swift */, - E9CD0D2D21809A5D001A99B3 /* SendMoneroPaymentIdView.xib */, - E9AFDBE321F32E88003130A8 /* TransactionFeeView.swift */, - E9AFDBE521F32E96003130A8 /* TransactionFeeView.xib */, - E983665D21F5972300178A8A /* TransactionScriptErrorView.swift */, - E983666021F5973900178A8A /* TransactionScriptErrorView.xib */, + E9B086912163882F00937644 /* AddAddressBook */, + E9B0869C2163883000937644 /* AddressBook */, + E9B086AD2163883000937644 /* AddressBook.storyboard */, ); - path = Views; + path = AddressBook; sourceTree = ""; }; - E9EC5C112176B2CD00E5C29A /* Presenter */ = { + E9B086912163882F00937644 /* AddAddressBook */ = { isa = PBXGroup; children = ( - E9C0B49B2176C46E00669D1D /* SendPresenterProtocol.swift */, - E9C0B49D2176C48300669D1D /* SendPresenter.swift */, - ); + E9B086922163882F00937644 /* AddAddressBookModuleBuilder.swift */, + E9CD0D3421815849001A99B3 /* AddAddressBookTypes.swift */, + E9B086972163883000937644 /* Views */, + E9B0869A2163883000937644 /* AddAddressBookModuleOutput.swift */, + E9B0869B2163883000937644 /* AddAddressBookViewController.swift */, + ); + path = AddAddressBook; + sourceTree = ""; + }; + E9B086972163883000937644 /* Views */ = { + isa = PBXGroup; + children = ( + E9B086982163883000937644 /* AddAddressTextField.xib */, + E9B086992163883000937644 /* AddAddressTextField.swift */, + ); + path = Views; + sourceTree = ""; + }; + E9B0869C2163883000937644 /* AddressBook */ = { + isa = PBXGroup; + children = ( + E9B0869D2163883000937644 /* AddressBookModuleOutput.swift */, + E9B086A42163883000937644 /* AddressBookModuleBuilder.swift */, + E9B086A52163883000937644 /* AddressBookTypes.swift */, + E9B086A92163883000937644 /* AddressBookViewController.swift */, + E9B086A02163883000937644 /* Presenter */, + E9B086A72163883000937644 /* Views */, + E9B086AA2163883000937644 /* Interactor */, + ); + path = AddressBook; + sourceTree = ""; + }; + E9B086A02163883000937644 /* Presenter */ = { + isa = PBXGroup; + children = ( + E9B086A12163883000937644 /* AddressBookPresenter.swift */, + E9B086A22163883000937644 /* AddressBookPresenterProtocol.swift */, + ); path = Presenter; sourceTree = ""; }; - E9EC5C122176B2D700E5C29A /* Interactor */ = { + E9B086A72163883000937644 /* Views */ = { isa = PBXGroup; children = ( - E9C0B49F2176C49B00669D1D /* SendInteractorProtocol.swift */, - E9C0B4A12176C4A800669D1D /* SendInteractor.swift */, + E9B086A82163883000937644 /* AddressBookCell.swift */, + ); + path = Views; + sourceTree = ""; + }; + E9B086AA2163883000937644 /* Interactor */ = { + isa = PBXGroup; + children = ( + E9B086AB2163883000937644 /* AddressBookInteractorProtocol.swift */, + E9B086AC2163883000937644 /* AddressBookInteractor.swift */, ); path = Interactor; sourceTree = ""; }; - E9F69B9422A522BC00CDBD00 /* Presenter */ = { + E9B086BF2163886800937644 /* Dex */ = { isa = PBXGroup; children = ( - E9F69B9722A522E400CDBD00 /* WalletSearchPresenter.swift */, + E9B086F32163886800937644 /* Dex.storyboard */, + E98F0587236B1CB00055DCCE /* DexDeepLinkLoading */, + E921ED02222DDA2B00DE286D /* DexScriptAssetMessage */, + E9B086C02163886800937644 /* DexChart */, + E9B086D92163886800937644 /* DexOrderBook */, + E9B086F42163886800937644 /* DexInfo */, + E9B086FF2163886800937644 /* DexTraderContainer */, + E9B0870F2163886800937644 /* DexList */, + E9B087282163886800937644 /* DexCreateOrder */, + E9B0873D2163886800937644 /* DexLastTrades */, + E9B087512163886800937644 /* DexMyOrders */, + E9B087662163886800937644 /* DexCompleteOrder */, + E9B0876E2163886800937644 /* DexMarket */, + E9B087842163886800937644 /* DexSort */, + ); + path = Dex; + sourceTree = ""; + }; + E9B086C02163886800937644 /* DexChart */ = { + isa = PBXGroup; + children = ( + E9B086C32163886800937644 /* DexChartTypes.swift */, + E9413AC122FA3D9C002C4A97 /* DexChartSettings.swift */, + E9B086C42163886800937644 /* DexChartConstants.swift */, + E9B086C52163886800937644 /* Presenter */, + E9B086C82163886800937644 /* DexChartHelper.swift */, + E9B086C92163886800937644 /* Models */, + E9B086CC2163886800937644 /* DexChartModuleBuilder.swift */, + E9B086CE2163886800937644 /* DexChartViewController.swift */, + E9B086CF2163886800937644 /* Views */, + E9B086D42163886800937644 /* Interactor */, + ); + path = DexChart; + sourceTree = ""; + }; + E9B086C52163886800937644 /* Presenter */ = { + isa = PBXGroup; + children = ( + E9B086C62163886800937644 /* DexChartPresenterProtocol.swift */, + E9B086C72163886800937644 /* DexChartPresenter.swift */, ); path = Presenter; sourceTree = ""; }; - E9F69B9922A5331B00CDBD00 /* Views */ = { + E9B086C92163886800937644 /* Models */ = { isa = PBXGroup; children = ( - E9F69B9A22A5333500CDBD00 /* WalletSearchHeaderCell.swift */, - E9F69B9B22A5333500CDBD00 /* WalletSearchHeaderCell.xib */, + E9B086CA2163886800937644 /* DexChartAxisFormatters.swift */, + ); + path = Models; + sourceTree = ""; + }; + E9B086CF2163886800937644 /* Views */ = { + isa = PBXGroup; + children = ( + E9B086D02163886800937644 /* DexChartCandlePriceView.xib */, + E9B086D12163886800937644 /* DexChartCandlePriceView.swift */, + E9B086D22163886800937644 /* DexChartHeaderView.swift */, + E9B086D32163886800937644 /* DexChartHeaderView.xib */, ); path = Views; sourceTree = ""; }; - E9F984A720E5266800D2CB4D /* Enter */ = { + E9B086D42163886800937644 /* Interactor */ = { isa = PBXGroup; children = ( - 044D6C8421978C8C003861A2 /* Edit */, - E9F984A820E526DA00D2CB4D /* Enter.storyboard */, - 04A4031F2164B8CD00652F21 /* Start */, + E9B086D52163886800937644 /* DexChartInteractor.swift */, + E9B086D72163886800937644 /* DexChartInteractorProtocol.swift */, ); - path = Enter; + path = Interactor; sourceTree = ""; }; - F74240AF1EAB8D1600C3B84D /* DataLayer */ = { + E9B086D92163886800937644 /* DexOrderBook */ = { isa = PBXGroup; children = ( - 0A5C919120F3D00D00443CE6 /* Assisstants */, - 0A1DAD6720F3971B004DA625 /* DataBase */, - 0A6CCD3920F4BC730023E36E /* Mapper */, - 0A979775210A19B400407F67 /* Repositories */, - 0A1DAD6620F396F4004DA625 /* Service */, + E9B086DC2163886800937644 /* DexOrderBookTypes.swift */, + E9B086DD2163886800937644 /* DexOrderBookViewController.swift */, + E9B086DE2163886800937644 /* Presenter */, + E9B086E12163886800937644 /* DexOrderBookModuleOutput.swift */, + E9B086E42163886800937644 /* DexOrderBookModuleBuilder.swift */, + E9B086E52163886800937644 /* Views */, + E9B086EA2163886800937644 /* Interactor */, ); - path = DataLayer; + path = DexOrderBook; sourceTree = ""; }; - F74240B01EAB8D1600C3B84D /* Model */ = { + E9B086DE2163886800937644 /* Presenter */ = { isa = PBXGroup; children = ( - 0A485E962100A89400079B49 /* Transaction */, - 0A5C919B20F3E7DD00443CE6 /* Asset.swift */, - F74240B11EAB8D1600C3B84D /* AddressBook.swift */, - F74240B21EAB8D1600C3B84D /* AssetBalance.swift */, - 0A485E8620FF570000079B49 /* AssetBalanceSettings.swift */, - 0AD83605217A1C14004413E9 /* AccountEnvironment.swift */, - 0AD83607217A1C26004413E9 /* AccountSettings.swift */, - E9F9A278218535A200FD68D7 /* DexAssetPair.swift */, - 0AF0C67621A97E1400602197 /* Alias.swift */, + E9B086DF2163886800937644 /* DexOrderBookPresenterProtocol.swift */, + E9B086E02163886800937644 /* DexOrderBookPresenter.swift */, ); - path = Model; + path = Presenter; sourceTree = ""; }; - F7E954DB1EA8FE0600A804DE = { + E9B086E52163886800937644 /* Views */ = { isa = PBXGroup; children = ( - F7E954E61EA8FE0700A804DE /* WavesWallet-iOS */, - 7BF89E9722272A5E00853F9D /* MonkeyTest */, - F7E954E51EA8FE0700A804DE /* Products */, - D6029DF045FAF50274C41646 /* Pods */, - 18CFECE732E67CAF8666D2C9 /* Frameworks */, + E9B086E62163886800937644 /* DexOrderBookLastPriceCell.swift */, + E9B086E72163886800937644 /* DexOrderBookCell.swift */, + E9B086E82163886800937644 /* DexOrderBookHeaderView.swift */, + E9B086E92163886800937644 /* DexOrderBookHeaderView.xib */, ); + path = Views; sourceTree = ""; }; - F7E954E51EA8FE0700A804DE /* Products */ = { + E9B086EA2163886800937644 /* Interactor */ = { isa = PBXGroup; children = ( - F7E954E41EA8FE0700A804DE /* WavesWallet-iOS.app */, - 7BF89E9622272A5E00853F9D /* MonkeyTest.xctest */, + E9B086EC2163886800937644 /* DexOrderBookInteractorProtocol.swift */, + E9B086ED2163886800937644 /* DexOrderBookInteractor.swift */, ); - name = Products; + path = Interactor; sourceTree = ""; }; - F7E954E61EA8FE0700A804DE /* WavesWallet-iOS */ = { + E9B086F42163886800937644 /* DexInfo */ = { isa = PBXGroup; children = ( - 0ADD7F1E21F22FB60075FC59 /* Extensions */, - 0A4E71942216C6CD00A46613 /* WavesWallet-iOS.entitlements */, - F7E954F51EA8FE0700A804DE /* Info.plist */, - 0AFBCA7F211306F600285BCB /* LaunchScreen.storyboard */, - F7E954E71EA8FE0700A804DE /* AppDelegate.swift */, - F74240AF1EAB8D1600C3B84D /* DataLayer */, - 0A5C919520F3D7D700443CE6 /* DomainLayer */, - 0A93FED120FCAAA30058179E /* PresentationLayer */, - 0A97974F2108805100407F67 /* Generated */, - 0A979752210885B500407F67 /* Resources */, + E9B086F72163886800937644 /* DexInfoModuleBuilder.swift */, + E9B086F82163886800937644 /* DexInfoViewController.swift */, + E9B086FB2163886800937644 /* DexInfoTypes.swift */, + E9B086FC2163886800937644 /* Views */, ); - path = "WavesWallet-iOS"; + path = DexInfo; sourceTree = ""; }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 7BF89E9522272A5E00853F9D /* MonkeyTest */ = { - isa = PBXNativeTarget; - buildConfigurationList = 7BF89E9D22272A5E00853F9D /* Build configuration list for PBXNativeTarget "MonkeyTest" */; - buildPhases = ( - 14543D7E4AECF68BEF3D3CC1 /* [CP] Check Pods Manifest.lock */, - 7BF89E9222272A5E00853F9D /* Sources */, - 7BF89E9322272A5E00853F9D /* Frameworks */, - 7BF89E9422272A5E00853F9D /* Resources */, - 499D8AE9AFF252388D25B2C8 /* [CP] Embed Pods Frameworks */, + E9B086FC2163886800937644 /* Views */ = { + isa = PBXGroup; + children = ( + E9B086FD2163886800937644 /* SearchBarView.swift */, + E9B086FE2163886800937644 /* SearchBarView.xib */, ); - buildRules = ( + path = Views; + sourceTree = ""; + }; + E9B086FF2163886800937644 /* DexTraderContainer */ = { + isa = PBXGroup; + children = ( + E9B087022163886800937644 /* DexTraderContainerTypes.swift */, + E9B087032163886800937644 /* DexTraderContainerViewController.swift */, + E9B087062163886800937644 /* Modules */, + E9B0870A2163886800937644 /* Views */, ); - dependencies = ( - 7BF89E9C22272A5E00853F9D /* PBXTargetDependency */, + path = DexTraderContainer; + sourceTree = ""; + }; + E9B087062163886800937644 /* Modules */ = { + isa = PBXGroup; + children = ( + E9B087072163886800937644 /* DexTraderContainerModuleOutput.swift */, + E9B087082163886800937644 /* DexTraderContainerModuleBuilder.swift */, + E9B087092163886800937644 /* DexTraderContainerInputProtocol.swift */, ); - name = MonkeyTest; - productName = MonkeyTest; - productReference = 7BF89E9622272A5E00853F9D /* MonkeyTest.xctest */; - productType = "com.apple.product-type.bundle.ui-testing"; + path = Modules; + sourceTree = ""; }; - F7E954E31EA8FE0700A804DE /* WavesWallet-iOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = F7E954F81EA8FE0700A804DE /* Build configuration list for PBXNativeTarget "WavesWallet-iOS" */; - buildPhases = ( - D0B2E799FD762C3AFCE7C323 /* [CP] Check Pods Manifest.lock */, - A60EA21BC9B82445DBBC7E14 /* [CP] Embed Pods Frameworks */, - 64578F1B5667F7D76B8CA9B1 /* [CP] Copy Pods Resources */, - 0A97974E21087D0400407F67 /* Gen Code */, - F7E954E01EA8FE0700A804DE /* Sources */, - F7E954E11EA8FE0700A804DE /* Frameworks */, - F7E954E21EA8FE0700A804DE /* Resources */, - 0A218B93215549BB00B989A1 /* Fabric run */, + E9B0870A2163886800937644 /* Views */ = { + isa = PBXGroup; + children = ( + E9B0870B2163886800937644 /* DexTraderContainerSegmentedControl.xib */, + E9B0870C2163886800937644 /* DexTraderContainerBaseHeaderView.swift */, + E9B0870D2163886800937644 /* DexTraderContainerButton.swift */, + E9B0870E2163886800937644 /* DexTraderContainerSegmentedControl.swift */, ); - buildRules = ( + path = Views; + sourceTree = ""; + }; + E9B0870F2163886800937644 /* DexList */ = { + isa = PBXGroup; + children = ( + E9B087102163886800937644 /* DexListModuleOutput.swift */, + E9B087132163886800937644 /* Presenter */, + E9B087162163886800937644 /* DexListTypes.swift */, + E9B087192163886800937644 /* Views */, + E9B0871D2163886800937644 /* DexListViewController.swift */, + E9B0871E2163886800937644 /* DexListModuleBuilder.swift */, + E9B0871F2163886800937644 /* Interactor */, ); - dependencies = ( + path = DexList; + sourceTree = ""; + }; + E9B087132163886800937644 /* Presenter */ = { + isa = PBXGroup; + children = ( + E9B087142163886800937644 /* DexListPresenterProtocol.swift */, + E9B087152163886800937644 /* DexListPresenter.swift */, ); - name = "WavesWallet-iOS"; - productName = "WavesWallet-iOS"; - productReference = F7E954E41EA8FE0700A804DE /* WavesWallet-iOS.app */; - productType = "com.apple.product-type.application"; + path = Presenter; + sourceTree = ""; }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - F7E954DC1EA8FE0600A804DE /* Project object */ = { - isa = PBXProject; - attributes = { - LastSwiftUpdateCheck = 1010; - LastUpgradeCheck = 1010; - ORGANIZATIONNAME = "Waves Platform"; - TargetAttributes = { - 7BF89E9522272A5E00853F9D = { - CreatedOnToolsVersion = 10.1; - LastSwiftMigration = 1020; - ProvisioningStyle = Automatic; - TestTargetID = F7E954E31EA8FE0700A804DE; - }; - F7E954E31EA8FE0700A804DE = { - CreatedOnToolsVersion = 8.3.2; - DevelopmentTeam = 96SW78M3KJ; - LastSwiftMigration = 1020; - ProvisioningStyle = Manual; - SystemCapabilities = { - com.apple.Push = { - enabled = 0; - }; - com.apple.SafariKeychain = { - enabled = 0; - }; - }; - }; - }; - }; - buildConfigurationList = F7E954DF1EA8FE0600A804DE /* Build configuration list for PBXProject "WavesWallet-iOS" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - English, - en, - ru, - ko, - es, - id, - de, - ja, - tr, - "pt-BR", - "pt-PT", - pl, - it, - "nl-NL", - "hi-IN", - "zh-Hans-CN", - "fr-FR", - ); - mainGroup = F7E954DB1EA8FE0600A804DE; - productRefGroup = F7E954E51EA8FE0700A804DE /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - F7E954E31EA8FE0700A804DE /* WavesWallet-iOS */, - 7BF89E9522272A5E00853F9D /* MonkeyTest */, + E9B087192163886800937644 /* Views */ = { + isa = PBXGroup; + children = ( + E9B0871A2163886800937644 /* DexListHeaderCell.swift */, + E9B0871B2163886800937644 /* DexListCell.swift */, + E9B0871C2163886800937644 /* DexListSkeletonCell.swift */, ); + path = Views; + sourceTree = ""; }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 7BF89E9422272A5E00853F9D /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( + E9B0871F2163886800937644 /* Interactor */ = { + isa = PBXGroup; + children = ( + E9B087212163886800937644 /* DexListInteractorProtocol.swift */, + E9B087222163886800937644 /* DexListInteractor.swift */, ); - runOnlyForDeploymentPostprocessing = 0; + path = Interactor; + sourceTree = ""; }; - F7E954E21EA8FE0700A804DE /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 0A150824219B0D6B00516037 /* GoogleService-Info.plist in Resources */, - E9236F1F2216F37300A12FD5 /* AppNewsView.xib in Resources */, - E9EC5BAA2175F35900E5C29A /* Send.storyboard in Resources */, - 0AF0C67D21AACB3700602197 /* GlobalErrorView.xib in Resources */, - 0AB63C1E216F952E0056B17E /* HistoryTransactionView.xib in Resources */, - E9642C9121CB326A0065A1BD /* CoinomatServiceErrorView.xib in Resources */, - E9B087A12163886800937644 /* DexChartHeaderView.xib in Resources */, - 0AAC28132215C4C700D8A404 /* SendFeeHeaderView.xib in Resources */, - E9B12DBA219E2D3900128EFE /* AssetBurnCell.xib in Resources */, - 0AF9222A212E0F1F003BA067 /* WalletLeasingCell.xib in Resources */, - 0A762DA02163AD0F0019D447 /* Support.storyboard in Resources */, - 0AF92231212E0F1F003BA067 /* WalletHeaderView.xib in Resources */, - E9AFDBE621F32E96003130A8 /* TransactionFeeView.xib in Resources */, - 0A762D15214FE3F300BE9204 /* InputTextField.xib in Resources */, - 04D4431C21885F50009CEB22 /* Fabric-Info.plist in Resources */, - 0A7CCDB7218A17A9005D372B /* MyAddress.storyboard in Resources */, - E96FEA26226E962300C0EE22 /* WalletSortEmptyAssetsCell.xib in Resources */, - E9B087BF2163886800937644 /* SearchBarView.xib in Resources */, - 0AA8CAD421527672000D09E6 /* PasscodeView.xib in Resources */, - E95B47CE21638A9F004D4E39 /* ShortInfoPageView.xib in Resources */, - 0AF922F7212E1234003BA067 /* SegmentedControl.xib in Resources */, - 04A2CFA5211213BE00784FEC /* History.storyboard in Resources */, - E95E14F5229FF63B003552B8 /* WalletQuickNoteCell.xib in Resources */, - 0AFBCA852113173300285BCB /* InfoPlist.strings in Resources */, - 7B5E74672239088800746ADD /* TransactionCardHeaderView.xib in Resources */, - 0AF922E9212E1234003BA067 /* EmptyCell.xib in Resources */, - 0AF922EF212E1234003BA067 /* AssetsSegmentedCell.xib in Resources */, - 0A3FE8A82135AE3600DBF4E1 /* AssetTransactionCell.xib in Resources */, - E96DAB71228EE643005ED12B /* WalletSortSegmentedControl.xib in Resources */, - 0AF921FB212E07B3003BA067 /* AssetChartHeaderView.xib in Resources */, - 048684F721258BC400D12189 /* HistoryHeaderView.xib in Resources */, - 0AF921F7212E07B3003BA067 /* AssetBalanceMoneyInfoView.xib in Resources */, - 0A071E41215AEF61007D9750 /* AccountPassword.storyboard in Resources */, - E9F69B9D22A5333500CDBD00 /* WalletSearchHeaderCell.xib in Resources */, - 0A96F1CC2151B392005E148F /* Passcode.storyboard in Resources */, - E9B12DB6219DD6E000128EFE /* AssetBalanceSpamCell.xib in Resources */, - 0ADD6C822167948500B06917 /* ProfileHeaderView.xib in Resources */, - 0A110CB82153CE31002A8FD7 /* Import.storyboard in Resources */, - 04EFAF4D2164F8D800277CCF /* EnterStartBlockCell.xib in Resources */, - 0AF92206212E07B3003BA067 /* AssetHeaderView.xib in Resources */, - E9D36DFA2175C755001E6DF0 /* AssetList.storyboard in Resources */, - 0AFBCA80211306F600285BCB /* LaunchScreen.storyboard in Resources */, - 0AFB594A2209F167001F0DD8 /* Sentry-io-Info.plist in Resources */, - E917B3AF21BD688500CC849A /* AmountSkeletonView.xib in Resources */, - E9B087F12163886800937644 /* DexLastTradesHeaderView.xib in Resources */, - E9B086B02163883000937644 /* AddAddressTextField.xib in Resources */, - E9310D1B21792D14008BF3EE /* SendConfirmationRecipientView.xib in Resources */, - 7BDA6AEA22313E85001DE71C /* TransactionImageView.xib in Resources */, - E92FAD0F226F6C050054D4AA /* WalletSortSeparatorCell.xib in Resources */, - 0AF92229212E0F1F003BA067 /* WalletHistoryCell.xib in Resources */, - E95E14F7229FF7A6003552B8 /* WalletAssetSkeletonCell.xib in Resources */, - 0A2060642181C2C20048CF83 /* environment_mainnet.json in Resources */, - 0A2060652181C2C20048CF83 /* environment_testnet.json in Resources */, - 0A4399662150465E0032E608 /* NewAccount.storyboard in Resources */, - 0AA8CAC921516077000D09E6 /* Backup.storyboard in Resources */, - 04831F89216A3EBF006D1ED6 /* LanguageTableCell.xib in Resources */, - 0A071E64215C65D2007D9750 /* UseTouchID.storyboard in Resources */, - 7BDA6AF422315466001DE71C /* ContactDetailView.xib in Resources */, - E9B087E72163886800937644 /* DexCreateOrderSegmentedControl.xib in Resources */, - E9B0879E2163886800937644 /* DexChartCandlePriceView.xib in Resources */, - E95B47EF21638B11004D4E39 /* StartLeasing.storyboard in Resources */, - E9EC5C102175F35900E5C29A /* AddressInputView.xib in Resources */, - E9B087C62163886800937644 /* DexTraderContainerSegmentedControl.xib in Resources */, - E95E14F3229FF31A003552B8 /* WalletLeasingBalanceCell.xib in Resources */, - 0AF92204212E07B3003BA067 /* AssetHeaderSkeletonView.xib in Resources */, - E98F1D2F22A5E2F200B4A8C4 /* WalletUpdateAppView.xib in Resources */, - 0A4140EB2174F09C00B1310E /* ChangePassword.storyboard in Resources */, - 0A2B7D34216037FD0098438D /* AssetViewHistoryCell.xib in Resources */, - 044D6C8B21978C9C003861A2 /* EditAccountName.storyboard in Resources */, - E983666121F5973900178A8A /* TransactionScriptErrorView.xib in Resources */, - E95B6B15219C347200A85B5D /* TokenBurnConfirmationIDView.xib in Resources */, - E9DEECEB20BEF97E00F28C67 /* Waves.storyboard in Resources */, - F74240C91EAB8EC800C3B84D /* Main.storyboard in Resources */, - E95B47F521638B11004D4E39 /* AmountInputView.xib in Resources */, - 7B5EDEC42253618C009C2B3B /* AccessibilityIdentifiers.strings in Resources */, - 0A61B59A214ACFD500EC60FC /* Languages.json in Resources */, - E911300E21BC029300588430 /* AssetSelectSkeletonView.xib in Resources */, - 7BDA6ADF222E9664001DE71C /* TransactionCard.storyboard in Resources */, - E9B087B92163886800937644 /* Dex.storyboard in Resources */, - E9193B8320D7E28400F5D983 /* Profile.storyboard in Resources */, - 04E1C358212615CA00C702BA /* HeaderSkeletonView.xib in Resources */, - 0A762D13214FE23E00BE9204 /* NewAccountAvatarView.xib in Resources */, - E9B087B02163886800937644 /* DexOrderBookHeaderView.xib in Resources */, - E9B087E32163886800937644 /* DexCreateOrderInputView.xib in Resources */, - E9D36DE92175C755001E6DF0 /* AssetSelectView.xib in Resources */, - 7BDA6AE2223025AD001DE71C /* BalanceLabel.xib in Resources */, - E944AA6F22444B780009F494 /* Amplitude-Info.plist in Resources */, - 0A02D20721AEA1B1005DF820 /* Appsflyer-Info.plist in Resources */, - E96358A622A73D70008A3395 /* WalletClearAssetsView.xib in Resources */, - 0AF92303212E1424003BA067 /* Waves.strings in Resources */, - 0AF922E2212E1234003BA067 /* TickerView.xib in Resources */, - 0AF92200212E07B3003BA067 /* AssetHistorySkeletonCell.xib in Resources */, - E95B47C021638A9F004D4E39 /* Hello.storyboard in Resources */, - 0AF921EB212E07B3003BA067 /* Asset.storyboard in Resources */, - E9D36DDD2175C755001E6DF0 /* Receive.storyboard in Resources */, - 0AF921FF212E07B3003BA067 /* AssetBalanceSkeletonCell.xib in Resources */, - E95E14F1229FF152003552B8 /* WalletTableAssetsCell.xib in Resources */, - E95E14FB229FFA65003552B8 /* WalletHistorySkeletonCell.xib in Resources */, - E95E151322A18C25003552B8 /* WalletSearchTableViewCell.xib in Resources */, - 7B3902A92237A75600AAFDB8 /* ActionsControl.xib in Resources */, - E95E14F9229FF933003552B8 /* WalletLeasingBalanceSkeletonCell.xib in Resources */, - E96FEA2A226F27BC00C0EE22 /* WalletSortCell.xib in Resources */, - 0A26549121BAE153005EA637 /* Assets.xcassets in Resources */, - 0AB63C2C2170EBF00056B17E /* Language.storyboard in Resources */, - 0A5D32F72154579C0009CDF3 /* MultyTextField.xib in Resources */, - 0A9797602108A11A00407F67 /* Wallet.storyboard in Resources */, - E9CD0D2E21809A5D001A99B3 /* SendMoneroPaymentIdView.xib in Resources */, - 0AACD59D21A59E7100B30815 /* SweetSnackView.xib in Resources */, - E9939B4722302E6100B50E67 /* InfoPageConfirmView.xib in Resources */, - E9B086BE2163883000937644 /* AddressBook.storyboard in Resources */, - 0AF92202212E07B3003BA067 /* AssetTransactionSkeletonCell.xib in Resources */, - 0A071E7A215DB0A9007D9750 /* ChooseAccount.storyboard in Resources */, - 0AF922EC212E1234003BA067 /* AssetsSegmentedControl.xib in Resources */, - E9F984A920E526DA00D2CB4D /* Enter.storyboard in Resources */, - 0AADFD0621F9F4AC001F5C0A /* AppSpector-Info.plist in Resources */, - E95B47C721638A9F004D4E39 /* LongInfoPageView.xib in Resources */, + E9B087282163886800937644 /* DexCreateOrder */ = { + isa = PBXGroup; + children = ( + E9B087332163886800937644 /* DexCreateOrderModuleBuilder.swift */, + E9B087292163886800937644 /* DexCreateOrderModuleOutput.swift */, + E9B087302163886800937644 /* DexCreateOrderTypes.swift */, + E9B0872C2163886800937644 /* DexCreateOrderViewController.swift */, + E9B0873A2163886800937644 /* Interactor */, + E9B0872D2163886800937644 /* Presenter */, + E9B087342163886800937644 /* Views */, + 7B7A4B7B22D6258C00E0A8CD /* DexCreateOrderInvalidPriceView.swift */, + 7B7A4B7D22D625B300E0A8CD /* DexCreateOrderInvalidPriceView.xib */, ); - runOnlyForDeploymentPostprocessing = 0; + path = DexCreateOrder; + sourceTree = ""; }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 0A218B93215549BB00B989A1 /* Fabric run */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Fabric run"; - outputPaths = ( + E9B0872D2163886800937644 /* Presenter */ = { + isa = PBXGroup; + children = ( + E9B0872E2163886800937644 /* DexCreateOrderPresenterProtocol.swift */, + E9B0872F2163886800937644 /* DexCreateOrderPresenter.swift */, ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "APIKey=$(/usr/libexec/PlistBuddy -c \"Print :Fabric:APIKey\" \"$PROJECT_DIR/WavesWallet-iOS/Resources/Fabric-Info.plist\")\nKEY=$(/usr/libexec/PlistBuddy -c \"Print :Fabric:BuildSecret\" \"$PROJECT_DIR/WavesWallet-iOS/Resources/Fabric-Info.plist\")\n\n\"${PODS_ROOT}/Fabric/run\" $APIKey $KEY\n\n"; + path = Presenter; + sourceTree = ""; }; - 0A97974E21087D0400407F67 /* Gen Code */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Gen Code"; - outputPaths = ( + E9B087342163886800937644 /* Views */ = { + isa = PBXGroup; + children = ( + E9B087352163886800937644 /* DexCreateOrderInputView.xib */, + E9B087362163886800937644 /* DexCreateOrderSegmentedControl.swift */, + E9B087372163886800937644 /* DexCreateOrderInputView.swift */, + E9B087382163886800937644 /* DexCreateOrderAmountButton.swift */, + E9B087392163886800937644 /* DexCreateOrderSegmentedControl.xib */, ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = "/bin/bash -l"; - shellScript = "\necho \"SwiftGen Begin\"\nHAS_NEED_GENERATE_CODE=\"$(ruby $PROJECT_DIR/fastlane/swiftgenhash.ruby)\"\n\nif [ \"$HAS_NEED_GENERATE_CODE\" == false ] ; then\n echo \"SwiftGen Cancel\"\n exit\nfi \n\nrm -rf $PROJECT_DIR/WavesWallet-iOS/Generated/\nmkdir $PROJECT_DIR/WavesWallet-iOS/Generated\n\n$PODS_ROOT/SwiftGen/bin/swiftgen storyboards -t swift4 -o $PROJECT_DIR/WavesWallet-iOS/Generated/Storyboards.swift $PROJECT_DIR/WavesWallet-iOS/\n\nSTRINGS=\"\"\nfor i in $(find ./WavesWallet-iOS/ -name \"*.strings\"); do\nif [[ $i = *\"en.lproj\"* ]]; then\nSTRINGS=\"$STRINGS $i\"\necho \"$STRINGS\"\nfi\ndone\n\n$PODS_ROOT/SwiftGen/bin/swiftgen strings --param enumName=Localizable --templatePath $PROJECT_DIR/Templates/structured-swift4.stencil -o $PROJECT_DIR/WavesWallet-iOS/Generated/Localizable.swift $STRINGS\n\n$PODS_ROOT/SwiftGen/bin/swiftgen xcassets -t swift4 -o $PROJECT_DIR/WavesWallet-iOS/Generated/Images.swift --param enumName=Images $PROJECT_DIR/WavesWallet-iOS/Resources/Assets.xcassets\n\n$PODS_ROOT/SwiftGen/bin/swiftgen strings --param enumName=AccessibilityIdentifiers --templatePath $PROJECT_DIR/Templates/structured-swift4.stencil -o $PROJECT_DIR/WavesWallet-iOS/Generated/AccessibilityIdentifiers.swift $PROJECT_DIR/WavesWallet-iOS/Resources/AccessibilityIdentifiers.strings\n\necho \"SwiftGen End\"\n\n"; + path = Views; + sourceTree = ""; }; - 14543D7E4AECF68BEF3D3CC1 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( + E9B0873A2163886800937644 /* Interactor */ = { + isa = PBXGroup; + children = ( + E9B0873B2163886800937644 /* DexCreateOrderInteractorProtocol.swift */, + E965702221935F2F0052F0FC /* DexCreateOrderInteractor.swift */, ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", + path = Interactor; + sourceTree = ""; + }; + E9B0873D2163886800937644 /* DexLastTrades */ = { + isa = PBXGroup; + children = ( + E9B087402163886800937644 /* DexLastTradesModuleOutput.swift */, + E9B087412163886800937644 /* DexLastTradesModuleBuilder.swift */, + E9B087422163886800937644 /* Presenter */, + E9B087452163886800937644 /* DexLastTradesTypes.swift */, + E9B087472163886800937644 /* DexLastTradesViewController.swift */, + E9B087492163886800937644 /* Views */, + E9B0874D2163886800937644 /* Interactor */, ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( + path = DexLastTrades; + sourceTree = ""; + }; + E9B087422163886800937644 /* Presenter */ = { + isa = PBXGroup; + children = ( + E9B087432163886800937644 /* DexLastTradesPresenterProtocol.swift */, + E9B087442163886800937644 /* DexLastTradesPresenter.swift */, ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-MonkeyTest-checkManifestLockResult.txt", + path = Presenter; + sourceTree = ""; + }; + E9B087492163886800937644 /* Views */ = { + isa = PBXGroup; + children = ( + E9B0874A2163886800937644 /* DexLastTradesHeaderView.xib */, + E9B0874B2163886800937644 /* DexLastTradesCell.swift */, + E9B0874C2163886800937644 /* DexLastTradesHeaderView.swift */, ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; + path = Views; + sourceTree = ""; }; - 499D8AE9AFF252388D25B2C8 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( + E9B0874D2163886800937644 /* Interactor */ = { + isa = PBXGroup; + children = ( + E9B0874F2163886800937644 /* DexLastTradesInteractor.swift */, + E9B087502163886800937644 /* DexLastTradesInteractorProtocol.swift */, ); - inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-MonkeyTest/Pods-MonkeyTest-frameworks.sh", - "${BUILT_PRODUCTS_DIR}/SwiftMonkey/SwiftMonkey.framework", + path = Interactor; + sourceTree = ""; + }; + E9B087512163886800937644 /* DexMyOrders */ = { + isa = PBXGroup; + children = ( + E9B087522163886800937644 /* DexMyOrdersViewController.swift */, + E9B087552163886800937644 /* Presenter */, + E9B087582163886800937644 /* DexMyOrdersModuleBuilder.swift */, + E96570422193E8570052F0FC /* DexMyOrdersModuleOutput.swift */, + E9B0875B2163886800937644 /* Views */, + E9B0875F2163886800937644 /* Interactor */, + E9B087632163886800937644 /* DexMyOrdersTypes.swift */, ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftMonkey.framework", + path = DexMyOrders; + sourceTree = ""; + }; + E9B087552163886800937644 /* Presenter */ = { + isa = PBXGroup; + children = ( + E9B087562163886800937644 /* DexMyOrdersPresenterProtocol.swift */, + E9B087572163886800937644 /* DexMyOrdersPresenter.swift */, ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-MonkeyTest/Pods-MonkeyTest-frameworks.sh\"\n"; - showEnvVarsInLog = 0; + path = Presenter; + sourceTree = ""; }; - 64578F1B5667F7D76B8CA9B1 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( + E9B0875B2163886800937644 /* Views */ = { + isa = PBXGroup; + children = ( + E9B0875E2163886800937644 /* DexMyOrdersCell.swift */, ); - inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-WavesWallet-iOS/Pods-WavesWallet-iOS-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInAppMessagingDisplay/InAppMessagingDisplayResources.bundle", + path = Views; + sourceTree = ""; + }; + E9B0875F2163886800937644 /* Interactor */ = { + isa = PBXGroup; + children = ( + E9B087602163886800937644 /* DexMyOrdersInteractor.swift */, + E9B087612163886800937644 /* DexMyOrdersInteractorProtocol.swift */, ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/InAppMessagingDisplayResources.bundle", + path = Interactor; + sourceTree = ""; + }; + E9B087662163886800937644 /* DexCompleteOrder */ = { + isa = PBXGroup; + children = ( + E9B087692163886800937644 /* DexCompleteOrderViewController.swift */, + E9B0876C2163886800937644 /* DexCompleteOrderModuleBuilder.swift */, ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-WavesWallet-iOS/Pods-WavesWallet-iOS-resources.sh\"\n"; - showEnvVarsInLog = 0; + path = DexCompleteOrder; + sourceTree = ""; }; - A60EA21BC9B82445DBBC7E14 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( + E9B0876E2163886800937644 /* DexMarket */ = { + isa = PBXGroup; + children = ( + E9B087742163886800937644 /* Presenter */, + E9B087772163886800937644 /* DexMarketViewController.swift */, + E9B087782163886800937644 /* DexMarketModuleOutput.swift */, + E9B087792163886800937644 /* DexMarketModuleBuilder.swift */, + E9B0877B2163886800937644 /* DexMarketTypes.swift */, + E9B0877D2163886800937644 /* Views */, + E9B0877F2163886800937644 /* Interactor */, ); - inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-WavesWallet-iOS/Pods-WavesWallet-iOS-frameworks.sh", - "${BUILT_PRODUCTS_DIR}/Alamofire/Alamofire.framework", - "${BUILT_PRODUCTS_DIR}/Amplitude-iOS/Amplitude_iOS.framework", - "${PODS_ROOT}/AppSpectorSDK/AppSpectorSDK.framework", - "${BUILT_PRODUCTS_DIR}/Base58/Base58.framework", - "${BUILT_PRODUCTS_DIR}/Blake2/Blake2.framework", - "${BUILT_PRODUCTS_DIR}/CSV.swift/CSV.framework", - "${BUILT_PRODUCTS_DIR}/Charts/Charts.framework", - "${BUILT_PRODUCTS_DIR}/CryptoSwift/CryptoSwift.framework", - "${BUILT_PRODUCTS_DIR}/Curve25519/Curve25519.framework", - "${BUILT_PRODUCTS_DIR}/DeviceKit/DeviceKit.framework", - "${BUILT_PRODUCTS_DIR}/GTMSessionFetcher/GTMSessionFetcher.framework", - "${BUILT_PRODUCTS_DIR}/GoogleUtilities/GoogleUtilities.framework", - "${BUILT_PRODUCTS_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework", - "${BUILT_PRODUCTS_DIR}/IdentityImg/IdentityImg.framework", - "${BUILT_PRODUCTS_DIR}/InfiniteCollectionView/InfiniteCollectionView.framework", - "${BUILT_PRODUCTS_DIR}/Keccak/Keccak.framework", - "${BUILT_PRODUCTS_DIR}/KeychainAccess/KeychainAccess.framework", - "${BUILT_PRODUCTS_DIR}/Kingfisher/Kingfisher.framework", - "${BUILT_PRODUCTS_DIR}/Koloda/Koloda.framework", - "${BUILT_PRODUCTS_DIR}/MGSwipeTableCell/MGSwipeTableCell.framework", - "${BUILT_PRODUCTS_DIR}/Moya/Moya.framework", - "${BUILT_PRODUCTS_DIR}/QRCode/QRCode.framework", - "${BUILT_PRODUCTS_DIR}/QRCodeReader.swift/QRCodeReader.framework", - "${BUILT_PRODUCTS_DIR}/RESideMenu/RESideMenu.framework", - "${BUILT_PRODUCTS_DIR}/ReachabilitySwift/Reachability.framework", - "${BUILT_PRODUCTS_DIR}/Realm/Realm.framework", - "${BUILT_PRODUCTS_DIR}/RealmSwift/RealmSwift.framework", - "${BUILT_PRODUCTS_DIR}/Result/Result.framework", - "${BUILT_PRODUCTS_DIR}/RxAlamofire/RxAlamofire.framework", - "${BUILT_PRODUCTS_DIR}/RxAtomic/RxAtomic.framework", - "${BUILT_PRODUCTS_DIR}/RxCocoa/RxCocoa.framework", - "${BUILT_PRODUCTS_DIR}/RxFeedback/RxFeedback.framework", - "${BUILT_PRODUCTS_DIR}/RxGesture/RxGesture.framework", - "${BUILT_PRODUCTS_DIR}/RxOptional/RxOptional.framework", - "${BUILT_PRODUCTS_DIR}/RxReachability/RxReachability.framework", - "${BUILT_PRODUCTS_DIR}/RxRealm/RxRealm.framework", - "${BUILT_PRODUCTS_DIR}/RxSwift/RxSwift.framework", - "${BUILT_PRODUCTS_DIR}/RxSwiftExt/RxSwiftExt.framework", - "${BUILT_PRODUCTS_DIR}/Sentry/Sentry.framework", - "${BUILT_PRODUCTS_DIR}/Skeleton/Skeleton.framework", - "${BUILT_PRODUCTS_DIR}/SwiftDate/SwiftDate.framework", - "${BUILT_PRODUCTS_DIR}/SwiftMonkeyPaws/SwiftMonkeyPaws.framework", - "${BUILT_PRODUCTS_DIR}/SwipeView/SwipeView.framework", - "${BUILT_PRODUCTS_DIR}/TPKeyboardAvoiding/TPKeyboardAvoiding.framework", - "${BUILT_PRODUCTS_DIR}/TTTAttributedLabel/TTTAttributedLabel.framework", - "${BUILT_PRODUCTS_DIR}/UITextView+Placeholder/UITextView_Placeholder.framework", - "${BUILT_PRODUCTS_DIR}/UPCarouselFlowLayout/UPCarouselFlowLayout.framework", - "${BUILT_PRODUCTS_DIR}/WavesSDKCrypto/WavesSDKCrypto.framework", - "${BUILT_PRODUCTS_DIR}/WavesSDKExtension/WavesSDKExtension.framework", - "${BUILT_PRODUCTS_DIR}/leveldb-library/leveldb.framework", - "${BUILT_PRODUCTS_DIR}/nanopb/nanopb.framework", - "${BUILT_PRODUCTS_DIR}/pop/pop.framework", + path = DexMarket; + sourceTree = ""; + }; + E9B087742163886800937644 /* Presenter */ = { + isa = PBXGroup; + children = ( + E9B087752163886800937644 /* DexMarketPresenter.swift */, + E9B087762163886800937644 /* DexMarketPresenterProtocol.swift */, ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Alamofire.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Amplitude_iOS.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AppSpectorSDK.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Base58.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Blake2.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CSV.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Charts.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CryptoSwift.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Curve25519.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DeviceKit.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GTMSessionFetcher.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleUtilities.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IQKeyboardManagerSwift.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IdentityImg.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/InfiniteCollectionView.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Keccak.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/KeychainAccess.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Kingfisher.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Koloda.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MGSwipeTableCell.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Moya.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/QRCode.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/QRCodeReader.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RESideMenu.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Reachability.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Realm.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RealmSwift.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Result.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RxAlamofire.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RxAtomic.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RxCocoa.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RxFeedback.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RxGesture.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RxOptional.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RxReachability.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RxRealm.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RxSwift.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RxSwiftExt.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Sentry.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Skeleton.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftDate.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftMonkeyPaws.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwipeView.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TPKeyboardAvoiding.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TTTAttributedLabel.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/UITextView_Placeholder.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/UPCarouselFlowLayout.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/WavesSDKCrypto.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/WavesSDKExtension.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/leveldb.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/nanopb.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/pop.framework", + path = Presenter; + sourceTree = ""; + }; + E9B0877D2163886800937644 /* Views */ = { + isa = PBXGroup; + children = ( + E9B0877E2163886800937644 /* DexMarketCell.swift */, ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-WavesWallet-iOS/Pods-WavesWallet-iOS-frameworks.sh\"\n"; - showEnvVarsInLog = 0; + path = Views; + sourceTree = ""; }; - D0B2E799FD762C3AFCE7C323 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( + E9B0877F2163886800937644 /* Interactor */ = { + isa = PBXGroup; + children = ( + E9B087802163886800937644 /* DexMarketInteractor.swift */, + E9B087812163886800937644 /* DexMarketInteractorProtocol.swift */, ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", + path = Interactor; + sourceTree = ""; + }; + E9B087842163886800937644 /* DexSort */ = { + isa = PBXGroup; + children = ( + E9B087852163886800937644 /* DexSortViewController.swift */, + E9B087882163886800937644 /* Presenter */, + E9B0878B2163886800937644 /* DexSortModuleBuilder.swift */, + E9B0878D2163886800937644 /* DexSortTypes.swift */, + E9B0878F2163886800937644 /* Views */, + E9B087912163886800937644 /* Interactor */, ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-WavesWallet-iOS-checkManifestLockResult.txt", + path = DexSort; + sourceTree = ""; + }; + E9B087882163886800937644 /* Presenter */ = { + isa = PBXGroup; + children = ( + E9B087892163886800937644 /* DexSortPresenter.swift */, + E9B0878A2163886800937644 /* DexSortPresenterProtocol.swift */, ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; + path = Presenter; + sourceTree = ""; }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 7BF89E9222272A5E00853F9D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 7BF89E9922272A5E00853F9D /* MonkeyTest.swift in Sources */, + E9B0878F2163886800937644 /* Views */ = { + isa = PBXGroup; + children = ( + E9B087902163886800937644 /* DexSortCell.swift */, ); - runOnlyForDeploymentPostprocessing = 0; + path = Views; + sourceTree = ""; }; - F7E954E01EA8FE0700A804DE /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - E9E62D1F22678B7000D7DC95 /* SweetLoggerSentry.swift in Sources */, - 0A5C53DF2139498800667E34 /* UnrecognisedTransactionDomainDTO.swift in Sources */, - 0A5E4BC9213820C500E3C3C3 /* LeaseCancelTransactionDomainDTO.swift in Sources */, - 0A5E4BD1213820C500E3C3C3 /* LeaseTransactionDomainDTO.swift in Sources */, - E9D0ED88225CBDEA0098C234 /* InvokeScriptTransactionDomainDTO.swift in Sources */, - 0A5E4BCE213820C500E3C3C3 /* ExchangeTransactionDomainDTO.swift in Sources */, - 7BAA9F7F22A03361003B6D01 /* ApplicationVersionRepositoryProtocol.swift in Sources */, - 0A5E4BCC213820C500E3C3C3 /* IssueTransactionDomainDTO.swift in Sources */, - 0A5E4BD2213820C500E3C3C3 /* AnyTransactionDomainDTO.swift in Sources */, - 04831F7B216917EF006D1ED6 /* SmartTransactionDomainDTO.swift in Sources */, - 0ADD804A21F73C360075FC59 /* ScriptTransactionDomainDTO.swift in Sources */, - 0ADD804821F73C280075FC59 /* AssetScriptTransactionDomainDTO.swift in Sources */, - 0A5E4BD3213820C500E3C3C3 /* AliasTransactionDomainDTO.swift in Sources */, - E9F78A3F229E990D0065324B /* ScrolledContainerView.swift in Sources */, - 0A5E4BCA213820C500E3C3C3 /* MassTransferTransactionDomainDTO.swift in Sources */, - 0A5E4BC8213820C500E3C3C3 /* DataTransactionDomainDTO.swift in Sources */, - 0A5E4BCD213820C500E3C3C3 /* TransferTransactionDomainDTO.swift in Sources */, - 0A5E4BD0213820C500E3C3C3 /* BurnTransactionDomainDTO.swift in Sources */, - 0AFB59482209C2F8001F0DD8 /* SponsorshipTransactionDomainDTO.swift in Sources */, - 0A5E4BCF213820C500E3C3C3 /* ReissueTransactionDomainDTO.swift in Sources */, - 0A218B8521551D1400B989A1 /* WalletsRepositoryLocal.swift in Sources */, - 0A88CC0A217E80040083874C /* WalletRealmFactory.swift in Sources */, - 0AD83601217A0D25004413E9 /* GitHubService.swift in Sources */, - 04831F7A216917B0006D1ED6 /* ApiServiceTypes.swift in Sources */, - 0AAB15C12165534500F1F7BC /* DomainLayerTypes.swift in Sources */, - E9DF24FA2221EF4D0077F2EB /* AssetDetailTypes.swift in Sources */, - 0A14CFD221441FDB00C3A4D5 /* TransactionDomainDTO+Mapper.swift in Sources */, - 0A751D38221715F80024D523 /* AppNewsCoordinator.swift in Sources */, - E991BB17220197280022E27D /* AliasApi.swift in Sources */, - E991BB1C2202CB3C0022E27D /* SendFeeModuleBuilder.swift in Sources */, - 0A5E4BCE213820C500E3C3C3 /* ExchangeTransactionDomainDTO.swift in Sources */, - 0A5C53DF2139498800667E34 /* UnrecognisedTransactionDomainDTO.swift in Sources */, - E9443012226E64E900EB6257 /* WalletSortInteractor.swift in Sources */, - 0A5E4BCC213820C500E3C3C3 /* IssueTransactionDomainDTO.swift in Sources */, - 0A5E4BD2213820C500E3C3C3 /* AnyTransactionDomainDTO.swift in Sources */, - 04831F7B216917EF006D1ED6 /* SmartTransactionDomainDTO.swift in Sources */, - 0ADD804A21F73C360075FC59 /* ScriptTransactionDomainDTO.swift in Sources */, - 0ADD804821F73C280075FC59 /* AssetScriptTransactionDomainDTO.swift in Sources */, - 0A6F60EC216F89B300A5C615 /* SmartTransactionDomain+Assistants.swift in Sources */, - E991BB202202CE090022E27D /* SendFeeTableViewCell.swift in Sources */, - E964067E21D5299D00569963 /* DexDomainDTO.swift in Sources */, - 0A8AFF282101F37200D0582B /* MatcherServiceTypes.swift in Sources */, - E96E2A0521D3D9AA00AC2FA9 /* DomainDexQueries.swift in Sources */, - 0ADD7F9F21F22FB60075FC59 /* UIViewController+Alert.swift in Sources */, - E9DC959621A3A5BD0020249F /* StartLeasingTypes.swift in Sources */, - 0ADD7FAC21F22FB60075FC59 /* UIViewController+Rx.swift in Sources */, - E9DB667B21A3938200962639 /* StartLeasingLoadingViewController.swift in Sources */, - E944300E226E645300EB6257 /* WalletSortPresenterProtocol.swift in Sources */, - 7B95115F225F7BA80030390C /* DateFormatter+UI.swift in Sources */, - E95B47F821638B11004D4E39 /* StartLeasingInteractor.swift in Sources */, - E95B47F021638B11004D4E39 /* StartLeasingViewController.swift in Sources */, - E9DB667521A3848900962639 /* StartLeasingCancelConfirmationViewController.swift in Sources */, - E95B47F621638B11004D4E39 /* StartLeasingInteractorProtocol.swift in Sources */, - E9DB667321A3846A00962639 /* StartLeasingConfirmationViewController.swift in Sources */, - 7BDA6AD9222D8D0A001DE71C /* TransactionCardSystem.swift in Sources */, - E944300A226E641E00EB6257 /* WalletSortTypes.swift in Sources */, - E95B47EB21638B11004D4E39 /* StartLeasingModuleBuilder.swift in Sources */, - 0ADD7FA021F22FB60075FC59 /* RateApp.swift in Sources */, - 044D6C8E21978CED003861A2 /* EditAccountNameModuleBuilder.swift in Sources */, - 044D6C8F21978CED003861A2 /* EditAccountNameViewController.swift in Sources */, - 0ADD7FAF21F22FB60075FC59 /* MailCompose+Support.swift in Sources */, - E9FB6E382178265100FA13C1 /* SendInteractor.swift in Sources */, - E97D451021C814C0000E3C48 /* OrderBookMatcher.swift in Sources */, - 0AAC2811221438B200D8A404 /* UIImageView+Rx.swift in Sources */, - 0A88CC06217D27DF0083874C /* AccountSettingsDomainDTO.swift in Sources */, - 0A6F60EA216F893600A5C615 /* WalletTypes.swift in Sources */, - 0ADD6C892167980E00B06917 /* ProfileBiometricCell.swift in Sources */, - 0A14E3E821871B7700EA7E91 /* AliasesHeadCell.swift in Sources */, - 0A9D6B62216E059F006822C5 /* WalletTypes+DisplayState.swift in Sources */, - E9B12DB5219DD6E000128EFE /* AssetBalanceSpamCell.swift in Sources */, - 0A9D6B68216E070E006822C5 /* WalletTypes+State.swift in Sources */, - 7BDA6AF222315024001DE71C /* ContactDetailView.swift in Sources */, - 0ADD7FA521F22FB60075FC59 /* UINavigationController+Additionals.swift in Sources */, - 0ADD803821F22FFB0075FC59 /* BackupCoordinator.swift in Sources */, - E98092A922A85EE700914CF1 /* WalletViewController.swift in Sources */, - 0A6F60E9216F88B200A5C615 /* WalletTypes+ViewModels.swift in Sources */, - 0A6F60EB216F895A00A5C615 /* WalletTypes+DTO.swift in Sources */, - 0A6F60E8216F888B00A5C615 /* DexMyOrdersTypes.swift in Sources */, - 0AF58F902191BC9300C8A4B3 /* PasscodePresenterProtocol.swift in Sources */, - E9D36DF72175C755001E6DF0 /* AssetListInteractor.swift in Sources */, - 0ADC17A22204A34100472130 /* ModalTableView.swift in Sources */, - 04831F7C2169210B006D1ED6 /* PasscodeViewController.swift in Sources */, - E95B47D321638AF2004D4E39 /* AccountPasswordViewController.swift in Sources */, - 7B5EDEC622536269009C2B3B /* AccessibilityIdentifiers.swift in Sources */, - 0A7CCDB1218A138D005D372B /* MyAddressModuleBuilder.swift in Sources */, - 04831F76216916EE006D1ED6 /* WalletInteractor.swift in Sources */, - E95E14FF22A07364003552B8 /* WalletDisplayData.swift in Sources */, - 04831F78216916EE006D1ED6 /* TransactionApi.swift in Sources */, - E9B12DAD219DCD1800128EFE /* TokenBurnSendInteractor.swift in Sources */, - E96570432193E8570052F0FC /* DexMyOrdersModuleOutput.swift in Sources */, - 0ADD802721F22FFA0075FC59 /* WalletCoordinator.swift in Sources */, - 0ADD804021F5D2DD0075FC59 /* AddressRepositoryRemote.swift in Sources */, - 0ADD802021F22FFA0075FC59 /* Coordinator.swift in Sources */, - 04831F7421691659006D1ED6 /* HistoryTransactionView.swift in Sources */, - 0ADD7FA421F22FB60075FC59 /* UIView+SafeArea.swift in Sources */, - 0A2B7D39216038A80098438D /* SpamService.swift in Sources */, - E9C0B4A42176C4BE00669D1D /* SendTypes.swift in Sources */, - 0ADD803A21F22FFB0075FC59 /* MainTabBarCoordinator.swift in Sources */, - 0A218B8721551E6600B989A1 /* WalletsRepositoryProtocol.swift in Sources */, - 0ADD802421F22FFA0075FC59 /* TabBarRouter.swift in Sources */, - 0A218B812155180C00B989A1 /* WalletDomainDTO.swift in Sources */, + E9B087912163886800937644 /* Interactor */ = { + isa = PBXGroup; + children = ( + E9B087922163886800937644 /* DexSortInteractor.swift */, + E9B087932163886800937644 /* DexSortInteractorProtocol.swift */, + ); + path = Interactor; + sourceTree = ""; + }; + E9B12DB0219DCFDC00128EFE /* Interactor */ = { + isa = PBXGroup; + children = ( + E9B12DAA219DCCDB00128EFE /* TokenBurnSendInteractorProtocol.swift */, + E9B12DAC219DCD1800128EFE /* TokenBurnSendInteractor.swift */, + ); + path = Interactor; + sourceTree = ""; + }; + E9B190AA22E7CD99008220B7 /* MarketPulseWidget */ = { + isa = PBXGroup; + children = ( + 7B848A51230075920092AD18 /* CommonResources */, + E9B190B022E7CD99008220B7 /* Info.plist */, + E991F8FB22E8BC41008D1AE4 /* MarketPulseWidget.entitlements */, + E9B190AD22E7CD99008220B7 /* MainInterface.storyboard */, + E958571422F35BBD007A0178 /* Sources */, + E958571522F35BCB007A0178 /* Resources */, + ); + path = MarketPulseWidget; + sourceTree = ""; + }; + E9C1B90C236C6D7400F8E988 /* ForceUpdateApp */ = { + isa = PBXGroup; + children = ( + E9C1B90D236C6D9500F8E988 /* ForceUpdateApp.storyboard */, + E9C1B90F236C6DA900F8E988 /* ForceUpdateAppViewController.swift */, + ); + path = ForceUpdateApp; + sourceTree = ""; + }; + E9CD0D2F218137FE001A99B3 /* MainTabBar */ = { + isa = PBXGroup; + children = ( + E9CD0D30218137FE001A99B3 /* MainTabBarController.swift */, + ); + path = MainTabBar; + sourceTree = ""; + }; + E9D36D6B2175C754001E6DF0 /* Receive */ = { + isa = PBXGroup; + children = ( + E9D36D6C2175C754001E6DF0 /* Сryptocurrency */, + E9D36D7D2175C754001E6DF0 /* Card */, + E9D36D8C2175C754001E6DF0 /* ReceiveTypes.swift */, + E9D36D8D2175C754001E6DF0 /* CardComplete */, + E9D36D932175C754001E6DF0 /* Receive.storyboard */, + E9D36D942175C754001E6DF0 /* ReceiveContainerViewController.swift */, + E9D36D952175C754001E6DF0 /* ReceiveContainerModuleBuilder.swift */, + E9D36D972175C754001E6DF0 /* Address */, + E9D36DA02175C754001E6DF0 /* Generate */, + E9D36DA82175C754001E6DF0 /* Views */, + E9D36DAB2175C754001E6DF0 /* Invoice */, + ); + path = Receive; + sourceTree = ""; + }; + E9D36D6C2175C754001E6DF0 /* Сryptocurrency */ = { + isa = PBXGroup; + children = ( + E9D36D6D2175C754001E6DF0 /* ReceiveCryptocurrencyTypes.swift */, + E9D36D702175C754001E6DF0 /* ReceiveCryptocurrencyModuleBuilder.swift */, + E9D36D712175C754001E6DF0 /* Presenter */, + E9D36D762175C754001E6DF0 /* Interactor */, + E9D36D7A2175C754001E6DF0 /* ReceiveCryptocurrencyViewController.swift */, + ); + path = "Сryptocurrency"; + sourceTree = ""; + }; + E9D36D712175C754001E6DF0 /* Presenter */ = { + isa = PBXGroup; + children = ( + E9D36D722175C754001E6DF0 /* ReceiveCryptocurrencyPresenterProtocol.swift */, + E9D36D732175C754001E6DF0 /* ReceiveCryptocurrencyPresenter.swift */, + ); + path = Presenter; + sourceTree = ""; + }; + E9D36D762175C754001E6DF0 /* Interactor */ = { + isa = PBXGroup; + children = ( + E9D36D782175C754001E6DF0 /* ReceiveCryptocurrencyInteractorProtocol.swift */, + E9D36D792175C754001E6DF0 /* ReceiveCryptocurrencyInteractor.swift */, + ); + path = Interactor; + sourceTree = ""; + }; + E9D36D7D2175C754001E6DF0 /* Card */ = { + isa = PBXGroup; + children = ( + E9D36D7E2175C754001E6DF0 /* ReceiveCardTypes.swift */, + E9D36D812175C754001E6DF0 /* Presenter */, + E9D36D842175C754001E6DF0 /* ReceiveCardViewController.swift */, + E9D36D852175C754001E6DF0 /* ReceiveCardModuleBuilder.swift */, + E9D36D882175C754001E6DF0 /* Interactor */, + ); + path = Card; + sourceTree = ""; + }; + E9D36D812175C754001E6DF0 /* Presenter */ = { + isa = PBXGroup; + children = ( + E9D36D822175C754001E6DF0 /* ReceiveCardPresenter.swift */, + E9D36D832175C754001E6DF0 /* ReceiveCardPresenterProtocol.swift */, + ); + path = Presenter; + sourceTree = ""; + }; + E9D36D882175C754001E6DF0 /* Interactor */ = { + isa = PBXGroup; + children = ( + E9D36D892175C754001E6DF0 /* ReceiveCardInteractorProtocol.swift */, + E9D36D8A2175C754001E6DF0 /* ReceiveCardInteractor.swift */, + ); + path = Interactor; + sourceTree = ""; + }; + E9D36D8D2175C754001E6DF0 /* CardComplete */ = { + isa = PBXGroup; + children = ( + E9D36D922175C754001E6DF0 /* ReceiveCardCompleteViewController.swift */, + ); + path = CardComplete; + sourceTree = ""; + }; + E9D36D972175C754001E6DF0 /* Address */ = { + isa = PBXGroup; + children = ( + E9D36D982175C754001E6DF0 /* ReceiveAddressViewController.swift */, + E9D36D9B2175C754001E6DF0 /* ReceiveAddressModuleBuilder.swift */, + E9D36D9E2175C754001E6DF0 /* ReceiveAddressTypes.swift */, + ); + path = Address; + sourceTree = ""; + }; + E9D36DA02175C754001E6DF0 /* Generate */ = { + isa = PBXGroup; + children = ( + E9D36DA32175C754001E6DF0 /* ReceiveGenerateAddressModuleBuilder.swift */, + E9D36DA52175C754001E6DF0 /* ReceiveGenerateTypes.swift */, + E9D36DA72175C754001E6DF0 /* ReceiveGenerateAddressViewController.swift */, + ); + path = Generate; + sourceTree = ""; + }; + E9D36DA82175C754001E6DF0 /* Views */ = { + isa = PBXGroup; + children = ( + E9D36DA92175C754001E6DF0 /* AssetSelectView.swift */, + E9D36DAA2175C754001E6DF0 /* AssetSelectView.xib */, + E911300B21BC028400588430 /* AssetSelectSkeletonView.swift */, + E911300D21BC029300588430 /* AssetSelectSkeletonView.xib */, + ); + path = Views; + sourceTree = ""; + }; + E9D36DAB2175C754001E6DF0 /* Invoice */ = { + isa = PBXGroup; + children = ( + E9D36DAE2175C754001E6DF0 /* ReceiveInvoiceViewController.swift */, + E9D36DAF2175C754001E6DF0 /* ReceiveInvoiceModuleBuilder.swift */, + E9D36DB12175C754001E6DF0 /* ReceiveInvoiveTypes.swift */, + E9D36DB22175C754001E6DF0 /* Interactor */, + ); + path = Invoice; + sourceTree = ""; + }; + E9D36DB22175C754001E6DF0 /* Interactor */ = { + isa = PBXGroup; + children = ( + E9D36DB32175C754001E6DF0 /* ReceiveInvoiceInteractorProtocol.swift */, + E9D36DB42175C754001E6DF0 /* ReceiveInvoiceInteractor.swift */, + ); + path = Interactor; + sourceTree = ""; + }; + E9D36DB52175C754001E6DF0 /* AssetList */ = { + isa = PBXGroup; + children = ( + E9D36DB82175C755001E6DF0 /* AssetListModuleBuilder.swift */, + E9D36DB92175C755001E6DF0 /* Presenter */, + E9D36DBC2175C755001E6DF0 /* AssetListViewController.swift */, + E9D36DBD2175C755001E6DF0 /* AssetListTypes.swift */, + E9D36DC02175C755001E6DF0 /* Views */, + E9D36DC22175C755001E6DF0 /* Interactor */, + E9D36DC52175C755001E6DF0 /* AssetListModuleOutput.swift */, + E9D36DC62175C755001E6DF0 /* AssetList.storyboard */, + ); + path = AssetList; + sourceTree = ""; + }; + E9D36DB92175C755001E6DF0 /* Presenter */ = { + isa = PBXGroup; + children = ( + E9D36DBA2175C755001E6DF0 /* AssetListPresenterProtocol.swift */, + E9D36DBB2175C755001E6DF0 /* AssetListPresenter.swift */, + ); + path = Presenter; + sourceTree = ""; + }; + E9D36DC02175C755001E6DF0 /* Views */ = { + isa = PBXGroup; + children = ( + E9D36DC12175C755001E6DF0 /* AssetListTableViewCell.swift */, + ); + path = Views; + sourceTree = ""; + }; + E9D36DC22175C755001E6DF0 /* Interactor */ = { + isa = PBXGroup; + children = ( + E9D36DC32175C755001E6DF0 /* AssetListInteractor.swift */, + E9D36DC42175C755001E6DF0 /* AssetListInteractorProtocol.swift */, + ); + path = Interactor; + sourceTree = ""; + }; + E9DB666F21A383E900962639 /* Confirmation */ = { + isa = PBXGroup; + children = ( + E9DB667221A3846A00962639 /* StartLeasingConfirmationViewController.swift */, + ); + path = Confirmation; + sourceTree = ""; + }; + E9DB667021A383F300962639 /* StartLeasing */ = { + isa = PBXGroup; + children = ( + E95B47D721638B11004D4E39 /* StartLeasingModuleBuilder.swift */, + E95B47DE21638B11004D4E39 /* StartLeasingViewController.swift */, + E920372A21A5F4C10055E4D8 /* StartLeasingConfirmModuleBuilder.swift */, + E95B47E121638B11004D4E39 /* Views */, + E95B47E621638B11004D4E39 /* Interactor */, + ); + path = StartLeasing; + sourceTree = ""; + }; + E9DB667821A38D7300962639 /* CancelConfirmation */ = { + isa = PBXGroup; + children = ( + E9DB667421A3848900962639 /* StartLeasingCancelConfirmationViewController.swift */, + ); + path = CancelConfirmation; + sourceTree = ""; + }; + E9DB667921A3937300962639 /* Loading */ = { + isa = PBXGroup; + children = ( + E9DB667A21A3938200962639 /* StartLeasingLoadingViewController.swift */, + ); + path = Loading; + sourceTree = ""; + }; + E9EC5B352175F35800E5C29A /* Send */ = { + isa = PBXGroup; + children = ( + E9EC5B362175F35800E5C29A /* Send.storyboard */, + E991BB182202C9E10022E27D /* SendFee */, + E9543900217FF9C8001A7860 /* Complete */, + E95438F6217F919B001A7860 /* Loading */, + E9310D0A217924B7008BF3EE /* Confirmaion */, + E9EC5B372175F35800E5C29A /* Send */, + ); + path = Send; + sourceTree = ""; + }; + E9EC5B372175F35800E5C29A /* Send */ = { + isa = PBXGroup; + children = ( + E9EC5C122176B2D700E5C29A /* Interactor */, + E9EC5C112176B2CD00E5C29A /* Presenter */, + E9EC5BA72175F35800E5C29A /* Views */, + E9EC5B3A2175F35800E5C29A /* SendViewController.swift */, + E9EC5B3B2175F35800E5C29A /* SendModuleBuilder.swift */, + E9C0B4A32176C4BE00669D1D /* SendTypes.swift */, + ); + path = Send; + sourceTree = ""; + }; + E9EC5BA72175F35800E5C29A /* Views */ = { + isa = PBXGroup; + children = ( + E9642C8E21CB32570065A1BD /* CoinomatServiceErrorView.swift */, + E9642C9021CB326A0065A1BD /* CoinomatServiceErrorView.xib */, + E9EC5BA82175F35800E5C29A /* AddressInputView.swift */, + E9EC5BA92175F35800E5C29A /* AddressInputView.xib */, + E9CD0D2B218099FB001A99B3 /* SendMoneroPaymentIdView.swift */, + E9CD0D2D21809A5D001A99B3 /* SendMoneroPaymentIdView.xib */, + E9AFDBE321F32E88003130A8 /* TransactionFeeView.swift */, + E9AFDBE521F32E96003130A8 /* TransactionFeeView.xib */, + E983665D21F5972300178A8A /* TransactionScriptErrorView.swift */, + E983666021F5973900178A8A /* TransactionScriptErrorView.xib */, + ); + path = Views; + sourceTree = ""; + }; + E9EC5C112176B2CD00E5C29A /* Presenter */ = { + isa = PBXGroup; + children = ( + E9C0B49B2176C46E00669D1D /* SendPresenterProtocol.swift */, + E9C0B49D2176C48300669D1D /* SendPresenter.swift */, + ); + path = Presenter; + sourceTree = ""; + }; + E9EC5C122176B2D700E5C29A /* Interactor */ = { + isa = PBXGroup; + children = ( + E9C0B49F2176C49B00669D1D /* SendInteractorProtocol.swift */, + E9C0B4A12176C4A800669D1D /* SendInteractor.swift */, + ); + path = Interactor; + sourceTree = ""; + }; + E9F69B9422A522BC00CDBD00 /* Presenter */ = { + isa = PBXGroup; + children = ( + E9F69B9722A522E400CDBD00 /* WalletSearchPresenter.swift */, + ); + path = Presenter; + sourceTree = ""; + }; + E9F69B9922A5331B00CDBD00 /* Views */ = { + isa = PBXGroup; + children = ( + E9F69B9A22A5333500CDBD00 /* WalletSearchHeaderCell.swift */, + E9F69B9B22A5333500CDBD00 /* WalletSearchHeaderCell.xib */, + ); + path = Views; + sourceTree = ""; + }; + E9F984A720E5266800D2CB4D /* Enter */ = { + isa = PBXGroup; + children = ( + 044D6C8421978C8C003861A2 /* Edit */, + E9F984A820E526DA00D2CB4D /* Enter.storyboard */, + 04A4031F2164B8CD00652F21 /* Start */, + ); + path = Enter; + sourceTree = ""; + }; + F7E954DB1EA8FE0600A804DE = { + isa = PBXGroup; + children = ( + F7E954E61EA8FE0700A804DE /* WavesWallet-iOS */, + 7B66860122B3F70E0029E6F1 /* DomainLayer */, + 7B66872422B7E68B0029E6F1 /* DataLayer */, + 7B431A8D22BD176D00DE73B9 /* DomainLayerTests */, + 7B431A9D22BD185B00DE73B9 /* DataLayerTests */, + 7B83A7D122D8C74F0038180D /* DummyForTest */, + 7B6686EF22B7C5120029E6F1 /* Extensions */, + E9B190AA22E7CD99008220B7 /* MarketPulseWidget */, + 7B66873122B7E6950029E6F1 /* Frameworks */, + 7BF89E9722272A5E00853F9D /* Analytics */, + 34D3652B38B4C48A2B987569 /* Pods */, + F7E954E51EA8FE0700A804DE /* Products */, + 7BDDFA74230B2E75007A179B /* Recovered References */, + ); + sourceTree = ""; + }; + F7E954E51EA8FE0700A804DE /* Products */ = { + isa = PBXGroup; + children = ( + F7E954E41EA8FE0700A804DE /* WavesWallet-iOS.app */, + 7BF89E9622272A5E00853F9D /* MonkeyTest.xctest */, + 7B66860022B3F70D0029E6F1 /* DomainLayer.framework */, + 7B6686EE22B7C5120029E6F1 /* Extensions.framework */, + 7B66872322B7E68B0029E6F1 /* DataLayer.framework */, + 7B431A8C22BD176D00DE73B9 /* DomainLayerTests.xctest */, + 7B431A9C22BD185A00DE73B9 /* DataLayerTests.xctest */, + 7B83A7D022D8C74E0038180D /* DummyForTest.app */, + E9B190A722E7CD99008220B7 /* MarketPulseWidget.appex */, + ); + name = Products; + sourceTree = ""; + }; + F7E954E61EA8FE0700A804DE /* WavesWallet-iOS */ = { + isa = PBXGroup; + children = ( + 0A4E71942216C6CD00A46613 /* WavesWallet-iOS.entitlements */, + 7B7422E3237ACC9D00E5910D /* WavesWallet-iOS-Dev.entitlements */, + 7B7422E4237ACC9D00E5910D /* WavesWallet-iOS-Test.entitlements */, + F7E954F51EA8FE0700A804DE /* Info.plist */, + 0AFBCA7F211306F600285BCB /* LaunchScreen.storyboard */, + F7E954E71EA8FE0700A804DE /* AppDelegate.swift */, + 0ADD7F1E21F22FB60075FC59 /* Extensions */, + 0A97974F2108805100407F67 /* Generated */, + 0ADD7FF721F22FFA0075FC59 /* Coordinators */, + 0AF92281212E1234003BA067 /* CustomViews */, + 0AF58F8B2191909200C8A4B3 /* Modules */, + 0A979752210885B500407F67 /* Resources */, + ); + path = "WavesWallet-iOS"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 7B6685FB22B3F70D0029E6F1 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 7B66860422B3F70E0029E6F1 /* DomainLayer.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7B6686E922B7C5120029E6F1 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 7B6686F222B7C5120029E6F1 /* Extensions.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7B66871E22B7E68B0029E6F1 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 7B66872722B7E68B0029E6F1 /* DataLayer.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 7B431A8B22BD176D00DE73B9 /* DomainLayerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7B431A9722BD176D00DE73B9 /* Build configuration list for PBXNativeTarget "DomainLayerTests" */; + buildPhases = ( + 998B1C8FFA65B3E372245AD9 /* [CP] Check Pods Manifest.lock */, + 7B431A8822BD176D00DE73B9 /* Sources */, + 7B431A8922BD176D00DE73B9 /* Frameworks */, + 7B431A8A22BD176D00DE73B9 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 7B83A7EB22D8D8050038180D /* PBXTargetDependency */, + ); + name = DomainLayerTests; + productName = DomainLayerTests; + productReference = 7B431A8C22BD176D00DE73B9 /* DomainLayerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 7B431A9B22BD185A00DE73B9 /* DataLayerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7B431AA322BD185B00DE73B9 /* Build configuration list for PBXNativeTarget "DataLayerTests" */; + buildPhases = ( + EBD87804B64040C2FA389FB9 /* [CP] Check Pods Manifest.lock */, + 7B431A9822BD185A00DE73B9 /* Sources */, + 7B431A9922BD185A00DE73B9 /* Frameworks */, + 7B431A9A22BD185A00DE73B9 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 7B83A7AF22D8C60E0038180D /* PBXTargetDependency */, + 7B83A7E722D8C7580038180D /* PBXTargetDependency */, + ); + name = DataLayerTests; + productName = DataLayerTests; + productReference = 7B431A9C22BD185A00DE73B9 /* DataLayerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 7B6685FF22B3F70D0029E6F1 /* DomainLayer */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7B66860D22B3F70E0029E6F1 /* Build configuration list for PBXNativeTarget "DomainLayer" */; + buildPhases = ( + B7DA885A26D76574BE740EBB /* [CP] Check Pods Manifest.lock */, + 7B6685FB22B3F70D0029E6F1 /* Headers */, + 7B6685FC22B3F70D0029E6F1 /* Sources */, + 7B6685FD22B3F70D0029E6F1 /* Frameworks */, + 7B6685FE22B3F70D0029E6F1 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 7B16BCEA22DBE5A900540418 /* PBXTargetDependency */, + ); + name = DomainLayer; + productName = DomainLayer; + productReference = 7B66860022B3F70D0029E6F1 /* DomainLayer.framework */; + productType = "com.apple.product-type.framework"; + }; + 7B6686ED22B7C5120029E6F1 /* Extensions */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7B6686F722B7C5120029E6F1 /* Build configuration list for PBXNativeTarget "Extensions" */; + buildPhases = ( + DD84860E0A3D36F2349E6018 /* [CP] Check Pods Manifest.lock */, + 7B6686E922B7C5120029E6F1 /* Headers */, + 7B6686EA22B7C5120029E6F1 /* Sources */, + 7B6686EB22B7C5120029E6F1 /* Frameworks */, + 7B6686EC22B7C5120029E6F1 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Extensions; + productName = Extensions; + productReference = 7B6686EE22B7C5120029E6F1 /* Extensions.framework */; + productType = "com.apple.product-type.framework"; + }; + 7B66872222B7E68B0029E6F1 /* DataLayer */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7B66872C22B7E68B0029E6F1 /* Build configuration list for PBXNativeTarget "DataLayer" */; + buildPhases = ( + 0C1B1745ADFE90B2804BA792 /* [CP] Check Pods Manifest.lock */, + 7B66871E22B7E68B0029E6F1 /* Headers */, + 7B66871F22B7E68B0029E6F1 /* Sources */, + 7B66872022B7E68B0029E6F1 /* Frameworks */, + 7B66872122B7E68B0029E6F1 /* Resources */, + 509DEBEE3F43E2E11ED0E0A0 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + 7B16BCE822DBE59B00540418 /* PBXTargetDependency */, + ); + name = DataLayer; + productName = DataLayer; + productReference = 7B66872322B7E68B0029E6F1 /* DataLayer.framework */; + productType = "com.apple.product-type.framework"; + }; + 7B83A7CF22D8C74E0038180D /* DummyForTest */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7B83A7DF22D8C7500038180D /* Build configuration list for PBXNativeTarget "DummyForTest" */; + buildPhases = ( + 7B83A7CC22D8C74E0038180D /* Sources */, + 7B83A7CD22D8C74E0038180D /* Frameworks */, + 7B83A7CE22D8C74E0038180D /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = DummyForTest; + productName = DummyForTest; + productReference = 7B83A7D022D8C74E0038180D /* DummyForTest.app */; + productType = "com.apple.product-type.application"; + }; + 7BF89E9522272A5E00853F9D /* MonkeyTest */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7BF89E9D22272A5E00853F9D /* Build configuration list for PBXNativeTarget "MonkeyTest" */; + buildPhases = ( + 6C1AE68B16E222EEBEDE7F95 /* [CP] Check Pods Manifest.lock */, + 7BF89E9222272A5E00853F9D /* Sources */, + 7BF89E9322272A5E00853F9D /* Frameworks */, + 7BF89E9422272A5E00853F9D /* Resources */, + 4DD1BDED2B0D3B94D02099C6 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 7BF89E9C22272A5E00853F9D /* PBXTargetDependency */, + ); + name = MonkeyTest; + productName = MonkeyTest; + productReference = 7BF89E9622272A5E00853F9D /* MonkeyTest.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; + E9B190A622E7CD99008220B7 /* MarketPulseWidget */ = { + isa = PBXNativeTarget; + buildConfigurationList = E9B190BA22E7CD9A008220B7 /* Build configuration list for PBXNativeTarget "MarketPulseWidget" */; + buildPhases = ( + 4CB768AA15C6C88E2B020BE7 /* [CP] Check Pods Manifest.lock */, + 7B848A66230075F60092AD18 /* Gen Code */, + E9B190A322E7CD99008220B7 /* Sources */, + E9B190A422E7CD99008220B7 /* Frameworks */, + E9B190A522E7CD99008220B7 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + E953CE3822EB19C2001D5800 /* PBXTargetDependency */, + E953CE3A22EB19C2001D5800 /* PBXTargetDependency */, + ); + name = MarketPulseWidget; + productName = MarketPulseWidget; + productReference = E9B190A722E7CD99008220B7 /* MarketPulseWidget.appex */; + productType = "com.apple.product-type.app-extension"; + }; + F7E954E31EA8FE0700A804DE /* WavesWallet-iOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = F7E954F81EA8FE0700A804DE /* Build configuration list for PBXNativeTarget "WavesWallet-iOS" */; + buildPhases = ( + B9AFABF42B5D32EEE3F0215B /* [CP] Check Pods Manifest.lock */, + 0A97974E21087D0400407F67 /* Gen Code */, + F7E954E01EA8FE0700A804DE /* Sources */, + F7E954E11EA8FE0700A804DE /* Frameworks */, + F7E954E21EA8FE0700A804DE /* Resources */, + 0A218B93215549BB00B989A1 /* Fabric run */, + 7B9393CC22DF5827006634A6 /* Embed Frameworks */, + E9B190BB22E7CD9A008220B7 /* Embed App Extensions */, + 5FAF4597FE7F72DBCD62054E /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 7B16BCDE22DBE39000540418 /* PBXTargetDependency */, + 7B16BCE022DBE39000540418 /* PBXTargetDependency */, + 7B16BCE222DBE39000540418 /* PBXTargetDependency */, + E999E6AD2323D61300EDDF45 /* PBXTargetDependency */, + ); + name = "WavesWallet-iOS"; + productName = "WavesWallet-iOS"; + productReference = F7E954E41EA8FE0700A804DE /* WavesWallet-iOS.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + F7E954DC1EA8FE0600A804DE /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1030; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = "Waves Platform"; + TargetAttributes = { + 7B431A8B22BD176D00DE73B9 = { + CreatedOnToolsVersion = 10.2.1; + DevelopmentTeam = 96SW78M3KJ; + ProvisioningStyle = Automatic; + TestTargetID = 7B83A7CF22D8C74E0038180D; + }; + 7B431A9B22BD185A00DE73B9 = { + CreatedOnToolsVersion = 10.2.1; + DevelopmentTeam = 96SW78M3KJ; + ProvisioningStyle = Automatic; + TestTargetID = 7B83A7CF22D8C74E0038180D; + }; + 7B6685FF22B3F70D0029E6F1 = { + CreatedOnToolsVersion = 10.2.1; + ProvisioningStyle = Manual; + }; + 7B6686ED22B7C5120029E6F1 = { + CreatedOnToolsVersion = 10.2.1; + ProvisioningStyle = Manual; + }; + 7B66872222B7E68B0029E6F1 = { + CreatedOnToolsVersion = 10.2.1; + ProvisioningStyle = Manual; + }; + 7B83A7CF22D8C74E0038180D = { + CreatedOnToolsVersion = 10.2.1; + DevelopmentTeam = 96SW78M3KJ; + ProvisioningStyle = Automatic; + }; + 7BF89E9522272A5E00853F9D = { + CreatedOnToolsVersion = 10.1; + LastSwiftMigration = 1020; + ProvisioningStyle = Automatic; + TestTargetID = F7E954E31EA8FE0700A804DE; + }; + E9B190A622E7CD99008220B7 = { + CreatedOnToolsVersion = 10.3; + DevelopmentTeam = 96SW78M3KJ; + ProvisioningStyle = Manual; + SystemCapabilities = { + com.apple.ApplicationGroups.iOS = { + enabled = 1; + }; + }; + }; + F7E954E31EA8FE0700A804DE = { + CreatedOnToolsVersion = 8.3.2; + DevelopmentTeam = 96SW78M3KJ; + LastSwiftMigration = 1020; + ProvisioningStyle = Manual; + SystemCapabilities = { + com.apple.ApplicationGroups.iOS = { + enabled = 1; + }; + com.apple.Push = { + enabled = 0; + }; + com.apple.SafariKeychain = { + enabled = 0; + }; + }; + }; + }; + }; + buildConfigurationList = F7E954DF1EA8FE0600A804DE /* Build configuration list for PBXProject "WavesWallet-iOS" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ru, + ko, + es, + id, + de, + ja, + tr, + "pt-BR", + "pt-PT", + pl, + it, + "nl-NL", + "hi-IN", + "zh-Hans-CN", + "fr-FR", + Base, + ); + mainGroup = F7E954DB1EA8FE0600A804DE; + productRefGroup = F7E954E51EA8FE0700A804DE /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + F7E954E31EA8FE0700A804DE /* WavesWallet-iOS */, + E9B190A622E7CD99008220B7 /* MarketPulseWidget */, + 7B6685FF22B3F70D0029E6F1 /* DomainLayer */, + 7B66872222B7E68B0029E6F1 /* DataLayer */, + 7B6686ED22B7C5120029E6F1 /* Extensions */, + 7BF89E9522272A5E00853F9D /* MonkeyTest */, + 7B431A8B22BD176D00DE73B9 /* DomainLayerTests */, + 7B431A9B22BD185A00DE73B9 /* DataLayerTests */, + 7B83A7CF22D8C74E0038180D /* DummyForTest */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 7B431A8A22BD176D00DE73B9 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7B431A9A22BD185A00DE73B9 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7B6685FE22B3F70D0029E6F1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7B6686EC22B7C5120029E6F1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7B66872122B7E68B0029E6F1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7B83A7CE22D8C74E0038180D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7B83A7DD22D8C7500038180D /* LaunchScreen.storyboard in Resources */, + 7B83A7DA22D8C7500038180D /* Assets.xcassets in Resources */, + 7B83A7D822D8C74F0038180D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7BF89E9422272A5E00853F9D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E9B190A522E7CD99008220B7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7B848A63230075920092AD18 /* spam.csv in Resources */, + 7B88186423044FCC00AB0549 /* Languages.json in Resources */, + E9B190AF22E7CD99008220B7 /* MainInterface.storyboard in Resources */, + 7B848A5E230075920092AD18 /* environment_testnet.json in Resources */, + 7B848A5C230075920092AD18 /* Appsflyer-Info.plist in Resources */, + 7B848A60230075920092AD18 /* Fabric-Info.plist in Resources */, + 7B848A5D230075920092AD18 /* AppSpector-Info.plist in Resources */, + 7B848A5B230075920092AD18 /* Sentry-io-Info.plist in Resources */, + 7B848A61230075920092AD18 /* Amplitude-Info.plist in Resources */, + E95310BE22E8A43000F72809 /* WidgetAssets.xcassets in Resources */, + 7B848A62230075920092AD18 /* environment_mainnet.json in Resources */, + 7B848A5F230075920092AD18 /* GoogleService-Info.plist in Resources */, + 7B848AA12304073B0092AD18 /* WavesMarketPulse.strings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F7E954E21EA8FE0700A804DE /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E9236F1F2216F37300A12FD5 /* AppNewsView.xib in Resources */, + E9EC5BAA2175F35900E5C29A /* Send.storyboard in Resources */, + 0AF0C67D21AACB3700602197 /* GlobalErrorView.xib in Resources */, + 0AB63C1E216F952E0056B17E /* HistoryTransactionView.xib in Resources */, + E9642C9121CB326A0065A1BD /* CoinomatServiceErrorView.xib in Resources */, + E9B087A12163886800937644 /* DexChartHeaderView.xib in Resources */, + 0AAC28132215C4C700D8A404 /* SendFeeHeaderView.xib in Resources */, + E9B12DBA219E2D3900128EFE /* AssetBurnCell.xib in Resources */, + 0AF9222A212E0F1F003BA067 /* WalletLeasingCell.xib in Resources */, + 0A762DA02163AD0F0019D447 /* Support.storyboard in Resources */, + 7BB03E4C22EF2DAB008F179D /* WidgetSettingsHeaderView.xib in Resources */, + 0AF92231212E0F1F003BA067 /* WalletHeaderView.xib in Resources */, + 7BFB475822FC5AD0002B19F8 /* Appsflyer-Info.plist in Resources */, + E9AFDBE621F32E96003130A8 /* TransactionFeeView.xib in Resources */, + 0A762D15214FE3F300BE9204 /* InputTextField.xib in Resources */, + 7BFB475F22FC5AD0002B19F8 /* spam.csv in Resources */, + 0A7CCDB7218A17A9005D372B /* MyAddress.storyboard in Resources */, + E96FEA26226E962300C0EE22 /* WalletSortEmptyAssetsCell.xib in Resources */, + E9B087BF2163886800937644 /* SearchBarView.xib in Resources */, + 0AA8CAD421527672000D09E6 /* PasscodeView.xib in Resources */, + 7BFB475E22FC5AD0002B19F8 /* environment_mainnet.json in Resources */, + E95B47CE21638A9F004D4E39 /* ShortInfoPageView.xib in Resources */, + 0AF922F7212E1234003BA067 /* SegmentedControl.xib in Resources */, + 04A2CFA5211213BE00784FEC /* History.storyboard in Resources */, + E95E14F5229FF63B003552B8 /* WalletQuickNoteCell.xib in Resources */, + 0AFBCA852113173300285BCB /* InfoPlist.strings in Resources */, + 7B65B6F722F9D647007D5C53 /* KeyboardControl.xib in Resources */, + 7B5E74672239088800746ADD /* TransactionCardHeaderView.xib in Resources */, + 0AF922E9212E1234003BA067 /* EmptyCell.xib in Resources */, + 0AF922EF212E1234003BA067 /* AssetsSegmentedCell.xib in Resources */, + 0A3FE8A82135AE3600DBF4E1 /* AssetTransactionCell.xib in Resources */, + E96DAB71228EE643005ED12B /* WalletSortSegmentedControl.xib in Resources */, + 0AF921FB212E07B3003BA067 /* AssetChartHeaderView.xib in Resources */, + 048684F721258BC400D12189 /* HistoryHeaderView.xib in Resources */, + 0AF921F7212E07B3003BA067 /* AssetBalanceMoneyInfoView.xib in Resources */, + 0A071E41215AEF61007D9750 /* AccountPassword.storyboard in Resources */, + E9F69B9D22A5333500CDBD00 /* WalletSearchHeaderCell.xib in Resources */, + 0A96F1CC2151B392005E148F /* Passcode.storyboard in Resources */, + E9B12DB6219DD6E000128EFE /* AssetBalanceSpamCell.xib in Resources */, + 0ADD6C822167948500B06917 /* ProfileHeaderView.xib in Resources */, + 0A110CB82153CE31002A8FD7 /* Import.storyboard in Resources */, + 04EFAF4D2164F8D800277CCF /* EnterStartBlockCell.xib in Resources */, + 0AF92206212E07B3003BA067 /* AssetHeaderView.xib in Resources */, + E9D36DFA2175C755001E6DF0 /* AssetList.storyboard in Resources */, + 0AFBCA80211306F600285BCB /* LaunchScreen.storyboard in Resources */, + E917B3AF21BD688500CC849A /* AmountSkeletonView.xib in Resources */, + E9B087F12163886800937644 /* DexLastTradesHeaderView.xib in Resources */, + E9B086B02163883000937644 /* AddAddressTextField.xib in Resources */, + E9310D1B21792D14008BF3EE /* SendConfirmationRecipientView.xib in Resources */, + 7BFB475722FC5AD0002B19F8 /* Sentry-io-Info.plist in Resources */, + 7B49912622F876E1005B7123 /* AssetsSearchHeaderView.xib in Resources */, + 7BDA6AEA22313E85001DE71C /* TransactionImageView.xib in Resources */, + E92FAD0F226F6C050054D4AA /* WalletSortSeparatorCell.xib in Resources */, + E9C1B90E236C6D9500F8E988 /* ForceUpdateApp.storyboard in Resources */, + 0AF92229212E0F1F003BA067 /* WalletHistoryCell.xib in Resources */, + E95E14F7229FF7A6003552B8 /* WalletAssetSkeletonCell.xib in Resources */, + 7BFB475A22FC5AD0002B19F8 /* environment_testnet.json in Resources */, + 0A4399662150465E0032E608 /* NewAccount.storyboard in Resources */, + 0AA8CAC921516077000D09E6 /* Backup.storyboard in Resources */, + 04831F89216A3EBF006D1ED6 /* LanguageTableCell.xib in Resources */, + 0A071E64215C65D2007D9750 /* UseTouchID.storyboard in Resources */, + 7BDA6AF422315466001DE71C /* ContactDetailView.xib in Resources */, + E9B087E72163886800937644 /* DexCreateOrderSegmentedControl.xib in Resources */, + E9B0879E2163886800937644 /* DexChartCandlePriceView.xib in Resources */, + 7B49912022F875D4005B7123 /* AssetsSearch.storyboard in Resources */, + E95B47EF21638B11004D4E39 /* StartLeasing.storyboard in Resources */, + 7B7A4B7E22D625B300E0A8CD /* DexCreateOrderInvalidPriceView.xib in Resources */, + 7BE09AD323140F0900A038AD /* MobileKeeper.storyboard in Resources */, + E9EC5C102175F35900E5C29A /* AddressInputView.xib in Resources */, + E9B087C62163886800937644 /* DexTraderContainerSegmentedControl.xib in Resources */, + E95E14F3229FF31A003552B8 /* WalletLeasingBalanceCell.xib in Resources */, + 0AF92204212E07B3003BA067 /* AssetHeaderSkeletonView.xib in Resources */, + 7B8818742305639700AB0549 /* ActionSheet.storyboard in Resources */, + E98F1D2F22A5E2F200B4A8C4 /* WalletUpdateAppView.xib in Resources */, + 0A4140EB2174F09C00B1310E /* ChangePassword.storyboard in Resources */, + 7BD6E10022E228F000BAAFC8 /* DebugView.xib in Resources */, + 0A2B7D34216037FD0098438D /* AssetViewHistoryCell.xib in Resources */, + 044D6C8B21978C9C003861A2 /* EditAccountName.storyboard in Resources */, + E983666121F5973900178A8A /* TransactionScriptErrorView.xib in Resources */, + E95B6B15219C347200A85B5D /* TokenBurnConfirmationIDView.xib in Resources */, + E9DEECEB20BEF97E00F28C67 /* Waves.storyboard in Resources */, + F74240C91EAB8EC800C3B84D /* Main.storyboard in Resources */, + E95B47F521638B11004D4E39 /* AmountInputView.xib in Resources */, + 7BFB475B22FC5AD0002B19F8 /* GoogleService-Info.plist in Resources */, + 7B5EDEC42253618C009C2B3B /* AccessibilityIdentifiers.strings in Resources */, + 0A61B59A214ACFD500EC60FC /* Languages.json in Resources */, + E911300E21BC029300588430 /* AssetSelectSkeletonView.xib in Resources */, + 7BDA6ADF222E9664001DE71C /* TransactionCard.storyboard in Resources */, + E9239572237518B7009C4091 /* PushNotificationsAlertView.xib in Resources */, + E9B087B92163886800937644 /* Dex.storyboard in Resources */, + E9193B8320D7E28400F5D983 /* Profile.storyboard in Resources */, + 04E1C358212615CA00C702BA /* HeaderSkeletonView.xib in Resources */, + 0A762D13214FE23E00BE9204 /* NewAccountAvatarView.xib in Resources */, + 7BD6E10A22E5AEEB00BAAFC8 /* DebugHeaderView.xib in Resources */, + E9B087B02163886800937644 /* DexOrderBookHeaderView.xib in Resources */, + 7BFB475C22FC5AD0002B19F8 /* Fabric-Info.plist in Resources */, + E9B087E32163886800937644 /* DexCreateOrderInputView.xib in Resources */, + 7B60E2BE2316CC0500113C38 /* ConfirmRequestTransactionKindView.xib in Resources */, + E9D36DE92175C755001E6DF0 /* AssetSelectView.xib in Resources */, + 7BDA6AE2223025AD001DE71C /* BalanceLabel.xib in Resources */, + E96358A622A73D70008A3395 /* WalletClearAssetsView.xib in Resources */, + 7BFB475D22FC5AD0002B19F8 /* Amplitude-Info.plist in Resources */, + 0AF92303212E1424003BA067 /* Waves.strings in Resources */, + 0AF922E2212E1234003BA067 /* TickerView.xib in Resources */, + 0AF92200212E07B3003BA067 /* AssetHistorySkeletonCell.xib in Resources */, + E95B47C021638A9F004D4E39 /* Hello.storyboard in Resources */, + 0AF921EB212E07B3003BA067 /* Asset.storyboard in Resources */, + E9D36DDD2175C755001E6DF0 /* Receive.storyboard in Resources */, + 0AF921FF212E07B3003BA067 /* AssetBalanceSkeletonCell.xib in Resources */, + E95E14F1229FF152003552B8 /* WalletTableAssetsCell.xib in Resources */, + E95E14FB229FFA65003552B8 /* WalletHistorySkeletonCell.xib in Resources */, + 7BFB475922FC5AD0002B19F8 /* AppSpector-Info.plist in Resources */, + E95E151322A18C25003552B8 /* WalletSearchTableViewCell.xib in Resources */, + 7B3902A92237A75600AAFDB8 /* ActionsControl.xib in Resources */, + E95E14F9229FF933003552B8 /* WalletLeasingBalanceSkeletonCell.xib in Resources */, + E96FEA2A226F27BC00C0EE22 /* WalletSortCell.xib in Resources */, + 0A26549121BAE153005EA637 /* Assets.xcassets in Resources */, + 0AB63C2C2170EBF00056B17E /* Language.storyboard in Resources */, + 0A5D32F72154579C0009CDF3 /* MultyTextField.xib in Resources */, + 0A9797602108A11A00407F67 /* Wallet.storyboard in Resources */, + 7B48F35F2330F7C000923E9E /* environment_stagenet.json in Resources */, + 7B26A87D22ED129300E7B024 /* WidgetSettings.storyboard in Resources */, + E9CD0D2E21809A5D001A99B3 /* SendMoneroPaymentIdView.xib in Resources */, + 0AACD59D21A59E7100B30815 /* SweetSnackView.xib in Resources */, + E9939B4722302E6100B50E67 /* InfoPageConfirmView.xib in Resources */, + E9B086BE2163883000937644 /* AddressBook.storyboard in Resources */, + 0AF92202212E07B3003BA067 /* AssetTransactionSkeletonCell.xib in Resources */, + 0A071E7A215DB0A9007D9750 /* ChooseAccount.storyboard in Resources */, + 0AF922EC212E1234003BA067 /* AssetsSegmentedControl.xib in Resources */, + E9F984A920E526DA00D2CB4D /* Enter.storyboard in Resources */, + E95B47C721638A9F004D4E39 /* LongInfoPageView.xib in Resources */, + 7B8818712305639600AB0549 /* ActionSheetHeaderView.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 0A218B93215549BB00B989A1 /* Fabric run */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Fabric run"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "APIKey=$(/usr/libexec/PlistBuddy -c \"Print :Fabric:APIKey\" \"$PROJECT_DIR/CommonResources/Fabric-Info.plist\")\nKEY=$(/usr/libexec/PlistBuddy -c \"Print :Fabric:BuildSecret\" \"$PROJECT_DIR/CommonResources/Fabric-Info.plist\")\n\n\"${PODS_ROOT}/Fabric/run\" $APIKey $KEY\n\n"; + }; + 0A97974E21087D0400407F67 /* Gen Code */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Gen Code"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = "/bin/bash -l"; + shellScript = "GENERATED_PATH=\"$PROJECT_DIR/WavesWallet-iOS/Generated\"\nPROJECT_PATH=\"$PROJECT_DIR/WavesWallet-iOS\"\nPROJECT_PARENT_PATH=$PROJECT_DIR\n\necho \"SwiftGen Begin\"\n\necho \"SwiftGen $PROJECT_PATH\"\necho \"SwiftGen $PROJECT_PARENT_PATH\"\n\nHAS_NEED_GENERATE_CODE=\"$(ruby $PROJECT_DIR/fastlane/swiftgenhash.ruby Wallet $PROJECT_PATH $PROJECT_PARENT_PATH)\"\n\necho \"SwiftGen Need $HAS_NEED_GENERATE_CODE\"\n\nif [ \"$HAS_NEED_GENERATE_CODE\" == false ] ; then\n echo \"SwiftGen Cancel\"\n exit\nfi \n\nrm -rf $GENERATED_PATH\nmkdir $GENERATED_PATH\n\n$PODS_ROOT/SwiftGen/bin/swiftgen storyboards -t swift4 -o $GENERATED_PATH/Storyboards.swift $PROJECT_PATH\n\nSTRINGS=\"\"\nfor i in $(find ./WavesWallet-iOS/ -name \"*.strings\"); do\nif [[ $i = *\"en.lproj\"* ]]; then\nSTRINGS=\"$STRINGS $i\"\necho \"$STRINGS\"\nfi\ndone\n\n$PODS_ROOT/SwiftGen/bin/swiftgen strings --param enumName=Localizable --templatePath $PROJECT_PARENT_PATH/Templates/structured-swift4.stencil -o $GENERATED_PATH/Localizable.swift $STRINGS\n\n$PODS_ROOT/SwiftGen/bin/swiftgen xcassets -t swift4 -o $GENERATED_PATH/Images.swift --param enumName=Images $PROJECT_PATH/Resources/Assets.xcassets\n\n$PODS_ROOT/SwiftGen/bin/swiftgen strings --param enumName=AccessibilityIdentifiers --templatePath $PROJECT_PARENT_PATH/Templates/structured-swift4.stencil -o $GENERATED_PATH/AccessibilityIdentifiers.swift $PROJECT_PATH/Resources/AccessibilityIdentifiers.strings\n\necho \"SwiftGen End\"\n\n\n"; + }; + 0C1B1745ADFE90B2804BA792 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-DataLayer-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 4CB768AA15C6C88E2B020BE7 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-MarketPulseWidget-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 4DD1BDED2B0D3B94D02099C6 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-MonkeyTest/Pods-MonkeyTest-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 509DEBEE3F43E2E11ED0E0A0 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-DataLayer/Pods-DataLayer-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + 5FAF4597FE7F72DBCD62054E /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-WavesWallet-iOS/Pods-WavesWallet-iOS-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 6C1AE68B16E222EEBEDE7F95 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-MonkeyTest-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 7B848A66230075F60092AD18 /* Gen Code */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Gen Code"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "GENERATED_PATH=\"$PROJECT_DIR/MarketPulseWidget/Sources/Generated\"\nPROJECT_PATH=\"$PROJECT_DIR/MarketPulseWidget\"\nPROJECT_PARENT_PATH=$PROJECT_DIR\n\necho \"SwiftGen Begin\"\n\nHAS_NEED_GENERATE_CODE=\"$(ruby $PROJECT_DIR/fastlane/swiftgenhash.ruby Widget $PROJECT_PATH $PROJECT_PARENT_PATH)\"\n\necho \"SwiftGen Need $HAS_NEED_GENERATE_CODE\"\n\nif [ \"$HAS_NEED_GENERATE_CODE\" == false ] ; then\n echo \"SwiftGen Cancel\"\n exit\nfi \n\nrm -rf $GENERATED_PATH\nmkdir $GENERATED_PATH\n\n$PODS_ROOT/SwiftGen/bin/swiftgen xcassets -t swift4 -o $GENERATED_PATH/Images.swift --param enumName=Images $PROJECT_PATH/Resources/WidgetAssets.xcassets\n\n$PODS_ROOT/SwiftGen/bin/swiftgen strings --param enumName=Localizable --templatePath $PROJECT_DIR/Templates/structured-swift4.stencil -o $GENERATED_PATH/Localizable.swift $PROJECT_PATH/Resources/Localization/en.lproj/WavesMarketPulse.strings\n\n"; + }; + 998B1C8FFA65B3E372245AD9 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-DomainLayerTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + B7DA885A26D76574BE740EBB /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-DomainLayer-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + B9AFABF42B5D32EEE3F0215B /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-WavesWallet-iOS-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + DD84860E0A3D36F2349E6018 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Extensions-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + EBD87804B64040C2FA389FB9 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-DataLayerTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 7B431A8822BD176D00DE73B9 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7B431A8F22BD176D00DE73B9 /* DomainLayerTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7B431A9822BD185A00DE73B9 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7B431A9F22BD185B00DE73B9 /* DataLayerTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7B6685FC22B3F70D0029E6F1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7B5FAA8922BBE3EC00621A44 /* DexDomainDTO.swift in Sources */, + 7B5FAA9C22BBE3EC00621A44 /* LeaseTransactionDomainDTO.swift in Sources */, + 7B5FAA7222BBE3EC00621A44 /* AssetsBalanceSettingsRepositoryProtocol.swift in Sources */, + 7BDC6D6022C397A600614E6B /* AnalyticManagerEvent+TokenBurn.swift in Sources */, + 7B848A6D2301784B0092AD18 /* WidgetSettingsUseCaseProtocol.swift in Sources */, + 7B5FAA9D22BBE3EC00621A44 /* AliasTransactionDomainDTO.swift in Sources */, + 7B5FAA9422BBE3EC00621A44 /* ScriptTransactionDomainDTO.swift in Sources */, + 7B5FAA8222BBE3EC00621A44 /* AuthenticationRepositoryProtocol.swift in Sources */, + E99A3B7722BE5DB70070AC76 /* GatewayDomainDTO.swift in Sources */, + 7B5FAA9622BBE3EC00621A44 /* UnrecognisedTransactionDomainDTO.swift in Sources */, + 7BDC6D5022C396FD00614E6B /* AnalyticManagerEvent+WavesQuickAction.swift in Sources */, + 7B5FAA9722BBE3EC00621A44 /* IssueTransactionDomainDTO.swift in Sources */, + 7B5FAAC222BBE3EC00621A44 /* BiometricManager.swift in Sources */, + 7B5FAAB722BBE3EC00621A44 /* CleanerWalletManagerBanner.swift in Sources */, + 7B5FAAB322BBE3EC00621A44 /* ApplicationVersionUseCase.swift in Sources */, + E97A74A522D3BAA200777C39 /* OrderBookUseCaseProtocol.swift in Sources */, + 7B5FAAA322BBE3EC00621A44 /* ResponseType.swift in Sources */, + 7B5FAA6A22BBE3EC00621A44 /* RepositoriesFactoryProtocol.swift in Sources */, + 7B5FAAB422BBE3EC00621A44 /* TransactionsUseCase.swift in Sources */, + 7BDC6D7422C3A1E000614E6B /* AnalyticManagerEvent+Widgets.swift in Sources */, + 7BDC6D3E22C2522F00614E6B /* SpamAssetsRepositoryProtocol.swift in Sources */, + 7B848A7123018C0E0092AD18 /* WidgetSettingsInizializationUseCaseProtocol.swift in Sources */, + 7B5FAABC22BBE3EC00621A44 /* Hash.swift in Sources */, + 7B5FAA7722BBE3EC00621A44 /* DexPairsPriceRepositoryProtocol.swift in Sources */, + 7B5FAAB122BBE3EC00621A44 /* AddressUseCase.swift in Sources */, + 7B5FAABE22BBE3EC00621A44 /* PublicKeyAccount.swift in Sources */, + 7BDC6D6E22C398F600614E6B /* AnalyticManagerEvent+AddressBook.swift in Sources */, + 7BDC6D5C22C3978400614E6B /* AnalyticManagerEvent+Alias.swift in Sources */, + 7B5FAAC122BBE3EC00621A44 /* Data+AES.swift in Sources */, + 7B5FAA9222BBE3EC00621A44 /* LeaseCancelTransactionDomainDTO.swift in Sources */, + 7B5FAAB522BBE3EC00621A44 /* AssetsBalanceSettingsUseCase.swift in Sources */, + 7B5FAA7522BBE3EC00621A44 /* NotificationNewsRepositoryProtocol.swift in Sources */, + 7BDC6D4A22C396C000614E6B /* AnalyticManagerEvent+SingIn.swift in Sources */, + 7B5FAAA522BBE3EC00621A44 /* UseCasesFactory.swift in Sources */, + E9618D1422EF933800FB7F06 /* WidgetSettingsRepositoryProtocol.swift in Sources */, + 7B5FAAAE22BBE3EC00621A44 /* AuthorizationUseCaseProtocol.swift in Sources */, + 7B5FAA9522BBE3EC00621A44 /* AnyTransactionDomainDTO.swift in Sources */, + 7B5FAA8522BBE3EC00621A44 /* DomainLayerTypes.swift in Sources */, + 7BDC6D4922C396BD00614E6B /* AnalyticManagerEvent+Send.swift in Sources */, + 7B5FAAAF22BBE3EC00621A44 /* AliasesUseCase.swift in Sources */, + 7B5FAA7D22BBE3EC00621A44 /* AssetsRepositoryProtocol.swift in Sources */, + 7B5FAABA22BBE3EC00621A44 /* SigningWalletsProtocol.swift in Sources */, + 7B5FAA7622BBE3EC00621A44 /* ApplicationVersionRepositoryProtocol.swift in Sources */, + 7B5FAA8C22BBE3EC00621A44 /* SponsorshipTransactionDomainDTO.swift in Sources */, + 7BDC6D4422C3965900614E6B /* AnalyticManagerEvent+ImportAccount.swift in Sources */, + 7B5FAACF22BCEA3500621A44 /* AliasesUseCaseProtocol.swift in Sources */, + 7B5FAABD22BBE3EC00621A44 /* Address.swift in Sources */, + 7B5FAA6F22BBE3EC00621A44 /* AccountSettingsRepositoryProtocol.swift in Sources */, + 7B5FAAB622BBE3EC00621A44 /* ApplicationDebugSettings.swift in Sources */, + 7B848A7E2301CB0F0092AD18 /* CorrectionPairsUseCase.swift in Sources */, + 7B5FAABB22BBE3EC00621A44 /* WordList.swift in Sources */, + 7B5FAA8622BBE3EC00621A44 /* AccountEnvironmentDomainDTO.swift in Sources */, + 7B5FAA8122BBE3EC00621A44 /* DexOrderBookRepositoryProtocol.swift in Sources */, + 7B5FAAA222BBE3EC00621A44 /* AccountSettingsDomainDTO.swift in Sources */, + 7B5FAA7C22BBE3EC00621A44 /* LastTradesRepositoryProtocol.swift in Sources */, + 7B5FAA7A22BBE3EC00621A44 /* CandlesRepositoryProtocol.swift in Sources */, + 7B5FAA8422BBE3EC00621A44 /* UtilsRepositoryProtocol.swift in Sources */, + 7B5FAA9122BBE3EC00621A44 /* SmartTransactionDomainDTO.swift in Sources */, + 7B5FAA9922BBE3EC00621A44 /* ExchangeTransactionDomainDTO.swift in Sources */, + 7B5FAA6C22BBE3EC00621A44 /* Asset+Assistants.swift in Sources */, + 7B5FAAAC22BBE3EC00621A44 /* AccountBalanceUseCase.swift in Sources */, + 7BDC6D4D22C396D500614E6B /* AnalyticManagerEvent+Receive.swift in Sources */, + 7B5FAAAD22BBE3EC00621A44 /* AuthorizationUseCase.swift in Sources */, + 7B5FAAA422BBE3EC00621A44 /* WalletEnvironment.swift in Sources */, + 7B5FAAC022BBE3EC00621A44 /* RXCrypto+SHA.swift in Sources */, + 7B5FAA8D22BBE3EC00621A44 /* AddressDomainDTO.swift in Sources */, + 7B5FAABF22BBE3EC00621A44 /* PrivateKeyAccount.swift in Sources */, + 7B5FAAA122BBE3EC00621A44 /* ContactDomainDTO.swift in Sources */, + 7B431A8322BCFFA900DE73B9 /* TransactionsUseCaseProtocol.swift in Sources */, + 7B97B0B222FCB5DA008BA3F4 /* Localizable.swift in Sources */, + 7B5FAAA022BBE3EC00621A44 /* CoinomatDomainDTO.swift in Sources */, + 7B5FAA8F22BBE3EC00621A44 /* DataTransactionDomainDTO.swift in Sources */, + 7BDC6D7322C3A05B00614E6B /* AnalyticManagerEvent+Menu.swift in Sources */, + 7B431A8622BD030600DE73B9 /* AddressUseCaseProtocol.swift in Sources */, + 7B5FAA6D22BBE3EC00621A44 /* DomainDexQueries.swift in Sources */, + 7B5FAAB822BBE3EC00621A44 /* SmartTransactionDomain+Assistants.swift in Sources */, + 7B5FAAB022BBE3EC00621A44 /* MigrationUseCase.swift in Sources */, + E9618D1622EF936800FB7F06 /* MarketPulseSettingsDomainDTO.swift in Sources */, + 7B5FAA8B22BBE3EC00621A44 /* AliasDomainDTO.swift in Sources */, + 7B5FAAA822BBE3EC00621A44 /* AnalyticAssetManager.swift in Sources */, + 7B5FAA6B22BBE3EC00621A44 /* TransactionDomainDTO+Mapper.swift in Sources */, + 7B5FAA7822BBE3EC00621A44 /* AddressBookRepositoryProtocol.swift in Sources */, + 7B5FAADB22BCEA4200621A44 /* AccountBalanceUseCaseProtocol.swift in Sources */, + 7B5FAA7B22BBE3EC00621A44 /* TransactionsRepositoryProtocol.swift in Sources */, + 7B5FAA8E22BBE3EC00621A44 /* InvokeScriptTransactionDomainDTO.swift in Sources */, + 7B5FAAAB22BBE3EC00621A44 /* AnalyticManager+Dex.swift in Sources */, + 7B5FAA7422BBE3EC00621A44 /* DexRealmRepositoryProtocol.swift in Sources */, + 7B5FAA7322BBE3EC00621A44 /* MatcherRepositoryProtocol.swift in Sources */, + 7B5FAA8322BBE3EC00621A44 /* EnvironmentRepositoryProtocol.swift in Sources */, + 7B5FAA9F22BBE3EC00621A44 /* AssetDomainDTO.swift in Sources */, + 7B5FAA6E22BBE3EC00621A44 /* WalletsRepositoryProtocol.swift in Sources */, + 7B0FD98F2319C0EA0004B52B /* MobileKeeperRepositoryProtocol.swift in Sources */, + 7B5FAAB222BBE3EC00621A44 /* AssetsUseCase.swift in Sources */, + 7B431A7E22BCFF3800DE73B9 /* AssetsUseCaseProtocol.swift in Sources */, + 7BDC6D5322C3971900614E6B /* AnalyticManagerEvent+Profile.swift in Sources */, + 7B5FAA9822BBE3EC00621A44 /* TransferTransactionDomainDTO.swift in Sources */, + 7B5FAA7F22BBE3EC00621A44 /* AliasesRepositoryProtocol.swift in Sources */, + 7B5FAADC22BCEA4200621A44 /* MigrationUseCaseProtocol.swift in Sources */, + 7B5FAA7E22BBE3EC00621A44 /* BlockRepositoryProtocol.swift in Sources */, + 7B5FAA7022BBE3EC00621A44 /* CoinomatRepositoryProtocol.swift in Sources */, + 7B848A7C2301C95A0092AD18 /* PairsPathUseCaseProtocol.swift in Sources */, + 7B5FAA9322BBE3EC00621A44 /* MassTransferTransactionDomainDTO.swift in Sources */, + 7B5FAA8722BBE3EC00621A44 /* CandleDomainDTO.swift in Sources */, + 7B5FAA8822BBE3EC00621A44 /* AssetBalanceDomainDTO.swift in Sources */, + 7B5FAA9A22BBE3EC00621A44 /* ReissueTransactionDomainDTO.swift in Sources */, + 7B5FAA9022BBE3EC00621A44 /* AssetScriptTransactionDomainDTO.swift in Sources */, + 7B5FAA6922BBE3EC00621A44 /* UseCasesFactoryProtocol.swift in Sources */, + 7B5FAA9B22BBE3EC00621A44 /* BurnTransactionDomainDTO.swift in Sources */, + E97A74A722D3BAD400777C39 /* OrderBookUseCase.swift in Sources */, + 7BDC6D5622C3975D00614E6B /* AnalyticManagerEvent+WalletHome.swift in Sources */, + 7B5FAA7922BBE3EC00621A44 /* WalletSeedRepositoryProtocol.swift in Sources */, + 7B5FAA8022BBE3EC00621A44 /* AccountBalanceRepositoryProtocol.swift in Sources */, + 7B5FAA9E22BBE3EC00621A44 /* NotificationNewsDomainDTO.swift in Sources */, + E99A3B7522BE5CEB0070AC76 /* GatewayRepositoryProtocol.swift in Sources */, + 7B5FAA8A22BBE3EC00621A44 /* WalletDomainDTO.swift in Sources */, + 7B5FAA7122BBE3EC00621A44 /* AddressRepositoryProtocol.swift in Sources */, + 7B848A7A2301C0950092AD18 /* WidgetSettingsInizializationUseCase.swift in Sources */, + 7BDC6D4122C3961F00614E6B /* AnalyticManagerEvent+CreateANewAccount.swift in Sources */, + 7BDC6D6B22C397CE00614E6B /* AnalyticManagerEvent+WalletLeasing.swift in Sources */, + 7B5FAAA722BBE3EC00621A44 /* AnalyticManagerProtocol.swift in Sources */, + 7B848A6F230178B70092AD18 /* WidgetSettingsUseCase.swift in Sources */, + 7B431A8122BCFF7100DE73B9 /* AssetsBalanceSettingsUseCaseProtocol.swift in Sources */, + 7B5FAAB922BBE3EC00621A44 /* CleanerWalletManager.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7B6686EA22B7C5120029E6F1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7B97B09822FC784F008BA3F4 /* UICollectionView+Reusable.swift in Sources */, + 7B97B0BA22FD71A8008BA3F4 /* AssetLogo.swift in Sources */, + 7B97B0A022FC784F008BA3F4 /* Decimal+Assisstants.swift in Sources */, + 7B97B09722FC784F008BA3F4 /* SectionDisplayCollection.swift in Sources */, + 7B97B07422FC784F008BA3F4 /* CGFloat+Min.swift in Sources */, + 7B97B07322FC784F008BA3F4 /* ControlEvent+ScrollView.swift in Sources */, + 7B97B09922FC784F008BA3F4 /* Reusable.swift in Sources */, + 7B97B08D22FC784F008BA3F4 /* UIView+Passtrough.swift in Sources */, + 7B97B07222FC784F008BA3F4 /* CALayer+Shadow.swift in Sources */, + 7B97B0A422FC784F008BA3F4 /* RunLoopThreadScheduler.swift in Sources */, + 7B97B09D22FC784F008BA3F4 /* UIView+Animation.swift in Sources */, + 7B97B09B22FC784F008BA3F4 /* NibLoadable.swift in Sources */, + 7B97B09122FC784F008BA3F4 /* CALayer+RoundingCorners.swift in Sources */, + 7B97B09622FC784F008BA3F4 /* ViewCalculate.swift in Sources */, + 7B97B09A22FC784F008BA3F4 /* UITableView+Reusable.swift in Sources */, + 7B97B0A322FC784F008BA3F4 /* TSUD+Rx.swift in Sources */, + 7B97B09F22FC784F008BA3F4 /* Sync.swift in Sources */, + 7B97B0A222FC784F008BA3F4 /* Money.swift in Sources */, + 7B97B09222FC784F008BA3F4 /* TimingFunction.swift in Sources */, + 7B97B08B22FC784F008BA3F4 /* CGSize+Hashable.swift in Sources */, + 7B97B09522FC784F008BA3F4 /* ViewConfiguration.swift in Sources */, + 7B88185F2304279A00AB0549 /* Language.swift in Sources */, + 7B97B07A22FC784F008BA3F4 /* UIColor+Hex.swift in Sources */, + 7B97B08522FC784F008BA3F4 /* UINavigationController+Additionals.swift in Sources */, + 7B97B07822FC784F008BA3F4 /* UIFeedbackGenerator.swift in Sources */, + 7B97B09022FC784F008BA3F4 /* UIScrollView+ContentInset.swift in Sources */, + 7B97B08022FC784F008BA3F4 /* UIApplication+OpenURL.swift in Sources */, + 7B97B07722FC784F008BA3F4 /* UIScrollView+Pagination.swift in Sources */, + 7B97B09E22FC784F008BA3F4 /* MoneyUtil.swift in Sources */, + 7B97B0A522FC784F008BA3F4 /* Mutating.swift in Sources */, + 7B97B08A22FC784F008BA3F4 /* UIViewController+SafeArea.swift in Sources */, + 7B97B07D22FC784F008BA3F4 /* UITableView+Animation.swift in Sources */, + 7B97B09422FC784F008BA3F4 /* ModuleBuilder.swift in Sources */, + 7B97B08C22FC784F008BA3F4 /* UIViewController+Rx.swift in Sources */, + 7B97B08F22FC784F008BA3F4 /* UIView+Shadow.swift in Sources */, + 7B97B0A722FC784F008BA3F4 /* Platform.swift in Sources */, + 7B97B09322FC784F008BA3F4 /* ModuleBuilderOutput.swift in Sources */, + 7B97B08722FC784F008BA3F4 /* UIView+TouchInset.swift in Sources */, + 7B97B07F22FC784F008BA3F4 /* String+Size.swift in Sources */, + 7B97B07622FC784F008BA3F4 /* UIImageView+Rx.swift in Sources */, + 7B97B07B22FC784F008BA3F4 /* UIView+Additionals.swift in Sources */, + 7B97B09C22FC784F008BA3F4 /* NibOwnerLoadable.swift in Sources */, + 7B97B0AD22FCB2BD008BA3F4 /* Reachability+Shared.swift in Sources */, + 7B97B08422FC784F008BA3F4 /* UIView+SafeArea.swift in Sources */, + 7B97B08622FC784F008BA3F4 /* TableViewNoShadow.swift in Sources */, + 7B97B08922FC784F008BA3F4 /* UIImage+Color.swift in Sources */, + 7B97B0A622FC784F008BA3F4 /* System.swift in Sources */, + 7B97B07922FC784F008BA3F4 /* UIColor+Asset.swift in Sources */, + 7B97B07E22FC784F008BA3F4 /* UIFont+Additions.swift in Sources */, + 7B97B08222FC784F008BA3F4 /* UIColor+Colors.swift in Sources */, + 7B881876230590BB00AB0549 /* DeepLink.swift in Sources */, + 7B97B07522FC784F008BA3F4 /* UIButton+WithoutAnimation.swift in Sources */, + 7B97B0B822FCBF56008BA3F4 /* Kingfisher+Rx.swift in Sources */, + 7B97B0A122FC784F008BA3F4 /* Balance.swift in Sources */, + 7B97B07C22FC784F008BA3F4 /* UITableView+HeaderView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7B66871F22B7E68B0029E6F1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E9618D1922F0473000FB7F06 /* MarketPulseTypes.swift in Sources */, + 7BF50AAD22D8B95400582783 /* LastTradesRepositoryRemote.swift in Sources */, + 7BF50A9522D8B95400582783 /* TransferTransaction+Mapper.swift in Sources */, + 7BF50AC322D8B95400582783 /* TimestampSignature.swift in Sources */, + 7BF50A6F22D8B95400582783 /* IssueTransaction.swift in Sources */, + 7BF50A7B22D8B95400582783 /* MassTransferTransaction.swift in Sources */, + 7BF50ABF22D8B95400582783 /* GatewayService.swift in Sources */, + 7BF50ABC22D8B95400582783 /* GitHubService.swift in Sources */, + 7BF50A7822D8B95400582783 /* ExchangeTransaction.swift in Sources */, + 7BF50A6B22D8B95400582783 /* SeedItem.swift in Sources */, + 7BF50A7722D8B95400582783 /* TransferTransaction.swift in Sources */, + 7BF50AB722D8B95400582783 /* AssetsRepositoryLocal.swift in Sources */, + 7BF50ACB22D8B95400582783 /* String+NormalizeAssetId.swift in Sources */, + 7BF50AA122D8B95400582783 /* ApplicationVersionRepository.swift in Sources */, + 7BF50AB022D8B95400582783 /* CandlesRepositoryRemote.swift in Sources */, + 7BF50AA722D8B95400582783 /* TransactionsRepositoryLocal.swift in Sources */, + 7BF50AB422D8B95400582783 /* AliasesRepository.swift in Sources */, + 7BF50ABB22D8B95400582783 /* AssetsSpamService.swift in Sources */, + 7BF50AB922D8B95400582783 /* EnvironmentRepository.swift in Sources */, + 7B848A742301AD0D0092AD18 /* WalletsRealmFactory.swift in Sources */, + 7BF50AAE22D8B95400582783 /* DexOrderBookRepositoryRemote.swift in Sources */, + 7BF50AA422D8B95400582783 /* AuthenticationRepositoryRemote.swift in Sources */, + 7BF50A7D22D8B95400582783 /* DataTransaction.swift in Sources */, + 7BF50A9A22D8B95400582783 /* Wallet+Mapper.swift in Sources */, + 7BF50A8122D8B95400582783 /* AssetBalanceSettings.swift in Sources */, + 7BF50AA922D8B95400582783 /* AddressBookRepository.swift in Sources */, + 7BF50A7622D8B95400582783 /* Transaction.swift in Sources */, + 7BF50AB522D8B95400582783 /* AliasesRepositoryLocal.swift in Sources */, + 7BF50A6E22D8B95400582783 /* ScriptTransaction.swift in Sources */, + 7BF50A6C22D8B95400582783 /* WalletRealmFactory.swift in Sources */, + 7BF50A7922D8B95400582783 /* AliasTransaction.swift in Sources */, + 7BF50AC122D8B95400582783 /* AnalyticManager.swift in Sources */, + 7BF50AAB22D8B95400582783 /* AccountBalanceRepositoryLocal.swift in Sources */, + 7BF50A8422D8B95400582783 /* AccountEnvironment.swift in Sources */, + 7BF50A9322D8B95400582783 /* SponsorshipTransaction+Mapper.swift in Sources */, + 7BF50A7122D8B95400582783 /* UnrecognisedTransaction.swift in Sources */, + 7BF50AC222D8B95400582783 /* TransactionSenderAssistant.swift in Sources */, + 7BF50AB322D8B95400582783 /* WalletSeedRepositoryLocal.swift in Sources */, + 7BF50ABD22D8B95400582783 /* TransactionFeeRulesGitHub.swift in Sources */, + 7BF50A8022D8B95400582783 /* AssetBalance.swift in Sources */, + 7BF50A8D22D8B95400582783 /* AssetScriptTransaction+Mapper.swift in Sources */, + 7BF50A8B22D8B95400582783 /* ReissueTransaction+Mapper.swift in Sources */, + 7BF50A9422D8B95400582783 /* IssueTransaction+Mapper.swift in Sources */, + 7BFB474C22FC5A41002B19F8 /* WidgetSettingsRepositoryStorage.swift in Sources */, + 7BF50A7A22D8B95400582783 /* ReissueTransaction.swift in Sources */, + 7BF50AA322D8B95400582783 /* CoinomatRepository.swift in Sources */, + 7BF50AB222D8B95400582783 /* WalletsRepositoryLocal.swift in Sources */, + 7BF50AB622D8B95400582783 /* AssetsBalanceSettingsRepositoryLocal.swift in Sources */, + 7BF50A9C22D8B95400582783 /* Asset+Mapper.swift in Sources */, + 7BF50AA022D8B95400582783 /* GatewayRepository.swift in Sources */, + 7BF50A9E22D8B95400582783 /* NotificationNewsRepository.swift in Sources */, + 7BF50A7522D8B95400582783 /* BurnTransaction.swift in Sources */, + E98A1A162301A0EF00E7EAAD /* MatcherRepositoryLocal.swift in Sources */, + 7BF50AC422D8B95400582783 /* Signature.swift in Sources */, + 7BF50A7F22D8B95400582783 /* Alias.swift in Sources */, + 7BF50A9622D8B95400582783 /* MassTransferTransaction+Mapper.swift in Sources */, + 7BF50A8C22D8B95400582783 /* InvokeScriptTransaction+Mapper.swift in Sources */, + 7BF50AA822D8B95400582783 /* RepositoriesFactory.swift in Sources */, + 7BF50AAF22D8B95400582783 /* DexRealmRepositoryLocal.swift in Sources */, + 7BF50A9022D8B95400582783 /* ScriptTransaction+Mapper.swift in Sources */, + 7BF50A8522D8B95400582783 /* AccountSettings.swift in Sources */, + 7BF50A9122D8B95400582783 /* LeaseCancelTransaction+Mapper.swift in Sources */, + 7BF50AB122D8B95400582783 /* DexPairsPriceRepositoryRemote.swift in Sources */, + 7BF50A7E22D8B95400582783 /* AddressBook.swift in Sources */, + 7BF50A8622D8B95400582783 /* WalletItem.swift in Sources */, + 7BF50A9722D8B95400582783 /* BurnTransaction+Mapper.swift in Sources */, + 7BF50A8A22D8B95400582783 /* AnyTransaction+Mapper.swift in Sources */, + 7BF50ACC22D8B95400582783 /* SweetLoggerSentry.swift in Sources */, + 7BF50AA622D8B95400582783 /* TransactionsRepositoryRemote.swift in Sources */, + 7BF50A9F22D8B95400582783 /* BlockRepositoryRemote.swift in Sources */, + 7BF50A8E22D8B95400582783 /* AliasTransaction+Mapper.swift in Sources */, + 7BF50A9D22D8B95400582783 /* SpamAssetsRepository.swift in Sources */, + 7BF50A8322D8B95400582783 /* Asset.swift in Sources */, + 7BF50A9B22D8B95400582783 /* AccountSettings+Mapper.swift in Sources */, + 7BF50AA522D8B95400582783 /* AddressRepositoryRemote.swift in Sources */, + 7BF50A7422D8B95400582783 /* InvokeScriptTransaction.swift in Sources */, + 7BF50A9822D8B95400582783 /* ExchangeTransaction+Mapper.swift in Sources */, + 7BF50A8222D8B95400582783 /* DexAssetPair.swift in Sources */, + 7BF50AC622D8B95400582783 /* NodePlugin.swift in Sources */, + 7BF50AC722D8B95400582783 /* MoyaProvider+Helper.swift in Sources */, + 7BF50AC822D8B95400582783 /* SentryNetworkLoggerPlugin.swift in Sources */, + 7BF50A7322D8B95400582783 /* LeaseCancelTransaction.swift in Sources */, + 7B3A9AB4231BE3900025CDCA /* MobileKeeperRepository.swift in Sources */, + 7BF50A9222D8B95400582783 /* DataTransaction+Mapper.swift in Sources */, + 7BF50A8922D8B95400582783 /* DexMyOrders+Mapper.swift in Sources */, + 7BF50ACA22D8B95400582783 /* DatabaseReference+Rx.swift in Sources */, + 7BF50A7222D8B95400582783 /* SponsorshipTransaction.swift in Sources */, + 7BF50AA222D8B95400582783 /* AccountSettingsRepository.swift in Sources */, + 7BF50AC522D8B95400582783 /* Results+Limit.swift in Sources */, + 7BF50A7022D8B95400582783 /* AssetScriptTransaction.swift in Sources */, + 7BF50A9922D8B95400582783 /* LeaseTransaction+Mapper.swift in Sources */, + 7BF50A8722D8B95400582783 /* WalletEncryption.swift in Sources */, + 7BF50A6D22D8B95400582783 /* LeaseTransaction.swift in Sources */, + 7BF50AC922D8B95400582783 /* SentryManager.swift in Sources */, + 7BF50A7C22D8B95400582783 /* AnyTransaction.swift in Sources */, + 7BF50A8F22D8B95400582783 /* UnrecognisedTransaction+Mapper.swift in Sources */, + 7BF50AAA22D8B95400582783 /* AccountBalanceRepositoryRemote.swift in Sources */, + 7BF50AC022D8B95400582783 /* SpamCSV+Assisstants.swift in Sources */, + 7BF50AAC22D8B95400582783 /* MatcherRepositoryRemote.swift in Sources */, + 7BF50AB822D8B95400582783 /* AssetsRepositoryRemote.swift in Sources */, + 7BF50ABA22D8B95400582783 /* SpamService.swift in Sources */, + 7BF50A8822D8B95400582783 /* DexAssetPairDomainDTO+Mapper.swift in Sources */, + 7BF50ABE22D8B95400582783 /* CoinomatService.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7B83A7CC22D8C74E0038180D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7B83A7D522D8C74F0038180D /* ViewController.swift in Sources */, + 7B83A7D322D8C74F0038180D /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7BF89E9222272A5E00853F9D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7BF89E9922272A5E00853F9D /* MonkeyTest.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E9B190A322E7CD99008220B7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E9A3ABBD2319EEB900EB4389 /* MatcherRepositoryLocal.swift in Sources */, + E96DE18A2317FE66005E1FD9 /* WidgetSettingsRepositoryStorage.swift in Sources */, + E92A11702317D1DD004EC6A1 /* WidgetPairPriceData.swift in Sources */, + E92A11642317CE35004EC6A1 /* WidgetPairsPriceDataTarget.swift in Sources */, + E958572122F3BBA0007A0178 /* MarketPulseDataBaseRepository.swift in Sources */, + E991F8FF22E8CFC1008D1AE4 /* MarketPulseWidgetInteractor.swift in Sources */, + 7B848A6B230077550092AD18 /* Images.swift in Sources */, + E958572022F3BBA0007A0178 /* MarketPulseDataBaseRepositoryProtocol.swift in Sources */, + E958571322F2E73D007A0178 /* WidgetSettings.swift in Sources */, + E96DE1862317F07B005E1FD9 /* WidgetAssetsDataTarget.swift in Sources */, + E984BB6D2318461A00D60C38 /* WidgetTransactionsDataTarget.swift in Sources */, + E991F90122E8CFD3008D1AE4 /* MarketPulseWidgetPresenter.swift in Sources */, + E92A11722317D2E9004EC6A1 /* WidgetResponseData.swift in Sources */, + E92A117B2317DD6F004EC6A1 /* WidgetMatcherServiceTypes.swift in Sources */, + E92A117E2317DF4B004EC6A1 /* WidgetSettingsMarcherTarget.swift in Sources */, + E9B190AC22E7CD99008220B7 /* MarketPulseWidgetViewController.swift in Sources */, + E984BB71231935DD00D60C38 /* WidgetPublicKeyMatcherTarget.swift in Sources */, + E984BB6B2318457800D60C38 /* WidgetTransactionsDataService.swift in Sources */, + E92A116B2317CF9A004EC6A1 /* InternalWidgetService.swift in Sources */, + E936C2EA2314BF590097515B /* WidgetSettingsInizialization.swift in Sources */, + E92A116D2317D12F004EC6A1 /* WidgetDataServiceTypes.swift in Sources */, + E92A11832317E7A9004EC6A1 /* WidgetAssetsRepositoryRemote.swift in Sources */, + E96DE1912318076A005E1FD9 /* WidgetAnalyticManager.swift in Sources */, + E92A11812317E10C004EC6A1 /* WidgetMatcherSettingService.swift in Sources */, + E984BB732319367400D60C38 /* WidgetPublicKeyMatcherService.swift in Sources */, + E92A11852317E883004EC6A1 /* WidgetAssetsDataService.swift in Sources */, + E92A11682317CEF6004EC6A1 /* WidgetPairsPriceDataService.swift in Sources */, + E95310B322E8507500F72809 /* MarketPulseWidgetCell.swift in Sources */, + 7B848A69230076AE0092AD18 /* Localizable.swift in Sources */, + E92A11752317D5DB004EC6A1 /* WidgetPairsPriceRepositoryRemote.swift in Sources */, + E92A11772317DB2E004EC6A1 /* WidgetMatcherRepositoryRemote.swift in Sources */, + E984BB6F23184EE100D60C38 /* WidgetTransactionsRepositoryRemote.swift in Sources */, + E95310BC22E85FEE00F72809 /* MarketPulseTypes.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F7E954E01EA8FE0700A804DE /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7B9393F722DF8982006634A6 /* DexCreateOrderInvalidPriceView.swift in Sources */, + E9F78A3F229E990D0065324B /* ScrolledContainerView.swift in Sources */, + E9DF24FA2221EF4D0077F2EB /* AssetDetailTypes.swift in Sources */, + 0A751D38221715F80024D523 /* AppNewsCoordinator.swift in Sources */, + E991BB1C2202CB3C0022E27D /* SendFeeModuleBuilder.swift in Sources */, + E9443012226E64E900EB6257 /* WalletSortInteractor.swift in Sources */, + E991BB202202CE090022E27D /* SendFeeTableViewCell.swift in Sources */, + E9DC959621A3A5BD0020249F /* StartLeasingTypes.swift in Sources */, + E9DB667B21A3938200962639 /* StartLeasingLoadingViewController.swift in Sources */, + E944300E226E645300EB6257 /* WalletSortPresenterProtocol.swift in Sources */, + E95B47F821638B11004D4E39 /* StartLeasingInteractor.swift in Sources */, + E95B47F021638B11004D4E39 /* StartLeasingViewController.swift in Sources */, + 7B49912C22F99B76005B7123 /* AssetsSearchEmptyCell.swift in Sources */, + E9DB667521A3848900962639 /* StartLeasingCancelConfirmationViewController.swift in Sources */, + E95B47F621638B11004D4E39 /* StartLeasingInteractorProtocol.swift in Sources */, + E9DB667321A3846A00962639 /* StartLeasingConfirmationViewController.swift in Sources */, + 7BDA6AD9222D8D0A001DE71C /* TransactionCardSystem.swift in Sources */, + E944300A226E641E00EB6257 /* WalletSortTypes.swift in Sources */, + E95B47EB21638B11004D4E39 /* StartLeasingModuleBuilder.swift in Sources */, + 7B49911A22F874DD005B7123 /* AssetsSearchAssetCell.swift in Sources */, + 044D6C8E21978CED003861A2 /* EditAccountNameModuleBuilder.swift in Sources */, + 044D6C8F21978CED003861A2 /* EditAccountNameViewController.swift in Sources */, + E9FB6E382178265100FA13C1 /* SendInteractor.swift in Sources */, + 0A6F60EA216F893600A5C615 /* WalletTypes.swift in Sources */, + 0ADD6C892167980E00B06917 /* ProfileBiometricCell.swift in Sources */, + 0A14E3E821871B7700EA7E91 /* AliasesHeadCell.swift in Sources */, + 0A9D6B62216E059F006822C5 /* WalletTypes+DisplayState.swift in Sources */, + E9B12DB5219DD6E000128EFE /* AssetBalanceSpamCell.swift in Sources */, + 0A9D6B68216E070E006822C5 /* WalletTypes+State.swift in Sources */, + 7BDA6AF222315024001DE71C /* ContactDetailView.swift in Sources */, + 0ADD803821F22FFB0075FC59 /* BackupCoordinator.swift in Sources */, + E98092A922A85EE700914CF1 /* WalletViewController.swift in Sources */, + 0A6F60E9216F88B200A5C615 /* WalletTypes+ViewModels.swift in Sources */, + 0A6F60EB216F895A00A5C615 /* WalletTypes+DTO.swift in Sources */, + 0A6F60E8216F888B00A5C615 /* DexMyOrdersTypes.swift in Sources */, + 0AF58F902191BC9300C8A4B3 /* PasscodePresenterProtocol.swift in Sources */, + E9D36DF72175C755001E6DF0 /* AssetListInteractor.swift in Sources */, + 7BFB480422FC742F002B19F8 /* UIAlertController+Factory.swift in Sources */, + 04831F7C2169210B006D1ED6 /* PasscodeViewController.swift in Sources */, + E95B47D321638AF2004D4E39 /* AccountPasswordViewController.swift in Sources */, + 7B8818722305639600AB0549 /* ActionSheetHeaderView.swift in Sources */, + 7B5EDEC622536269009C2B3B /* AccessibilityIdentifiers.swift in Sources */, + 0A7CCDB1218A138D005D372B /* MyAddressModuleBuilder.swift in Sources */, + 7BFB481122FC742F002B19F8 /* ModalPresentationAnimator.swift in Sources */, + 04831F76216916EE006D1ED6 /* WalletInteractor.swift in Sources */, + E95E14FF22A07364003552B8 /* WalletDisplayData.swift in Sources */, + E9B12DAD219DCD1800128EFE /* TokenBurnSendInteractor.swift in Sources */, + E96570432193E8570052F0FC /* DexMyOrdersModuleOutput.swift in Sources */, + 0ADD802721F22FFA0075FC59 /* WalletCoordinator.swift in Sources */, + 0ADD802021F22FFA0075FC59 /* Coordinator.swift in Sources */, + 04831F7421691659006D1ED6 /* HistoryTransactionView.swift in Sources */, + E9B387CF23690DCD001FCA60 /* SendCoordinator.swift in Sources */, + E9C0B4A42176C4BE00669D1D /* SendTypes.swift in Sources */, + 0ADD803A21F22FFB0075FC59 /* MainTabBarCoordinator.swift in Sources */, + 0ADD802421F22FFA0075FC59 /* TabBarRouter.swift in Sources */, 7B3902A32237A00300AAFDB8 /* TransactionCardSponsorshipDetailCell.swift in Sources */, E9B087E62163886800937644 /* DexCreateOrderAmountButton.swift in Sources */, - E901CE592149D27000942783 /* ExchangeTransaction.swift in Sources */, E9F78A3D229E98B40065324B /* NewSegmentedControl.swift in Sources */, - E910B7E921C3261B00E402AB /* CoinomatRepository.swift in Sources */, 7BDA6ADB222D8D16001DE71C /* TransactionCardType.swift in Sources */, - 0A3AD40721492E9400F8A929 /* ExchangeApiFilters.swift in Sources */, E9B086BB2163883000937644 /* AddressBookViewController.swift in Sources */, - 0A1DAD6D20F39F94004DA625 /* NodeServiceTypes.swift in Sources */, 0AACD5AB21A6CAC800B30815 /* SweetSnackBack+Factory.swift in Sources */, E9B087AA2163886800937644 /* DexOrderBookPresenter.swift in Sources */, 0AF58F9B2191D6D000C8A4B3 /* PasscodeChangePasscodeByPasswordPresenter.swift in Sources */, - E967786921EC491600CE56D6 /* CandlesRepositoryRemote.swift in Sources */, + 7B97B0A822FC78EA008BA3F4 /* DateFormatter+UI.swift in Sources */, 0ADD801F21F22FFA0075FC59 /* RoutingCoordinator.swift in Sources */, - 0A2B7D3B216038F80098438D /* AssetsSpamService.swift in Sources */, + 7BFB481322FC742F002B19F8 /* ModalTableView.swift in Sources */, 0A7CCDAD218A138D005D372B /* MyAddressTypes.swift in Sources */, - 0A4E7DEE22018C5F007BBA39 /* ModalPresentationAnimator.swift in Sources */, - 0A3FE8AE2136E51900DBF4E1 /* TransactionContainersNode.swift in Sources */, 7B5EDEC222522837009C2B3B /* TransactionCardSystemOrder+Mapper.swift in Sources */, - 0A3FE8AC2136AF4B00DBF4E1 /* TransactionsRepositoryProtocol.swift in Sources */, E9B087E22163886800937644 /* DexCreateOrderModuleBuilder.swift in Sources */, - 0A6AC3E8218489F5005D2525 /* AliasDomainDTO.swift in Sources */, - 0ADD7FB321F22FB60075FC59 /* TimingFunction.swift in Sources */, - E944AA74224465BE0009F494 /* AnalyticManager.swift in Sources */, - 0A5E4BD92138297000E3C3C3 /* TransactionsRepositoryRemote.swift in Sources */, E9D36DF32175C755001E6DF0 /* AssetListPresenter.swift in Sources */, E965702321935F2F0052F0FC /* DexCreateOrderInteractor.swift in Sources */, - 0A5C53E52139609600667E34 /* TransactionsRepositoryLocal.swift in Sources */, - 0A98D14C2138A30700550FE0 /* AnyTransaction+Mapper.swift in Sources */, - 0ABD1BED2146C2760027A7A2 /* BlocksNodeService.swift in Sources */, - 0ABD1BEC2146BFEE0027A7A2 /* BlockNode.swift in Sources */, - 0ADD7FBF21F22FB60075FC59 /* NSAttributedString+Styles.swift in Sources */, - 0A751D36221711380024D523 /* NotificationNewsRepository.swift in Sources */, E9B087CC2163886800937644 /* DexListPresenterProtocol.swift in Sources */, + 7BFB480622FC742F002B19F8 /* BiometricType.swift in Sources */, 0ADD6C832167948500B06917 /* ProfileHeaderView.swift in Sources */, 0ACC0233217E2BA1000E3EE0 /* DynamicHeaderTableView.swift in Sources */, 0A7CCDB2218A138D005D372B /* MyAddressAliacesSkeletonCell.swift in Sources */, - 0A762DA22163AD1A0019D447 /* SupportViewController.swift in Sources */, - 0AAC2A442146C40A00F6EB27 /* TransactionsInteractor.swift in Sources */, E9B0880D2163886800937644 /* DexMarketPresenterProtocol.swift in Sources */, E9B086BC2163883000937644 /* AddressBookInteractorProtocol.swift in Sources */, 04831F6421691429006D1ED6 /* SuccessSystemMessageView.swift in Sources */, - 0ADD7FA821F22FB60075FC59 /* UIImage+Color.swift in Sources */, + 7B9B326122E6004700DB1C59 /* DebugRootView.swift in Sources */, E9B087CE2163886800937644 /* DexListTypes.swift in Sources */, - 0A751D3222170EF60024D523 /* NotificationNewsRepositoryProtocol.swift in Sources */, 0A5933162183604F0059A77A /* AddressesKeysPresenter.swift in Sources */, - 0ADD804221F71FDA0075FC59 /* ScriptTransactionNode.swift in Sources */, 0ADD803621F22FFB0075FC59 /* PasscodeLogInCoordinator.swift in Sources */, E9D36DEF2175C755001E6DF0 /* ReceiveInvoiceInteractor.swift in Sources */, - 0A5C53DD2139491C00667E34 /* UnrecognisedTransactionNode.swift in Sources */, - 0A5C53E121394A2B00667E34 /* UnrecognisedTransaction+Mapper.swift in Sources */, 04A403222164D80200652F21 /* EnterStartTypes.swift in Sources */, 7B3902AD2237D31900AAFDB8 /* TransactionCardShowAllCell.swift in Sources */, E9B0879F2163886800937644 /* DexChartCandlePriceView.swift in Sources */, - 0A3FE8BD2137007500DBF4E1 /* ExchangeTransactionNode.swift in Sources */, - 0ADD7FF121F22FB60075FC59 /* SectionDisplayCollection.swift in Sources */, - 7B951121225CD6790030390C /* Language.swift in Sources */, - 0ADD7FEB21F22FB60075FC59 /* SkeletonAnimatable.swift in Sources */, - E922D25F21B81BE800575955 /* CandleDomainDTO.swift in Sources */, - 0A3FE8BC2137007500DBF4E1 /* BurnTransactionNode.swift in Sources */, E9D36DCD2175C755001E6DF0 /* ReceiveCryptocurrencyInteractorProtocol.swift in Sources */, 0ADD7FAB21F22FB60075FC59 /* PasteboardButton.swift in Sources */, - E99DD81D21CEF09C0091AFEC /* CandleApiFilters.swift in Sources */, E9D36DE02175C755001E6DF0 /* ReceiveAddressViewController.swift in Sources */, 0A96F1DA2152CDB7005E148F /* PasscodeTypes.swift in Sources */, - 0AEB35A021165CBF00EDD63C /* AssetBalanceDomainDTO.swift in Sources */, E9B087C92163886800937644 /* DexTraderContainerSegmentedControl.swift in Sources */, - 0A5E4BB721380B3300E3C3C3 /* BurnTransaction.swift in Sources */, E9B087BC2163886800937644 /* DexInfoViewController.swift in Sources */, - 0A3FE8BF2137007500DBF4E1 /* AliasTransactionNode.swift in Sources */, 0A762DAA21661AC40019D447 /* ProfileModuleBuilder.swift in Sources */, 0A071E7E215DB158007D9750 /* ChooseAccountPresenter.swift in Sources */, - 0A5E4BE721383E1600E3C3C3 /* BurnTransaction+Mapper.swift in Sources */, E9D36DD82175C755001E6DF0 /* ReceiveCardInteractor.swift in Sources */, - 0A5E4BB32138046E00E3C3C3 /* AliasTransaction.swift in Sources */, - 0ADD7F9A21F22FB60075FC59 /* UIFont+Additions.swift in Sources */, - 0A3FE8BE2137007500DBF4E1 /* LeaseCancelTransactionNode.swift in Sources */, 0A4E71962216E98200A46613 /* SendFeeIndicatorCell.swift in Sources */, - 0A5E4BB12138034500E3C3C3 /* LeaseCancelTransaction.swift in Sources */, - 0A485EA02100B0BD00079B49 /* LeaseTransaction.swift in Sources */, - 0A84F00121F4BBA000C0B7DB /* AddressRepositoryProtocol.swift in Sources */, - 0A88CC08217D281F0083874C /* AccountEnvironmentRepository.swift in Sources */, - 0ADD7FA721F22FB60075FC59 /* ActivityIndicator+Rx.swift in Sources */, - 0A218B8B2155335F00B989A1 /* WalletSeedRepositoryProtocol.swift in Sources */, - E96E29FE21D3492F00AC2FA9 /* MatcherService.swift in Sources */, + 7B3681AB231555B8000D5592 /* ConfirmRequestKeyValueCell.swift in Sources */, E9B087BE2163886800937644 /* SearchBarView.swift in Sources */, + 7BFB481B22FC742F002B19F8 /* NewUserWithoutBackupStorageTrack.swift in Sources */, + 7B88186F2305639600AB0549 /* ActionSheet.swift in Sources */, 04831F87216A363F006D1ED6 /* LanguageTableCell.swift in Sources */, - 0ADD7F9121F22FB60075FC59 /* UIButton+WithoutAnimation.swift in Sources */, E9B087CD2163886800937644 /* DexListPresenter.swift in Sources */, - 0A5E4BE32138395200E3C3C3 /* AliasTransaction+Mapper.swift in Sources */, - 7B601B2A2240C4B80040975C /* SmartTransactionDTO+EncodingToString.swift in Sources */, - 0A3FE8BA2137007500DBF4E1 /* LeaseTransactionNode.swift in Sources */, - E94A6E9F215AD53E001814F7 /* ContactDomainDTO.swift in Sources */, - E97D451221C817CC000E3C48 /* DexOrderBookRepositoryRemote.swift in Sources */, - 0ADD7FF021F22FB60075FC59 /* ViewCalculate.swift in Sources */, - 0A3FE8B92137007500DBF4E1 /* ReissueTransactionNode.swift in Sources */, - 0AF0C67221A97C4700602197 /* AliasesInteractor.swift in Sources */, - 0A5E4BE12138378500E3C3C3 /* LeaseCancelTransaction+Mapper.swift in Sources */, - 0A5E4BAF213801C400E3C3C3 /* ReissueTransaction.swift in Sources */, - 0A5E4BDF213832A000E3C3C3 /* ReissueTransaction+Mapper.swift in Sources */, + 7B88186E2305639600AB0549 /* ActionSheetViewController.swift in Sources */, 0ADD803521F22FFB0075FC59 /* PasscodeCoordinator.swift in Sources */, - 0A3FE8C02137007500DBF4E1 /* DataTransactionNode.swift in Sources */, E9310D1D217942C8008BF3EE /* BlueBgView.swift in Sources */, - 0AEB358F2115DFF500EDD63C /* AssetDomainDTO.swift in Sources */, 7B3902A52237A5A900AAFDB8 /* TransactionCardDashedLineCell.swift in Sources */, 0A14E3EC21871BA300EA7E91 /* AliasesInfoView.swift in Sources */, E9D36DF92175C755001E6DF0 /* AssetListModuleOutput.swift in Sources */, 0A7CCDB4218A138D005D372B /* MyAddressAliacesCell.swift in Sources */, + 7BFB480022FC742F002B19F8 /* SmartTransactionDTO+EncodingToString.swift in Sources */, + 7BE09AB22313E31300A038AD /* MobileKeeperCoordinator.swift in Sources */, E991BB1A2202CA250022E27D /* SendFeeViewController.swift in Sources */, 0AF92201212E07B3003BA067 /* AssetHeaderSkeletonView.swift in Sources */, - E94A7007215AEB0E001814F7 /* AddressBookRepository.swift in Sources */, + 7B3A9AB6231D66B80025CDCA /* NetworkError+Title.swift in Sources */, E95B6B0F219C22E400A85B5D /* TokenBurnConfirmationViewController.swift in Sources */, 0A14E3E62187185700EA7E91 /* AliasesViewModuleBuilder.swift in Sources */, 7BDA6ADD222E95C8001DE71C /* TransactionCardView.swift in Sources */, - 7BBDA0B62226CA5C00A83411 /* NodePlugin.swift in Sources */, - 7BAA9F7D22A03329003B6D01 /* ApplicationVersionRepository.swift in Sources */, 0AF921F5212E07B3003BA067 /* AssetDetailCell.swift in Sources */, E9B087EE2163886800937644 /* DexLastTradesPresenter.swift in Sources */, E9D36DDC2175C755001E6DF0 /* ReceiveCardCompleteViewController.swift in Sources */, E9B086B92163883000937644 /* AddressBookTypes.swift in Sources */, - E991BB15220189530022E27D /* AliasApiService.swift in Sources */, - 0A7E0CD120F2AF6C0010CA6C /* BaseTargetType.swift in Sources */, 0AF92300212E1234003BA067 /* NavigationAccessoryView.swift in Sources */, - E97D450B21C802AB000E3C48 /* DexPairsPriceRepositoryRemote.swift in Sources */, + 7BFB480D22FC742F002B19F8 /* QRCodeReader+Factory.swift in Sources */, E9B087CA2163886800937644 /* DexListModuleOutput.swift in Sources */, E9B086B12163883000937644 /* AddAddressTextField.swift in Sources */, 0AF9222F212E0F1F003BA067 /* WalletAssetSkeletonCell.swift in Sources */, E9B088112163886800937644 /* DexMarketTypes.swift in Sources */, E9B0881E2163886800937644 /* DexSortInteractor.swift in Sources */, - E94A7004215AEA4A001814F7 /* AddressBookRepositoryProtocol.swift in Sources */, + 7BFB481822FC742F002B19F8 /* BiometricManager+String.swift in Sources */, 0AFF5C7D215BD08500B82940 /* AccountPasswordTypes.swift in Sources */, - E96E2A0221D34AA200AC2FA9 /* MatcherRepositoryRemote.swift in Sources */, 0A20606821822C3A0048CF83 /* AddressesKeysViewController.swift in Sources */, - 0ADD7FEC21F22FB60075FC59 /* ModuleBuilderOutput.swift in Sources */, E9DF24F62221ED640077F2EB /* AssetDetailInteractor.swift in Sources */, E9B0881B2163886800937644 /* DexSortModuleBuilder.swift in Sources */, - 0ADD7FB121F22FB60075FC59 /* UIScrollView+ContentInset.swift in Sources */, - 0ADD7F9521F22FB60075FC59 /* UIColor+Asset.swift in Sources */, E9B087FE2163886800937644 /* DexMyOrdersCell.swift in Sources */, E9939B4522302E3800B50E67 /* InfoPageConfirmView.swift in Sources */, E944300C226E643B00EB6257 /* WalletSortModuleBuilder.swift in Sources */, - 0A7E0CD920F2BCFF0010CA6C /* TransactionsApiService.swift in Sources */, 0A59331B21870B130059A77A /* AliasesTypes.swift in Sources */, 0AF58F992191CCA200C8A4B3 /* PasscodeVerifyAccessPresenter.swift in Sources */, - E97D450D21C8127F000E3C48 /* DexOrderBookRepositoryProtocol.swift in Sources */, - 0AD8360E217DD34B004413E9 /* AccountSettings+Mapper.swift in Sources */, - 0ADD7FAE21F22FB60075FC59 /* UIView+Passtrough.swift in Sources */, E9B0881C2163886800937644 /* DexSortTypes.swift in Sources */, E95B47C221638A9F004D4E39 /* HelloLanguagesViewController.swift in Sources */, E95B47CD21638A9F004D4E39 /* ShortInfoPageView.swift in Sources */, 0A96F1D82152CC09005E148F /* NewAccountTypes.swift in Sources */, + E9C1B910236C6DA900F8E988 /* ForceUpdateAppViewController.swift in Sources */, 0A3FE8AA2135AE4000DBF4E1 /* AssetTransactionCell.swift in Sources */, 0AF922EB212E1234003BA067 /* DottedLineView.swift in Sources */, E9B087A82163886800937644 /* DexOrderBookViewController.swift in Sources */, - 0AF2536521B6C2F900B8F7DF /* AssetsBalanceSettingsRepositoryLocal.swift in Sources */, E9B088002163886800937644 /* DexMyOrdersInteractorProtocol.swift in Sources */, E95E151222A18C25003552B8 /* WalletSearchTableViewCell.swift in Sources */, E9F69B9822A522E400CDBD00 /* WalletSearchPresenter.swift in Sources */, @@ -5649,48 +7339,45 @@ E95E151522A197B8003552B8 /* WalletSearchViewController.swift in Sources */, E9B0881A2163886800937644 /* DexSortPresenterProtocol.swift in Sources */, 0AED6BBA216620F000481B42 /* ProfileTypes.swift in Sources */, - 0A5C919A20F3DB4C00443CE6 /* AccountAssetsBalanceNode.swift in Sources */, + E9845D3B2374645900716515 /* PushNotificationsCoordinator.swift in Sources */, 0A5D32F9215461E90009CDF3 /* ImportTypes.swift in Sources */, 0AF921F6212E07B3003BA067 /* AssetBalanceCell.swift in Sources */, 0AAB15C321655BDB00F1F7BC /* ProfileInfoCell.swift in Sources */, - 0A57C39021F74EB0003B5386 /* ScriptTransaction.swift in Sources */, E9B087B22163886800937644 /* DexOrderBookInteractorProtocol.swift in Sources */, E9B087DC2163886800937644 /* DexCreateOrderModuleOutput.swift in Sources */, - 0A88CC02217D217D0083874C /* SpamCSV+Assisstants.swift in Sources */, + E98F0589236B1CCF0055DCCE /* DexDeepLinkLoadingViewController.swift in Sources */, E9FE4D7A20EA7F8500208F29 /* ConfirmBackupViewController.swift in Sources */, E9D36DE62175C755001E6DF0 /* ReceiveGenerateTypes.swift in Sources */, - 0A4D221E21809E3600155A8E /* AccountEnvironmentDomainDTO.swift in Sources */, - E9F9A27C21853E7D00FD68D7 /* DexRealmRepositoryProtocol.swift in Sources */, + 7BFB481722FC742F002B19F8 /* NSAttributedString+Styles.swift in Sources */, E9B088062163886800937644 /* DexCompleteOrderViewController.swift in Sources */, - E9740E5E21D1C90F00EAD3ED /* PairsPriceApiService.swift in Sources */, 048684F521258B0B00D12189 /* HistoryHeaderView.swift in Sources */, E9B086BA2163883000937644 /* AddressBookCell.swift in Sources */, - 0ADD7F8F21F22FB60075FC59 /* CALayer+Shadow.swift in Sources */, + 7BFB480E22FC742F002B19F8 /* MailCompose+Support.swift in Sources */, 0A6AC3E021847F8D005D2525 /* AddressesKeysModuleBuilder.swift in Sources */, E9443014226E64F600EB6257 /* WalletSortInteractorProtocol.swift in Sources */, 0A97975C210888B600407F67 /* Localizable.swift in Sources */, + 7BD6E10522E5AE0200BAAFC8 /* DebugHeaderView.swift in Sources */, 0AF58F9F2192056400C8A4B3 /* PasscodeChangePasswordPresenter.swift in Sources */, 0AF922ED212E1234003BA067 /* AssetsSegmentedControl.swift in Sources */, - E922D26421B82C2100575955 /* CandlesRepositoryProtocol.swift in Sources */, E9CBE6C22094C0E7008C8F44 /* MenuViewController.swift in Sources */, 0AF922FE212E1234003BA067 /* GradientView.swift in Sources */, 0AF922F3212E1234003BA067 /* SeparatorView.swift in Sources */, E9B0881D2163886800937644 /* DexSortCell.swift in Sources */, 7BDA6AE822313E59001DE71C /* TransactionImageView.swift in Sources */, 0A7CCDB3218A138D005D372B /* MyAddressQRCodeCell.swift in Sources */, + 7B36819D23142639000D5592 /* ConfirmRequestSystem.swift in Sources */, + 7B8818602304474E00AB0549 /* AuthorizationInteractorLocalizableImp.swift in Sources */, 0A96F1DF21544331005E148F /* MultyTextField.swift in Sources */, + 7BFB480722FC742F002B19F8 /* UITableView+Skeleton.swift in Sources */, 04831086211967D600509CED /* HistoryModuleOutput.swift in Sources */, - 0ADD7F9D21F22FB60075FC59 /* UIResponder+Rx.swift in Sources */, 0AF922FC212E1234003BA067 /* CenteringContentButton.swift in Sources */, E9DF24F82221EE180077F2EB /* AssetDetailPresenter.swift in Sources */, E9310D1921792D01008BF3EE /* SendConfirmationRecipientView.swift in Sources */, - 0A485E9E2100AE9B00079B49 /* IssueTransaction.swift in Sources */, E9B087D02163886800937644 /* DexListCell.swift in Sources */, - E9A380AD21D3035B004377A6 /* OrderMatcher.swift in Sources */, E9D36DCA2175C755001E6DF0 /* ReceiveCryptocurrencyPresenterProtocol.swift in Sources */, - 0A4E7DED22018C5F007BBA39 /* ModalViewControllerTransitioning.swift in Sources */, E9B088072163886800937644 /* DexCompleteOrderModuleBuilder.swift in Sources */, E9B086B22163883000937644 /* AddAddressBookModuleOutput.swift in Sources */, + 7B65B6F322F9D03E007D5C53 /* WidgetSettingsSkeletonCell.swift in Sources */, E9D36DF82175C755001E6DF0 /* AssetListInteractorProtocol.swift in Sources */, E9B087F22163886800937644 /* DexLastTradesCell.swift in Sources */, 0AF9222B212E0F1F003BA067 /* WalletLeasingCell.swift in Sources */, @@ -5705,26 +7392,19 @@ E980EACE20A9F5BF001834DB /* ScannerCustomView.swift in Sources */, 0A4508F82177970F00EBF669 /* AlertDeleteAccountViewController.swift in Sources */, 0AAB15C921655C1800F1F7BC /* ProfileValueCell.swift in Sources */, - E9419CCB21CFAD76004DACCA /* MarketMatcher.swift in Sources */, - 7BDA6AF02231405D001DE71C /* SmartTransactionKind+UIImage.swift in Sources */, E92703C6226FDD0C0022D5F0 /* WalletSortPresenter.swift in Sources */, E9B087DE2163886800937644 /* DexCreateOrderViewController.swift in Sources */, 0A14E3F721875F5600EA7E91 /* CreateAliasInputCell.swift in Sources */, E95B6B13219C345B00A85B5D /* TokenBurnConfirmationIDView.swift in Sources */, 0A7CCDAC218A138D005D372B /* MyAddressPresenter.swift in Sources */, - 0AEB358C2115DB3C00EDD63C /* AssetsRepositoryProtocol.swift in Sources */, E983665E21F5972300178A8A /* TransactionScriptErrorView.swift in Sources */, - E90223C421D53A8F0057AA45 /* DexAssetPairDomainDTO+Mapper.swift in Sources */, + 7B26A89022EEECC200E7B024 /* WidgetSettingsAssetCell.swift in Sources */, E9B087962163886800937644 /* DexChartTypes.swift in Sources */, 04E1C35A2126B21A00C702BA /* HistoryTransactionSkeletonCell.swift in Sources */, - 0A3FE8B82137007500DBF4E1 /* TransferTransactionNode.swift in Sources */, 0AD83612217DDD94004413E9 /* NetworkSettingsTypes.swift in Sources */, 0AF922EE212E1234003BA067 /* AssetsSegmentedCell.swift in Sources */, - 0ADD803E21F5B7090075FC59 /* AssetDetailNode.swift in Sources */, - 0A344E2F2194747E007809B1 /* MigrationInteractor.swift in Sources */, E938356F20A472B4001A2509 /* HistoryTransactionCell.swift in Sources */, E991BB2E2202DD420022E27D /* SendFeeHeaderView.swift in Sources */, - E910B7EC21C3266F00E402AB /* CoinomatDomainDTO.swift in Sources */, 04016E0221949A8400BA5235 /* ImportAccountManuallyViewController.swift in Sources */, E920372B21A5F4C10055E4D8 /* StartLeasingConfirmModuleBuilder.swift in Sources */, 0AF922F6212E1234003BA067 /* SegmentedControl.swift in Sources */, @@ -5732,22 +7412,16 @@ E96FEA29226F27BC00C0EE22 /* WalletSortCell.swift in Sources */, 0A59331821870ABB0059A77A /* AliasesViewController.swift in Sources */, 0A14E3EF21875AF500EA7E91 /* CreateAliasViewController.swift in Sources */, - 0A5B6E6F211A2B6D005A7F09 /* TransactionNodeService.swift in Sources */, - E944AA78224467570009F494 /* AnalyticManager+WalletAsset.swift in Sources */, E9C8F94D20F66D64004C438A /* ConfirmBackupStackBaseView.swift in Sources */, - 7B951131225CDA880030390C /* Sync.swift in Sources */, 0ADD803021F22FFB0075FC59 /* QRCodeReaderControllerCoordinator.swift in Sources */, - 0ADD7FF421F22FB60075FC59 /* UITableView+Reusable.swift in Sources */, 0AD63240217633C20047D467 /* ChangePasswordModuleBuilder.swift in Sources */, - 0A5E4BE921383F3D00E3C3C3 /* ExchangeTransaction+Mapper.swift in Sources */, 0AF58F942191C1D300C8A4B3 /* PasscodeRegistationPresenter.swift in Sources */, E9B087E52163886800937644 /* DexCreateOrderInputView.swift in Sources */, - F74240B81EAB8D1600C3B84D /* Transaction.swift in Sources */, - 0A071E43215B0A1B007D9750 /* SigningWalletsProtocol.swift in Sources */, 0ADD802221F22FFA0075FC59 /* WindowRouter.swift in Sources */, E95B6B0A219B3B0100A85B5D /* TokenBurnViewController.swift in Sources */, 0A14E3E42187184000EA7E91 /* AliasesPresenterProtocol.swift in Sources */, - 0AFB59422209B2BD001F0DD8 /* SponsorshipTransactionNode.swift in Sources */, + 7B0FD98B23196C430004B52B /* ConfirmRequestDTORequest+Mapper.swift in Sources */, + 7B3681A123142A33000D5592 /* ConfirmRequestModuleOutput.swift in Sources */, 0AF92205212E07B3003BA067 /* WrapperAssetsSegmentedControl.swift in Sources */, E9D36DC72175C755001E6DF0 /* ReceiveCryptocurrencyTypes.swift in Sources */, E95B47F221638B11004D4E39 /* AmountInputView.swift in Sources */, @@ -5756,240 +7430,179 @@ E9236F212216F48A00A12FD5 /* PopupActionView.swift in Sources */, E9B087F02163886800937644 /* DexLastTradesViewController.swift in Sources */, E9B087C72163886800937644 /* DexTraderContainerBaseHeaderView.swift in Sources */, - E97D450921C80233000E3C48 /* DexPairsPriceRepositoryProtocol.swift in Sources */, - 0ABD1BE821469D2F0027A7A2 /* AddressDomainDTO.swift in Sources */, E9B087FB2163886800937644 /* DexMyOrdersModuleBuilder.swift in Sources */, 0AE491F82107A52E009223DB /* WalletPresenterProtocol.swift in Sources */, - 0A57C38C21F74E21003B5386 /* ScriptTransaction+Mapper.swift in Sources */, 0A071E77215DB07C007D9750 /* ChooseAccountTypes.swift in Sources */, 0AF921FE212E07B3003BA067 /* AssetTransactionSkeletonCell.swift in Sources */, E9EC5BAD2175F35900E5C29A /* SendModuleBuilder.swift in Sources */, E9157BEE21A4C081009F99B6 /* StartLeasingCompleteViewController.swift in Sources */, - 0A3FE8C121370B1100DBF4E1 /* IssueTransactionNode.swift in Sources */, E9B087F32163886800937644 /* DexLastTradesHeaderView.swift in Sources */, 04EB742A2113415E004A065B /* HistoryTypes+State.swift in Sources */, E991BB262202D58C0022E27D /* SendFeePresenter.swift in Sources */, - 0ADD7F9021F22FB60075FC59 /* ControlEvent+ScrollView.swift in Sources */, E9B087F92163886800937644 /* DexMyOrdersPresenterProtocol.swift in Sources */, - 0A4C9AA320EE65910095A417 /* SeedItem.swift in Sources */, 0AF922F0212E1234003BA067 /* SkeletonTableHeaderFooterView.swift in Sources */, + 7BD6E10222E50EB200BAAFC8 /* DebugViewController.swift in Sources */, + 7B26A88C22ED191900E7B024 /* WidgetSettingsModuleBuilder.swift in Sources */, + 7B26A88322ED14DA00E7B024 /* WidgetSettingsSystem.swift in Sources */, 048310842119675300509CED /* HistoryModuleBuilder.swift in Sources */, + 7BD6E0FE22E228DC00BAAFC8 /* DebugView.swift in Sources */, 0AF922E5212E1234003BA067 /* HalfModalTransitionAnimator.swift in Sources */, E9B087A92163886800937644 /* DexOrderBookPresenterProtocol.swift in Sources */, E9B087E42163886800937644 /* DexCreateOrderSegmentedControl.swift in Sources */, 04016E00219499DA00BA5235 /* ImportAccountScanViewController.swift in Sources */, - 0A3FE8BB2137007500DBF4E1 /* MassTransferTransactionNode.swift in Sources */, 0AF922E3212E1234003BA067 /* HalfModalPresentationController.swift in Sources */, - 0A485E8720FF570000079B49 /* AssetBalanceSettings.swift in Sources */, E9D36DD32175C755001E6DF0 /* ReceiveCardPresenter.swift in Sources */, - 0A1DAD7320F3A12B004DA625 /* AssetsNodeService.swift in Sources */, + E9239571237518B7009C4091 /* PushNotificationsAlertView.swift in Sources */, E9C8F94B20F66A05004C438A /* ConfirmBackupStackListView.swift in Sources */, - 0AFB59462209C20E001F0DD8 /* SponsorshipTransaction+Mapper.swift in Sources */, - 7B951118225CD5850030390C /* DatabaseReference+Rx.swift in Sources */, E9A4812F20D8DDBB00272C6D /* ChangePasswordViewController.swift in Sources */, - E9C1F5C6224D60B1006DBD8E /* ApplicationDebugSettings.swift in Sources */, 0A6AC3D921839F4E005D2525 /* AddressesKeysValueCell.swift in Sources */, F7E954E81EA8FE0700A804DE /* AppDelegate.swift in Sources */, 0A96F1D12151B6B5005E148F /* PasscodeNumberButton.swift in Sources */, - E9F9A279218535A200FD68D7 /* DexAssetPair.swift in Sources */, E9B087EB2163886800937644 /* DexLastTradesModuleOutput.swift in Sources */, - 0A84F00321F4C68000C0B7DB /* TransactionFeeRulesGitHub.swift in Sources */, E9B0879B2163886800937644 /* DexChartAxisFormatters.swift in Sources */, E9B087C42163886800937644 /* DexTraderContainerModuleBuilder.swift in Sources */, E991BB2A2202D5E00022E27D /* SendFeeInteractorProtocol.swift in Sources */, + 7B8818782305926E00AB0549 /* WidgetSettingsCoordinator.swift in Sources */, 0A762D9721639FCC0019D447 /* WavesButton.swift in Sources */, E95E150F22A18B67003552B8 /* CustomNavigationBar.swift in Sources */, - 0AF0C67421A97D3500602197 /* AliasesRepositoryLocal.swift in Sources */, E9D36DF62175C755001E6DF0 /* AssetListTableViewCell.swift in Sources */, - 0AEB35A421165E1300EDD63C /* AccountBalanceRepositoryRemote.swift in Sources */, - E94E4E6921CF9F6D00053A49 /* CoinomatService.swift in Sources */, E9B087CF2163886800937644 /* DexListHeaderCell.swift in Sources */, 0AFB59402209AD56001F0DD8 /* TestViewController.swift in Sources */, - 7B951130225CDA880030390C /* MoneyUtil.swift in Sources */, E9B087A72163886800937644 /* DexOrderBookTypes.swift in Sources */, E9642C8F21CB32570065A1BD /* CoinomatServiceErrorView.swift in Sources */, E9B087B32163886800937644 /* DexOrderBookInteractor.swift in Sources */, - 0ADD7FEE21F22FB60075FC59 /* ViewConfiguration.swift in Sources */, E9F69B9C22A5333500CDBD00 /* WalletSearchHeaderCell.swift in Sources */, E9543902217FF9EC001A7860 /* SendCompleteViewController.swift in Sources */, - 0A485E9A2100A8ED00079B49 /* TransferTransaction.swift in Sources */, E9B087D52163886800937644 /* DexListInteractorProtocol.swift in Sources */, E9B087D22163886800937644 /* DexListViewController.swift in Sources */, + 7B2408002317F26100D35F59 /* ConfirmRequestButtonsCell.swift in Sources */, + 7BFB480222FC742F002B19F8 /* AssetsRepositoryMock.swift in Sources */, E9CD0D32218137FE001A99B3 /* MainTabBarController.swift in Sources */, - 0A218B95215556F600B989A1 /* AuthenticationRepositoryProtocol.swift in Sources */, - 0A218B892155221F00B989A1 /* Wallet+Mapper.swift in Sources */, 0ADD803921F22FFB0075FC59 /* BackupTostCoordinator.swift in Sources */, E9B087E12163886800937644 /* DexCreateOrderTypes.swift in Sources */, - E98D14D12266B25500BE5481 /* CleanerWalletManager.swift in Sources */, - E9DDF73D2240F58900B83CFD /* UtilsNode.swift in Sources */, - 0A218B8E215534E000B989A1 /* WalletSeedRepositoryLocal.swift in Sources */, E9B08822216388B100937644 /* HighlightedButton.swift in Sources */, E9B087C52163886800937644 /* DexTraderContainerInputProtocol.swift in Sources */, 0AF922F1212E1234003BA067 /* SkeletonTableCell.swift in Sources */, 04D882BF21706FEF00EAAB90 /* InfoPagesCell.swift in Sources */, E9F984AB20E52D8E00D2CB4D /* EnterStartViewController.swift in Sources */, E9B087AF2163886800937644 /* DexOrderBookHeaderView.swift in Sources */, - 0ADD7FF621F22FB60075FC59 /* NibOwnerLoadable.swift in Sources */, E9B087982163886800937644 /* DexChartPresenterProtocol.swift in Sources */, E9D36DC92175C755001E6DF0 /* ReceiveCryptocurrencyModuleBuilder.swift in Sources */, E9B087AE2163886800937644 /* DexOrderBookCell.swift in Sources */, 0A7CCDAE218A138D005D372B /* MyAddressViewController.swift in Sources */, - E9EE476D225E91ED0005176A /* InvokeScriptTransaction.swift in Sources */, - 7B95112F225CDA880030390C /* Money.swift in Sources */, 0AFF5C8D215CE2D000B82940 /* UseTouchIDModuleBuilder.swift in Sources */, 0AF921F3212E07B3003BA067 /* AssetEmptyHistoryCell.swift in Sources */, 0AF0C67B21AACA4F00602197 /* GlobalErrorView.swift in Sources */, E9BB2D852260DEB000366278 /* TransactionCardInvokeScriptCell.swift in Sources */, E9D36DD62175C755001E6DF0 /* ReceiveCardModuleBuilder.swift in Sources */, 0A14E3F121875B1300EA7E91 /* CreateAliasPresenter.swift in Sources */, - 0A4C9AA120EE65800095A417 /* WalletItem.swift in Sources */, - 0ADD7F9421F22FB60075FC59 /* UIFeedbackGenerator.swift in Sources */, + 7B0FD98923196A3F0004B52B /* ConfirmRequestDTOTransaction+Mapper.swift in Sources */, + 7B36819A23142625000D5592 /* ConfirmRequestType.swift in Sources */, E92FAD0E226F6C050054D4AA /* WalletSortSeparatorCell.swift in Sources */, + 7BDC6D7922C3CD8400614E6B /* InputScrollButtonsView.swift in Sources */, E9D36DE82175C755001E6DF0 /* AssetSelectView.swift in Sources */, - 0ADC179E2204A23000472130 /* ModalRootView.swift in Sources */, + 7B26A88A22ED180A00E7B024 /* UIDeveloperCoordinator.swift in Sources */, E9C4134C20E826E300AA044F /* DottedRoundView.swift in Sources */, E9B087D12163886800937644 /* DexListSkeletonCell.swift in Sources */, - 0A5E4BDD2138311C00E3C3C3 /* TransferTransaction+Mapper.swift in Sources */, E9B087C82163886800937644 /* DexTraderContainerButton.swift in Sources */, 0AF6AD25218A54840004F107 /* CopyableImageView.swift in Sources */, 0A762D17214FF1CD00BE9204 /* InputTextField.swift in Sources */, E9A05C5820E9264300B0E0FA /* UseTouchIDViewController.swift in Sources */, + E9239570237518B7009C4091 /* PushNotificationsManager.swift in Sources */, 7BDA6AD7222D8CA1001DE71C /* TransactionCardViewController.swift in Sources */, + 7BFB481A22FC742F002B19F8 /* QRCodeParser.swift in Sources */, 7B3902A122379BFE00AAFDB8 /* TransactionCardAssetDetailCell.swift in Sources */, 0A96F1DE2152E14D005E148F /* PasscodeBuilder.swift in Sources */, - E922D26A21B831B600575955 /* LastTradesRepositoryRemote.swift in Sources */, - 0ADD7F9721F22FB60075FC59 /* UIView+Additionals.swift in Sources */, + 7B49911722F874B0005B7123 /* AssetsSearchViewController.swift in Sources */, E9B086AE2163883000937644 /* AddAddressBookModuleBuilder.swift in Sources */, E9B087DF2163886800937644 /* DexCreateOrderPresenterProtocol.swift in Sources */, - E99DD81B21CEE7690091AFEC /* CandlesApiService.swift in Sources */, E9C0B49C2176C46E00669D1D /* SendPresenterProtocol.swift in Sources */, 0A071E82215DB182007D9750 /* ChooseAccountModuleBuilder.swift in Sources */, E94231F022A40FA80087F82F /* WalletSearchModuleBuilder.swift in Sources */, - 7B951127225CD7160030390C /* QRCodeParser.swift in Sources */, - 0AF58FA121931AD400C8A4B3 /* WalletEncryption.swift in Sources */, 0ADD802A21F22FFA0075FC59 /* EnterLanguageCoordinator.swift in Sources */, E921ED04222DDA4600DE286D /* DexScriptAssetMessageViewController.swift in Sources */, - 0AE657342106375D003D2DB8 /* TimestampSignature.swift in Sources */, 0A43996921504CF60032E608 /* SideMenu.swift in Sources */, + 7B3681B12315612C000D5592 /* ConfirmRequestSkeletonCell.swift in Sources */, 04A403242164D89700652F21 /* EnterStartBlockCell.swift in Sources */, - 0AFB59442209B5F3001F0DD8 /* SponsorshipTransaction.swift in Sources */, - 7B95112E225CDA880030390C /* Balance.swift in Sources */, - 0ADD7FA921F22FB60075FC59 /* UIViewController+SafeArea.swift in Sources */, 7B39029D2236ABFF00AAFDB8 /* TransactionCardStatusCell.swift in Sources */, E9D36DF12175C755001E6DF0 /* AssetListModuleBuilder.swift in Sources */, 0AF921ED212E07B3003BA067 /* AssetDetailViewController.swift in Sources */, E9B0880E2163886800937644 /* DexMarketViewController.swift in Sources */, 0A5F953F2185FAD4005308AC /* AliasWithoutViewController.swift in Sources */, - E9D0ED8A225CBECA0098C234 /* InvokeScriptTransaction+Mapper.swift in Sources */, 0A9797612108A60000407F67 /* Storyboards.swift in Sources */, - 0A762D9B2163A0B60019D447 /* FactoryInteractors.swift in Sources */, - 0ADD7F9621F22FB60075FC59 /* UIColor+Hex.swift in Sources */, + 7BFB480822FC742F002B19F8 /* SkeletonAnimatable.swift in Sources */, 0A59330C218343B00059A77A /* AddressesKeysAliacesCell.swift in Sources */, - 0ADD7FD021F22FB60075FC59 /* GlobalConstants.swift in Sources */, 0AFF5C7B215BCFEA00B82940 /* AccountPasswordModuleBuilder.swift in Sources */, - 0ADD7FD321F22FB60075FC59 /* AssetLogo.swift in Sources */, - 0ABD1BE621469CE70027A7A2 /* AddressInteractor.swift in Sources */, + 7B3681A923155499000D5592 /* ConfirmRequestFromToCell.swift in Sources */, 0AF921EC212E07B3003BA067 /* AssetDetailInteractorProtocol.swift in Sources */, - 0A6CCD3D20F4CF490023E36E /* AccountBalanceInteractor.swift in Sources */, - 0ADD7F9C21F22FB60075FC59 /* UIViewController+Additionals.swift in Sources */, 0ADD6C87216796DB00B06917 /* ProfileLanguageCell.swift in Sources */, - 0A1DAD6520F395F2004DA625 /* AssetsInteractor.swift in Sources */, - 7B951135225CDAA90030390C /* CGSize+Hashable.swift in Sources */, E9236F1D2216F35B00A12FD5 /* AppNewsView.swift in Sources */, - 0A7643FA211874F400B633E1 /* FactoryInteractorsProtocol.swift in Sources */, E9B086B32163883000937644 /* AddAddressBookViewController.swift in Sources */, E96358A422A73D62008A3395 /* WalletClearAssetsView.swift in Sources */, 0AE491F62107A529009223DB /* WalletInteractorProtocol.swift in Sources */, E9CD0D3521815849001A99B3 /* AddAddressBookTypes.swift in Sources */, 7BDA6AF622316078001DE71C /* TransactionCardMassSentRecipientCell.swift in Sources */, 044A1FD22114CA6D00B63C6A /* HistoryInteractor.swift in Sources */, - 0AF0C67921AA25B200602197 /* AliasesRepository.swift in Sources */, - 7B951116225CD55F0030390C /* Mutating.swift in Sources */, 044A1FD02114BDBF00B63C6A /* HistoryPresenter.swift in Sources */, E9C0B4A02176C49B00669D1D /* SendInteractorProtocol.swift in Sources */, 0A2B7D35216037FD0098438D /* AssetViewHistoryCell.swift in Sources */, 0AF92228212E0F1F003BA067 /* WalletLeasingBalanceCell.swift in Sources */, 0AF92225212E0F1F003BA067 /* WalletHeaderView.swift in Sources */, - 0A485EA22100C4FA00079B49 /* LeaseTransaction+Mapper.swift in Sources */, - 0ADD804421F72B2C0075FC59 /* AssetScriptTransactionNode.swift in Sources */, - E99DD81F21CEF7AC0091AFEC /* CandleApi.swift in Sources */, 0AF921FC212E07B3003BA067 /* AssetChartHeaderView.swift in Sources */, E9D36DCB2175C755001E6DF0 /* ReceiveCryptocurrencyPresenter.swift in Sources */, 0ADD802621F22FFA0075FC59 /* AppCoordinator.swift in Sources */, E9B0880F2163886800937644 /* DexMarketModuleOutput.swift in Sources */, + 7BD6E10822E5AE7000BAAFC8 /* DebugInfoCell.swift in Sources */, E9443008226E62A600EB6257 /* WalletSortViewController.swift in Sources */, - 0AAC2A462146C65900F6EB27 /* BlockRepositoryProtocol.swift in Sources */, E9F69B9222A5217200CDBD00 /* WalletSearchTypes.swift in Sources */, E911300C21BC028400588430 /* AssetSelectSkeletonView.swift in Sources */, - E9DDF73A2240F52D00B83CFD /* EnvironmentRepository.swift in Sources */, E9B088192163886800937644 /* DexSortPresenter.swift in Sources */, - 0A1DAD7120F3A112004DA625 /* AddressesNodeService.swift in Sources */, - E944AA7A22446A530009F494 /* AnalyticManager+WalletStart.swift in Sources */, - E971DA5220FFF4B600616A03 /* BiometricManager.swift in Sources */, - 0A2CD238216D0F0000162063 /* AuthorizationInteractorProtocol.swift in Sources */, E97667CE227F0F8C0050E0D6 /* TransactionCardOrderFilledCell.swift in Sources */, - E922D26821B8311F00575955 /* LastTradesRepositoryProtocol.swift in Sources */, 0ADD802B21F22FFA0075FC59 /* ChooseAccountCoordinator.swift in Sources */, - 7B95111A225CD5B70030390C /* BiometricType.swift in Sources */, - 0ADD7FB421F22FB60075FC59 /* UIView+Animation.swift in Sources */, - 0ADD7FAD21F22FB60075FC59 /* QRCodeReader+Factory.swift in Sources */, - 0A5C3202213D916900420004 /* AnyTransaction.swift in Sources */, - 0ADD7FCA21F22FB60075FC59 /* DisplayError.swift in Sources */, - E92D9BFF2148740B006D6D6B /* InputScrollButtonsView.swift in Sources */, E9B12DAF219DCDD300128EFE /* TokenBurnTypes.swift in Sources */, - 0ADD7F9921F22FB60075FC59 /* UITableView+Animation.swift in Sources */, 0AAB15CA21655EB000F1F7BC /* ProfileViewController.swift in Sources */, - 0A88CC04217D27370083874C /* AccountSettingsRepositoryProtocol.swift in Sources */, - 0ADC17A02204A24C00472130 /* ModalScrollViewController.swift in Sources */, 0AF922E6212E1234003BA067 /* HalfModalTransitioningDelegate.swift in Sources */, + 7B0FD985231952740004B52B /* ConfirmRequestLoadingViewController.swift in Sources */, E9FE4D7820EA767B00208F29 /* SaveBackupPhraseViewController.swift in Sources */, - 7BAA9F7B22A032DF003B6D01 /* ApplicationVersionUseCase.swift in Sources */, 0AF921FA212E07B3003BA067 /* AssetBalanceMoneyInfoView.swift in Sources */, + 7BFB481422FC742F002B19F8 /* ModalScrollViewController.swift in Sources */, 0AF92203212E07B3003BA067 /* AssetBalanceSkeletonCell.swift in Sources */, 0ADD802121F22FFA0075FC59 /* NavigationRouter.swift in Sources */, - 0AEB35942115E45500EDD63C /* AssetsRepositoryRemote.swift in Sources */, - E9BCF48121636DAC00FA6502 /* ResponseType.swift in Sources */, - 0ADD7F9221F22FB60075FC59 /* UIScrollView+Pagination.swift in Sources */, E9EC5BAC2175F35900E5C29A /* SendViewController.swift in Sources */, - 0A218B9721555A4B00B989A1 /* AuthenticationRepositoryRemote.swift in Sources */, - 7BF89E892226E00800853F9D /* SentryManager.swift in Sources */, - 7B951129225CD7350030390C /* AppSettings.swift in Sources */, - 0A98D14A2138910600550FE0 /* DataTransaction+Mapper.swift in Sources */, 0ADD801D21F22FFA0075FC59 /* DexCoordinator.swift in Sources */, + 7BFB480F22FC742F002B19F8 /* ModalRootView.swift in Sources */, 0A071E85215DB1B3007D9750 /* ChooseAccountCell.swift in Sources */, - 0A751D3A22171ABB0024D523 /* Kingfisher+Rx.swift in Sources */, + 7BFB480922FC742F002B19F8 /* RateApp.swift in Sources */, 7B39029722366D0100AAFDB8 /* AddressBookButton.swift in Sources */, E9B088122163886800937644 /* DexMarketCell.swift in Sources */, - 0A4E7DEF22018C5F007BBA39 /* ModalPresentationController.swift in Sources */, - 0A764402211881A900B633E1 /* FactoryRepositoriesProtocol.swift in Sources */, E991BB282202D5AA0022E27D /* SendFeePresenterProtocol.swift in Sources */, 7B5E7465223907AA00746ADD /* TransactionCardHeaderView.swift in Sources */, - 7B95111E225CD6140030390C /* RunLoopThreadScheduler.swift in Sources */, E923A768219D714E000DD9F6 /* TokenBurnLoadingViewController.swift in Sources */, E9443018226E757E00EB6257 /* WalletSort+Mapper.swift in Sources */, + 7B65B6F522F9D63D007D5C53 /* KeyboardControl.swift in Sources */, + 7BFB481022FC742F002B19F8 /* ModalViewControllerTransitioning.swift in Sources */, 04831F6321691429006D1ED6 /* MoneyTextField.swift in Sources */, 0AF922F4212E1234003BA067 /* TickerView.swift in Sources */, + 7BFB481222FC742F002B19F8 /* ModalPresentationController.swift in Sources */, + E902BBD0236A664300141CF4 /* DexDeepLinkCoordinator.swift in Sources */, 0AF92226212E0F1F003BA067 /* WalletHistoryCell.swift in Sources */, 0AF921FD212E07B3003BA067 /* AssetHistorySkeletonCell.swift in Sources */, E9D36DF52175C755001E6DF0 /* AssetListTypes.swift in Sources */, - 0ADD7FB221F22FB60075FC59 /* CALayer+RoundingCorners.swift in Sources */, E9B088172163886800937644 /* DexSortViewController.swift in Sources */, - 0A6CCD3B20F4CE250023E36E /* Asset+Mapper.swift in Sources */, E9D36DDF2175C755001E6DF0 /* ReceiveContainerModuleBuilder.swift in Sources */, E9B087D62163886800937644 /* DexListInteractor.swift in Sources */, - 0ADD7FBA21F22FB60075FC59 /* CGFloat+Min.swift in Sources */, - 0AEB35A621165E1D00EDD63C /* AccountBalanceRepositoryLocal.swift in Sources */, - F74240B61EAB8D1600C3B84D /* AddressBook.swift in Sources */, E9AFDBE421F32E88003130A8 /* TransactionFeeView.swift in Sources */, 7BD2FD35223C5E1F0098CFB9 /* TransactionCardCoordinator.swift in Sources */, - 0A1DAD6220F3876C004DA625 /* AssetApi.swift in Sources */, + 7BFB480C22FC742F002B19F8 /* GlobalConstants.swift in Sources */, E9CD0D2C218099FB001A99B3 /* SendMoneroPaymentIdView.swift in Sources */, 04016DFC219420C900BA5235 /* ImportAccountViewController.swift in Sources */, 0ADD802521F22FFA0075FC59 /* SlideMenuRouter.swift in Sources */, + 7B3681AF23155805000D5592 /* ConfirmRequestBalanceCell.swift in Sources */, E9D36DE22175C755001E6DF0 /* ReceiveAddressModuleBuilder.swift in Sources */, E9B087E82163886800937644 /* DexCreateOrderInteractorProtocol.swift in Sources */, - E9DDF7402240F5FD00B83CFD /* UtilsNodeService.swift in Sources */, + 7B49911E22F875A1005B7123 /* AssetsSearchViewBuilder.swift in Sources */, 04615A23211A31C90000FF80 /* HistoryModuleInput.swift in Sources */, + 7B3681A72315534E000D5592 /* ConfirmRequestTransactionKindCell.swift in Sources */, 0AA8CAD22152763A000D09E6 /* PasscodeView.swift in Sources */, E9B086B62163883000937644 /* AddressBookPresenter.swift in Sources */, 04E1C3562126157000C702BA /* HeaderSkeletonView.swift in Sources */, @@ -6001,97 +7614,82 @@ 0AF922FD212E1234003BA067 /* BorderButtView.swift in Sources */, 0A3FE8A62135AC2B00DBF4E1 /* AssetTransactionsCell.swift in Sources */, 0AFBCA8A2113254100285BCB /* WalletModuleBuilder.swift in Sources */, - E967786B21EC660C00CE56D6 /* DexMyOrders+Mapper.swift in Sources */, E9B088142163886800937644 /* DexMarketInteractorProtocol.swift in Sources */, E902F61520E5829B00A46335 /* ChooseAccountViewController.swift in Sources */, - 0AD83608217A1C26004413E9 /* AccountSettings.swift in Sources */, 0AF921E8212E07B3003BA067 /* AssetDetailPresenterProtocol.swift in Sources */, - 0ADD7F9B21F22FB60075FC59 /* UIApplication+OpenURL.swift in Sources */, - 0A4E7DEC22018C5F007BBA39 /* ModalPresentationAnimatorContext.swift in Sources */, E9B087FF2163886800937644 /* DexMyOrdersInteractor.swift in Sources */, + 7B26A87F22ED13F300E7B024 /* WidgetSettingsViewController.swift in Sources */, 0484474A2118658400552772 /* HistoryTypes+ViewModels.swift in Sources */, E9B087A42163886800937644 /* DexChartInteractorProtocol.swift in Sources */, 0AD83614217DDDAC004413E9 /* NetworkSettingsPresenter.swift in Sources */, E9B087F62163886800937644 /* DexLastTradesInteractorProtocol.swift in Sources */, + 7B8818732305639700AB0549 /* ActionSheetViewBuilder.swift in Sources */, 0ADD802D21F22FFB0075FC59 /* ImportCoordinator.swift in Sources */, - 0AEB35A221165D2100EDD63C /* AccountBalanceRepositoryProtocol.swift in Sources */, - 7BDA6AD5222D8C82001DE71C /* System.swift in Sources */, E9B087BD2163886800937644 /* DexInfoTypes.swift in Sources */, 7B39029522366B8E00AAFDB8 /* TransactionCardAddressCell.swift in Sources */, E9D36DDA2175C755001E6DF0 /* ReceiveTypes.swift in Sources */, - 0A14CFCF2144159300C3A4D5 /* Asset+Assistants.swift in Sources */, E991BB2C2202D6560022E27D /* SendFeeTypes.swift in Sources */, + E9443BA822DCCC2B00AFF151 /* TransactionCardExchangeFeeCell.swift in Sources */, 0AF921F4212E07B3003BA067 /* AssetChartCell.swift in Sources */, - 0A5D3302215842860009CDF3 /* AuthorizationInteractor.swift in Sources */, E9B087C12163886800937644 /* DexTraderContainerTypes.swift in Sources */, - E944AA822245394C0009F494 /* AnalyticAssetManager.swift in Sources */, 7B5EDEC022522655009C2B3B /* TransactionCardKeyLoadingCell.swift in Sources */, 0A762DAC21661B000019D447 /* ProfilePresenter.swift in Sources */, E9D36DD52175C755001E6DF0 /* ReceiveCardViewController.swift in Sources */, E9D36DE52175C755001E6DF0 /* ReceiveGenerateAddressModuleBuilder.swift in Sources */, 7BDA6AE42230281A001DE71C /* TransactionCardGeneralCell.swift in Sources */, - 0A5E4BDB21382C2200E3C3C3 /* IssueTransaction+Mapper.swift in Sources */, - 0ADD7F9821F22FB60075FC59 /* UITableView+HeaderView.swift in Sources */, 7B39029B2236A17900AAFDB8 /* TransactionCardKeyBalanceCell.swift in Sources */, 0AFF5C7F215BD08E00B82940 /* AccountPasswordInteractor.swift in Sources */, 7B3A51A8223AA08F00C3BF38 /* TransactionCardAssetCell.swift in Sources */, 0ADD803421F22FFB0075FC59 /* HistoryCoordinator.swift in Sources */, - E92A8DE12278ACFF0009DF27 /* TSUD+Rx.swift in Sources */, 0AFF5C81215BD09500B82940 /* AccountPasswordPresenter.swift in Sources */, - 0A5E4BE521383B3600E3C3C3 /* MassTransferTransaction+Mapper.swift in Sources */, E9B12DAB219DCCDB00128EFE /* TokenBurnSendInteractorProtocol.swift in Sources */, E9B0879D2163886800937644 /* DexChartViewController.swift in Sources */, + 7BB03E4A22EF2C84008F179D /* WidgetSettingsHeaderView.swift in Sources */, E9B087FA2163886800937644 /* DexMyOrdersPresenter.swift in Sources */, 0ADD802321F22FFA0075FC59 /* Router.swift in Sources */, 0ADD802C21F22FFA0075FC59 /* HelloCoordinator.swift in Sources */, E96FEA25226E962300C0EE22 /* WalletSortEmptyAssetsCell.swift in Sources */, + 7B0FD98723195D6A0004B52B /* ConfirmRequestCompleteViewController.swift in Sources */, E9B087AB2163886800937644 /* DexOrderBookModuleOutput.swift in Sources */, - 0ADD7FED21F22FB60075FC59 /* ModuleBuilder.swift in Sources */, E9A3AFAE222DEECB009FB45A /* DexScriptAssetMessageModuleBuilder.swift in Sources */, 7B390299223698D300AAFDB8 /* TransactionCardKeyValueCell.swift in Sources */, 7B5E746922390B8200746ADD /* TransactionCardBuilder.swift in Sources */, E9D36DD12175C755001E6DF0 /* ReceiveCardTypes.swift in Sources */, - 0A5C919C20F3E7DD00443CE6 /* Asset.swift in Sources */, - 0ADD7FA621F22FB60075FC59 /* UIView+TouchInset.swift in Sources */, + 7BD6E10E22E5CD5E00BAAFC8 /* DebugEnviromentsCell.swift in Sources */, + 7B49912E22F9B470005B7123 /* AssetsSearchModuleOutput.swift in Sources */, E9D36DCE2175C755001E6DF0 /* ReceiveCryptocurrencyInteractor.swift in Sources */, 0A88CBFE2177FE130083874C /* ChangePasswordTypes.swift in Sources */, - 0ADD7FA121F22FB60075FC59 /* UIColor+Colors.swift in Sources */, 7B3902AB2237AEE200AAFDB8 /* TransactionCardActionsCell.swift in Sources */, E9B087EC2163886800937644 /* DexLastTradesModuleBuilder.swift in Sources */, + 7BFB480322FC742F002B19F8 /* SmartTransactionKind+UIImage.swift in Sources */, 0A6AC3DE2183CEFF005D2525 /* AddressesKeysSkeletonCell.swift in Sources */, + 7B3681AD231556B4000D5592 /* ConfirmRequestFeeAndTimestampCell.swift in Sources */, 0A2B7D37216038540098438D /* HalfModalInteractiveTransition.swift in Sources */, - 0A485E8B20FFAC6C00079B49 /* LeasingNodeService.swift in Sources */, E9D36DEC2175C755001E6DF0 /* ReceiveInvoiceModuleBuilder.swift in Sources */, E97EC83F20E67BE900AB006B /* NewAccountViewController.swift in Sources */, 0AF92227212E0F1F003BA067 /* WalletTableAssetsCell.swift in Sources */, E9D36DF42175C755001E6DF0 /* AssetListViewController.swift in Sources */, + 7B3681982314260C000D5592 /* ConfirmRequestViewController.swift in Sources */, 04831F6221691429006D1ED6 /* HighlightedView.swift in Sources */, E923A76D219D73BF000DD9F6 /* TokenBurnCompleteViewController.swift in Sources */, 0A7CCDB5218A138D005D372B /* MyAddressInfoAddressCell.swift in Sources */, E9B086B42163883000937644 /* AddressBookModuleOutput.swift in Sources */, - F74240B71EAB8D1600C3B84D /* AssetBalance.swift in Sources */, - E9D0ED86225CB8400098C234 /* InvokeScriptTransactionNode.swift in Sources */, E9B087C22163886800937644 /* DexTraderContainerViewController.swift in Sources */, - 0ADD7FEA21F22FB60075FC59 /* UITableView+Skeleton.swift in Sources */, 0A96F1DC2152E05A005E148F /* PasscodeInteractor.swift in Sources */, E923A765219D53EE000DD9F6 /* TokenBurnInteractor.swift in Sources */, - 7B951137225CF7A00030390C /* Reachability+Shared.swift in Sources */, E9B087F52163886800937644 /* DexLastTradesInteractor.swift in Sources */, - 0ADD7FB921F22FB60075FC59 /* UIAlertController+Factory.swift in Sources */, E9B12DB9219E2D3900128EFE /* AssetBurnCell.swift in Sources */, E9D36DE32175C755001E6DF0 /* ReceiveAddressTypes.swift in Sources */, - 0AC33AF021A826B700B66747 /* NetworkError.swift in Sources */, - 0AEB35912115E44300EDD63C /* AssetsRepositoryLocal.swift in Sources */, 0AFA0C7D2174A2300003FE3B /* BrowserViewController.swift in Sources */, - 0A6AC3E421848920005D2525 /* AliasesRepositoryProtocol.swift in Sources */, E9B087A02163886800937644 /* DexChartHeaderView.swift in Sources */, 0A14E3EA21871B9000EA7E91 /* AliasesAliasCell.swift in Sources */, + 7BFB480A22FC742F002B19F8 /* DisplayError.swift in Sources */, + 7B26A88122ED140100E7B024 /* WidgetSettingsType.swift in Sources */, + 7B97B0A922FC78FE008BA3F4 /* UIViewController+Additionals.swift in Sources */, 0ADD802E21F22FFB0075FC59 /* NewAccountCoordinator.swift in Sources */, - 7B951123225CD6AD0030390C /* SentryNetworkLoggerPlugin.swift in Sources */, 0AACD59B21A59E7100B30815 /* SweetSnackbar.swift in Sources */, E95438F8217F91BA001A7860 /* SendLoadingViewController.swift in Sources */, 0ADD803221F22FFB0075FC59 /* AddressesKeysCoordinator.swift in Sources */, - 0AAC2A482146C69700F6EB27 /* BlockRepositoryRemote.swift in Sources */, 0AF921EE212E07B3003BA067 /* AssetDetailModuleBuild.swift in Sources */, 0AC1251221A758BD00357C93 /* LongInfoPageView.swift in Sources */, 0A96F1D32151BD46005E148F /* PasscodeTopBarView.swift in Sources */, @@ -6100,37 +7698,33 @@ E9B086B82163883000937644 /* AddressBookModuleBuilder.swift in Sources */, E9D36DEB2175C755001E6DF0 /* ReceiveInvoiceViewController.swift in Sources */, E9B087AD2163886800937644 /* DexOrderBookLastPriceCell.swift in Sources */, - E9A380A721D2E1C5004377A6 /* PairPriceApi.swift in Sources */, + 7B8818702305639600AB0549 /* ActionSheetElementCell.swift in Sources */, + 7B49912822F87C7A005B7123 /* AssetsSearchSystem.swift in Sources */, 0AF92208212E07B3003BA067 /* AssetHeaderView.swift in Sources */, E9B087D32163886800937644 /* DexListModuleBuilder.swift in Sources */, 04EB742621133318004A065B /* HistoryViewController.swift in Sources */, - 0AD83606217A1C14004413E9 /* AccountEnvironment.swift in Sources */, 0AF922F2212E1234003BA067 /* CopyableLabel.swift in Sources */, - E96E2A0021D34A2100AC2FA9 /* MatcherRepositoryProtocol.swift in Sources */, 0A9797652108B18C00407F67 /* WalletModuleOutput.swift in Sources */, E9D36DCF2175C755001E6DF0 /* ReceiveCryptocurrencyViewController.swift in Sources */, - 0A4C9AAB20EF6BFF0095A417 /* AssetsApiService.swift in Sources */, E9B088102163886800937644 /* DexMarketModuleBuilder.swift in Sources */, E9C0B49E2176C48300669D1D /* SendPresenter.swift in Sources */, + 7B26A88E22EEEA7000E7B024 /* WidgetSettingsModuleOutput.swift in Sources */, + 7B97B0BC22FD92AC008BA3F4 /* AssetLogo+Styles.swift in Sources */, + 7B49911C22F8754A005B7123 /* AssetsSearch.swift in Sources */, E9D36DDE2175C755001E6DF0 /* ReceiveContainerViewController.swift in Sources */, E9B087992163886800937644 /* DexChartPresenter.swift in Sources */, - 0AE6572F2106340A003D2DB8 /* Signature.swift in Sources */, + 7BD6E10C22E5B6D700BAAFC8 /* DebugSwitchCell.swift in Sources */, 7BDA6AE6223028DC001DE71C /* BalanceLabel.swift in Sources */, E96DAB73228EEC87005ED12B /* WalletSortSegmentedControl.swift in Sources */, - 7B951133225CDAA00030390C /* Decimal+Assisstants.swift in Sources */, E97EC84320E689A800AB006B /* ImportAccountPasswordViewController.swift in Sources */, - 0A751D3422170F3D0024D523 /* NotificationNewsDomainDTO.swift in Sources */, 0A762D9C2163A1C90019D447 /* HistoryTypes.swift in Sources */, - 0A764401211881A500B633E1 /* FactoryRepositories.swift in Sources */, - 0ADD7FF521F22FB60075FC59 /* NibLoadable.swift in Sources */, 0AD83616217DE071004413E9 /* NetworkSettingsModuleBuilder.swift in Sources */, - 0ADD7FF221F22FB60075FC59 /* UICollectionView+Reusable.swift in Sources */, 7B3902A72237A74900AAFDB8 /* ActionsControl.swift in Sources */, 04F2DD2E219F27AB0070AF9D /* MultilineTextField.swift in Sources */, E991BB242202D5740022E27D /* SendFeeInteractor.swift in Sources */, 0A593312218344000059A77A /* AddressesKeysHiddenPrivateKeyCell.swift in Sources */, + 7B60E2BC2316CBEA00113C38 /* ConfirmRequestTransactionKindView.swift in Sources */, E9DEECE920BEF96700F28C67 /* WavesPopupViewController.swift in Sources */, - 0ADD7FF321F22FB60075FC59 /* Reusable.swift in Sources */, E9D36DED2175C755001E6DF0 /* ReceiveInvoiveTypes.swift in Sources */, E904525A20B4EF4200A490E5 /* PopupViewController.swift in Sources */, 7B6922C6223BA1730056DA67 /* TransactionCardSystemTransaction+Mapper.swift in Sources */, @@ -6138,45 +7732,35 @@ E9B0879C2163886800937644 /* DexChartModuleBuilder.swift in Sources */, 0AF58F9D2191DEA300C8A4B3 /* PasscodeEnableBiometricPresenter.swift in Sources */, 04F9979621AA197B0036768D /* CameraAccess.swift in Sources */, + 7BFB480B22FC742F002B19F8 /* Notifications.swift in Sources */, 0A14E3F521875B5100EA7E91 /* CreateAliasModuleBuilder.swift in Sources */, - E9BB724821C2A94000B2AF7E /* CoinomatRepositoryProtocol.swift in Sources */, 0AAB15C521655BEC00F1F7BC /* ProfileBackupPhraseCell.swift in Sources */, 0A41410B217603F800B1310E /* ChangePasswordPresenter.swift in Sources */, - E944AA76224465D60009F494 /* AnalyticManager+Dex.swift in Sources */, E9B087C32163886800937644 /* DexTraderContainerModuleOutput.swift in Sources */, - 0A5E4BB5213805B400E3C3C3 /* MassTransferTransaction.swift in Sources */, - 0A57C38E21F74E2E003B5386 /* AssetScriptTransaction+Mapper.swift in Sources */, - 0A5E4BBA21381E3400E3C3C3 /* DataTransaction.swift in Sources */, E98F1D2D22A5E2E600B4A8C4 /* WalletUpdateAppView.swift in Sources */, 0ADD803721F22FFB0075FC59 /* SlideCoordinator.swift in Sources */, E9310D0C217924D0008BF3EE /* SendConfirmationViewController.swift in Sources */, E9D36DD72175C755001E6DF0 /* ReceiveCardInteractorProtocol.swift in Sources */, + 7B36819F23142A0F000D5592 /* ConfirmRequestModuleBuilder.swift in Sources */, E9D36DE72175C755001E6DF0 /* ReceiveGenerateAddressViewController.swift in Sources */, 0A762D11214FDFA100BE9204 /* NewAccountAvatarView.swift in Sources */, + E9413AC222FA3D9C002C4A97 /* DexChartSettings.swift in Sources */, 0ADD801E21F22FFA0075FC59 /* PresentationCoordinator.swift in Sources */, - 0A5C3204213E93C700420004 /* UnrecognisedTransaction.swift in Sources */, E9B087EF2163886800937644 /* DexLastTradesTypes.swift in Sources */, - 0A4508FA2178938C00EBF669 /* EnvironmentRepositoryProtocol.swift in Sources */, - 0A8AFF2A2101F47F00D0582B /* OrderBookMatcherService.swift in Sources */, - 0AE657312106368F003D2DB8 /* BalanceMatcherService.swift in Sources */, + 7B88186223044B7F00AB0549 /* Language+List.swift in Sources */, F7C683BE1EA93C5800C87DAF /* CustomNavigationController.swift in Sources */, - E9F9A27E218540F700FD68D7 /* DexRealmRepositoryLocal.swift in Sources */, E9B087ED2163886800937644 /* DexLastTradesPresenterProtocol.swift in Sources */, 0AF922F5212E1234003BA067 /* SegmentedControlScrollView.swift in Sources */, 0AACD59C21A59E7100B30815 /* SweetSnackView.swift in Sources */, - 0ADD7FA321F22FB60075FC59 /* Notifications.swift in Sources */, + 7BFB481522FC742F002B19F8 /* ModalPresentationAnimatorContext.swift in Sources */, E9B087972163886800937644 /* DexChartConstants.swift in Sources */, - 0A00B185221AE325005A9053 /* AssetsBalanceSettingsRepositoryProtocol.swift in Sources */, 0A36A37D215E493D0060F49E /* NeedBackupViewController.swift in Sources */, 0ADD802921F22FFA0075FC59 /* EnterCoordinator.swift in Sources */, 0AE491E1210786BC009223DB /* ConfirmBackupStackInputView.swift in Sources */, - 0ADD7FB021F22FB60075FC59 /* UIView+Shadow.swift in Sources */, - 0A57C39221F74EBA003B5386 /* AssetScriptTransaction.swift in Sources */, E95B47D121638A9F004D4E39 /* InfoPagesViewController.swift in Sources */, 0AF9222E212E0F1F003BA067 /* WalletHistorySkeletonCell.swift in Sources */, E917B3AD21BD685800CC849A /* AmountSkeletonView.swift in Sources */, E9B086B72163883000937644 /* AddressBookPresenterProtocol.swift in Sources */, - 0AF2536321B0351A00B8F7DF /* AssetsBalanceSettingsInteractor.swift in Sources */, 0ADD802F21F22FFB0075FC59 /* EditAccountNameCoordinator.swift in Sources */, 0AAB15C721655C0600F1F7BC /* ProfileDisabledButtomTableCell.swift in Sources */, E9EC5C0F2175F35900E5C29A /* AddressInputView.swift in Sources */, @@ -6185,93 +7769,2287 @@ 0A96F1D52152C80E005E148F /* PasscodePresenter.swift in Sources */, 7B39029F223790BF00AAFDB8 /* TransactionCardDescriptionCell.swift in Sources */, 7B3902B02237D8FA00AAFDB8 /* TransactionCardExchangeCell.swift in Sources */, - 7B95111C225CD5EE0030390C /* Results+Limit.swift in Sources */, 0A4C9A2820ED443C0095A417 /* WalletPresenter.swift in Sources */, - 0ADD803C21F5B60D0075FC59 /* AddressScriptInfoNode.swift in Sources */, - 0A5C919820F3DB1100443CE6 /* AccountBalanceNode.swift in Sources */, - 0AF0C67721A97E1400602197 /* Alias.swift in Sources */, 0AF922E7212E1234003BA067 /* EmptyCell.swift in Sources */, E9F984B220E53FE000D2CB4D /* LanguageViewController.swift in Sources */, + 7B49912222F876AA005B7123 /* AssetsSearchHeaderView.swift in Sources */, 0AF92230212E0F1F003BA067 /* WalletSegmentedControl.swift in Sources */, 0A59331421835C9C0059A77A /* AddressesKeysTypes.swift in Sources */, E91DC0E120E0054A00BAB519 /* NetworkSettingsViewController.swift in Sources */, - 0ADD7FA221F22FB60075FC59 /* ControlEvent+Signal.swift in Sources */, - 0A1DAD6920F39AE3004DA625 /* ResponseApi.swift in Sources */, - E9A6A49A227661940093FC59 /* TableViewNoShadow.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 7BF89E9C22272A5E00853F9D /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = F7E954E31EA8FE0700A804DE /* WavesWallet-iOS */; - targetProxy = 7BF89E9B22272A5E00853F9D /* PBXContainerItemProxy */; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 7B16BCDE22DBE39000540418 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 7B6685FF22B3F70D0029E6F1 /* DomainLayer */; + targetProxy = 7B16BCDD22DBE39000540418 /* PBXContainerItemProxy */; + }; + 7B16BCE022DBE39000540418 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 7B6686ED22B7C5120029E6F1 /* Extensions */; + targetProxy = 7B16BCDF22DBE39000540418 /* PBXContainerItemProxy */; + }; + 7B16BCE222DBE39000540418 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 7B66872222B7E68B0029E6F1 /* DataLayer */; + targetProxy = 7B16BCE122DBE39000540418 /* PBXContainerItemProxy */; + }; + 7B16BCE822DBE59B00540418 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 7B6685FF22B3F70D0029E6F1 /* DomainLayer */; + targetProxy = 7B16BCE722DBE59B00540418 /* PBXContainerItemProxy */; + }; + 7B16BCEA22DBE5A900540418 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 7B6686ED22B7C5120029E6F1 /* Extensions */; + targetProxy = 7B16BCE922DBE5A900540418 /* PBXContainerItemProxy */; + }; + 7B83A7AF22D8C60E0038180D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = F7E954E31EA8FE0700A804DE /* WavesWallet-iOS */; + targetProxy = 7B83A7AE22D8C60E0038180D /* PBXContainerItemProxy */; + }; + 7B83A7E722D8C7580038180D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 7B83A7CF22D8C74E0038180D /* DummyForTest */; + targetProxy = 7B83A7E622D8C7580038180D /* PBXContainerItemProxy */; + }; + 7B83A7EB22D8D8050038180D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 7B83A7CF22D8C74E0038180D /* DummyForTest */; + targetProxy = 7B83A7EA22D8D8050038180D /* PBXContainerItemProxy */; + }; + 7BF89E9C22272A5E00853F9D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = F7E954E31EA8FE0700A804DE /* WavesWallet-iOS */; + targetProxy = 7BF89E9B22272A5E00853F9D /* PBXContainerItemProxy */; + }; + E953CE3822EB19C2001D5800 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 7B6685FF22B3F70D0029E6F1 /* DomainLayer */; + targetProxy = E953CE3722EB19C2001D5800 /* PBXContainerItemProxy */; + }; + E953CE3A22EB19C2001D5800 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 7B6686ED22B7C5120029E6F1 /* Extensions */; + targetProxy = E953CE3922EB19C2001D5800 /* PBXContainerItemProxy */; + }; + E999E6AD2323D61300EDDF45 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = E9B190A622E7CD99008220B7 /* MarketPulseWidget */; + targetProxy = E999E6AC2323D61300EDDF45 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 0AF92301212E1424003BA067 /* Waves.strings */ = { + isa = PBXVariantGroup; + children = ( + 0AF92302212E1424003BA067 /* en */, + 0AF92304212E142A003BA067 /* ru */, + 0A15081C219AE51100516037 /* ko */, + 0A15081E219AE53700516037 /* es */, + 0AACD5A121A5C15800B30815 /* id */, + 0AACD5A521A5C18300B30815 /* de */, + 0A02D20921AEDD3C005DF820 /* ja */, + 0A9CA14D21C16B4A003C0A1B /* tr */, + 0A9CA15121C16E70003C0A1B /* pt-BR */, + 0A7BFD4E21CCEA8100B29654 /* pt-PT */, + E96D1B922249923000D31D17 /* pl */, + E96D1B942249956F00D31D17 /* it */, + 7B95110F225CC2CF0030390C /* nl-NL */, + 7B951111225CC2E60030390C /* hi-IN */, + 7B951113225CC32C0030390C /* zh-Hans-CN */, + 7B32A904229EEFB1004789E7 /* fr-FR */, + ); + name = Waves.strings; + sourceTree = ""; + }; + 0AFBCA832113173300285BCB /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 0AFBCA862113188A00285BCB /* en */, + 0AFBCA872113188B00285BCB /* ru */, + 0A15081B219AE51100516037 /* ko */, + 0A15081D219AE53600516037 /* es */, + 0AACD5A021A5C15800B30815 /* id */, + 0AACD5A421A5C18300B30815 /* de */, + 0A02D20821AEDD3C005DF820 /* ja */, + 0A9CA14C21C16B4A003C0A1B /* tr */, + 0A9CA15021C16E6F003C0A1B /* pt-BR */, + 0A7BFD4D21CCEA8000B29654 /* pt-PT */, + E96D1B912249922F00D31D17 /* pl */, + E96D1B932249956E00D31D17 /* it */, + 7B95110E225CC2CF0030390C /* nl-NL */, + 7B951110225CC2E60030390C /* hi-IN */, + 7B951112225CC32B0030390C /* zh-Hans-CN */, + 7B32A903229EEFB0004789E7 /* fr-FR */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + 7B83A7D622D8C74F0038180D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 7B83A7D722D8C74F0038180D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 7B83A7DB22D8C7500038180D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 7B83A7DC22D8C7500038180D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; + 7B848A912304073B0092AD18 /* WavesMarketPulse.strings */ = { + isa = PBXVariantGroup; + children = ( + 7B848A922304073B0092AD18 /* de */, + 7B848A932304073B0092AD18 /* ja */, + 7B848A942304073B0092AD18 /* en */, + 7B848A952304073B0092AD18 /* es */, + 7B848A962304073B0092AD18 /* it */, + 7B848A972304073B0092AD18 /* fr-FR */, + 7B848A982304073B0092AD18 /* ko */, + 7B848A992304073B0092AD18 /* hi-IN */, + 7B848A9A2304073B0092AD18 /* tr */, + 7B848A9B2304073B0092AD18 /* pt-BR */, + 7B848A9C2304073B0092AD18 /* nl-NL */, + 7B848A9D2304073B0092AD18 /* ru */, + 7B848A9E2304073B0092AD18 /* id */, + 7B848A9F2304073B0092AD18 /* zh-Hans-CN */, + 7B848AA02304073B0092AD18 /* pt-PT */, + 32D0AB8E233A565D00E6C26A /* pl */, + ); + name = WavesMarketPulse.strings; + sourceTree = ""; + }; + E9B190AD22E7CD99008220B7 /* MainInterface.storyboard */ = { + isa = PBXVariantGroup; + children = ( + E9B190AE22E7CD99008220B7 /* Base */, + ); + name = MainInterface.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 0A15081F219B04DF00516037 /* Test-Dev */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREPROCESSOR_DEFINITIONS = "TEST=1"; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = TEST; + SWIFT_INCLUDE_PATHS = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 4.2; + VALIDATE_PRODUCT = YES; + }; + name = "Test-Dev"; + }; + 0A150820219B04DF00516037 /* Test-Dev */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 5E9E95698304826A9178CFEB /* Pods-WavesWallet-iOS.test-dev.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-Test"; + CLANG_USE_OPTIMIZATION_PROFILE = YES; + CODE_SIGN_ENTITLEMENTS = "WavesWallet-iOS/WavesWallet-iOS-Test.entitlements"; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 3920; + DEFINES_MODULE = NO; + DEVELOPMENT_TEAM = 96SW78M3KJ; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + HEADER_SEARCH_PATHS = "$(inherited)"; + INFOPLIST_FILE = "WavesWallet-iOS/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 11; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = "$(inherited)"; + MARKETING_VERSION = 2.6.2; + ONLY_ACTIVE_ARCH = YES; + OTHER_LDFLAGS = "$(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = com.wavesplatform.waveswallet.test; + PRODUCT_MODULE_NAME = WavesWallet_iOS; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE_SPECIFIER = "match Development com.wavesplatform.waveswallet.test"; + SWIFT_COMPILATION_MODE = singlefile; + SWIFT_INCLUDE_PATHS = "$(inherited) \"${PODS_CONFIGURATION_BUILD_DIR}/Alamofire\" \"${PODS_CONFIGURATION_BUILD_DIR}/Charts\" \"${PODS_CONFIGURATION_BUILD_DIR}/Differentiator\" \"${PODS_CONFIGURATION_BUILD_DIR}/Gloss\" \"${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift\" \"${PODS_CONFIGURATION_BUILD_DIR}/KeychainAccess\" \"${PODS_CONFIGURATION_BUILD_DIR}/Koloda\" \"${PODS_CONFIGURATION_BUILD_DIR}/Moya\" \"${PODS_CONFIGURATION_BUILD_DIR}/QRCode\" \"${PODS_CONFIGURATION_BUILD_DIR}/QRCodeReader.swift\" \"${PODS_CONFIGURATION_BUILD_DIR}/RealmSwift\" \"${PODS_CONFIGURATION_BUILD_DIR}/Result\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxCocoa\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxDataSources\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxGesture\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxRealm\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxSwift\" \"${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON\" \"${PODS_CONFIGURATION_BUILD_DIR}/UPCarouselFlowLayout\" \"${PODS_ROOT}/Headers/Public\"/**"; + SWIFT_OBJC_BRIDGING_HEADER = "WavesWallet-iOS/Resources/ObjCBridgingHeader.h"; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = ""; + }; + name = "Test-Dev"; + }; + 0A762DA4216512420019D447 /* Test-Prod */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREPROCESSOR_DEFINITIONS = "TEST=1"; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = TEST; + SWIFT_INCLUDE_PATHS = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 4.2; + VALIDATE_PRODUCT = YES; + }; + name = "Test-Prod"; + }; + 0A762DA5216512420019D447 /* Test-Prod */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 42BA6C1489543A7B9FBD6970 /* Pods-WavesWallet-iOS.test-prod.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-Test"; + CLANG_USE_OPTIMIZATION_PROFILE = YES; + CODE_SIGN_ENTITLEMENTS = "WavesWallet-iOS/WavesWallet-iOS-Test.entitlements"; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 3920; + DEFINES_MODULE = NO; + DEVELOPMENT_TEAM = 96SW78M3KJ; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + HEADER_SEARCH_PATHS = "$(inherited)"; + INFOPLIST_FILE = "WavesWallet-iOS/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 11; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = "$(inherited)"; + MARKETING_VERSION = 2.6.2; + OTHER_LDFLAGS = "$(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = com.wavesplatform.waveswallet.test; + PRODUCT_MODULE_NAME = WavesWallet_iOS; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE_SPECIFIER = "match AppStore com.wavesplatform.waveswallet.test"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = TEST; + SWIFT_COMPILATION_MODE = singlefile; + SWIFT_INCLUDE_PATHS = "$(inherited) \"${PODS_CONFIGURATION_BUILD_DIR}/Alamofire\" \"${PODS_CONFIGURATION_BUILD_DIR}/Charts\" \"${PODS_CONFIGURATION_BUILD_DIR}/Differentiator\" \"${PODS_CONFIGURATION_BUILD_DIR}/Gloss\" \"${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift\" \"${PODS_CONFIGURATION_BUILD_DIR}/KeychainAccess\" \"${PODS_CONFIGURATION_BUILD_DIR}/Koloda\" \"${PODS_CONFIGURATION_BUILD_DIR}/Moya\" \"${PODS_CONFIGURATION_BUILD_DIR}/QRCode\" \"${PODS_CONFIGURATION_BUILD_DIR}/QRCodeReader.swift\" \"${PODS_CONFIGURATION_BUILD_DIR}/RealmSwift\" \"${PODS_CONFIGURATION_BUILD_DIR}/Result\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxCocoa\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxDataSources\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxGesture\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxRealm\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxSwift\" \"${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON\" \"${PODS_CONFIGURATION_BUILD_DIR}/UPCarouselFlowLayout\" \"${PODS_ROOT}/Headers/Public\"/**"; + SWIFT_OBJC_BRIDGING_HEADER = "WavesWallet-iOS/Resources/ObjCBridgingHeader.h"; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = ""; + }; + name = "Test-Prod"; + }; + 7B431A9322BD176D00DE73B9 /* Dev-Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D0CCB8B5087EC114938067B4 /* Pods-DomainLayerTests.dev-debug.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 96SW78M3KJ; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = DomainLayerTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + OTHER_SWIFT_FLAGS = "$(inherited) -D COCOAPODS"; + PRODUCT_BUNDLE_IDENTIFIER = WV.DomainLayerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DummyForTest.app/DummyForTest"; + }; + name = "Dev-Debug"; + }; + 7B431A9422BD176D00DE73B9 /* Release-Prod */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E750B898EC2D32D49A39F690 /* Pods-DomainLayerTests.release-prod.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 96SW78M3KJ; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = DomainLayerTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + OTHER_SWIFT_FLAGS = "$(inherited) -D COCOAPODS"; + PRODUCT_BUNDLE_IDENTIFIER = WV.DomainLayerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DummyForTest.app/DummyForTest"; + }; + name = "Release-Prod"; + }; + 7B431A9522BD176D00DE73B9 /* Test-Dev */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DF56F95985E2EA4D53A570EC /* Pods-DomainLayerTests.test-dev.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 96SW78M3KJ; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = DomainLayerTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + OTHER_SWIFT_FLAGS = "$(inherited) -D COCOAPODS"; + PRODUCT_BUNDLE_IDENTIFIER = WV.DomainLayerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DummyForTest.app/DummyForTest"; + }; + name = "Test-Dev"; + }; + 7B431A9622BD176D00DE73B9 /* Test-Prod */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = AAE0DD42A072FF6782D8699E /* Pods-DomainLayerTests.test-prod.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 96SW78M3KJ; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = DomainLayerTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + OTHER_SWIFT_FLAGS = "$(inherited) -D COCOAPODS"; + PRODUCT_BUNDLE_IDENTIFIER = WV.DomainLayerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DummyForTest.app/DummyForTest"; + }; + name = "Test-Prod"; + }; + 7B431AA422BD185B00DE73B9 /* Dev-Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A79335F0C0282C9BC73BC68E /* Pods-DataLayerTests.dev-debug.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 96SW78M3KJ; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = DataLayerTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = WV.DataLayerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DummyForTest.app/DummyForTest"; + }; + name = "Dev-Debug"; + }; + 7B431AA522BD185B00DE73B9 /* Release-Prod */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = FD35BB6367E2BF6D13D33388 /* Pods-DataLayerTests.release-prod.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 96SW78M3KJ; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = DataLayerTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = WV.DataLayerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DummyForTest.app/DummyForTest"; + }; + name = "Release-Prod"; + }; + 7B431AA622BD185B00DE73B9 /* Test-Dev */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DD32EC8514D2E93CE1593C7F /* Pods-DataLayerTests.test-dev.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 96SW78M3KJ; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = DataLayerTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = WV.DataLayerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DummyForTest.app/DummyForTest"; + }; + name = "Test-Dev"; + }; + 7B431AA722BD185B00DE73B9 /* Test-Prod */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = BAA94A74B517FBB13852F114 /* Pods-DataLayerTests.test-prod.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 96SW78M3KJ; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = DataLayerTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = WV.DataLayerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DummyForTest.app/DummyForTest"; + }; + name = "Test-Prod"; + }; + 7B66860922B3F70E0029E6F1 /* Dev-Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 45AA58BA32AC1AF6D19F9EEF /* Pods-DomainLayer.dev-debug.xcconfig */; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 3920; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 3920; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = DomainLayer/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 11; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = "$(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = com.wavesplatform.waveswallet.domainlayer; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = "Dev-Debug"; + }; + 7B66860A22B3F70E0029E6F1 /* Release-Prod */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 79716E63B228F54DC963B57A /* Pods-DomainLayer.release-prod.xcconfig */; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 3920; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 3920; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = DomainLayer/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 11; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = "$(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = com.wavesplatform.waveswallet.domainlayer; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = "Release-Prod"; + }; + 7B66860B22B3F70E0029E6F1 /* Test-Dev */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 613D35B159856DDD30F86C98 /* Pods-DomainLayer.test-dev.xcconfig */; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 3920; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 3920; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = DomainLayer/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 11; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = "$(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = com.wavesplatform.waveswallet.domainlayer; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = "Test-Dev"; + }; + 7B66860C22B3F70E0029E6F1 /* Test-Prod */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = BDE6D164A37B938C860EDF5F /* Pods-DomainLayer.test-prod.xcconfig */; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 3920; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 3920; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = DomainLayer/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 11; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = "$(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = com.wavesplatform.waveswallet.domainlayer; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = "Test-Prod"; + }; + 7B6686F822B7C5120029E6F1 /* Dev-Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 330A6CFEA80C3C564AC3C090 /* Pods-Extensions.dev-debug.xcconfig */; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 3920; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 3920; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + HEADER_SEARCH_PATHS = "$(inherited)"; + INFOPLIST_FILE = Extensions/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 11; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + OTHER_CFLAGS = "$(inherited)"; + OTHER_LDFLAGS = "$(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = com.wavesplatform.waveswallet.extensions; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = "Dev-Debug"; + }; + 7B6686F922B7C5120029E6F1 /* Release-Prod */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 15AE893AD1EB53FBCDA161D5 /* Pods-Extensions.release-prod.xcconfig */; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 3920; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 3920; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + GCC_C_LANGUAGE_STANDARD = gnu11; + HEADER_SEARCH_PATHS = "$(inherited)"; + INFOPLIST_FILE = Extensions/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 11; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + OTHER_CFLAGS = "$(inherited)"; + OTHER_LDFLAGS = "$(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = com.wavesplatform.waveswallet.extensions; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = "Release-Prod"; + }; + 7B6686FA22B7C5120029E6F1 /* Test-Dev */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = B7A25F7D6E4B1692329D7BF7 /* Pods-Extensions.test-dev.xcconfig */; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 3920; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 3920; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + GCC_C_LANGUAGE_STANDARD = gnu11; + HEADER_SEARCH_PATHS = "$(inherited)"; + INFOPLIST_FILE = Extensions/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 11; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + OTHER_CFLAGS = "$(inherited)"; + OTHER_LDFLAGS = "$(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = com.wavesplatform.waveswallet.extensions; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = "Test-Dev"; + }; + 7B6686FB22B7C5120029E6F1 /* Test-Prod */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 5B93090B2CB93A36B3FC8D0F /* Pods-Extensions.test-prod.xcconfig */; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 3920; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 3920; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + GCC_C_LANGUAGE_STANDARD = gnu11; + HEADER_SEARCH_PATHS = "$(inherited)"; + INFOPLIST_FILE = Extensions/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 11; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + OTHER_CFLAGS = "$(inherited)"; + OTHER_LDFLAGS = "$(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = com.wavesplatform.waveswallet.extensions; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = "Test-Prod"; + }; + 7B66872D22B7E68B0029E6F1 /* Dev-Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = AD61D54FAF8C35F7FE42B48C /* Pods-DataLayer.dev-debug.xcconfig */; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 3920; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 3920; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = DataLayer/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 11; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = "$(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = com.wavesplatform.waveswallet.datalayer; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = "Dev-Debug"; + }; + 7B66872E22B7E68B0029E6F1 /* Release-Prod */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 8C9A1159470FED7057790330 /* Pods-DataLayer.release-prod.xcconfig */; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 3920; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 3920; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = DataLayer/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 11; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = "$(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = com.wavesplatform.waveswallet.datalayer; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = "Release-Prod"; + }; + 7B66872F22B7E68B0029E6F1 /* Test-Dev */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = FBF207267CD94C94CF647176 /* Pods-DataLayer.test-dev.xcconfig */; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 3920; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 3920; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = DataLayer/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 11; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = "$(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = com.wavesplatform.waveswallet.datalayer; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = "Test-Dev"; + }; + 7B66873022B7E68B0029E6F1 /* Test-Prod */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 95576FFA8929D9E05D7BF2BE /* Pods-DataLayer.test-prod.xcconfig */; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 3920; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 3920; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = DataLayer/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 11; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = "$(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = com.wavesplatform.waveswallet.datalayer; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = "Test-Prod"; + }; + 7B83A7E022D8C7500038180D /* Dev-Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = 96SW78M3KJ; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + INFOPLIST_FILE = DummyForTest/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_BUNDLE_IDENTIFIER = WV.DummyForTest; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = "Dev-Debug"; + }; + 7B83A7E122D8C7500038180D /* Dev-Adhoc */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = 96SW78M3KJ; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + INFOPLIST_FILE = DummyForTest/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = WV.DummyForTest; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = "Dev-Adhoc"; + }; + 7B83A7E222D8C7500038180D /* Release-Prod */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = 96SW78M3KJ; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + INFOPLIST_FILE = DummyForTest/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = WV.DummyForTest; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = "Release-Prod"; + }; + 7B83A7E322D8C7500038180D /* Release-Dev */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = 96SW78M3KJ; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + INFOPLIST_FILE = DummyForTest/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = WV.DummyForTest; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = "Release-Dev"; + }; + 7B83A7E422D8C7500038180D /* Test-Dev */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = 96SW78M3KJ; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + INFOPLIST_FILE = DummyForTest/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = WV.DummyForTest; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = "Test-Dev"; + }; + 7B83A7E522D8C7500038180D /* Test-Prod */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = 96SW78M3KJ; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + INFOPLIST_FILE = DummyForTest/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = WV.DummyForTest; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = "Test-Prod"; + }; + 7BF509DE22D89DDF00582783 /* Dev-Adhoc */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_INCLUDE_PATHS = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.2; + }; + name = "Dev-Adhoc"; + }; + 7BF509DF22D89DDF00582783 /* Dev-Adhoc */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D206585280B732B56334628E /* Pods-WavesWallet-iOS.dev-adhoc.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-Dev"; + CLANG_USE_OPTIMIZATION_PROFILE = YES; + CODE_SIGN_ENTITLEMENTS = "WavesWallet-iOS/WavesWallet-iOS-Dev.entitlements"; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 3920; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = NO; + DEVELOPMENT_TEAM = 96SW78M3KJ; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + HEADER_SEARCH_PATHS = "$(inherited)"; + INFOPLIST_FILE = "WavesWallet-iOS/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 11; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = "$(inherited)"; + MARKETING_VERSION = 2.6.2; + OTHER_LDFLAGS = "$(inherited)"; + OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" -Xfrontend -warn-long-function-bodies=200 -Xfrontend -warn-long-expression-type-checking=200"; + PRODUCT_BUNDLE_IDENTIFIER = com.wavesplatform.waveswallet.dev; + PRODUCT_MODULE_NAME = WavesWallet_iOS; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE_SPECIFIER = "match AdHoc com.wavesplatform.waveswallet.dev"; + SWIFT_COMPILATION_MODE = singlefile; + SWIFT_INCLUDE_PATHS = "$(inherited) \"${PODS_CONFIGURATION_BUILD_DIR}/Alamofire\" \"${PODS_CONFIGURATION_BUILD_DIR}/Charts\" \"${PODS_CONFIGURATION_BUILD_DIR}/Differentiator\" \"${PODS_CONFIGURATION_BUILD_DIR}/Gloss\" \"${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift\" \"${PODS_CONFIGURATION_BUILD_DIR}/KeychainAccess\" \"${PODS_CONFIGURATION_BUILD_DIR}/Koloda\" \"${PODS_CONFIGURATION_BUILD_DIR}/Moya\" \"${PODS_CONFIGURATION_BUILD_DIR}/QRCode\" \"${PODS_CONFIGURATION_BUILD_DIR}/QRCodeReader.swift\" \"${PODS_CONFIGURATION_BUILD_DIR}/RealmSwift\" \"${PODS_CONFIGURATION_BUILD_DIR}/Result\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxCocoa\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxDataSources\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxGesture\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxRealm\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxSwift\" \"${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON\" \"${PODS_CONFIGURATION_BUILD_DIR}/UPCarouselFlowLayout\" \"${PODS_ROOT}/Headers/Public\"/**"; + SWIFT_OBJC_BRIDGING_HEADER = "WavesWallet-iOS/Resources/ObjCBridgingHeader.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = ""; + }; + name = "Dev-Adhoc"; + }; + 7BF509E022D89DDF00582783 /* Dev-Adhoc */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A9E634B5E087D00A1F31D61E /* Pods-MonkeyTest.dev-adhoc.xcconfig */; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + "MONKEY_TEST=1", + ); + INFOPLIST_FILE = MonkeyTest/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = WV.MonkeyTest; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = "WavesWallet-iOS"; + }; + name = "Dev-Adhoc"; + }; + 7BF509E122D89DDF00582783 /* Dev-Adhoc */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 358F7A355EB990FE9BE8A2BE /* Pods-DomainLayer.dev-adhoc.xcconfig */; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 3920; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 3920; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = DomainLayer/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 11; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = "$(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = com.wavesplatform.waveswallet.domainlayer; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = "Dev-Adhoc"; + }; + 7BF509E222D89DDF00582783 /* Dev-Adhoc */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 8E83213560285F82F0869981 /* Pods-Extensions.dev-adhoc.xcconfig */; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 3920; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 3920; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + HEADER_SEARCH_PATHS = "$(inherited)"; + INFOPLIST_FILE = Extensions/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 11; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + OTHER_CFLAGS = "$(inherited)"; + OTHER_LDFLAGS = "$(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = com.wavesplatform.waveswallet.extensions; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = "Dev-Adhoc"; + }; + 7BF509E322D89DDF00582783 /* Dev-Adhoc */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4002342AE27E8283A7330127 /* Pods-DataLayer.dev-adhoc.xcconfig */; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 3920; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 3920; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = DataLayer/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 11; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = "$(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = com.wavesplatform.waveswallet.datalayer; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = "Dev-Adhoc"; + }; + 7BF509E422D89DDF00582783 /* Dev-Adhoc */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DAD260D2DDC7E839EDD12EA6 /* Pods-DomainLayerTests.dev-adhoc.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 96SW78M3KJ; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = DomainLayerTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + OTHER_SWIFT_FLAGS = "$(inherited) -D COCOAPODS"; + PRODUCT_BUNDLE_IDENTIFIER = WV.DomainLayerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DummyForTest.app/DummyForTest"; + }; + name = "Dev-Adhoc"; + }; + 7BF509E522D89DDF00582783 /* Dev-Adhoc */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 14D96B733AE3D2EDCB81A40F /* Pods-DataLayerTests.dev-adhoc.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 96SW78M3KJ; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = DataLayerTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = WV.DataLayerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DummyForTest.app/DummyForTest"; + }; + name = "Dev-Adhoc"; + }; + 7BF509E622D89FA200582783 /* Release-Dev */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = ""; + SWIFT_INCLUDE_PATHS = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 4.2; + VALIDATE_PRODUCT = YES; + }; + name = "Release-Dev"; + }; + 7BF509E722D89FA200582783 /* Release-Dev */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7A79F97385011A8CE0363A70 /* Pods-WavesWallet-iOS.release-dev.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_USE_OPTIMIZATION_PROFILE = YES; + CODE_SIGN_ENTITLEMENTS = "WavesWallet-iOS/WavesWallet-iOS.entitlements"; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 3920; + DEFINES_MODULE = NO; + DEVELOPMENT_TEAM = 96SW78M3KJ; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + HEADER_SEARCH_PATHS = "$(inherited)"; + INFOPLIST_FILE = "WavesWallet-iOS/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 11; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = "$(inherited)"; + MARKETING_VERSION = 2.6.2; + ONLY_ACTIVE_ARCH = YES; + OTHER_LDFLAGS = "$(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = com.wavesplatform.WavesWallet; + PRODUCT_MODULE_NAME = WavesWallet_iOS; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE_SPECIFIER = "match Development com.wavesplatform.WavesWallet"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = ""; + SWIFT_INCLUDE_PATHS = "$(inherited) \"${PODS_CONFIGURATION_BUILD_DIR}/Alamofire\" \"${PODS_CONFIGURATION_BUILD_DIR}/Charts\" \"${PODS_CONFIGURATION_BUILD_DIR}/Differentiator\" \"${PODS_CONFIGURATION_BUILD_DIR}/Gloss\" \"${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift\" \"${PODS_CONFIGURATION_BUILD_DIR}/KeychainAccess\" \"${PODS_CONFIGURATION_BUILD_DIR}/Koloda\" \"${PODS_CONFIGURATION_BUILD_DIR}/Moya\" \"${PODS_CONFIGURATION_BUILD_DIR}/QRCode\" \"${PODS_CONFIGURATION_BUILD_DIR}/QRCodeReader.swift\" \"${PODS_CONFIGURATION_BUILD_DIR}/RealmSwift\" \"${PODS_CONFIGURATION_BUILD_DIR}/Result\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxCocoa\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxDataSources\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxGesture\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxRealm\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxSwift\" \"${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON\" \"${PODS_CONFIGURATION_BUILD_DIR}/UPCarouselFlowLayout\" \"${PODS_ROOT}/Headers/Public\"/**"; + SWIFT_OBJC_BRIDGING_HEADER = "WavesWallet-iOS/Resources/ObjCBridgingHeader.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = ""; + }; + name = "Release-Dev"; + }; + 7BF509E822D89FA200582783 /* Release-Dev */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 8B03F78A9DF177D8D9723E8D /* Pods-MonkeyTest.release-dev.xcconfig */; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = MonkeyTest/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = WV.MonkeyTest; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = "WavesWallet-iOS"; + }; + name = "Release-Dev"; + }; + 7BF509E922D89FA200582783 /* Release-Dev */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = CEB61763B0920D458B8C82AE /* Pods-DomainLayer.release-dev.xcconfig */; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 3920; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 3920; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = DomainLayer/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 11; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = "$(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = com.wavesplatform.waveswallet.domainlayer; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = "Release-Dev"; + }; + 7BF509EA22D89FA200582783 /* Release-Dev */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 8A551BA048F9720698C5BF39 /* Pods-Extensions.release-dev.xcconfig */; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 3920; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 3920; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + GCC_C_LANGUAGE_STANDARD = gnu11; + HEADER_SEARCH_PATHS = "$(inherited)"; + INFOPLIST_FILE = Extensions/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 11; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + OTHER_CFLAGS = "$(inherited)"; + OTHER_LDFLAGS = "$(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = com.wavesplatform.waveswallet.extensions; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = "Release-Dev"; + }; + 7BF509EB22D89FA200582783 /* Release-Dev */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 30B16B6ED15D84C95E9C0700 /* Pods-DataLayer.release-dev.xcconfig */; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 3920; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 3920; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = DataLayer/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 11; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = "$(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = com.wavesplatform.waveswallet.datalayer; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = "Release-Dev"; + }; + 7BF509EC22D89FA200582783 /* Release-Dev */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = F65361A881CC9B52F2835293 /* Pods-DomainLayerTests.release-dev.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 96SW78M3KJ; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = DomainLayerTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + OTHER_SWIFT_FLAGS = "$(inherited) -D COCOAPODS"; + PRODUCT_BUNDLE_IDENTIFIER = WV.DomainLayerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DummyForTest.app/DummyForTest"; + }; + name = "Release-Dev"; + }; + 7BF509ED22D89FA200582783 /* Release-Dev */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C880B220C9E5499780C35467 /* Pods-DataLayerTests.release-dev.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 96SW78M3KJ; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = DataLayerTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = WV.DataLayerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DummyForTest.app/DummyForTest"; + }; + name = "Release-Dev"; + }; + 7BF89E9E22272A5E00853F9D /* Dev-Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AE17C6CE90449256074E98F /* Pods-MonkeyTest.dev-debug.xcconfig */; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + "MONKEY_TEST=1", + ); + INFOPLIST_FILE = MonkeyTest/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = WV.MonkeyTest; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = "WavesWallet-iOS"; + }; + name = "Dev-Debug"; + }; + 7BF89E9F22272A5E00853F9D /* Release-Prod */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 42540834023E32A59FAD0948 /* Pods-MonkeyTest.release-prod.xcconfig */; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = MonkeyTest/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = WV.MonkeyTest; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = "WavesWallet-iOS"; + }; + name = "Release-Prod"; + }; + 7BF89EA022272A5E00853F9D /* Test-Dev */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 664726FDDF58367CA0C7AEFA /* Pods-MonkeyTest.test-dev.xcconfig */; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = MonkeyTest/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = WV.MonkeyTest; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = "WavesWallet-iOS"; + }; + name = "Test-Dev"; }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 0AF92301212E1424003BA067 /* Waves.strings */ = { - isa = PBXVariantGroup; - children = ( - 0AF92302212E1424003BA067 /* en */, - 0AF92304212E142A003BA067 /* ru */, - 0A15081C219AE51100516037 /* ko */, - 0A15081E219AE53700516037 /* es */, - 0AACD5A121A5C15800B30815 /* id */, - 0AACD5A521A5C18300B30815 /* de */, - 0A02D20921AEDD3C005DF820 /* ja */, - 0A9CA14D21C16B4A003C0A1B /* tr */, - 0A9CA15121C16E70003C0A1B /* pt-BR */, - 0A7BFD4E21CCEA8100B29654 /* pt-PT */, - E96D1B922249923000D31D17 /* pl */, - E96D1B942249956F00D31D17 /* it */, - 7B95110F225CC2CF0030390C /* nl-NL */, - 7B951111225CC2E60030390C /* hi-IN */, - 7B951113225CC32C0030390C /* zh-Hans-CN */, - 7B32A904229EEFB1004789E7 /* fr-FR */, - ); - name = Waves.strings; - sourceTree = ""; + 7BF89EA122272A5E00853F9D /* Test-Prod */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0F5A04DF94D5267FF54BF4A9 /* Pods-MonkeyTest.test-prod.xcconfig */; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = MonkeyTest/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = WV.MonkeyTest; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = "WavesWallet-iOS"; + }; + name = "Test-Prod"; }; - 0AFBCA832113173300285BCB /* InfoPlist.strings */ = { - isa = PBXVariantGroup; - children = ( - 0AFBCA862113188A00285BCB /* en */, - 0AFBCA872113188B00285BCB /* ru */, - 0A15081B219AE51100516037 /* ko */, - 0A15081D219AE53600516037 /* es */, - 0AACD5A021A5C15800B30815 /* id */, - 0AACD5A421A5C18300B30815 /* de */, - 0A02D20821AEDD3C005DF820 /* ja */, - 0A9CA14C21C16B4A003C0A1B /* tr */, - 0A9CA15021C16E6F003C0A1B /* pt-BR */, - 0A7BFD4D21CCEA8000B29654 /* pt-PT */, - E96D1B912249922F00D31D17 /* pl */, - E96D1B932249956E00D31D17 /* it */, - 7B95110E225CC2CF0030390C /* nl-NL */, - 7B951110225CC2E60030390C /* hi-IN */, - 7B951112225CC32B0030390C /* zh-Hans-CN */, - 7B32A903229EEFB0004789E7 /* fr-FR */, - ); - name = InfoPlist.strings; - sourceTree = ""; + E9B190B422E7CD9A008220B7 /* Dev-Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 39D072CCF146C6CC2C64586F /* Pods-MarketPulseWidget.dev-debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_ENTITLEMENTS = MarketPulseWidget/MarketPulseWidget.entitlements; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = 96SW78M3KJ; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + INFOPLIST_FILE = MarketPulseWidget/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.wavesplatform.waveswallet.dev.widgetmarketpulse; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "match Development com.wavesplatform.waveswallet.dev.widgetmarketpulse"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = "Dev-Debug"; + }; + E9B190B522E7CD9A008220B7 /* Dev-Adhoc */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7BDD7F47C7597E6AD76837FD /* Pods-MarketPulseWidget.dev-adhoc.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_ENTITLEMENTS = MarketPulseWidget/MarketPulseWidget.entitlements; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = 96SW78M3KJ; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + INFOPLIST_FILE = MarketPulseWidget/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.wavesplatform.waveswallet.dev.widgetmarketpulse; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "match AdHoc com.wavesplatform.waveswallet.dev.widgetmarketpulse"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = "Dev-Adhoc"; + }; + E9B190B622E7CD9A008220B7 /* Release-Prod */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 09C7B309A88856F7E5362438 /* Pods-MarketPulseWidget.release-prod.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_ENTITLEMENTS = MarketPulseWidget/MarketPulseWidget.entitlements; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 3920; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = 96SW78M3KJ; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + INFOPLIST_FILE = MarketPulseWidget/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.wavesplatform.WavesWallet.widgetmarketpulse; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "match AppStore com.wavesplatform.WavesWallet.widgetmarketpulse"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = "Release-Prod"; }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 0A15081F219B04DF00516037 /* Test-Build */ = { + E9B190B722E7CD9A008220B7 /* Release-Dev */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 1E821BB79863BE6E2DFD41B1 /* Pods-MarketPulseWidget.release-dev.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; @@ -6290,74 +10068,55 @@ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_ENTITLEMENTS = MarketPulseWidget/MarketPulseWidget.entitlements; + CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = 96SW78M3KJ; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; - GCC_PREPROCESSOR_DEFINITIONS = "TEST=1"; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + INFOPLIST_FILE = MarketPulseWidget/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.wavesplatform.WavesWallet.widgetmarketpulse; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "match Development com.wavesplatform.WavesWallet.widgetmarketpulse"; SDKROOT = iphoneos; - SWIFT_INCLUDE_PATHS = ""; + SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 4.2; - VALIDATE_PRODUCT = YES; - }; - name = "Test-Build"; - }; - 0A150820219B04DF00516037 /* Test-Build */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = AFB68EB998D497670C5F75E3 /* Pods-WavesWallet-iOS.test-build.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-Test"; - CLANG_USE_OPTIMIZATION_PROFILE = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 3857; - DEFINES_MODULE = NO; - DEVELOPMENT_TEAM = 96SW78M3KJ; - FRAMEWORK_SEARCH_PATHS = "$(inherited)"; - HEADER_SEARCH_PATHS = "$(inherited)"; - INFOPLIST_FILE = "WavesWallet-iOS/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 11; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = "$(inherited)"; - PRODUCT_BUNDLE_IDENTIFIER = com.wavesplatform.waveswallet.test; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE = ""; - PROVISIONING_PROFILE_SPECIFIER = "match Development com.wavesplatform.waveswallet.test"; - SWIFT_COMPILATION_MODE = singlefile; - SWIFT_INCLUDE_PATHS = "$(inherited) \"${PODS_CONFIGURATION_BUILD_DIR}/Alamofire\" \"${PODS_CONFIGURATION_BUILD_DIR}/Charts\" \"${PODS_CONFIGURATION_BUILD_DIR}/Differentiator\" \"${PODS_CONFIGURATION_BUILD_DIR}/Gloss\" \"${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift\" \"${PODS_CONFIGURATION_BUILD_DIR}/KeychainAccess\" \"${PODS_CONFIGURATION_BUILD_DIR}/Koloda\" \"${PODS_CONFIGURATION_BUILD_DIR}/Moya\" \"${PODS_CONFIGURATION_BUILD_DIR}/QRCode\" \"${PODS_CONFIGURATION_BUILD_DIR}/QRCodeReader.swift\" \"${PODS_CONFIGURATION_BUILD_DIR}/RealmSwift\" \"${PODS_CONFIGURATION_BUILD_DIR}/Result\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxAlamofire\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxCocoa\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxDataSources\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxGesture\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxRealm\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxSwift\" \"${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON\" \"${PODS_CONFIGURATION_BUILD_DIR}/UPCarouselFlowLayout\" \"${PODS_ROOT}/Headers/Public\"/**"; - SWIFT_OBJC_BRIDGING_HEADER = "WavesWallet-iOS/Resources/ObjCBridgingHeader.h"; - SWIFT_OPTIMIZATION_LEVEL = "-O"; SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = ""; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; }; - name = "Test-Build"; + name = "Release-Dev"; }; - 0A762DA4216512420019D447 /* Test */ = { + E9B190B822E7CD9A008220B7 /* Test-Dev */ = { isa = XCBuildConfiguration; + baseConfigurationReference = ABBE8EE95A2EDD196C036A99 /* Pods-MarketPulseWidget.test-dev.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; @@ -6376,160 +10135,111 @@ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_ENTITLEMENTS = MarketPulseWidget/MarketPulseWidget.entitlements; + CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = 96SW78M3KJ; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; - GCC_PREPROCESSOR_DEFINITIONS = "TEST=1"; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + INFOPLIST_FILE = MarketPulseWidget/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.wavesplatform.waveswallet.test.widgetmarketpulse; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "match Development com.wavesplatform.waveswallet.test.widgetmarketpulse"; SDKROOT = iphoneos; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = ""; - SWIFT_INCLUDE_PATHS = ""; + SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 4.2; - VALIDATE_PRODUCT = YES; - }; - name = Test; - }; - 0A762DA5216512420019D447 /* Test */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 2A5A5CDBE4190D8A1A1C4124 /* Pods-WavesWallet-iOS.test.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-Test"; - CLANG_USE_OPTIMIZATION_PROFILE = YES; - CODE_SIGN_IDENTITY = "iPhone Distribution"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 3857; - DEFINES_MODULE = NO; - DEVELOPMENT_TEAM = 96SW78M3KJ; - FRAMEWORK_SEARCH_PATHS = "$(inherited)"; - HEADER_SEARCH_PATHS = "$(inherited)"; - INFOPLIST_FILE = "WavesWallet-iOS/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 11; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = "$(inherited)"; - PRODUCT_BUNDLE_IDENTIFIER = com.wavesplatform.waveswallet.test; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE = ""; - PROVISIONING_PROFILE_SPECIFIER = "match AdHoc com.wavesplatform.waveswallet.test"; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = ""; - SWIFT_COMPILATION_MODE = singlefile; - SWIFT_INCLUDE_PATHS = "$(inherited) \"${PODS_CONFIGURATION_BUILD_DIR}/Alamofire\" \"${PODS_CONFIGURATION_BUILD_DIR}/Charts\" \"${PODS_CONFIGURATION_BUILD_DIR}/Differentiator\" \"${PODS_CONFIGURATION_BUILD_DIR}/Gloss\" \"${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift\" \"${PODS_CONFIGURATION_BUILD_DIR}/KeychainAccess\" \"${PODS_CONFIGURATION_BUILD_DIR}/Koloda\" \"${PODS_CONFIGURATION_BUILD_DIR}/Moya\" \"${PODS_CONFIGURATION_BUILD_DIR}/QRCode\" \"${PODS_CONFIGURATION_BUILD_DIR}/QRCodeReader.swift\" \"${PODS_CONFIGURATION_BUILD_DIR}/RealmSwift\" \"${PODS_CONFIGURATION_BUILD_DIR}/Result\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxAlamofire\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxCocoa\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxDataSources\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxGesture\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxRealm\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxSwift\" \"${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON\" \"${PODS_CONFIGURATION_BUILD_DIR}/UPCarouselFlowLayout\" \"${PODS_ROOT}/Headers/Public\"/**"; - SWIFT_OBJC_BRIDGING_HEADER = "WavesWallet-iOS/Resources/ObjCBridgingHeader.h"; - SWIFT_OPTIMIZATION_LEVEL = "-O"; SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = ""; - }; - name = Test; - }; - 7BF89E9E22272A5E00853F9D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = F7361C3F79C88A0896BACB0C /* Pods-MonkeyTest.debug.xcconfig */; - buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - "MONKEY_TEST=1", - ); - INFOPLIST_FILE = MonkeyTest/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.1; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = WV.MonkeyTest; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 4.2; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_TARGET_NAME = "WavesWallet-iOS"; - }; - name = Debug; - }; - 7BF89E9F22272A5E00853F9D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 8929E19527D7945D5DC03230 /* Pods-MonkeyTest.release.xcconfig */; - buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = MonkeyTest/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.1; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = WV.MonkeyTest; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 4.2; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_TARGET_NAME = "WavesWallet-iOS"; - }; - name = Release; - }; - 7BF89EA022272A5E00853F9D /* Test-Build */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D0E2547DB09713AC51E70B93 /* Pods-MonkeyTest.test-build.xcconfig */; - buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = MonkeyTest/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.1; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = WV.MonkeyTest; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_TARGET_NAME = "WavesWallet-iOS"; + VALIDATE_PRODUCT = YES; }; - name = "Test-Build"; + name = "Test-Dev"; }; - 7BF89EA122272A5E00853F9D /* Test */ = { + E9B190B922E7CD9A008220B7 /* Test-Prod */ = { isa = XCBuildConfiguration; - baseConfigurationReference = A1E804B3D4295816120F6042 /* Pods-MonkeyTest.test.xcconfig */; + baseConfigurationReference = 4A5FEAF1E09BD85095F7190B /* Pods-MarketPulseWidget.test-prod.xcconfig */; buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_ENTITLEMENTS = MarketPulseWidget/MarketPulseWidget.entitlements; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = 96SW78M3KJ; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = MonkeyTest/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.1; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + INFOPLIST_FILE = MarketPulseWidget/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; + MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = WV.MonkeyTest; + PRODUCT_BUNDLE_IDENTIFIER = com.wavesplatform.waveswallet.test.widgetmarketpulse; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 4.2; + PROVISIONING_PROFILE_SPECIFIER = "match AppStore com.wavesplatform.waveswallet.test.widgetmarketpulse"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_TARGET_NAME = "WavesWallet-iOS"; + VALIDATE_PRODUCT = YES; }; - name = Test; + name = "Test-Prod"; }; - F7E954F61EA8FE0700A804DE /* Debug */ = { + F7E954F61EA8FE0700A804DE /* Dev-Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; @@ -6572,7 +10282,6 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", - TRACE_RESOURCES, ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; @@ -6580,7 +10289,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -6589,9 +10298,9 @@ SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 4.2; }; - name = Debug; + name = "Dev-Debug"; }; - F7E954F71EA8FE0700A804DE /* Release */ = { + F7E954F71EA8FE0700A804DE /* Release-Prod */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; @@ -6635,7 +10344,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_INCLUDE_PATHS = ""; @@ -6643,18 +10352,20 @@ SWIFT_VERSION = 4.2; VALIDATE_PRODUCT = YES; }; - name = Release; + name = "Release-Prod"; }; - F7E954F91EA8FE0700A804DE /* Debug */ = { + F7E954F91EA8FE0700A804DE /* Dev-Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 965E90884D099176A23D5038 /* Pods-WavesWallet-iOS.debug.xcconfig */; + baseConfigurationReference = 16E2A809803D77F7ACA94D8C /* Pods-WavesWallet-iOS.dev-debug.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-Dev"; CLANG_USE_OPTIMIZATION_PROFILE = YES; + CODE_SIGN_ENTITLEMENTS = "WavesWallet-iOS/WavesWallet-iOS-Dev.entitlements"; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 3857; + CURRENT_PROJECT_VERSION = 3920; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = NO; DEVELOPMENT_TEAM = 96SW78M3KJ; @@ -6664,30 +10375,35 @@ IPHONEOS_DEPLOYMENT_TARGET = 11; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LIBRARY_SEARCH_PATHS = "$(inherited)"; + MARKETING_VERSION = 2.6.2; + OTHER_LDFLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" -Xfrontend -warn-long-function-bodies=200 -Xfrontend -warn-long-expression-type-checking=200"; PRODUCT_BUNDLE_IDENTIFIER = com.wavesplatform.waveswallet.dev; + PRODUCT_MODULE_NAME = WavesWallet_iOS; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = "match Development com.wavesplatform.waveswallet.dev"; SWIFT_COMPILATION_MODE = singlefile; - SWIFT_INCLUDE_PATHS = "$(inherited) \"${PODS_CONFIGURATION_BUILD_DIR}/Alamofire\" \"${PODS_CONFIGURATION_BUILD_DIR}/Charts\" \"${PODS_CONFIGURATION_BUILD_DIR}/Differentiator\" \"${PODS_CONFIGURATION_BUILD_DIR}/Gloss\" \"${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift\" \"${PODS_CONFIGURATION_BUILD_DIR}/KeychainAccess\" \"${PODS_CONFIGURATION_BUILD_DIR}/Koloda\" \"${PODS_CONFIGURATION_BUILD_DIR}/Moya\" \"${PODS_CONFIGURATION_BUILD_DIR}/QRCode\" \"${PODS_CONFIGURATION_BUILD_DIR}/QRCodeReader.swift\" \"${PODS_CONFIGURATION_BUILD_DIR}/RealmSwift\" \"${PODS_CONFIGURATION_BUILD_DIR}/Result\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxAlamofire\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxCocoa\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxDataSources\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxGesture\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxRealm\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxSwift\" \"${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON\" \"${PODS_CONFIGURATION_BUILD_DIR}/UPCarouselFlowLayout\" \"${PODS_ROOT}/Headers/Public\"/**"; + SWIFT_INCLUDE_PATHS = "$(inherited) \"${PODS_CONFIGURATION_BUILD_DIR}/Alamofire\" \"${PODS_CONFIGURATION_BUILD_DIR}/Charts\" \"${PODS_CONFIGURATION_BUILD_DIR}/Differentiator\" \"${PODS_CONFIGURATION_BUILD_DIR}/Gloss\" \"${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift\" \"${PODS_CONFIGURATION_BUILD_DIR}/KeychainAccess\" \"${PODS_CONFIGURATION_BUILD_DIR}/Koloda\" \"${PODS_CONFIGURATION_BUILD_DIR}/Moya\" \"${PODS_CONFIGURATION_BUILD_DIR}/QRCode\" \"${PODS_CONFIGURATION_BUILD_DIR}/QRCodeReader.swift\" \"${PODS_CONFIGURATION_BUILD_DIR}/RealmSwift\" \"${PODS_CONFIGURATION_BUILD_DIR}/Result\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxCocoa\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxDataSources\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxGesture\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxRealm\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxSwift\" \"${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON\" \"${PODS_CONFIGURATION_BUILD_DIR}/UPCarouselFlowLayout\" \"${PODS_ROOT}/Headers/Public\"/**"; SWIFT_OBJC_BRIDGING_HEADER = "WavesWallet-iOS/Resources/ObjCBridgingHeader.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = ""; }; - name = Debug; + name = "Dev-Debug"; }; - F7E954FA1EA8FE0700A804DE /* Release */ = { + F7E954FA1EA8FE0700A804DE /* Release-Prod */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 3780CE9B95DA4BD90D83FC04 /* Pods-WavesWallet-iOS.release.xcconfig */; + baseConfigurationReference = 344A99254C39E6D45BA6BFEE /* Pods-WavesWallet-iOS.release-prod.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_USE_OPTIMIZATION_PROFILE = YES; + CODE_SIGN_ENTITLEMENTS = "WavesWallet-iOS/WavesWallet-iOS.entitlements"; CODE_SIGN_IDENTITY = "iPhone Distribution"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 3857; + CURRENT_PROJECT_VERSION = 3920; DEFINES_MODULE = NO; DEVELOPMENT_TEAM = 96SW78M3KJ; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -6696,54 +10412,154 @@ IPHONEOS_DEPLOYMENT_TARGET = 11; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LIBRARY_SEARCH_PATHS = "$(inherited)"; + MARKETING_VERSION = 2.6.2; + OTHER_LDFLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.wavesplatform.WavesWallet; + PRODUCT_MODULE_NAME = WavesWallet_iOS; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = "match AppStore com.wavesplatform.WavesWallet"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = ""; - SWIFT_INCLUDE_PATHS = "$(inherited) \"${PODS_CONFIGURATION_BUILD_DIR}/Alamofire\" \"${PODS_CONFIGURATION_BUILD_DIR}/Charts\" \"${PODS_CONFIGURATION_BUILD_DIR}/Differentiator\" \"${PODS_CONFIGURATION_BUILD_DIR}/Gloss\" \"${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift\" \"${PODS_CONFIGURATION_BUILD_DIR}/KeychainAccess\" \"${PODS_CONFIGURATION_BUILD_DIR}/Koloda\" \"${PODS_CONFIGURATION_BUILD_DIR}/Moya\" \"${PODS_CONFIGURATION_BUILD_DIR}/QRCode\" \"${PODS_CONFIGURATION_BUILD_DIR}/QRCodeReader.swift\" \"${PODS_CONFIGURATION_BUILD_DIR}/RealmSwift\" \"${PODS_CONFIGURATION_BUILD_DIR}/Result\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxAlamofire\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxCocoa\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxDataSources\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxGesture\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxRealm\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxSwift\" \"${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON\" \"${PODS_CONFIGURATION_BUILD_DIR}/UPCarouselFlowLayout\" \"${PODS_ROOT}/Headers/Public\"/**"; + SWIFT_INCLUDE_PATHS = "$(inherited) \"${PODS_CONFIGURATION_BUILD_DIR}/Alamofire\" \"${PODS_CONFIGURATION_BUILD_DIR}/Charts\" \"${PODS_CONFIGURATION_BUILD_DIR}/Differentiator\" \"${PODS_CONFIGURATION_BUILD_DIR}/Gloss\" \"${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift\" \"${PODS_CONFIGURATION_BUILD_DIR}/KeychainAccess\" \"${PODS_CONFIGURATION_BUILD_DIR}/Koloda\" \"${PODS_CONFIGURATION_BUILD_DIR}/Moya\" \"${PODS_CONFIGURATION_BUILD_DIR}/QRCode\" \"${PODS_CONFIGURATION_BUILD_DIR}/QRCodeReader.swift\" \"${PODS_CONFIGURATION_BUILD_DIR}/RealmSwift\" \"${PODS_CONFIGURATION_BUILD_DIR}/Result\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxCocoa\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxDataSources\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxGesture\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxRealm\" \"${PODS_CONFIGURATION_BUILD_DIR}/RxSwift\" \"${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON\" \"${PODS_CONFIGURATION_BUILD_DIR}/UPCarouselFlowLayout\" \"${PODS_ROOT}/Headers/Public\"/**"; SWIFT_OBJC_BRIDGING_HEADER = "WavesWallet-iOS/Resources/ObjCBridgingHeader.h"; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = ""; }; - name = Release; + name = "Release-Prod"; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 7B431A9722BD176D00DE73B9 /* Build configuration list for PBXNativeTarget "DomainLayerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7B431A9322BD176D00DE73B9 /* Dev-Debug */, + 7BF509E422D89DDF00582783 /* Dev-Adhoc */, + 7B431A9422BD176D00DE73B9 /* Release-Prod */, + 7BF509EC22D89FA200582783 /* Release-Dev */, + 7B431A9522BD176D00DE73B9 /* Test-Dev */, + 7B431A9622BD176D00DE73B9 /* Test-Prod */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = "Dev-Debug"; + }; + 7B431AA322BD185B00DE73B9 /* Build configuration list for PBXNativeTarget "DataLayerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7B431AA422BD185B00DE73B9 /* Dev-Debug */, + 7BF509E522D89DDF00582783 /* Dev-Adhoc */, + 7B431AA522BD185B00DE73B9 /* Release-Prod */, + 7BF509ED22D89FA200582783 /* Release-Dev */, + 7B431AA622BD185B00DE73B9 /* Test-Dev */, + 7B431AA722BD185B00DE73B9 /* Test-Prod */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = "Dev-Debug"; + }; + 7B66860D22B3F70E0029E6F1 /* Build configuration list for PBXNativeTarget "DomainLayer" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7B66860922B3F70E0029E6F1 /* Dev-Debug */, + 7BF509E122D89DDF00582783 /* Dev-Adhoc */, + 7B66860A22B3F70E0029E6F1 /* Release-Prod */, + 7BF509E922D89FA200582783 /* Release-Dev */, + 7B66860B22B3F70E0029E6F1 /* Test-Dev */, + 7B66860C22B3F70E0029E6F1 /* Test-Prod */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = "Dev-Debug"; + }; + 7B6686F722B7C5120029E6F1 /* Build configuration list for PBXNativeTarget "Extensions" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7B6686F822B7C5120029E6F1 /* Dev-Debug */, + 7BF509E222D89DDF00582783 /* Dev-Adhoc */, + 7B6686F922B7C5120029E6F1 /* Release-Prod */, + 7BF509EA22D89FA200582783 /* Release-Dev */, + 7B6686FA22B7C5120029E6F1 /* Test-Dev */, + 7B6686FB22B7C5120029E6F1 /* Test-Prod */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = "Dev-Debug"; + }; + 7B66872C22B7E68B0029E6F1 /* Build configuration list for PBXNativeTarget "DataLayer" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7B66872D22B7E68B0029E6F1 /* Dev-Debug */, + 7BF509E322D89DDF00582783 /* Dev-Adhoc */, + 7B66872E22B7E68B0029E6F1 /* Release-Prod */, + 7BF509EB22D89FA200582783 /* Release-Dev */, + 7B66872F22B7E68B0029E6F1 /* Test-Dev */, + 7B66873022B7E68B0029E6F1 /* Test-Prod */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = "Dev-Debug"; + }; + 7B83A7DF22D8C7500038180D /* Build configuration list for PBXNativeTarget "DummyForTest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7B83A7E022D8C7500038180D /* Dev-Debug */, + 7B83A7E122D8C7500038180D /* Dev-Adhoc */, + 7B83A7E222D8C7500038180D /* Release-Prod */, + 7B83A7E322D8C7500038180D /* Release-Dev */, + 7B83A7E422D8C7500038180D /* Test-Dev */, + 7B83A7E522D8C7500038180D /* Test-Prod */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = "Dev-Debug"; + }; 7BF89E9D22272A5E00853F9D /* Build configuration list for PBXNativeTarget "MonkeyTest" */ = { isa = XCConfigurationList; buildConfigurations = ( - 7BF89E9E22272A5E00853F9D /* Debug */, - 7BF89E9F22272A5E00853F9D /* Release */, - 7BF89EA022272A5E00853F9D /* Test-Build */, - 7BF89EA122272A5E00853F9D /* Test */, + 7BF89E9E22272A5E00853F9D /* Dev-Debug */, + 7BF509E022D89DDF00582783 /* Dev-Adhoc */, + 7BF89E9F22272A5E00853F9D /* Release-Prod */, + 7BF509E822D89FA200582783 /* Release-Dev */, + 7BF89EA022272A5E00853F9D /* Test-Dev */, + 7BF89EA122272A5E00853F9D /* Test-Prod */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = "Dev-Debug"; + }; + E9B190BA22E7CD9A008220B7 /* Build configuration list for PBXNativeTarget "MarketPulseWidget" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E9B190B422E7CD9A008220B7 /* Dev-Debug */, + E9B190B522E7CD9A008220B7 /* Dev-Adhoc */, + E9B190B622E7CD9A008220B7 /* Release-Prod */, + E9B190B722E7CD9A008220B7 /* Release-Dev */, + E9B190B822E7CD9A008220B7 /* Test-Dev */, + E9B190B922E7CD9A008220B7 /* Test-Prod */, ); defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; + defaultConfigurationName = "Dev-Debug"; }; F7E954DF1EA8FE0600A804DE /* Build configuration list for PBXProject "WavesWallet-iOS" */ = { isa = XCConfigurationList; buildConfigurations = ( - F7E954F61EA8FE0700A804DE /* Debug */, - F7E954F71EA8FE0700A804DE /* Release */, - 0A15081F219B04DF00516037 /* Test-Build */, - 0A762DA4216512420019D447 /* Test */, + F7E954F61EA8FE0700A804DE /* Dev-Debug */, + 7BF509DE22D89DDF00582783 /* Dev-Adhoc */, + F7E954F71EA8FE0700A804DE /* Release-Prod */, + 7BF509E622D89FA200582783 /* Release-Dev */, + 0A15081F219B04DF00516037 /* Test-Dev */, + 0A762DA4216512420019D447 /* Test-Prod */, ); defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; + defaultConfigurationName = "Dev-Debug"; }; F7E954F81EA8FE0700A804DE /* Build configuration list for PBXNativeTarget "WavesWallet-iOS" */ = { isa = XCConfigurationList; buildConfigurations = ( - F7E954F91EA8FE0700A804DE /* Debug */, - F7E954FA1EA8FE0700A804DE /* Release */, - 0A150820219B04DF00516037 /* Test-Build */, - 0A762DA5216512420019D447 /* Test */, + F7E954F91EA8FE0700A804DE /* Dev-Debug */, + 7BF509DF22D89DDF00582783 /* Dev-Adhoc */, + F7E954FA1EA8FE0700A804DE /* Release-Prod */, + 7BF509E722D89FA200582783 /* Release-Dev */, + 0A150820219B04DF00516037 /* Test-Dev */, + 0A762DA5216512420019D447 /* Test-Prod */, ); defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; + defaultConfigurationName = "Dev-Debug"; }; /* End XCConfigurationList section */ }; diff --git a/WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/WavesWallet-iOS-Test-Build.xcscheme b/WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/DataLayerTests.xcscheme similarity index 62% rename from WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/WavesWallet-iOS-Test-Build.xcscheme rename to WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/DataLayerTests.xcscheme index 01d48443..6472fc3f 100644 --- a/WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/WavesWallet-iOS-Test-Build.xcscheme +++ b/WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/DataLayerTests.xcscheme @@ -1,6 +1,6 @@ @@ -32,9 +32,9 @@ skipped = "NO"> @@ -42,9 +42,9 @@ @@ -52,59 +52,48 @@ - + allowLocationSimulation = "YES"> + - - - - - + - + - + + buildConfiguration = "Dev-Debug"> diff --git a/WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/DomainLayer.xcscheme b/WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/DomainLayer.xcscheme new file mode 100644 index 00000000..8f976e8f --- /dev/null +++ b/WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/DomainLayer.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/DomainLayerTests.xcscheme b/WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/DomainLayerTests.xcscheme new file mode 100644 index 00000000..34200584 --- /dev/null +++ b/WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/DomainLayerTests.xcscheme @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/Extensions.xcscheme b/WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/Extensions.xcscheme new file mode 100644 index 00000000..710a16fb --- /dev/null +++ b/WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/Extensions.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/MarketPulseWidget.xcscheme b/WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/MarketPulseWidget.xcscheme new file mode 100644 index 00000000..1010cf91 --- /dev/null +++ b/WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/MarketPulseWidget.xcscheme @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/MonkeyTest-Dev.xcscheme b/WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/MonkeyTest-Dev.xcscheme index f3261710..12fa4c42 100644 --- a/WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/MonkeyTest-Dev.xcscheme +++ b/WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/MonkeyTest-Dev.xcscheme @@ -1,13 +1,17 @@ + buildForTesting = "YES" + buildForRunning = "YES" + buildForProfiling = "YES" + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + @@ -81,28 +117,44 @@ ReferencedContainer = "container:WavesWallet-iOS.xcodeproj"> + + + + + + + + + + + + + isEnabled = "NO"> - - - - + buildConfiguration = "Dev-Debug"> diff --git a/WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/WavesWallet-iOS-Release.xcscheme b/WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/WavesWallet-Release.xcscheme similarity index 83% rename from WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/WavesWallet-iOS-Release.xcscheme rename to WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/WavesWallet-Release.xcscheme index 433df245..766fb9ea 100644 --- a/WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/WavesWallet-iOS-Release.xcscheme +++ b/WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/WavesWallet-Release.xcscheme @@ -1,6 +1,6 @@ - - - - + buildConfiguration = "Release-Dev"> diff --git a/WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/WavesWallet-iOS-Test.xcscheme b/WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/WavesWallet-Test.xcscheme similarity index 76% rename from WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/WavesWallet-iOS-Test.xcscheme rename to WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/WavesWallet-Test.xcscheme index f9a9efcc..1f8eb9a1 100644 --- a/WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/WavesWallet-iOS-Test.xcscheme +++ b/WavesWallet-iOS.xcodeproj/xcshareddata/xcschemes/WavesWallet-Test.xcscheme @@ -1,6 +1,6 @@ - - - - + allowLocationSimulation = "YES"> - - - - + buildConfiguration = "Test-Dev"> diff --git a/WavesWallet-iOS/AppDelegate.swift b/WavesWallet-iOS/AppDelegate.swift index 8a400ba2..2acf983a 100644 --- a/WavesWallet-iOS/AppDelegate.swift +++ b/WavesWallet-iOS/AppDelegate.swift @@ -10,17 +10,18 @@ import RESideMenu import RxSwift import IQKeyboardManagerSwift import UIKit -import Moya -import RealmSwift -import FirebaseCore -import FirebaseDatabase -import Fabric -import Crashlytics import AppsFlyerLib -import Kingfisher -import Amplitude_iOS -import WavesSDKExtension + +import WavesSDKExtensions +import WavesSDK +import WavesSDKCrypto + +import Extensions +import DomainLayer +import DataLayer +import Firebase +import FirebaseMessaging #if DEBUG || TEST import AppSpectorSDK @@ -38,98 +39,75 @@ enum UITest { } #endif -@UIApplicationMain - class AppDelegate: UIResponder, UIApplicationDelegate { +//TODO: Rename WavesWallet +@UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var disposeBag: DisposeBag = DisposeBag() var window: UIWindow? var appCoordinator: AppCoordinator! - let migrationInteractor: MigrationInteractor = FactoryInteractors.instance.migrationInteractor - + lazy var migrationInteractor: MigrationUseCaseProtocol = UseCasesFactory.instance.migration + #if DEBUG var paws: MonkeyPaws? #endif - //TODO: Refactor method very long func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - if let path = Bundle.main.path(forResource: "GoogleService-Info", ofType: "plist"), - let options = FirebaseOptions(contentsOfFile: path) { - - FirebaseApp.configure(options: options) - Database.database().isPersistenceEnabled = false - Fabric.with([Crashlytics.self]) + var url: URL? + + if let path = launchOptions?[.url] as? String { + url = URL(string: path) } - if let path = Bundle.main.path(forResource: "Appsflyer-Info", ofType: "plist"), - let root = NSDictionary(contentsOfFile: path)?["Appsflyer"] as? NSDictionary { - if let devKey = root["AppsFlyerDevKey"] as? String, - let appId = root["AppleAppID"] as? String { - AppsFlyerTracker.shared().appsFlyerDevKey = devKey - AppsFlyerTracker.shared().appleAppID = appId - } + if let scheme = url?.scheme, DeepLink.scheme != scheme { + return false } + + var deepLink: DeepLink? = nil - if let path = Bundle.main.path(forResource: "Amplitude-Info", ofType: "plist"), - let apiKey = NSDictionary(contentsOfFile: path)?["API_KEY"] as? String { - Amplitude.instance()?.initializeApiKey(apiKey) - Amplitude.instance()?.setDeviceId(UIDevice.uuid) + if let url = url { + deepLink = DeepLink(url: url) } - IQKeyboardManager.shared.enable = true - UIBarButtonItem.appearance().tintColor = UIColor.black - - Language.load() - - Swizzle(initializers: [UIView.passtroughInit, UIView.insetsInit, UIView.shadowInit]).start() - - #if DEBUG || TEST - SweetLogger.current.plugins = [SweetLoggerConsole(visibleLevels: [], - isShortLog: true), - SweetLoggerSentry(visibleLevels: [.error])] - - SweetLogger.current.visibleLevels = [.warning, .debug, .error] - - AppsFlyerTracker.shared()?.isDebug = false + guard setupLayers() else { return false } - if let path = Bundle.main.path(forResource: "AppSpector-Info", ofType: "plist"), - let apiKey = NSDictionary(contentsOfFile: path)?["API_KEY"] as? String { - let config = AppSpectorConfig(apiKey: apiKey) - AppSpector.run(with: config) - } - - #else - SweetLogger.current.plugins = [SweetLoggerSentry(visibleLevels: [.error])] - SweetLogger.current.visibleLevels = [.warning, .debug, .error] - AppsFlyerTracker.shared()?.isDebug = false - #endif - - self.window = UIWindow(frame: UIScreen.main.bounds) - self.window?.backgroundColor = .basic50 + setupUI() + setupServices() - #if DEBUG - if UITest.isEnabledonkeyTest { - paws = MonkeyPaws(view: window!) - } - #endif + let router = WindowRouter.windowFactory(window: self.window!) - appCoordinator = AppCoordinator(WindowRouter(window: self.window!)) + appCoordinator = AppCoordinator(router, deepLink: deepLink) migrationInteractor .migration() + .observeOn(MainScheduler.asyncInstance) .subscribe(onNext: { (_) in }, onError: { (_) in }, onCompleted: { self.appCoordinator.start() + }) .disposed(by: disposeBag) - + + application.registerForRemoteNotifications() + return true } + func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { + + if DeepLink.scheme != url.scheme { + return false + } + + self.appCoordinator.openURL(link: DeepLink(url: url)) + + return true + } + func applicationWillResignActive(_ application: UIApplication) {} func applicationDidEnterBackground(_ application: UIApplication) { @@ -139,8 +117,9 @@ enum UITest { func applicationWillEnterForeground(_ application: UIApplication) {} func applicationDidBecomeActive(_ application: UIApplication) { - appCoordinator.applicationDidBecomeActive() + appCoordinator.applicationDidBecomeActive() AppsFlyerTracker.shared().trackAppLaunch() + application.applicationIconBadgeNumber = 0 } func applicationWillTerminate(_ application: UIApplication) {} @@ -151,10 +130,83 @@ enum UITest { annotation: Any) -> Bool { return false } + + func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { + Messaging.messaging().apnsToken = deviceToken + } } -//TODO: Remove code extension AppDelegate { + + func setupUI() { + Swizzle(initializers: [UIView.passtroughInit, UIView.insetsInit, UIView.shadowInit]).start() + + self.window = UIWindow(frame: UIScreen.main.bounds) + self.window?.backgroundColor = .basic50 + + #if DEBUG + if UITest.isEnabledonkeyTest { + paws = MonkeyPaws(view: window!) + } + #endif + + IQKeyboardManager.shared.enable = true + UIBarButtonItem.appearance().tintColor = UIColor.black + + Language.load(localizable: Localizable.self, languages: Language.list) + } + + func setupLayers() -> Bool { + + guard let googleServiceInfoPath = Bundle.main.path(forResource: "GoogleService-Info", ofType: "plist") else { + return false + } + + guard let appsflyerInfoPath = Bundle.main.path(forResource: "Appsflyer-Info", ofType: "plist") else { + return false + } + + guard let amplitudeInfoPath = Bundle.main.path(forResource: "Amplitude-Info", ofType: "plist") else { + return false + } + + guard let sentryIoInfoPath = Bundle.main.path(forResource: "Sentry-io-Info", ofType: "plist") else { + return false + } + + let resourses = RepositoriesFactory.Resources(googleServiceInfo: googleServiceInfoPath, + appsflyerInfo: appsflyerInfoPath, + amplitudeInfo: amplitudeInfoPath, + sentryIoInfoPath: sentryIoInfoPath) + let repositories = RepositoriesFactory(resources: resourses) + + UseCasesFactory.initialization(repositories: repositories, authorizationInteractorLocalizable: AuthorizationInteractorLocalizableImp()) + + UNUserNotificationCenter.current().delegate = self + return true + } + + func setupServices() { + #if DEBUG || TEST + + SweetLogger.current.add(plugin: SweetLoggerConsole(visibleLevels: [.warning, .debug, .error, .network], + isShortLog: true)) + SweetLogger.current.visibleLevels = [.warning, .debug, .error, .network] + + AppsFlyerTracker.shared()?.isDebug = false + + if let path = Bundle.main.path(forResource: "AppSpector-Info", ofType: "plist"), + let apiKey = NSDictionary(contentsOfFile: path)?["API_KEY"] as? String { + let config = AppSpectorConfig(apiKey: apiKey) + AppSpector.run(with: config) + } + + #else + SweetLogger.current.add(plugin: SweetLoggerSentry(visibleLevels: [.error])) + SweetLogger.current.visibleLevels = [.warning, .debug, .error] + AppsFlyerTracker.shared()?.isDebug = false + #endif + } class func shared() -> AppDelegate { return UIApplication.shared.delegate as! AppDelegate @@ -164,3 +216,12 @@ extension AppDelegate { return self.window?.rootViewController as! RESideMenu } } + +//MARK: - UNUserNotificationCenterDelegate +extension AppDelegate: UNUserNotificationCenterDelegate { + + func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { + completionHandler([.alert, .sound]) + } + +} diff --git a/WavesWallet-iOS/Coordinators/AppCoordinator.swift b/WavesWallet-iOS/Coordinators/AppCoordinator.swift new file mode 100644 index 00000000..54594807 --- /dev/null +++ b/WavesWallet-iOS/Coordinators/AppCoordinator.swift @@ -0,0 +1,459 @@ +// +// AppCoordinator.swift +// WavesWallet-iOS +// +// Created by mefilt on 13.09.2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import UIKit +import RxSwift +import RESideMenu +import RxOptional +import WavesSDKExtensions +import WavesSDK +import Extensions +import DomainLayer + +private enum Contants { + + #if DEBUG + static let delay: TimeInterval = 1 + #else + static let delay: TimeInterval = 10 + #endif +} + +struct Application: TSUD { + + struct Settings: Codable, Mutating { + var isAlreadyShowHelloDisplay: Bool = false + } + + private static let key: String = "com.waves.application.settings" + + static var defaultValue: Settings { + return Settings(isAlreadyShowHelloDisplay: false) + } + + static var stringKey: String { + return Application.key + } +} + +protocol ApplicationCoordinatorProtocol: AnyObject { + func showEnterDisplay() +} + +final class AppCoordinator: Coordinator { + + var childCoordinators: [Coordinator] = [] + weak var parent: Coordinator? + + private let windowRouter: WindowRouter + + private let authoAuthorizationInteractor: AuthorizationUseCaseProtocol = UseCasesFactory.instance.authorization + private let mobileKeeperRepository: MobileKeeperRepositoryProtocol = UseCasesFactory.instance.repositories.mobileKeeperRepository + private let applicationVersionUseCase: ApplicationVersionUseCaseProtocol = UseCasesFactory.instance.applicationVersionUseCase + + private let disposeBag: DisposeBag = DisposeBag() + private var deepLink: DeepLink? = nil + private var isActiveApp: Bool = false + private var snackError: String? = nil + private var isActiveForceUpdate: Bool = false + +#if DEBUG || TEST + init(_ debugWindowRouter: DebugWindowRouter, deepLink: DeepLink?) { + self.windowRouter = debugWindowRouter + debugWindowRouter.delegate = self + self.deepLink = deepLink + } +#else + init(_ windowRouter: WindowRouter, deepLink: DeepLink?) { + self.windowRouter = windowRouter + self.deepLink = deepLink + } +#endif + + func start() { + self.isActiveApp = true + + #if DEBUG || TEST + if CommandLine.arguments.contains("UI-Develop") { + addChildCoordinatorAndStart(childCoordinator: UIDeveloperCoordinator(windowRouter: windowRouter)) + } else { + logInApplication() + } + #else + logInApplication() + #endif + + if let deepLink = deepLink { + openURL(link: deepLink) + } + + checkAndRunForceUpdate() + } + + private var isMainTabDisplayed: Bool { + return childCoordinators.first(where: { $0 is MainTabBarCoordinator }) != nil + } +} + +// MARK: Methods for showing differnt displays +extension AppCoordinator: PresentationCoordinator { + + enum Display { + case hello + case slide(DomainLayer.DTO.Wallet) + case enter + case passcode(DomainLayer.DTO.Wallet) + case widgetSettings + case mobileKeeper(DomainLayer.DTO.MobileKeeper.Request) + case send(DeepLink) + case dex(DeepLink) + case forceUpdate(DomainLayer.DTO.VersionUpdateData) + } + + func showDisplay(_ display: AppCoordinator.Display) { + + switch display { + case .hello: + guard isActiveForceUpdate == false else { return } + + let helloCoordinator = HelloCoordinator(windowRouter: windowRouter) + helloCoordinator.delegate = self + addChildCoordinatorAndStart(childCoordinator: helloCoordinator) + + case .passcode(let wallet): + guard isActiveForceUpdate == false else { return } + + guard isHasCoordinator(type: PasscodeLogInCoordinator.self) != true else { return } + + let passcodeCoordinator = PasscodeLogInCoordinator(wallet: wallet, routerKind: .alertWindow) + passcodeCoordinator.delegate = self + + addChildCoordinatorAndStart(childCoordinator: passcodeCoordinator) + + case .slide(let wallet): + guard isActiveForceUpdate == false else { return } + guard isHasCoordinator(type: SlideCoordinator.self) != true else { + showDeepLinkVcIfNeed() + return + } + + let slideCoordinator = SlideCoordinator(windowRouter: windowRouter, wallet: wallet) + slideCoordinator.menuViewControllerDelegate = self + addChildCoordinatorAndStart(childCoordinator: slideCoordinator) + showDeepLinkVcIfNeed() + + case .enter: + guard isActiveForceUpdate == false else { return } + + let prevSlideCoordinator = self.childCoordinators.first { (coordinator) -> Bool in + return coordinator is SlideCoordinator + } + + guard prevSlideCoordinator?.isHasCoordinator(type: EnterCoordinator.self) != true else { return } + + let slideCoordinator = SlideCoordinator(windowRouter: windowRouter, wallet: nil) + slideCoordinator.menuViewControllerDelegate = self + addChildCoordinatorAndStart(childCoordinator: slideCoordinator) + + case .widgetSettings: + guard isActiveForceUpdate == false else { return } + guard isHasCoordinator(type: WidgetSettingsCoordinator.self) != true else { + return + } + + let coordinator = WidgetSettingsCoordinator(windowRouter: windowRouter) + addChildCoordinatorAndStart(childCoordinator: coordinator) + + case .mobileKeeper(let request): + guard isActiveForceUpdate == false else { return } + + let coordinator = MobileKeeperCoordinator(windowRouter: windowRouter, request: request) + addChildCoordinatorAndStart(childCoordinator: coordinator) + + case .send(let link): + guard isActiveForceUpdate == false else { return } + deepLink = link + + case.dex(let link): + guard isActiveForceUpdate == false else { return } + deepLink = link + + case .forceUpdate(let data): + isActiveForceUpdate = true + + //add coordinator + let vc = StoryboardScene.ForceUpdateApp.forceUpdateAppViewController.instantiate() + vc.data = data + windowRouter.window.rootViewController = vc + windowRouter.window.makeKeyAndVisible() + } + } + + func openURL(link: DeepLink) { + guard isActiveForceUpdate == false else { return } + if link.url.absoluteString == DeepLink.widgetSettings { + self.showDisplay(.widgetSettings) + } + else if link.isClientSendLink { + self.showDisplay(.send(link)) + } + else if link.isClientDexLink { + self.showDisplay(.dex(link)) + } + else if link.isMobileKeeper { + + mobileKeeperRepository + .decodableRequest(link.url) + .observeOn(MainScheduler.asyncInstance) + .subscribe(onNext: { (request) in + guard let request = request else { return } + self.showDisplay(.mobileKeeper(request)) + }, onError: { [weak self] (error) in + + if let error = error as? MobileKeeperUseCaseError { + self?.showErrorView(with: error) + } + }) + .disposed(by: disposeBag) + } + } + + //TODO: Localization + private func showErrorView(with error: MobileKeeperUseCaseError) { + + if let snackError = snackError { + UIApplication.shared.windows.last?.rootViewController?.hideSnack(key: snackError) + } + + switch error { + case .dAppDontOpen: + snackError = showErrorSnack("Application don't open") + + case .dataIncorrect: + snackError = showErrorSnack("Request incorect") + + case .transactionDontSupport: + snackError = showErrorSnack("Transaction don't support") + default: + snackError = UIApplication.shared.windows.last?.rootViewController?.showErrorNotFoundSnackWithoutAction() + } + } + + private func showErrorSnack(_ message: (String)) -> String? { + return UIApplication.shared.windows.last?.rootViewController?.showErrorSnackWithoutAction(title: message) + } +} + +// MARK: Main Logic +extension AppCoordinator { + + private func showDeepLinkVcIfNeed() { + if let link = deepLink, link.isClientSendLink { + + guard isHasCoordinator(type: SendCoordinator.self) != true else { + return + } + let coordinator = SendCoordinator(windowRouter: windowRouter, deepLink: link) + addChildCoordinatorAndStart(childCoordinator: coordinator) + } + else if let link = deepLink, link.isClientDexLink { + guard isHasCoordinator(type: DexDeepLinkCoordinator.self) != true else { + return + } + let coordinator = DexDeepLinkCoordinator(windowRouter: windowRouter, deepLink: link) + addChildCoordinatorAndStart(childCoordinator: coordinator) + } + } + + private func display(by wallet: DomainLayer.DTO.Wallet?) -> Observable { + + if let wallet = wallet { + return display(by: wallet) + } else { + let settings = Application.get() + if settings.isAlreadyShowHelloDisplay { + return Observable.just(Display.enter) + } else { + return Observable.just(Display.hello) + } + } + } + + private func display(by wallet: DomainLayer.DTO.Wallet) -> Observable { + return authoAuthorizationInteractor + .isAuthorizedWallet(wallet) + .map { isAuthorizedWallet -> Display in + if isAuthorizedWallet { + return Display.slide(wallet) + } else { + return Display.passcode(wallet) + } + } + } + + private func logInApplication() { + authoAuthorizationInteractor + .lastWalletLoggedIn() + .take(1) + .catchError { _ -> Observable in + return Observable.just(nil) + } + .subscribeOn(ConcurrentDispatchQueueScheduler(queue: DispatchQueue.global())) + .observeOn(MainScheduler.asyncInstance) + .flatMap(weak: self, selector: { $0.display }) + .subscribe(weak: self, onNext: { $0.showDisplay }) + .disposed(by: disposeBag) + } + + private func revokeAuthAndOpenPasscode() { + + Observable + .just(1) + .delay(Contants.delay, scheduler: MainScheduler.asyncInstance) + .flatMap { [weak self] _ -> Observable in + + guard let self = self else { return Observable.never() } + + if self.isActiveApp == true { + return Observable.never() + } + + return + self + .authoAuthorizationInteractor + .revokeAuth() + .flatMap({ [weak self] (_) -> Observable in + guard let self = self else { return Observable.never() } + + return self.authoAuthorizationInteractor + .lastWalletLoggedIn() + .take(1) + }) + } + .share() + .subscribeOn(ConcurrentDispatchQueueScheduler(queue: DispatchQueue.global())) + .observeOn(MainScheduler.asyncInstance) + .subscribe(weak: self, onNext: { owner, wallet in + if let wallet = wallet { + owner.showDisplay(.passcode(wallet)) + } else if Application.get().isAlreadyShowHelloDisplay { + owner.showDisplay(.enter) + } + }) + .disposed(by: disposeBag) + } +} + +// MARK: HelloCoordinatorDelegate +extension AppCoordinator: HelloCoordinatorDelegate { + + func userFinishedGreet() { + var settings = Application.get() + settings.isAlreadyShowHelloDisplay = true + Application.set(settings) + showDisplay(.enter) + } + + func userChangedLanguage(_ language: Language) { + Language.change(language) + } +} + +// MARK: PasscodeLogInCoordinatorDelegate +extension AppCoordinator: PasscodeLogInCoordinatorDelegate { + + func passcodeCoordinatorLogInCompleted(wallet: DomainLayer.DTO.Wallet) { + showDisplay(.slide(wallet)) + } + + func passcodeCoordinatorWalletLogouted() { + showDisplay(.enter) + deepLink = nil + } +} + + +// MARK: Lifecycle application +extension AppCoordinator { + + func applicationDidEnterBackground() { + isActiveApp = false + deepLink = nil + revokeAuthAndOpenPasscode() + } + + func applicationDidBecomeActive() { + if isActiveApp { + return + } + isActiveApp = true + } +} + + + +// MARK: DebugWindowRouterDelegate +extension AppCoordinator: DebugWindowRouterDelegate { + + func relaunchApplication() { + + self.authoAuthorizationInteractor + .logout() + .subscribe(onCompleted: { [weak self] in + guard let self = self else { return } + self.showDisplay(.enter) + }) + .disposed(by: self.disposeBag) + } +} + + +// MARK: MenuViewControllerDelegate +extension AppCoordinator: MenuViewControllerDelegate { + + func menuViewControllerDidTapWavesLogo() { + + let vc = StoryboardScene.Support.debugViewController.instantiate() + vc.delegate = self + let nv = CustomNavigationController() + nv.viewControllers = [vc] + nv.modalPresentationStyle = .fullScreen + self.windowRouter.window.rootViewController?.present(nv, animated: true, completion: nil) + } +} + +// MARK: DebugViewControllerDelegate +extension AppCoordinator: DebugViewControllerDelegate { + + func dissmissDebugVC(isNeedRelaunchApp: Bool) { + + if isNeedRelaunchApp { + relaunchApplication() + } + + self.windowRouter.window.rootViewController?.dismiss(animated: true, completion: nil) + } +} + +//MARK: - ForceUpdate +private extension AppCoordinator { + func checkAndRunForceUpdate() { + + applicationVersionUseCase.isNeedForceUpdate() + .observeOn(MainScheduler.instance) + .subscribe(onNext: { [weak self] data in + guard let self = self else { return } + + if data.isNeedForceUpdate { + self.showDisplay(.forceUpdate(data)) + } + }).disposed(by: disposeBag) + + } +} diff --git a/WavesWallet-iOS/PresentationLayer/Coordinators/AppNewsCoordinator.swift b/WavesWallet-iOS/Coordinators/AppNewsCoordinator.swift similarity index 79% rename from WavesWallet-iOS/PresentationLayer/Coordinators/AppNewsCoordinator.swift rename to WavesWallet-iOS/Coordinators/AppNewsCoordinator.swift index 5489e072..8553c385 100644 --- a/WavesWallet-iOS/PresentationLayer/Coordinators/AppNewsCoordinator.swift +++ b/WavesWallet-iOS/Coordinators/AppNewsCoordinator.swift @@ -10,7 +10,9 @@ import Foundation import RxSwift import RxCocoa import Kingfisher -import WavesSDKExtension +import WavesSDKExtensions +import DomainLayer +import Extensions private struct ApplicationNewsSettings: TSUD, Codable, Mutating { @@ -42,7 +44,7 @@ final class AppNewsCoordinator: Coordinator { var childCoordinators: [Coordinator] = [] weak var parent: Coordinator? - private let notificationNewsRepository: NotificationNewsRepositoryProtocol = FactoryRepositories.instance.notificationNewsRepository + private let notificationNewsRepository: NotificationNewsRepositoryProtocol = UseCasesFactory.instance.repositories.notificationNewsRepository private let disposeBag: DisposeBag = DisposeBag() @@ -100,13 +102,21 @@ final class AppNewsCoordinator: Coordinator { guard let self = self else { return } if let image = image { - let news = AppNewsView.show(model: .init(title: titleValue, - subtitle: subTitleValue, - image: image)) + + let news = AppNewsView.show(model: AppNewsView.Model(title: titleValue, + subtitle: subTitleValue, + image: image)) news.tapDismiss = { [weak self] in guard let self = self else { return } self.closeCoordinator() } + + news.didSelectLinkWith = { url in + let vc = BrowserViewController(url: url) + let nav = UINavigationController(rootViewController: vc) + nav.modalPresentationStyle = .fullScreen + AppDelegate.shared().window?.rootViewController?.present(nav, animated: true, completion: nil) + } var showIdSet = settings.showIdSet showIdSet.insert(first.id) diff --git a/WavesWallet-iOS/PresentationLayer/Coordinators/Backup/BackupCoordinator.swift b/WavesWallet-iOS/Coordinators/Backup/BackupCoordinator.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Coordinators/Backup/BackupCoordinator.swift rename to WavesWallet-iOS/Coordinators/Backup/BackupCoordinator.swift diff --git a/WavesWallet-iOS/PresentationLayer/Coordinators/Backup/BackupTostCoordinator.swift b/WavesWallet-iOS/Coordinators/Backup/BackupTostCoordinator.swift similarity index 96% rename from WavesWallet-iOS/PresentationLayer/Coordinators/Backup/BackupTostCoordinator.swift rename to WavesWallet-iOS/Coordinators/Backup/BackupTostCoordinator.swift index d8627e1c..cbc16c40 100644 --- a/WavesWallet-iOS/PresentationLayer/Coordinators/Backup/BackupTostCoordinator.swift +++ b/WavesWallet-iOS/Coordinators/Backup/BackupTostCoordinator.swift @@ -8,6 +8,7 @@ import UIKit import RxSwift +import DomainLayer extension Coordinator { @@ -54,7 +55,7 @@ final class BackupTostCoordinator: Coordinator { weak var parent: Coordinator? private let disposeBag: DisposeBag = DisposeBag() - private let authorization: AuthorizationInteractorProtocol = FactoryInteractors.instance.authorization + private let authorization: AuthorizationUseCaseProtocol = UseCasesFactory.instance.authorization private let navigationRouter: NavigationRouter private var snackBackupSeedKey: String? @@ -116,7 +117,7 @@ final private class BackupContainer: Coordinator { weak var parent: Coordinator? private let disposeBag: DisposeBag = DisposeBag() - private let authorization: AuthorizationInteractorProtocol = FactoryInteractors.instance.authorization + private let authorization: AuthorizationUseCaseProtocol = UseCasesFactory.instance.authorization private let signedWallet: DomainLayer.DTO.SignedWallet private let navigationRouter: NavigationRouter diff --git a/WavesWallet-iOS/PresentationLayer/Coordinators/CoordinatorKit/Coordinator.swift b/WavesWallet-iOS/Coordinators/CoordinatorKit/Coordinator.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Coordinators/CoordinatorKit/Coordinator.swift rename to WavesWallet-iOS/Coordinators/CoordinatorKit/Coordinator.swift index 52310707..ae458021 100644 --- a/WavesWallet-iOS/PresentationLayer/Coordinators/CoordinatorKit/Coordinator.swift +++ b/WavesWallet-iOS/Coordinators/CoordinatorKit/Coordinator.swift @@ -7,6 +7,7 @@ // import Foundation +import Extensions protocol Coordinator: AnyObject { diff --git a/WavesWallet-iOS/PresentationLayer/Coordinators/CoordinatorKit/PresentationCoordinator.swift b/WavesWallet-iOS/Coordinators/CoordinatorKit/PresentationCoordinator.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Coordinators/CoordinatorKit/PresentationCoordinator.swift rename to WavesWallet-iOS/Coordinators/CoordinatorKit/PresentationCoordinator.swift diff --git a/WavesWallet-iOS/Coordinators/CoordinatorKit/Router/DebugRootView.swift b/WavesWallet-iOS/Coordinators/CoordinatorKit/Router/DebugRootView.swift new file mode 100644 index 00000000..9af5861a --- /dev/null +++ b/WavesWallet-iOS/Coordinators/CoordinatorKit/Router/DebugRootView.swift @@ -0,0 +1,192 @@ +// +// DebugRootView.swift +// WavesWallet-iOS +// +// Created by rprokofev on 22.07.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import UIKit +import DomainLayer + +private struct Constants { + + static let firstPosition: CGPoint = CGPoint(x: 44, y: 44) + + static let size: CGFloat = 35 +} + +protocol DebugWindowRouterDelegate: AnyObject { + func relaunchApplication() +} + +final class DebugRootView: UIView { + + private lazy var debugView: DebugView = DebugView(frame: .zero) + + private lazy var panGesture: UIPanGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handlerPanGesture(_:))) + + var debugPosition: CGPoint = CGPoint.zero + + let environmentRepository: EnvironmentRepositoryProtocol = UseCasesFactory.instance.repositories.environmentRepository + + var didTapOnButton: (() -> Void)? + + override func didMoveToWindow() { + super.didMoveToWindow() + + debugPosition = ApplicationDebugSettings.debugButtonPosition ?? CGPoint(x: 44, y: 44) + + addSubview(debugView) + + debugView.layer.zPosition = 666 + debugView.didTapOnView = { [weak self] in + self?.didTapOnButton?() + } + + updateContent() + + panGesture.delegate = self + addGestureRecognizer(panGesture) + } + + override func layoutSubviews() { + super.layoutSubviews() + debugView.frame = CGRect(x: debugPosition.x, y: debugPosition.y, width: Constants.size, height: Constants.size) + } + + @objc private func handlerPanGesture(_ recognizer: UIPanGestureRecognizer) { + + let location = recognizer.location(in: self) + + switch recognizer.state { + case .began: + break + + case .changed: + + var newFrame = debugView.frame + newFrame.origin = CGPoint(x: location.x - newFrame.width * 0.5, y: location.y - newFrame.height * 0.5) + + if self.frame.contains(newFrame) == false { + return + } + + debugView.center = location + + default: + ApplicationDebugSettings.debugButtonPosition = location + + } + } + + func updateContent() { + debugView.chainIdLabel.text = environmentRepository.environmentKind.rawValue + } +} + +// MARK: UIGestureRecognizerDelegate + +extension DebugRootView: UIGestureRecognizerDelegate {} + + +final class DebugWindow: UIWindow { + + override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { + + let hitView = super.hitTest(point, with: event) + + if (hitView?.isKind(of: DebugView.self) ?? false) == true { + return nil + } + + if (hitView is DebugRootView) { + return nil + } + + return hitView + } +} + +final class DebugWindowRouter: WindowRouter { + + private let contentView: UIView = UIView() + + private lazy var debugRootView = DebugRootView() + + private lazy var debugWindow: DebugWindow = { + + let window = DebugWindow() + let vc = UIViewController() + vc.view = debugRootView + vc.view.frame = UIScreen.main.bounds + vc.view.backgroundColor = .clear + window.backgroundColor = .clear + window.rootViewController = vc + window.windowLevel = .alert + return window + }() + + weak var delegate: DebugWindowRouterDelegate? + + override init(window: UIWindow) { + super.init(window: window) + } + + override func windowDidAppear() { + super.windowDidAppear() + + debugRootView.didTapOnButton = { [weak self] in + self?.showSupport() + } + + debugWindow.makeKeyAndVisible() + } + + private func showSupport() { + let vc = StoryboardScene.Support.debugViewController.instantiate() + vc.delegate = self + let nv = CustomNavigationController() + nv.viewControllers = [vc] + nv.modalPresentationStyle = .fullScreen + debugWindow.rootViewController?.present(nv, animated: true, completion: nil) + } +} + +// MARK: DebugViewControllerDelegate + +extension DebugWindowRouter: DebugViewControllerDelegate { + + func dissmissDebugVC(isNeedRelaunchApp: Bool) { + + debugRootView.updateContent() + + debugWindow.rootViewController?.presentedViewController?.dismiss(animated: true, completion: nil) + + if isNeedRelaunchApp { + self.delegate?.relaunchApplication() + } + } + + func relaunchApplication() { + self.delegate?.relaunchApplication() + } +} + +extension WindowRouter { + + #if DEBUG || TEST + + static func windowFactory(window: UIWindow) -> DebugWindowRouter { + return DebugWindowRouter(window: window) + } + + #else + + static func windowFactory(window: UIWindow) -> WindowRouter { + return WindowRouter(window: window) + } + + #endif +} diff --git a/WavesWallet-iOS/PresentationLayer/Coordinators/CoordinatorKit/Router/NavigationRouter.swift b/WavesWallet-iOS/Coordinators/CoordinatorKit/Router/NavigationRouter.swift similarity index 93% rename from WavesWallet-iOS/PresentationLayer/Coordinators/CoordinatorKit/Router/NavigationRouter.swift rename to WavesWallet-iOS/Coordinators/CoordinatorKit/Router/NavigationRouter.swift index 7c9c089a..f2cbc335 100644 --- a/WavesWallet-iOS/PresentationLayer/Coordinators/CoordinatorKit/Router/NavigationRouter.swift +++ b/WavesWallet-iOS/Coordinators/CoordinatorKit/Router/NavigationRouter.swift @@ -90,6 +90,12 @@ extension NavigationRouter: Router { } func present(_ viewController: UIViewController, animated: Bool, completion: (() -> Void)?) { + + if #available(iOS 13, *) { + if viewController.modalPresentationStyle == .pageSheet && !(viewController is UIAlertController) { + viewController.modalPresentationStyle = .fullScreen + } + } navigationController.topViewController?.present(viewController, animated: animated, completion: completion) } diff --git a/WavesWallet-iOS/PresentationLayer/Coordinators/CoordinatorKit/Router/Router.swift b/WavesWallet-iOS/Coordinators/CoordinatorKit/Router/Router.swift similarity index 76% rename from WavesWallet-iOS/PresentationLayer/Coordinators/CoordinatorKit/Router/Router.swift rename to WavesWallet-iOS/Coordinators/CoordinatorKit/Router/Router.swift index 48a3ae40..8ec383e8 100644 --- a/WavesWallet-iOS/PresentationLayer/Coordinators/CoordinatorKit/Router/Router.swift +++ b/WavesWallet-iOS/Coordinators/CoordinatorKit/Router/Router.swift @@ -21,6 +21,12 @@ protocol Router { extension Router { func present(_ viewController: UIViewController, animated: Bool = true, completion: (() -> Void)? = nil) { + + if #available(iOS 13, *) { + if viewController.modalPresentationStyle == .pageSheet && !(viewController is UIAlertController) { + viewController.modalPresentationStyle = .fullScreen + } + } self.viewController.present(viewController, animated: animated, completion: nil) } diff --git a/WavesWallet-iOS/PresentationLayer/Coordinators/CoordinatorKit/Router/SlideMenuRouter.swift b/WavesWallet-iOS/Coordinators/CoordinatorKit/Router/SlideMenuRouter.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Coordinators/CoordinatorKit/Router/SlideMenuRouter.swift rename to WavesWallet-iOS/Coordinators/CoordinatorKit/Router/SlideMenuRouter.swift diff --git a/WavesWallet-iOS/PresentationLayer/Coordinators/CoordinatorKit/Router/TabBarRouter.swift b/WavesWallet-iOS/Coordinators/CoordinatorKit/Router/TabBarRouter.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Coordinators/CoordinatorKit/Router/TabBarRouter.swift rename to WavesWallet-iOS/Coordinators/CoordinatorKit/Router/TabBarRouter.swift diff --git a/WavesWallet-iOS/PresentationLayer/Coordinators/CoordinatorKit/Router/WindowRouter.swift b/WavesWallet-iOS/Coordinators/CoordinatorKit/Router/WindowRouter.swift similarity index 69% rename from WavesWallet-iOS/PresentationLayer/Coordinators/CoordinatorKit/Router/WindowRouter.swift rename to WavesWallet-iOS/Coordinators/CoordinatorKit/Router/WindowRouter.swift index 591ab683..29d9ba33 100755 --- a/WavesWallet-iOS/PresentationLayer/Coordinators/CoordinatorKit/Router/WindowRouter.swift +++ b/WavesWallet-iOS/Coordinators/CoordinatorKit/Router/WindowRouter.swift @@ -6,12 +6,14 @@ // import UIKit +import DomainLayer private enum Constants { static let animationDuration: TimeInterval = 0.24 } -final class WindowRouter: NSObject { +//TODO: Router protocol +class WindowRouter: NSObject { enum AnimateKind { case crossDissolve @@ -30,22 +32,29 @@ final class WindowRouter: NSObject { switch animated { case .crossDissolve: if let view = window.rootViewController?.view { - UIView.transition(from: view, to: viewController.view, duration: Constants.animationDuration, options: [.transitionCrossDissolve], completion: { _ in - self.window.rootViewController = viewController + + self.window.rootViewController = viewController + UIView.transition(from: view, to: viewController.view, duration: Constants.animationDuration, options: [.transitionCrossDissolve], completion: { animated in + self.windowDidAppear() }) } else { self.window.rootViewController = viewController + self.window.makeKeyAndVisible() + self.windowDidAppear() } } } else { self.window.rootViewController = viewController + self.window.makeKeyAndVisible() + self.windowDidAppear() } - window.makeKeyAndVisible() + + } - + public func dissmissWindow(animated: AnimateKind? = nil, completed: (() -> Void)? = nil) { - UIView.animate(withDuration: 0.24, delay: 0, options: [.curveEaseInOut], animations: { + UIView.animate(withDuration: Constants.animationDuration, delay: 0, options: [.curveEaseInOut], animations: { var newFrame = self.window.frame newFrame.origin.y = newFrame.height self.window.frame = newFrame @@ -55,4 +64,6 @@ final class WindowRouter: NSObject { } } + + func windowDidAppear() {} } diff --git a/WavesWallet-iOS/PresentationLayer/Coordinators/CoordinatorKit/RoutingCoordinator.swift b/WavesWallet-iOS/Coordinators/CoordinatorKit/RoutingCoordinator.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Coordinators/CoordinatorKit/RoutingCoordinator.swift rename to WavesWallet-iOS/Coordinators/CoordinatorKit/RoutingCoordinator.swift diff --git a/WavesWallet-iOS/PresentationLayer/Coordinators/DexCoordinator.swift b/WavesWallet-iOS/Coordinators/DexCoordinator.swift similarity index 93% rename from WavesWallet-iOS/PresentationLayer/Coordinators/DexCoordinator.swift rename to WavesWallet-iOS/Coordinators/DexCoordinator.swift index 4d4f8d9a..ccf33627 100644 --- a/WavesWallet-iOS/PresentationLayer/Coordinators/DexCoordinator.swift +++ b/WavesWallet-iOS/Coordinators/DexCoordinator.swift @@ -8,7 +8,9 @@ import UIKit import RxSwift -import WavesSDKExtension +import WavesSDKExtensions +import Extensions +import DomainLayer private struct SettingsScriptPair: TSUD, Codable, Mutating { @@ -61,9 +63,9 @@ private struct SettingsScriptPair: TSUD, Codable, Mutating { } } -final class DexCoordinator: Coordinator { +class DexCoordinator: Coordinator { - private let auth = FactoryInteractors.instance.authorization + private let auth = UseCasesFactory.instance.authorization private let dispose = DisposeBag() var childCoordinators: [Coordinator] = [] @@ -75,7 +77,10 @@ final class DexCoordinator: Coordinator { private lazy var dexListViewContoller: UIViewController = { return DexListModuleBuilder(output: self).build() }() - + + private lazy var dexCreateOrderPopup = PopupViewController() + + private var navigationRouter: NavigationRouter init(navigationRouter: NavigationRouter) { @@ -233,8 +238,7 @@ private extension DexCoordinator { } else { let controller = DexCreateOrderModuleBuilder(output: self).build(input: input) - let popup = PopupViewController() - popup.present(contentViewController: controller) + self.dexCreateOrderPopup.present(contentViewController: controller) } }) .disposed(by: disposeBag) @@ -243,8 +247,22 @@ private extension DexCoordinator { //MARK: - DexCreateOrderModuleOutput extension DexCoordinator: DexCreateOrderModuleOutput { + + func dexCreateOrderWarningForPrice(isPriceHigherMarket: Bool, callback: @escaping ((_ isSuccess: Bool) -> Void)) { + + let priceView = DexCreateOrderInvalidPriceView + .show(model: .init(pricePercent: UIGlobalConstants.limitPriceOrderPercent, + isPriceHigherMarket: isPriceHigherMarket)) + + priceView.buttonDidTap = { isSuccess in + callback(isSuccess) + } + } + func dexCreateOrderDidCreate(output: DexCreateOrder.DTO.Output) { - + + self.dexCreateOrderPopup.dismissPopup() + let controller = DexCompleteOrderModuleBuilder().build(input: output) navigationRouter.pushViewController(controller) diff --git a/WavesWallet-iOS/Coordinators/DexDeepLinkCoordinator.swift b/WavesWallet-iOS/Coordinators/DexDeepLinkCoordinator.swift new file mode 100644 index 00000000..887d7546 --- /dev/null +++ b/WavesWallet-iOS/Coordinators/DexDeepLinkCoordinator.swift @@ -0,0 +1,63 @@ +// +// DexDeepLinkCoordinator.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 31.10.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import Extensions + +final class DexDeepLinkCoordinator: DexCoordinator { + + private var navigationRouter: NavigationRouter + private var windowRouter: WindowRouter + private var deepLink: DeepLink + + init(windowRouter: WindowRouter, deepLink: DeepLink) { + + self.deepLink = deepLink + let window = UIWindow() + window.windowLevel = UIWindow.Level(rawValue: UIWindow.Level.normal.rawValue + 1.0) + self.windowRouter = WindowRouter.windowFactory(window: window) + self.navigationRouter = NavigationRouter(navigationController: CustomNavigationController()) + super.init(navigationRouter: navigationRouter) + + NotificationCenter.default.addObserver(self, selector: #selector(dismiss), name: UIApplication.didEnterBackgroundNotification, object: nil) + } + + override func start() { + + let vc = StoryboardScene.Dex.dexDeepLinkLoadingViewController.instantiate() + vc.deepLink = deepLink + vc.didComplete = { [weak self] pair in + guard let self = self else { return } + + if let vc = DexTraderContainerModuleBuilder(output: self, orderBookOutput: self, lastTradesOutput: self, myOrdersOutpout: self) + .build(input: pair) as? DexTraderContainerViewController { + + vc.backAction = { [weak self] in + guard let self = self else { return } + self.dismiss() + } + self.navigationRouter.popAllAndSetRootViewController(vc) + } + + } + vc.didFail = { [weak self] in + guard let self = self else { return } + self.dismiss() + } + + windowRouter.setRootViewController(self.navigationRouter.navigationController) + navigationRouter.pushViewController(vc) + } + + @objc private func dismiss() { + windowRouter.dissmissWindow(animated: nil, completed: { [weak self] in + guard let self = self else { return } + self.removeFromParentCoordinator() + }) + } +} diff --git a/WavesWallet-iOS/Coordinators/Enter/ChooseAccountCoordinator.swift b/WavesWallet-iOS/Coordinators/Enter/ChooseAccountCoordinator.swift new file mode 100644 index 00000000..d328e2e1 --- /dev/null +++ b/WavesWallet-iOS/Coordinators/Enter/ChooseAccountCoordinator.swift @@ -0,0 +1,267 @@ +// +// ChooseAccountCoordinator.swift +// WavesWallet-iOS +// +// Created by Prokofev Ruslan on 28/09/2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import UIKit +import Extensions +import DomainLayer + +protocol ChooseAccountCoordinatorDelegate: AnyObject { + func userChooseCompleted(wallet: DomainLayer.DTO.Wallet) + func userDidTapBackButton() +} + +final class ChooseAccountCoordinator: Coordinator { + + var childCoordinators: [Coordinator] = [] + weak var parent: Coordinator? + + weak var delegate: ChooseAccountCoordinatorDelegate? + private let navigationRouter: NavigationRouter + private weak var applicationCoordinator: ApplicationCoordinatorProtocol? + + private lazy var popoverViewControllerTransitioning = ModalViewControllerTransitioning { [weak self] in + guard let self = self else { return } + } + + init(navigationRouter: NavigationRouter, applicationCoordinator: ApplicationCoordinatorProtocol?) { + self.navigationRouter = navigationRouter + self.applicationCoordinator = applicationCoordinator + } + + func start() { + + + let vc = ChooseAccountModuleBuilder(output: self) + .build(input: .init()) + navigationRouter.pushViewController(vc, animated: true, completion: { [weak self] in + guard let self = self else { return } + self.removeFromParentCoordinator() + }) + } + + private func showEdit(wallet: DomainLayer.DTO.Wallet, animated: Bool = true) { + let editCoordinator = EditAccountNameCoordinator(navigationRouter: navigationRouter, wallet: wallet) + addChildCoordinatorAndStart(childCoordinator: editCoordinator) + } + + private func showAccountPassword(kind: AccountPasswordTypes.DTO.Kind) { + + let vc = AccountPasswordModuleBuilder(output: self) + .build(input: .init(kind: kind)) + navigationRouter.pushViewController(vc) + } + + private func addOrImportAccountShow() { + + let elements: [ActionSheet.DTO.Element] = [.init(title: Localizable.Waves.Enter.Button.Createnewaccount.title), + .init(title: Localizable.Waves.Enter.Button.Importaccount.title)] + + let data = ActionSheet.DTO.Data.init(title: Localizable.Waves.Chooseaccount.Alert.pleaseSelect, + elements: elements, + selectedElement: nil) + + let vc = ActionSheetViewBuilder { [weak self] (element) in + + guard let self = self else { return } + + self.navigationRouter.dismiss(animated: true, completion: { [weak self] in + guard let self = self else { return } + + if element.title == Localizable.Waves.Enter.Button.Createnewaccount.title { + self.showDisplay(.newAccount) + } else { + self.showDisplay(.importAccount) + } + }) + } + .build(input: data) + + vc.modalPresentationStyle = .custom + vc.transitioningDelegate = popoverViewControllerTransitioning + + self.navigationRouter.present(vc, animated: true) {} + } + + private func passcodeRegistration(with account: PasscodeTypes.DTO.Account) { + + let passcodeCoordinator = PasscodeCoordinator(kind: .registration(account), behaviorPresentation: .push(navigationRouter, dissmissToRoot: false)) + passcodeCoordinator.delegate = self + + addChildCoordinatorAndStart(childCoordinator: passcodeCoordinator) + } +} + +// MARK: PresentationCoordinator + +extension ChooseAccountCoordinator: PresentationCoordinator { + + enum Display { + case passcodeLogIn(DomainLayer.DTO.Wallet) + case passcodeChangePasscode(DomainLayer.DTO.Wallet, password: String) + case editAccountName(DomainLayer.DTO.Wallet) + case accountPasswordLogIn(DomainLayer.DTO.Wallet) + case passcodeRegistration(PasscodeTypes.DTO.Account) + case importAccount + case newAccount + } + + func showDisplay(_ display: Display) { + switch display { + + case .passcodeLogIn(let wallet): + guard isHasCoordinator(type: PasscodeLogInCoordinator.self) != true else { return } + + let passcodeCoordinator = PasscodeLogInCoordinator(wallet: wallet, routerKind: .navigation(navigationRouter)) + passcodeCoordinator.delegate = self + + addChildCoordinatorAndStart(childCoordinator: passcodeCoordinator) + + case .passcodeChangePasscode(let wallet, let password): + guard isHasCoordinator(type: PasscodeCoordinator.self) != true else { return } + + let passcodeCoordinator = PasscodeCoordinator(kind: .changePasscodeByPassword(wallet, password: password), behaviorPresentation: .push(navigationRouter, dissmissToRoot: true)) + passcodeCoordinator.delegate = self + + addChildCoordinatorAndStart(childCoordinator: passcodeCoordinator) + + case .editAccountName(let wallet): + showEdit(wallet: wallet) + + case .accountPasswordLogIn(let wallet): + showAccountPassword(kind: .logIn(wallet)) + + case .passcodeRegistration(let account): + passcodeRegistration(with: account) + + case .importAccount: + let coordinator = ImportCoordinator(navigationRouter: navigationRouter) { [weak self] account in + + guard let self = self else { return } + self.passcodeRegistration(with: .init(privateKey: account.privateKey, + password: account.password, + name: account.name, + needBackup: false)) + } + addChildCoordinatorAndStart(childCoordinator: coordinator) + + case .newAccount: + let coordinator = NewAccountCoordinator(navigationRouter: navigationRouter) { [weak self] account, needBackup in + + guard let self = self else { return } + + let account: PasscodeTypes.DTO.Account = .init(privateKey: account.privateKey, + password: account.password, + name: account.name, + needBackup: needBackup) + + self.showDisplay(.passcodeRegistration(account)) + } + addChildCoordinatorAndStart(childCoordinator: coordinator) + + } + } + +} + +// MARK: ChooseAccountModuleOutput +extension ChooseAccountCoordinator: ChooseAccountModuleOutput { + + func userChooseAccount(wallet: DomainLayer.DTO.Wallet, passcodeNotCreated: Bool) -> Void { + if passcodeNotCreated { + showDisplay(.accountPasswordLogIn(wallet)) + } else { + showDisplay(.passcodeLogIn(wallet)) + } + } + + func userEditAccount(wallet: DomainLayer.DTO.Wallet) { + showDisplay(.editAccountName(wallet)) + } + + func chooseAccountDidTapBack() { + self.delegate?.userDidTapBackButton() + } + + func chooseAccountDidTapAddAccount() { + addOrImportAccountShow() + } +} + +// MARK: AccountPasswordModuleOutput +extension ChooseAccountCoordinator: AccountPasswordModuleOutput { + + func accountPasswordAuthorizationCompleted(wallet: DomainLayer.DTO.Wallet, password: String) { + showDisplay(.passcodeChangePasscode(wallet, password: password)) + } + + func accountPasswordVerifyAccess(signedWallet: DomainLayer.DTO.SignedWallet, password: String) {} +} + +// MARK: PasscodeLogInCoordinatorDelegate +extension ChooseAccountCoordinator: PasscodeLogInCoordinatorDelegate { + + func passcodeCoordinatorLogInCompleted(wallet: DomainLayer.DTO.Wallet) { + //TODO: Как бы сбросить состояние по другому? + let index = self.navigationRouter + .navigationController + .viewControllers + .enumerated() + .first { $0.element is ChooseAccountViewController } + + if let index = index { + let result = self.navigationRouter.navigationController.viewControllers.prefix(index.offset + 1) + self.navigationRouter.navigationController.viewControllers = Array(result) + } + + delegate?.userChooseCompleted(wallet: wallet) + removeFromParentCoordinator() + } +} + +// MARK: PasscodeCoordinatorDelegate +extension ChooseAccountCoordinator: PasscodeCoordinatorDelegate { + + func passcodeCoordinatorVerifyAcccesCompleted(signedWallet: DomainLayer.DTO.SignedWallet) {} + + func passcodeCoordinatorAuthorizationCompleted(wallet: DomainLayer.DTO.Wallet) { + //TODO: Как бы сбросить состояние по другому? +// self.navigationRouter.navigationController.viewControllers = self.viewControllers ?? [] + + //TODO: Fix + let index = self.navigationRouter + .navigationController + .viewControllers + .enumerated() + .first { $0.element is ChooseAccountViewController } + + if let index = index { + let result = self.navigationRouter.navigationController.viewControllers.prefix(index.offset + 1) + self.navigationRouter.navigationController.viewControllers = Array(result) + } + + delegate?.userChooseCompleted(wallet: wallet) + removeFromParentCoordinator() + } + + func passcodeCoordinatorWalletLogouted() { + //TODO: Как бы сбросить состояние по другому? + let index = self.navigationRouter + .navigationController + .viewControllers + .enumerated() + .first { $0.element is ChooseAccountViewController } + + if let index = index { + let result = self.navigationRouter.navigationController.viewControllers.prefix(index.offset + 1) + self.navigationRouter.navigationController.viewControllers = Array(result) + } + + self.applicationCoordinator?.showEnterDisplay() + removeFromParentCoordinator() + } +} diff --git a/WavesWallet-iOS/PresentationLayer/Coordinators/Enter/EditAccountNameCoordinator.swift b/WavesWallet-iOS/Coordinators/Enter/EditAccountNameCoordinator.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Coordinators/Enter/EditAccountNameCoordinator.swift rename to WavesWallet-iOS/Coordinators/Enter/EditAccountNameCoordinator.swift index 878de21a..2dcf9858 100644 --- a/WavesWallet-iOS/PresentationLayer/Coordinators/Enter/EditAccountNameCoordinator.swift +++ b/WavesWallet-iOS/Coordinators/Enter/EditAccountNameCoordinator.swift @@ -7,6 +7,7 @@ // import UIKit +import DomainLayer final class EditAccountNameCoordinator: Coordinator { diff --git a/WavesWallet-iOS/PresentationLayer/Coordinators/Enter/EnterCoordinator.swift b/WavesWallet-iOS/Coordinators/Enter/EnterCoordinator.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Coordinators/Enter/EnterCoordinator.swift rename to WavesWallet-iOS/Coordinators/Enter/EnterCoordinator.swift index e06e1801..2ecf32d0 100644 --- a/WavesWallet-iOS/PresentationLayer/Coordinators/Enter/EnterCoordinator.swift +++ b/WavesWallet-iOS/Coordinators/Enter/EnterCoordinator.swift @@ -7,6 +7,7 @@ // import UIKit +import DomainLayer protocol EnterCoordinatorDelegate: AnyObject { func userCompletedLogIn(wallet: DomainLayer.DTO.Wallet) @@ -153,5 +154,9 @@ extension EnterCoordinator: ChooseAccountCoordinatorDelegate { delegate?.userCompletedLogIn(wallet: wallet) removeFromParentCoordinator() - } + } + + func userDidTapBackButton() { + self.navigationRouter.popViewController() + } } diff --git a/WavesWallet-iOS/PresentationLayer/Coordinators/Enter/EnterLanguageCoordinator.swift b/WavesWallet-iOS/Coordinators/Enter/EnterLanguageCoordinator.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Coordinators/Enter/EnterLanguageCoordinator.swift rename to WavesWallet-iOS/Coordinators/Enter/EnterLanguageCoordinator.swift diff --git a/WavesWallet-iOS/PresentationLayer/Coordinators/Enter/HelloCoordinator.swift b/WavesWallet-iOS/Coordinators/Enter/HelloCoordinator.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Coordinators/Enter/HelloCoordinator.swift rename to WavesWallet-iOS/Coordinators/Enter/HelloCoordinator.swift index 0c48bad2..160db309 100644 --- a/WavesWallet-iOS/PresentationLayer/Coordinators/Enter/HelloCoordinator.swift +++ b/WavesWallet-iOS/Coordinators/Enter/HelloCoordinator.swift @@ -8,6 +8,7 @@ import Foundation import UIKit +import Extensions protocol HelloCoordinatorDelegate: AnyObject { func userFinishedGreet() diff --git a/WavesWallet-iOS/PresentationLayer/Coordinators/Enter/ImportCoordinator.swift b/WavesWallet-iOS/Coordinators/Enter/ImportCoordinator.swift similarity index 96% rename from WavesWallet-iOS/PresentationLayer/Coordinators/Enter/ImportCoordinator.swift rename to WavesWallet-iOS/Coordinators/Enter/ImportCoordinator.swift index 94c7b189..fef66374 100644 --- a/WavesWallet-iOS/PresentationLayer/Coordinators/Enter/ImportCoordinator.swift +++ b/WavesWallet-iOS/Coordinators/Enter/ImportCoordinator.swift @@ -8,8 +8,9 @@ import UIKit import RxSwift -import WavesSDKExtension -import WavesSDKCrypto +import WavesSDKExtensions +import DomainLayer +import Extensions private enum Constants { static let duration: TimeInterval = 3 @@ -24,7 +25,7 @@ final class ImportCoordinator: Coordinator { private let completed: ((ImportTypes.DTO.Account) -> Void) private let disposeBag: DisposeBag = DisposeBag() - private let auth: AuthorizationInteractorProtocol = FactoryInteractors.instance.authorization + private let auth: AuthorizationUseCaseProtocol = UseCasesFactory.instance.authorization private var currentPrivateKeyAccount: PrivateKeyAccount? diff --git a/WavesWallet-iOS/PresentationLayer/Coordinators/Enter/NewAccountCoordinator.swift b/WavesWallet-iOS/Coordinators/Enter/NewAccountCoordinator.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Coordinators/Enter/NewAccountCoordinator.swift rename to WavesWallet-iOS/Coordinators/Enter/NewAccountCoordinator.swift index 14fed4a1..506ad2ad 100644 --- a/WavesWallet-iOS/PresentationLayer/Coordinators/Enter/NewAccountCoordinator.swift +++ b/WavesWallet-iOS/Coordinators/Enter/NewAccountCoordinator.swift @@ -7,7 +7,7 @@ // import UIKit -import WavesSDKExtension +import WavesSDKExtensions final class NewAccountCoordinator: Coordinator { var childCoordinators: [Coordinator] = [] diff --git a/WavesWallet-iOS/PresentationLayer/Coordinators/History/HistoryCoordinator.swift b/WavesWallet-iOS/Coordinators/History/HistoryCoordinator.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Coordinators/History/HistoryCoordinator.swift rename to WavesWallet-iOS/Coordinators/History/HistoryCoordinator.swift index db2f7ea5..9a8df65c 100644 --- a/WavesWallet-iOS/PresentationLayer/Coordinators/History/HistoryCoordinator.swift +++ b/WavesWallet-iOS/Coordinators/History/HistoryCoordinator.swift @@ -8,6 +8,7 @@ import UIKit import RxSwift +import DomainLayer final class HistoryCoordinator: Coordinator { diff --git a/WavesWallet-iOS/PresentationLayer/Coordinators/History/TransactionCardCoordinator.swift b/WavesWallet-iOS/Coordinators/History/TransactionCardCoordinator.swift similarity index 94% rename from WavesWallet-iOS/PresentationLayer/Coordinators/History/TransactionCardCoordinator.swift rename to WavesWallet-iOS/Coordinators/History/TransactionCardCoordinator.swift index 24d3fec8..18b6cda4 100644 --- a/WavesWallet-iOS/PresentationLayer/Coordinators/History/TransactionCardCoordinator.swift +++ b/WavesWallet-iOS/Coordinators/History/TransactionCardCoordinator.swift @@ -9,6 +9,8 @@ import Foundation import UIKit import RxSwift +import DomainLayer +import Extensions private struct Constants { static let wavesExplorerTransactionUrl = "https://wavesexplorer.com/tx/" @@ -88,7 +90,7 @@ extension TransactionCardCoordinator: StartLeasingModuleOutput { func startLeasingDidSuccess(transaction: DomainLayer.DTO.SmartTransaction, kind: StartLeasingTypes.Kind) { switch kind { - case .cancel(let tx): + case .cancel(_): delegate?.transactionCardCoordinatorCanceledLeasing() transactionCardViewDismissCard() default: @@ -107,6 +109,12 @@ extension TransactionCardCoordinator: TransactionCardModuleOutput { func transactionCardAddContact(address: String) { + UseCasesFactory + .instance + .analyticManager + .trackEvent(.addressBook(.transactionAddressSave)) + + let vc = AddAddressBookModuleBuilder(output: self) .build(input: AddAddressBook.DTO.Input(kind: .add(address, isMutable: false))) self.cardNavigationRouter.pushViewController(vc) @@ -114,6 +122,11 @@ extension TransactionCardCoordinator: TransactionCardModuleOutput { func transactionCardEditContact(contact: DomainLayer.DTO.Contact) { + UseCasesFactory + .instance + .analyticManager + .trackEvent(.addressBook(.transactionAddressEdit)) + let vc = AddAddressBookModuleBuilder(output: self) .build(input: AddAddressBook.DTO.Input(kind:.edit(contact: contact, isMutable: false))) @@ -158,8 +171,7 @@ extension TransactionCardCoordinator: TransactionCardModuleOutput { if let url = url { let vc = BrowserViewController(url: url) - let nv = CustomNavigationController(rootViewController: vc) - + let nv = UINavigationController(rootViewController: vc) cardNavigationRouter.present(nv, animated: true, completion: nil) } diff --git a/WavesWallet-iOS/PresentationLayer/Coordinators/History/TransactionHistoryCoordinator.swift b/WavesWallet-iOS/Coordinators/History/TransactionHistoryCoordinator.swift similarity index 96% rename from WavesWallet-iOS/PresentationLayer/Coordinators/History/TransactionHistoryCoordinator.swift rename to WavesWallet-iOS/Coordinators/History/TransactionHistoryCoordinator.swift index 628a5f98..85bab425 100644 --- a/WavesWallet-iOS/PresentationLayer/Coordinators/History/TransactionHistoryCoordinator.swift +++ b/WavesWallet-iOS/Coordinators/History/TransactionHistoryCoordinator.swift @@ -96,16 +96,7 @@ extension TransactionHistoryCoordinator: TransactionHistoryModuleOutput { // MARK: - StartLeasingModuleOutput extension TransactionHistoryCoordinator: StartLeasingModuleOutput { - func startLeasingDidSuccess(transaction: DomainLayer.DTO.SmartTransaction, kind: StartLeasingTypes.Kind) { - - switch kind { - case .cancel: - break - //TODO: here can be logic - default: - break - } - } + func startLeasingDidSuccess(transaction: DomainLayer.DTO.SmartTransaction, kind: StartLeasingTypes.Kind) {} } // MARK: AddAddressBookModuleOutput extension TransactionHistoryCoordinator: AddAddressBookModuleOutput { diff --git a/WavesWallet-iOS/PresentationLayer/Coordinators/MainTabBarCoordinator.swift b/WavesWallet-iOS/Coordinators/MainTabBarCoordinator.swift similarity index 91% rename from WavesWallet-iOS/PresentationLayer/Coordinators/MainTabBarCoordinator.swift rename to WavesWallet-iOS/Coordinators/MainTabBarCoordinator.swift index 7e1af463..07996ccf 100644 --- a/WavesWallet-iOS/PresentationLayer/Coordinators/MainTabBarCoordinator.swift +++ b/WavesWallet-iOS/Coordinators/MainTabBarCoordinator.swift @@ -9,6 +9,7 @@ import UIKit import RxSwift import RxCocoa +import DomainLayer private enum Constants { static let tabBarItemImageInset = UIEdgeInsets.init(top: 0, left: 0, bottom: -8, right: 0) @@ -42,8 +43,8 @@ final class MainTabBarCoordinator: NSObject, Coordinator { private weak var applicationCoordinator: ApplicationCoordinatorProtocol? private let disposeBag = DisposeBag() - private let authorizationInteractor: AuthorizationInteractorProtocol = FactoryInteractors.instance.authorization - private let walletsRepository: WalletsRepositoryProtocol = FactoryRepositories.instance.walletsRepositoryLocal + private let authorizationInteractor: AuthorizationUseCaseProtocol = UseCasesFactory.instance.authorization + private let walletsRepository: WalletsRepositoryProtocol = UseCasesFactory.instance.repositories.walletsRepositoryLocal private let navigationRouterWallet: NavigationRouter = { @@ -181,6 +182,12 @@ extension MainTabBarCoordinator: UITabBarControllerDelegate { func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool { if viewController is PopoperButtonViewController { + + UseCasesFactory + .instance + .analyticManager + .trackEvent(.wavesQuickAction(.wavesActionPanel)) + let vc = StoryboardScene.Waves.wavesPopupViewController.instantiate() vc.moduleOutput = self let popup = PopupViewController() @@ -213,7 +220,14 @@ extension MainTabBarCoordinator: WavesPopupModuleOutput { } func showSend() { + if let nav = selectedViewController as? CustomNavigationController { + + UseCasesFactory + .instance + .analyticManager + .trackEvent(.wavesQuickAction(.wavesActionSend)) + let vc = SendModuleBuilder().build(input: .empty) nav.pushViewController(vc, animated: true) } @@ -222,6 +236,12 @@ extension MainTabBarCoordinator: WavesPopupModuleOutput { func showReceive() { if let nav = selectedViewController as? CustomNavigationController { + + UseCasesFactory + .instance + .analyticManager + .trackEvent(.wavesQuickAction(.wavesActionReceive)) + let vc = ReceiveContainerModuleBuilder().build(input: nil) nav.pushViewController(vc, animated: true) } diff --git a/WavesWallet-iOS/Coordinators/MobileKeeperCoordinator.swift b/WavesWallet-iOS/Coordinators/MobileKeeperCoordinator.swift new file mode 100644 index 00000000..f757d5cc --- /dev/null +++ b/WavesWallet-iOS/Coordinators/MobileKeeperCoordinator.swift @@ -0,0 +1,288 @@ +// +// MobileKeeperCoordinator.swift +// WavesWallet-iOS +// +// Created by rprokofev on 26.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import DomainLayer +import WavesSDK + +protocol MobileKeeperCoordinatorDelegate: AnyObject { + + func mobileKeeperCoordinatorError(_ error: MobileKeeperUseCaseError) +} + +final class MobileKeeperCoordinator: Coordinator { + + var childCoordinators: [Coordinator] = [] + + weak var parent: Coordinator? + + private var navigationRouter: NavigationRouter + + private var windowRouter: WindowRouter + + private let disposeBag: DisposeBag = DisposeBag() + + private lazy var popoverViewControllerTransitioning = ModalViewControllerTransitioning { [weak self] in + guard let self = self else { return } + } + private let request: DomainLayer.DTO.MobileKeeper.Request + + private let mobileKeeperRepository: MobileKeeperRepositoryProtocol = UseCasesFactory.instance.repositories.mobileKeeperRepository + + private var snackError: String? = nil + + weak var delegate: MobileKeeperCoordinatorDelegate? + + init(windowRouter: WindowRouter, request: DomainLayer.DTO.MobileKeeper.Request) { + + self.request = request + let window = UIWindow() + window.windowLevel = UIWindow.Level.init(rawValue: UIWindow.Level.normal.rawValue + 1.0) + self.windowRouter = WindowRouter.windowFactory(window: window) + self.navigationRouter = NavigationRouter(navigationController: CustomNavigationController()) + } + + func start() { + + windowRouter.setRootViewController(self.navigationRouter.navigationController) + let coordinator = ChooseAccountCoordinator(navigationRouter: navigationRouter, applicationCoordinator: self) + coordinator.delegate = self + addChildCoordinatorAndStart(childCoordinator: coordinator) + } + + private func closeWindow(completed: (() -> Void)? = nil) { + self.windowRouter.dissmissWindow(animated: .crossDissolve) { + completed?() + self.removeFromParentCoordinator() + } + } + + private func rejectAndClose(request: DomainLayer.DTO.MobileKeeper.Request) { + + mobileKeeperRepository + .rejectRequest(request) + .observeOn(MainScheduler.asyncInstance) + .subscribe(onNext: { [weak self] (result) in + + self?.closeWindow(completed: { + if result == false { + self?.delegate?.mobileKeeperCoordinatorError(MobileKeeperUseCaseError.dAppDontOpen) + } + }) + }, onError: { [weak self] (error) in + + self?.closeWindow(completed: { + if let error = error as? MobileKeeperUseCaseError { + self?.delegate?.mobileKeeperCoordinatorError(error) + } + }) + }) + .disposed(by: disposeBag) + + } + + private func errorAndClose(request: DomainLayer.DTO.MobileKeeper.Request, error: DomainLayer.DTO.MobileKeeper.Error) { + + mobileKeeperRepository + .errorRequest(request, error: error) + .observeOn(MainScheduler.asyncInstance) + .subscribe(onNext: { [weak self] (result) in + + if result == false { + self?.delegate?.mobileKeeperCoordinatorError(MobileKeeperUseCaseError.dAppDontOpen) + } + self?.closeWindow() + }, onError: { [weak self] (error) in + + self?.closeWindow(completed: { + if let error = error as? MobileKeeperUseCaseError { + self?.delegate?.mobileKeeperCoordinatorError(error) + } + }) + }) + .disposed(by: disposeBag) + } + +} + +// MARK: ApplicationCoordinatorProtocol + +extension MobileKeeperCoordinator: ApplicationCoordinatorProtocol { + func showEnterDisplay() { + rejectAndClose(request: request) + } +} + +// MARK: ChooseAccountCoordinatorDelegate + +extension MobileKeeperCoordinator: ChooseAccountCoordinatorDelegate { + + func userChooseCompleted(wallet: DomainLayer.DTO.Wallet) { + + UseCasesFactory + .instance + .authorization + .authorizedWallet() + .take(1) + .observeOn(MainScheduler.asyncInstance) + .subscribe(onNext: { [weak self] (wallet) in + guard let self = self else { return } + + let vc = ConfirmRequestModuleBuilder(output: self) + .build(input: .init(request: self.request, signedWallet: wallet )) + + self.navigationRouter.pushViewController(vc) + }) + .disposed(by: disposeBag) + } + + func userDidTapBackButton() { + rejectAndClose(request: request) + } +} + +extension MobileKeeperCoordinator: ConfirmRequestModuleOutput { + + func confirmRequestDidTapClose(_ prepareRequest: DomainLayer.DTO.MobileKeeper.PrepareRequest) { + errorAndClose(request: prepareRequest.request, error: .invalidRequest) + } + + func confirmRequestDidTapReject(_ complitingRequest: ConfirmRequest.DTO.ComplitingRequest) { + rejectAndClose(request: complitingRequest.prepareRequest.request) + } + + func confirmRequestDidTapApprove(_ complitingRequest: ConfirmRequest.DTO.ComplitingRequest) { + + let action = complitingRequest.prepareRequest.request.action + + switch action { + case .send: + let vc = StoryboardScene.MobileKeeper.confirmRequestLoadingViewController.instantiate() + navigationRouter.pushViewController(vc) + case .sign: + break + } + + mobileKeeperRepository + .completeRequest(complitingRequest.prepareRequest) + .observeOn(MainScheduler.asyncInstance) + .subscribe(onNext: { [weak self] (completed) in + + guard let self = self else { return } + + switch completed.request.action { + case .send: + let vc = StoryboardScene.MobileKeeper.confirmRequestCompleteViewController.instantiate() + + vc.completedRequest = completed + vc.complitingRequest = complitingRequest + vc.okButtonDidTap = { [weak self] () -> Void in + + guard let self = self else { return } + + self.mobileKeeperRepository + .approveRequest(completed) + .observeOn(MainScheduler.asyncInstance) + .subscribe(onNext: { [weak self] (result) in + + self?.closeWindow(completed: { + if result == false { + self?.delegate?.mobileKeeperCoordinatorError(MobileKeeperUseCaseError.dAppDontOpen) + } + }) + + }, onError: { [weak self] (error) in + + self?.closeWindow(completed: { + if let error = error as? MobileKeeperUseCaseError { + self?.delegate?.mobileKeeperCoordinatorError(error) + } + }) + }) + .disposed(by: self.disposeBag) + } + + self.navigationRouter.pushViewController(vc) + case .sign: + + self.mobileKeeperRepository + .approveRequest(completed) + .observeOn(MainScheduler.asyncInstance) + .subscribe(onNext: { [weak self] (result) in + + self?.closeWindow(completed: { + if result == false { + self?.delegate?.mobileKeeperCoordinatorError(MobileKeeperUseCaseError.dAppDontOpen) + } + }) + + }, onError: { [weak self] (error) in + + self?.closeWindow(completed: { + if let error = error as? MobileKeeperUseCaseError { + self?.handlerError(with: error) + } + }) + }) + .disposed(by: self.disposeBag) + + } + }, onError: { [weak self] (error) in + + if let error = error as? MobileKeeperUseCaseError { + self?.handlerError(with: error) + + } + }) + .disposed(by: disposeBag) + } + + private func handlerError(with error: MobileKeeperUseCaseError) { + + switch error { + case .dAppDontOpen: + showErrorView(with: error) + + case .dataIncorrect: + errorAndClose(request: request, error: .invalidRequest) + + case .transactionDontSupport: + errorAndClose(request: request, error: .transactionDontSupport) + + default: + break + } + + showErrorView(with: error) + } + + private func showErrorView(with error: MobileKeeperUseCaseError) { + + if let snackError = snackError { + UIApplication.shared.windows.last?.rootViewController?.hideSnack(key: snackError) + } + + switch error { + case .dAppDontOpen: + snackError = showErrorSnack("Application don't open") + + case .dataIncorrect: + snackError = showErrorSnack("Request incorect") + + case .transactionDontSupport: + snackError = showErrorSnack("Transaction don't support") + default: + snackError = UIApplication.shared.windows.last?.rootViewController?.showErrorNotFoundSnackWithoutAction() + } + } + + private func showErrorSnack(_ message: (String)) -> String? { + return UIApplication.shared.windows.last?.rootViewController?.showErrorSnackWithoutAction(title: message) + } +} diff --git a/WavesWallet-iOS/PresentationLayer/Coordinators/Passcode/PasscodeCoordinator.swift b/WavesWallet-iOS/Coordinators/Passcode/PasscodeCoordinator.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Coordinators/Passcode/PasscodeCoordinator.swift rename to WavesWallet-iOS/Coordinators/Passcode/PasscodeCoordinator.swift index bf0952b1..64ad6569 100644 --- a/WavesWallet-iOS/PresentationLayer/Coordinators/Passcode/PasscodeCoordinator.swift +++ b/WavesWallet-iOS/Coordinators/Passcode/PasscodeCoordinator.swift @@ -7,6 +7,7 @@ // import UIKit +import DomainLayer protocol PasscodeCoordinatorDelegate: AnyObject { func passcodeCoordinatorAuthorizationCompleted(wallet: DomainLayer.DTO.Wallet) diff --git a/WavesWallet-iOS/PresentationLayer/Coordinators/Passcode/PasscodeLogInCoordinator.swift b/WavesWallet-iOS/Coordinators/Passcode/PasscodeLogInCoordinator.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Coordinators/Passcode/PasscodeLogInCoordinator.swift rename to WavesWallet-iOS/Coordinators/Passcode/PasscodeLogInCoordinator.swift index 5f7077da..d5dbdff3 100644 --- a/WavesWallet-iOS/PresentationLayer/Coordinators/Passcode/PasscodeLogInCoordinator.swift +++ b/WavesWallet-iOS/Coordinators/Passcode/PasscodeLogInCoordinator.swift @@ -8,6 +8,7 @@ import Foundation import UIKit +import DomainLayer protocol PasscodeLogInCoordinatorDelegate: AnyObject { func passcodeCoordinatorLogInCompleted(wallet: DomainLayer.DTO.Wallet) @@ -42,7 +43,7 @@ final class PasscodeLogInCoordinator: Coordinator { let window = UIWindow() window.windowLevel = UIWindow.Level.normal - self.windowRouter = WindowRouter(window: window) + self.windowRouter = WindowRouter.windowFactory(window: window) self.passcodeNavigationRouter = NavigationRouter(navigationController: CustomNavigationController()) case .navigation(let navRouter): diff --git a/WavesWallet-iOS/PresentationLayer/Coordinators/Profile/AddressesKeysCoordinator.swift b/WavesWallet-iOS/Coordinators/Profile/AddressesKeysCoordinator.swift similarity index 92% rename from WavesWallet-iOS/PresentationLayer/Coordinators/Profile/AddressesKeysCoordinator.swift rename to WavesWallet-iOS/Coordinators/Profile/AddressesKeysCoordinator.swift index 52595c67..aac0fdc1 100644 --- a/WavesWallet-iOS/PresentationLayer/Coordinators/Profile/AddressesKeysCoordinator.swift +++ b/WavesWallet-iOS/Coordinators/Profile/AddressesKeysCoordinator.swift @@ -8,6 +8,8 @@ import UIKit import RxSwift +import DomainLayer +import Extensions private enum Constants { static let popoverHeight: CGFloat = 378 @@ -22,7 +24,7 @@ final class AddressesKeysCoordinator: Coordinator { private let wallet: DomainLayer.DTO.Wallet private var rootViewController: UIViewController? - private let authorization = FactoryInteractors.instance.authorization + private let authorization = UseCasesFactory.instance.authorization private let disposeBag: DisposeBag = DisposeBag() private weak var applicationCoordinator: ApplicationCoordinatorProtocol? private var currentPopup: PopupViewController? @@ -83,7 +85,7 @@ extension AddressesKeysCoordinator: AliasesModuleOutput { self.currentPopup?.dismissPopup { let vc = CreateAliasModuleBuilder(output: self).build() self.navigationRouter.pushViewController(vc) - AnalyticManager.trackEvent(.createAlias(.createProfile)) + UseCasesFactory.instance.analyticManager.trackEvent(.alias(.createProfile)) } } } @@ -95,7 +97,7 @@ extension AddressesKeysCoordinator: AliasWithoutViewControllerDelegate { self.currentPopup?.dismissPopup { let vc = CreateAliasModuleBuilder(output: self).build() self.navigationRouter.pushViewController(vc, animated: true) - AnalyticManager.trackEvent(.createAlias(.createProfile)) + UseCasesFactory.instance.analyticManager.trackEvent(.alias(.createProfile)) } } } diff --git a/WavesWallet-iOS/PresentationLayer/Coordinators/Profile/ProfileCoordinator.swift b/WavesWallet-iOS/Coordinators/Profile/ProfileCoordinator.swift similarity index 80% rename from WavesWallet-iOS/PresentationLayer/Coordinators/Profile/ProfileCoordinator.swift rename to WavesWallet-iOS/Coordinators/Profile/ProfileCoordinator.swift index 49c38b21..6f4dd8c9 100644 --- a/WavesWallet-iOS/PresentationLayer/Coordinators/Profile/ProfileCoordinator.swift +++ b/WavesWallet-iOS/Coordinators/Profile/ProfileCoordinator.swift @@ -10,6 +10,8 @@ import UIKit import RxSwift import StoreKit import MessageUI +import DomainLayer +import Extensions private enum Constants { static let supporURL = URL(string: "https://support.wavesplatform.com/")! @@ -22,7 +24,7 @@ final class ProfileCoordinator: Coordinator { weak var parent: Coordinator? private weak var applicationCoordinator: ApplicationCoordinatorProtocol? - private let authorization = FactoryInteractors.instance.authorization + private let authorization = UseCasesFactory.instance.authorization private let navigationRouter: NavigationRouter private let disposeBag: DisposeBag = DisposeBag() @@ -58,6 +60,12 @@ extension ProfileCoordinator: ProfileModuleOutput { let seed = signedWallet.seedWords + UseCasesFactory + .instance + .analyticManager + .trackEvent(.profile(.profileBackupPhrase)) + + if wallet.isBackedUp == false { let backup = BackupCoordinator(seed: seed, @@ -77,6 +85,12 @@ extension ProfileCoordinator: ProfileModuleOutput { } func showAddressesKeys(wallet: DomainLayer.DTO.Wallet) { + + UseCasesFactory + .instance + .analyticManager + .trackEvent(.profile(.profileAddressAndKeys)) + guard let applicationCoordinator = self.applicationCoordinator else { return } let coordinator = AddressesKeysCoordinator(navigationRouter: navigationRouter, @@ -86,24 +100,48 @@ extension ProfileCoordinator: ProfileModuleOutput { } func showAddressBook() { + + UseCasesFactory + .instance + .analyticManager + .trackEvent(.addressBook(.profileAddressBookPage)) + let vc = AddressBookModuleBuilder(output: nil) .build(input: .init(isEditMode: true)) navigationRouter.pushViewController(vc) } func showLanguage() { + + UseCasesFactory + .instance + .analyticManager + .trackEvent(.profile(.profileLanguage)) + let language = StoryboardScene.Language.languageViewController.instantiate() language.delegate = self navigationRouter.pushViewController(language) } func showNetwork(wallet: DomainLayer.DTO.Wallet) { + + UseCasesFactory + .instance + .analyticManager + .trackEvent(.profile(.profileNetwork)) + let vc = NetworkSettingsModuleBuilder(output: self) .build(input: .init(wallet: wallet)) navigationRouter.pushViewController(vc) } func showRateApp() { + + UseCasesFactory + .instance + .analyticManager + .trackEvent(.profile(.profileRateApp)) + #if DEBUG if UITest.isEnabledonkeyTest { return @@ -113,6 +151,12 @@ extension ProfileCoordinator: ProfileModuleOutput { } func showFeedback() { + + UseCasesFactory + .instance + .analyticManager + .trackEvent(.profile(.profileFeedback)) + #if DEBUG if UITest.isEnabledonkeyTest { return @@ -124,6 +168,12 @@ extension ProfileCoordinator: ProfileModuleOutput { } func showSupport() { + + UseCasesFactory + .instance + .analyticManager + .trackEvent(.profile(.profileSupport)) + #if DEBUG if UITest.isEnabledonkeyTest { return @@ -145,6 +195,12 @@ extension ProfileCoordinator: ProfileModuleOutput { } func showChangePasscode(wallet: DomainLayer.DTO.Wallet) { + + UseCasesFactory + .instance + .analyticManager + .trackEvent(.profile(.profileChangePasscode)) + let passcode = PasscodeCoordinator(kind: .changePasscode(wallet), behaviorPresentation: .push(navigationRouter, dissmissToRoot: true)) @@ -153,12 +209,19 @@ extension ProfileCoordinator: ProfileModuleOutput { } func showChangePassword(wallet: DomainLayer.DTO.Wallet) { + + UseCasesFactory + .instance + .analyticManager + .trackEvent(.profile(.profileChangePassword)) + let vc = ChangePasswordModuleBuilder(output: self) .build(input: .init(wallet: wallet)) navigationRouter.pushViewController(vc) } func accountLogouted() { + #if DEBUG if UITest.isEnabledonkeyTest { return @@ -168,6 +231,12 @@ extension ProfileCoordinator: ProfileModuleOutput { } func accountDeleted() { + + UseCasesFactory + .instance + .analyticManager + .trackEvent(.profile(.profileDeleteAccount)) + #if DEBUG if UITest.isEnabledonkeyTest { return diff --git a/WavesWallet-iOS/Coordinators/PushNotificationsCoordinator.swift b/WavesWallet-iOS/Coordinators/PushNotificationsCoordinator.swift new file mode 100644 index 00000000..4468709c --- /dev/null +++ b/WavesWallet-iOS/Coordinators/PushNotificationsCoordinator.swift @@ -0,0 +1,73 @@ +// +// PushNotificationsCoordinator.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 07.11.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import Extensions +import WavesSDKExtensions + +private struct PushNotificationsAlertSettings: TSUD, Codable, Mutating { + + var hasShowAlert: Bool + + private enum Constants { + static let key: String = "com.waves.pushNotifications.settings" + } + + init(hasShowAlert: Bool) { + self.hasShowAlert = hasShowAlert + } + + init() { + hasShowAlert = false + } + + static var defaultValue: PushNotificationsAlertSettings { + return PushNotificationsAlertSettings(hasShowAlert: false) + } + + static var stringKey: String { + return Constants.key + } +} + +final class PushNotificationsCoordinator: NSObject, Coordinator { + + var childCoordinators: [Coordinator] = [] + + var parent: Coordinator? + + func start() { + + if PushNotificationsAlertSettings.get().hasShowAlert == false { + + let pushAlert = PushNotificationsAlertView.show() + pushAlert.activateAction = { [weak self] in + guard let self = self else { return } + self.activateNotifications() + } + pushAlert.laterAction = { [weak self] in + guard let self = self else { return } + self.laterAction() + } + } + else { + removeFromParentCoordinator() + } + } + + private func activateNotifications() { + PushNotificationsManager.registerRemoteNotifications() + PushNotificationsAlertSettings.set(.init(hasShowAlert: true)) + removeFromParentCoordinator() + } + + private func laterAction() { + PushNotificationsAlertSettings.set(.init(hasShowAlert: true)) + removeFromParentCoordinator() + } +} diff --git a/WavesWallet-iOS/PresentationLayer/Coordinators/QRCodeReaderControllerCoordinator.swift b/WavesWallet-iOS/Coordinators/QRCodeReaderControllerCoordinator.swift similarity index 96% rename from WavesWallet-iOS/PresentationLayer/Coordinators/QRCodeReaderControllerCoordinator.swift rename to WavesWallet-iOS/Coordinators/QRCodeReaderControllerCoordinator.swift index 4233615e..441e01cb 100644 --- a/WavesWallet-iOS/PresentationLayer/Coordinators/QRCodeReaderControllerCoordinator.swift +++ b/WavesWallet-iOS/Coordinators/QRCodeReaderControllerCoordinator.swift @@ -40,7 +40,6 @@ final class QRCodeReaderControllerCoordinator: Coordinator { CameraAccess.requestAccess(success: { [weak self] in guard let self = self else { return } - self.readerVC.modalPresentationStyle = .formSheet self.navigationRouter.present(self.readerVC) }, failure: { [weak self] in guard let self = self else { return } diff --git a/WavesWallet-iOS/Coordinators/SendCoordinator.swift b/WavesWallet-iOS/Coordinators/SendCoordinator.swift new file mode 100644 index 00000000..d288b8f5 --- /dev/null +++ b/WavesWallet-iOS/Coordinators/SendCoordinator.swift @@ -0,0 +1,51 @@ +// +// SendCoordinator.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 30.10.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import Extensions + +final class SendCoordinator: Coordinator { + + var childCoordinators: [Coordinator] = [] + + weak var parent: Coordinator? + + private var navigationRouter: NavigationRouter + private var windowRouter: WindowRouter + private var deepLink: DeepLink + + init(windowRouter: WindowRouter, deepLink: DeepLink) { + + self.deepLink = deepLink + let window = UIWindow() + window.windowLevel = UIWindow.Level(rawValue: UIWindow.Level.normal.rawValue + 1.0) + self.windowRouter = WindowRouter.windowFactory(window: window) + self.navigationRouter = NavigationRouter(navigationController: CustomNavigationController()) + + NotificationCenter.default.addObserver(self, selector: #selector(dismiss), name: UIApplication.didEnterBackgroundNotification, object: nil) + } + + func start() { + + if let vc = SendModuleBuilder().build(input: .deepLink(deepLink)) as? SendViewController { + windowRouter.setRootViewController(self.navigationRouter.navigationController) + navigationRouter.pushViewController(vc) + vc.backTappedAction = { [weak self] in + guard let self = self else { return } + self.dismiss() + } + } + } + + @objc private func dismiss() { + windowRouter.dissmissWindow(animated: nil, completed: { [weak self] in + guard let self = self else { return } + self.removeFromParentCoordinator() + }) + } +} diff --git a/WavesWallet-iOS/PresentationLayer/Coordinators/SlideCoordinator.swift b/WavesWallet-iOS/Coordinators/SlideCoordinator.swift similarity index 94% rename from WavesWallet-iOS/PresentationLayer/Coordinators/SlideCoordinator.swift rename to WavesWallet-iOS/Coordinators/SlideCoordinator.swift index f1a87864..f8d4a34e 100644 --- a/WavesWallet-iOS/PresentationLayer/Coordinators/SlideCoordinator.swift +++ b/WavesWallet-iOS/Coordinators/SlideCoordinator.swift @@ -8,6 +8,7 @@ import UIKit import RxSwift +import DomainLayer final class SlideCoordinator: Coordinator { @@ -20,6 +21,8 @@ final class SlideCoordinator: Coordinator { private let slideMenuRouter: SlideMenuRouter private let disposeBag = DisposeBag() + weak var menuViewControllerDelegate: MenuViewControllerDelegate? + init(windowRouter: WindowRouter, wallet: DomainLayer.DTO.Wallet?) { self.windowRouter = windowRouter self.wallet = wallet @@ -32,6 +35,7 @@ final class SlideCoordinator: Coordinator { let menuController = StoryboardScene.Main.menuViewController.instantiate() slideMenuRouter.setLeftMenuViewController(menuController) + menuController.delegate = menuViewControllerDelegate self.windowRouter.setRootViewController(slideMenuRouter.slideMenu, animated: .crossDissolve) if let wallet = wallet { diff --git a/WavesWallet-iOS/Coordinators/UITest/UIDeveloperCoordinator.swift b/WavesWallet-iOS/Coordinators/UITest/UIDeveloperCoordinator.swift new file mode 100644 index 00000000..8e8b125c --- /dev/null +++ b/WavesWallet-iOS/Coordinators/UITest/UIDeveloperCoordinator.swift @@ -0,0 +1,35 @@ +// +// UIDeveloperCoordinator.swift +// WavesWallet-iOS +// +// Created by rprokofev on 28.07.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import UIKit + +final class UIDeveloperCoordinator: Coordinator { + + var childCoordinators: [Coordinator] = [] + weak var parent: Coordinator? + + private var windowRouter: WindowRouter + private var navigationRouter: NavigationRouter + + weak var delegate: HelloCoordinatorDelegate? + + init(windowRouter: WindowRouter) { + self.windowRouter = windowRouter + self.navigationRouter = NavigationRouter(navigationController: CustomNavigationController()) + } + + func start() { + +// let coordinator = WidgetSettingsCoordinator.init(navigationRouter: navigationRouter) +// +// addChildCoordinatorAndStart(childCoordinator: coordinator) +// +// self.windowRouter.setRootViewController(self.navigationRouter.navigationController) + } +} diff --git a/WavesWallet-iOS/PresentationLayer/Coordinators/WalletCoordinator.swift b/WavesWallet-iOS/Coordinators/WalletCoordinator.swift similarity index 78% rename from WavesWallet-iOS/PresentationLayer/Coordinators/WalletCoordinator.swift rename to WavesWallet-iOS/Coordinators/WalletCoordinator.swift index d36915a7..277a02ee 100644 --- a/WavesWallet-iOS/PresentationLayer/Coordinators/WalletCoordinator.swift +++ b/WavesWallet-iOS/Coordinators/WalletCoordinator.swift @@ -8,9 +8,9 @@ import UIKit import RxSwift -import AppsFlyerLib -import FirebaseAnalytics -import WavesSDKExtension +import WavesSDKExtensions +import DomainLayer +import Extensions private enum Constants { static let popoverHeight: CGFloat = 378 @@ -33,9 +33,11 @@ final class WalletCoordinator: Coordinator { private var currentPopup: PopupViewController? = nil private let disposeBag: DisposeBag = DisposeBag() - private let authorization: AuthorizationInteractorProtocol = FactoryInteractors.instance.authorization - private let walletsRepository: WalletsRepositoryProtocol = FactoryRepositories.instance.walletsRepositoryLocal - + private let authorization: AuthorizationUseCaseProtocol = UseCasesFactory.instance.authorization + private let walletsRepository: WalletsRepositoryProtocol = UseCasesFactory.instance.repositories.walletsRepositoryLocal + + private var hasSendedNewUserWithoutBackupStorageTrack: Bool = false + init(navigationRouter: NavigationRouter){ self.navigationRouter = navigationRouter } @@ -46,24 +48,38 @@ final class WalletCoordinator: Coordinator { } private func setupLifeCycleTost() { - walletViewContoller.rx.viewDidAppear.asObservable().subscribe(onNext: { [weak self] _ in - guard let self = self else { return } - self.showLegalOrBackupIfNeed() - }).disposed(by: disposeBag) + + walletViewContoller.rx + .viewDidAppear + .asObservable() + .subscribe(onNext: { [weak self] _ in + guard let self = self else { return } + self.showLegalOrBackupIfNeed() + }) + .disposed(by: disposeBag) - walletViewContoller.rx.viewDidDisappear.asObservable().subscribe(onNext: { [weak self] _ in - guard let self = self else { return } + walletViewContoller.rx + .viewDidDisappear + .asObservable() + .subscribe(onNext: { [weak self] _ in + guard let self = self else { return } - self.childCoordinators - .first(where: { (coordinator) -> Bool in - return coordinator is BackupTostCoordinator - })? - .removeFromParentCoordinator() - }) - .disposed(by: disposeBag) + self.childCoordinators + .first(where: { (coordinator) -> Bool in + return coordinator is BackupTostCoordinator + })? + .removeFromParentCoordinator() + }) + .disposed(by: disposeBag) } - private func showBackupTost() { + private func showBackupTost() { + + if !hasSendedNewUserWithoutBackupStorageTrack { + hasSendedNewUserWithoutBackupStorageTrack = true + NewUserWithoutBackupStorageTrack.sendEvent() + } + let coordinator = BackupTostCoordinator(navigationRouter: navigationRouter) addChildCoordinatorAndStart(childCoordinator: coordinator) } @@ -73,9 +89,15 @@ final class WalletCoordinator: Coordinator { addChildCoordinatorAndStart(childCoordinator: coordinator) } + private func showPushAlertSettings() { + let coordinator = PushNotificationsCoordinator() + addChildCoordinatorAndStart(childCoordinator: coordinator) + } + private func showNewsAndBackupTost() { showBackupTost() showNews() + showPushAlertSettings() } private func showLegalOrBackupIfNeed() { @@ -94,12 +116,24 @@ final class WalletCoordinator: Coordinator { // MARK: WalletModuleOutput extension WalletCoordinator: WalletModuleOutput { + func openAppStore() { + + UseCasesFactory + .instance + .analyticManager + .trackEvent(.walletHome(.updateBanner)) + RateApp.show() } func presentSearchScreen(from startPoint: CGFloat, assets: [DomainLayer.DTO.SmartAssetBalance]) { + UseCasesFactory + .instance + .analyticManager + .trackEvent(.walletHome(.tokenSearch)) + if let vc = WalletSearchModuleBuilder(output: self).build(input: assets) as? WalletSearchViewController { vc.modalPresentationStyle = .custom navigationRouter.present(vc, animated: false) { @@ -109,11 +143,23 @@ extension WalletCoordinator: WalletModuleOutput { } func showWalletSort(balances: [DomainLayer.DTO.SmartAssetBalance]) { + + UseCasesFactory + .instance + .analyticManager + .trackEvent(.walletHome(.tokenSortingPage)) + let vc = WalletSortModuleBuilder().build(input: balances) navigationRouter.pushViewController(vc) } func showMyAddress() { + + UseCasesFactory + .instance + .analyticManager + .trackEvent(.walletHome(.qrCard)) + let vc = MyAddressModuleBuilder(output: self).build() self.myAddressVC = vc navigationRouter.pushViewController(vc) @@ -139,7 +185,7 @@ extension WalletCoordinator: WalletModuleOutput { let controller = StartLeasingModuleBuilder(output: self).build(input: availableMoney) navigationRouter.pushViewController(controller) - AnalyticManager.trackEvent(.leasing(.leasingStartTap)) + UseCasesFactory.instance.analyticManager.trackEvent(.walletLeasing(.leasingStartTap)) } func showLeasingTransaction(transactions: [DomainLayer.DTO.SmartTransaction], index: Int) { @@ -204,7 +250,7 @@ extension WalletCoordinator: AssetDetailModuleOutput { vc.delegate = delegate navigationRouter.pushViewController(vc) - AnalyticManager.trackEvent(.tokenBurn(.tap)) + UseCasesFactory.instance.analyticManager.trackEvent(.tokenBurn(.tap)) } } @@ -214,21 +260,10 @@ extension WalletCoordinator: TransactionCardCoordinatorDelegate { walletViewContoller.viewWillAppear(false) } } -// MARK: - StartLeasingModuleOutput +// MARK: - StartLeasingModuleOutput extension WalletCoordinator: StartLeasingModuleOutput { - - func startLeasingDidSuccess(transaction: DomainLayer.DTO.SmartTransaction, kind: StartLeasingTypes.Kind) { - - switch kind { - case .send: - //TODO: Here can be some logic - break - - default: - break - } - } + func startLeasingDidSuccess(transaction: DomainLayer.DTO.SmartTransaction, kind: StartLeasingTypes.Kind) {} } fileprivate extension AssetDetailModuleBuilder.Input { @@ -295,7 +330,7 @@ extension WalletCoordinator: AliasesModuleOutput { let vc = CreateAliasModuleBuilder(output: self).build() self.navigationRouter.pushViewController(vc) - AnalyticManager.trackEvent(.createAlias(.aliasCreateVcard)) + UseCasesFactory.instance.analyticManager.trackEvent(.alias(.aliasCreateVcard)) } } } @@ -310,7 +345,7 @@ extension WalletCoordinator: AliasWithoutViewControllerDelegate { let vc = CreateAliasModuleBuilder(output: self).build() self.navigationRouter.pushViewController(vc) - AnalyticManager.trackEvent(.createAlias(.aliasCreateVcard)) + UseCasesFactory.instance.analyticManager.trackEvent(.alias(.aliasCreateVcard)) } } } diff --git a/WavesWallet-iOS/Coordinators/WidgetSettingsCoordinator.swift b/WavesWallet-iOS/Coordinators/WidgetSettingsCoordinator.swift new file mode 100644 index 00000000..a50acd77 --- /dev/null +++ b/WavesWallet-iOS/Coordinators/WidgetSettingsCoordinator.swift @@ -0,0 +1,176 @@ +// +// WidgetSettingsCoordinator.swift +// WavesWallet-iOS +// +// Created by rprokofev on 01.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import UIKit +import RxSwift +import WavesSDKExtensions +import DomainLayer +import Extensions + +private enum StatePopover { + + case none + case syncAssets([DomainLayer.DTO.Asset]) +} + +private enum WidgetState { + case none + case callback((([DomainLayer.DTO.Asset]) -> Void)) +} + +final class WidgetSettingsCoordinator: Coordinator { + + var childCoordinators: [Coordinator] = [] + + weak var parent: Coordinator? + + private var navigationRouter: NavigationRouter + + private var windowRouter: WindowRouter + + private let disposeBag: DisposeBag = DisposeBag() + + private var statePopover: StatePopover = .none + + private var widgetState: WidgetState = .none + + private lazy var popoverViewControllerTransitioning = ModalViewControllerTransitioning { [weak self] in + guard let self = self else { return } + + switch self.statePopover { + case .syncAssets(let assets): + if case .callback(let callback) = self.widgetState { + callback(assets) + } + + default: + break + } + } + + init(windowRouter: WindowRouter) { + + let window = UIWindow() + window.windowLevel = UIWindow.Level.init(rawValue: UIWindow.Level.normal.rawValue + 1.0) + self.windowRouter = WindowRouter.windowFactory(window: window) + self.navigationRouter = NavigationRouter(navigationController: CustomNavigationController()) + + NotificationCenter.default.addObserver(self, selector: #selector(didEnterBackground), name: UIApplication.didEnterBackgroundNotification, object: nil) + } + + @objc private func didEnterBackground() { + widgetSettingsClose() + } + + func start() { + + let vc = WidgetSettingsModuleBuilder(output: self).build() + + windowRouter.setRootViewController(self.navigationRouter.navigationController) + self.navigationRouter.pushViewController(vc) + } +} + +// MARK: AssetsSearchModuleOutput + +extension WidgetSettingsCoordinator: AssetsSearchModuleOutput { + + func assetsSearchSelectedAssets(_ assets: [DomainLayer.DTO.Asset]) { + self.statePopover = .syncAssets(assets) + } + + func assetsSearchClose() { + self.navigationRouter.dismiss(animated: true, completion: nil) + } +} + +// MARK: WidgetSettingsModuleOutput + +extension WidgetSettingsCoordinator: WidgetSettingsModuleOutput { + + func widgetSettingsClose() { + + windowRouter.dissmissWindow(animated: nil, completed: { [weak self] in + guard let self = self else { return } + self.removeFromParentCoordinator() + }) + } + + func widgetSettingsSyncAssets(_ current: [DomainLayer.DTO.Asset], minCountAssets: Int, maxCountAssets: Int, callback: @escaping (([DomainLayer.DTO.Asset]) -> Void)) { + + let vc = AssetsSearchViewBuilder(output: self) + .build(input: .init(assets: current, minCountAssets: minCountAssets, maxCountAssets: maxCountAssets)) + + vc.modalPresentationStyle = .custom + vc.transitioningDelegate = popoverViewControllerTransitioning + + self.widgetState = .callback(callback) + + self.navigationRouter.present(vc, animated: true) { + + } + } + + func widgetSettingsChangeInterval(_ selected: DomainLayer.DTO.Widget.Interval?, callback: @escaping (_ asset: DomainLayer.DTO.Widget.Interval) -> Void) { + + let all = DomainLayer.DTO.Widget.Interval.all + + let elements: [ActionSheet.DTO.Element] = all.map { .init(title: $0.title) } + + let selectedElement = elements.first(where: { $0.title == (selected?.title ?? "") }) + + let data = ActionSheet.DTO.Data.init(title: Localizable.Waves.Widgetsettings.Actionsheet.Changeinterval.title, + elements: elements, + selectedElement: selectedElement) + + let vc = ActionSheetViewBuilder { [weak self] (element) in + guard let interval = all.first(where: { (interval) -> Bool in + return interval.title == element.title + }) else { return } + callback(interval) + self?.navigationRouter.dismiss(animated: true, completion: nil) + } + .build(input: data) + + vc.modalPresentationStyle = .custom + vc.transitioningDelegate = popoverViewControllerTransitioning + + self.navigationRouter.present(vc, animated: true) { + + } + } + + func widgetSettingsChangeStyle(_ selected: DomainLayer.DTO.Widget.Style?, callback: @escaping (_ style: DomainLayer.DTO.Widget.Style) -> Void) { + + let all = DomainLayer.DTO.Widget.Style.all + + let elements: [ActionSheet.DTO.Element] = all.map { .init(title: $0.title) } + + let selectedElement = elements.first(where: { $0.title == (selected?.title ?? "") }) + + let data = ActionSheet.DTO.Data.init(title: Localizable.Waves.Widgetsettings.Actionsheet.Changestyle.title, + elements: elements, + selectedElement: selectedElement) + + let vc = ActionSheetViewBuilder { [weak self] (element) in + guard let style = all.first(where: { (style) -> Bool in + return style.title == element.title + }) else { return } + callback(style) + self?.navigationRouter.dismiss(animated: true, completion: nil) + } + .build(input: data) + + vc.modalPresentationStyle = .custom + vc.transitioningDelegate = popoverViewControllerTransitioning + + self.navigationRouter.present(vc, animated: true) { + + } + } +} diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/ActionsControl.swift b/WavesWallet-iOS/CustomViews/ActionsControl.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/CustomViews/ActionsControl.swift rename to WavesWallet-iOS/CustomViews/ActionsControl.swift index 14417bd3..a4d82305 100644 --- a/WavesWallet-iOS/PresentationLayer/CustomViews/ActionsControl.swift +++ b/WavesWallet-iOS/CustomViews/ActionsControl.swift @@ -8,6 +8,7 @@ import Foundation import UIKit +import Extensions private struct Constants { static let spacingBetweenButtons: CGFloat = 8 diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/ActionsControl.xib b/WavesWallet-iOS/CustomViews/ActionsControl.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/ActionsControl.xib rename to WavesWallet-iOS/CustomViews/ActionsControl.xib diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/AddressBookButton.swift b/WavesWallet-iOS/CustomViews/AddressBookButton.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/CustomViews/AddressBookButton.swift rename to WavesWallet-iOS/CustomViews/AddressBookButton.swift index 7487c03a..d4c0bb01 100644 --- a/WavesWallet-iOS/PresentationLayer/CustomViews/AddressBookButton.swift +++ b/WavesWallet-iOS/CustomViews/AddressBookButton.swift @@ -8,6 +8,7 @@ import Foundation import UIKit +import Extensions final class AddressBookButton: UIButton { diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/AssetSegmented/AssetsSegmentedCell.swift b/WavesWallet-iOS/CustomViews/AssetSegmented/AssetsSegmentedCell.swift similarity index 66% rename from WavesWallet-iOS/PresentationLayer/CustomViews/AssetSegmented/AssetsSegmentedCell.swift rename to WavesWallet-iOS/CustomViews/AssetSegmented/AssetsSegmentedCell.swift index 24103e4e..cb8cdd76 100644 --- a/WavesWallet-iOS/PresentationLayer/CustomViews/AssetSegmented/AssetsSegmentedCell.swift +++ b/WavesWallet-iOS/CustomViews/AssetSegmented/AssetsSegmentedCell.swift @@ -8,16 +8,13 @@ import UIKit import RxSwift +import DomainLayer +import Extensions final class AssetsSegmentedCell: UICollectionViewCell, NibReusable { - enum Constants { - static let sizeLogo = CGSize(width: 48, height: 48) - static let sponsoredSize = CGSize(width: 18, height: 18) - } - struct Model { - let icon: DomainLayer.DTO.Asset.Icon + let icon: AssetLogo.Icon let isHiddenArrow: Bool let isSponsored: Bool let hasScript: Bool @@ -45,11 +42,7 @@ extension AssetsSegmentedCell: ViewConfiguration { self.model = model AssetLogo.logo(icon: model.icon, - style: AssetLogo.Style(size: Constants.sizeLogo, - font: UIFont.systemFont(ofSize: 15), - specs: .init(isSponsored: model.isSponsored, - hasScript: model.hasScript, - size: Constants.sponsoredSize))) + style: .large) .observeOn(MainScheduler.instance) .subscribe(onNext: { [weak self] (image) in guard let self = self else { return } diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/AssetSegmented/AssetsSegmentedCell.xib b/WavesWallet-iOS/CustomViews/AssetSegmented/AssetsSegmentedCell.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/AssetSegmented/AssetsSegmentedCell.xib rename to WavesWallet-iOS/CustomViews/AssetSegmented/AssetsSegmentedCell.xib diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/AssetSegmented/AssetsSegmentedControl.swift b/WavesWallet-iOS/CustomViews/AssetSegmented/AssetsSegmentedControl.swift similarity index 95% rename from WavesWallet-iOS/PresentationLayer/CustomViews/AssetSegmented/AssetsSegmentedControl.swift rename to WavesWallet-iOS/CustomViews/AssetSegmented/AssetsSegmentedControl.swift index 3b6a0217..f06a24e1 100644 --- a/WavesWallet-iOS/PresentationLayer/CustomViews/AssetSegmented/AssetsSegmentedControl.swift +++ b/WavesWallet-iOS/CustomViews/AssetSegmented/AssetsSegmentedControl.swift @@ -10,11 +10,14 @@ import Foundation import UIKit import UPCarouselFlowLayout import InfiniteCollectionView +import DomainLayer +import Extensions fileprivate enum Constants { static let spacing: CGFloat = 24 static let scaleCell: CGFloat = 0.7 static let currentPageEmpty: Int = -1 + static let sizeLogo = CGSize(width: 48, height: 48) } final class AssetsSegmentedControl: UIControl, NibOwnerLoadable { @@ -30,7 +33,7 @@ final class AssetsSegmentedControl: UIControl, NibOwnerLoadable { let id: String let name: String let kind: Kind - let icon: DomainLayer.DTO.Asset.Icon + let icon: AssetLogo.Icon let isSponsored: Bool let hasScript: Bool } @@ -92,7 +95,7 @@ final class AssetsSegmentedControl: UIControl, NibOwnerLoadable { let layout = collectionView.collectionViewLayout as! UPCarouselFlowLayout layout.spacingMode = UPCarouselFlowLayoutSpacingMode.fixed(spacing: Constants.spacing) layout.sideItemScale = Constants.scaleCell - + collectionView.registerCell(type: AssetsSegmentedCell.self) } @@ -113,11 +116,11 @@ final class AssetsSegmentedControl: UIControl, NibOwnerLoadable { case 0: return 0 case 1: - return AssetsSegmentedCell.Constants.sizeLogo.width + return Constants.sizeLogo.width default: let smallCellsCount: CGFloat = CGFloat(count) - 1 - return AssetsSegmentedCell.Constants.sizeLogo.width - + (AssetsSegmentedCell.Constants.sizeLogo.width * Constants.scaleCell) * smallCellsCount + return Constants.sizeLogo.width + + (Constants.sizeLogo.width * Constants.scaleCell) * smallCellsCount + Constants.spacing * smallCellsCount } } diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/AssetSegmented/AssetsSegmentedControl.xib b/WavesWallet-iOS/CustomViews/AssetSegmented/AssetsSegmentedControl.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/AssetSegmented/AssetsSegmentedControl.xib rename to WavesWallet-iOS/CustomViews/AssetSegmented/AssetsSegmentedControl.xib diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/BalanceLabel.swift b/WavesWallet-iOS/CustomViews/BalanceLabel.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/CustomViews/BalanceLabel.swift rename to WavesWallet-iOS/CustomViews/BalanceLabel.swift index fa6ba3c7..3bdc39f3 100644 --- a/WavesWallet-iOS/PresentationLayer/CustomViews/BalanceLabel.swift +++ b/WavesWallet-iOS/CustomViews/BalanceLabel.swift @@ -8,6 +8,8 @@ import Foundation import UIKit +import Extensions +import DomainLayer final class BalanceLabel: UIView, NibOwnerLoadable { diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/BalanceLabel.xib b/WavesWallet-iOS/CustomViews/BalanceLabel.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/BalanceLabel.xib rename to WavesWallet-iOS/CustomViews/BalanceLabel.xib diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/BlueBgView.swift b/WavesWallet-iOS/CustomViews/BlueBgView.swift similarity index 50% rename from WavesWallet-iOS/PresentationLayer/CustomViews/BlueBgView.swift rename to WavesWallet-iOS/CustomViews/BlueBgView.swift index ff1dfb6a..7f380eee 100644 --- a/WavesWallet-iOS/PresentationLayer/CustomViews/BlueBgView.swift +++ b/WavesWallet-iOS/CustomViews/BlueBgView.swift @@ -7,7 +7,7 @@ // import UIKit -import DeviceKit +import Extensions final class BlueBgView: UIView { @@ -35,32 +35,3 @@ final class BlueBgView: UIView { image?.draw(in: UIScreen.main.bounds) } } - -fileprivate extension Platform { - - private static let device = Device() - - static let isIphonePlus: Bool = { - - return device.isOneOf([.iPhone6Plus, .simulator(.iPhone6Plus), - .iPhone6sPlus, .simulator(.iPhone6sPlus), - .iPhone7Plus, .simulator(.iPhone7Plus), - .iPhone8Plus, .simulator(.iPhone8Plus)]) - }() - - static let isIphoneX: Bool = { - - return device.isOneOf([.iPhoneX, .simulator(.iPhoneX), - .iPhoneXs, .simulator(.iPhoneXs)]) - }() - - static let isIphoneXMax: Bool = { - - return device.isOneOf([.iPhoneXsMax, .simulator(.iPhoneXsMax)]) - }() - - static let isIphoneXR: Bool = { - - return device.isOneOf([.iPhoneXr, .simulator(.iPhoneXr)]) - }() -} diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/BorderButtView.swift b/WavesWallet-iOS/CustomViews/BorderButtView.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/BorderButtView.swift rename to WavesWallet-iOS/CustomViews/BorderButtView.swift diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/CenteringContentButton.swift b/WavesWallet-iOS/CustomViews/CenteringContentButton.swift similarity index 87% rename from WavesWallet-iOS/PresentationLayer/CustomViews/CenteringContentButton.swift rename to WavesWallet-iOS/CustomViews/CenteringContentButton.swift index e329a508..16d53b4a 100644 --- a/WavesWallet-iOS/PresentationLayer/CustomViews/CenteringContentButton.swift +++ b/WavesWallet-iOS/CustomViews/CenteringContentButton.swift @@ -14,6 +14,8 @@ final class CenteringContentButton: UIButton { static let titleTopPadding: CGFloat = 8 } + @IBInspectable var titleTopPadding: CGFloat = Constants.titleTopPadding + override func imageRect(forContentRect contentRect: CGRect) -> CGRect { let iconSize = super.imageRect(forContentRect: contentRect).size @@ -22,7 +24,7 @@ final class CenteringContentButton: UIButton { var height = iconSize.height - height += titleSize.height + Constants.titleTopPadding + height += titleSize.height + titleTopPadding return CGRect(x: (contentRect.size.width - iconSize.width) * 0.5, @@ -39,7 +41,7 @@ final class CenteringContentButton: UIButton { var height = titleSize.height if iconSize.height > 0 { - height += iconSize.height + Constants.titleTopPadding + height += iconSize.height + titleTopPadding } return CGRect(x: (contentRect.size.width - titleSize.width) * 0.5, diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/ContactDetailView.swift b/WavesWallet-iOS/CustomViews/ContactDetailView.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/CustomViews/ContactDetailView.swift rename to WavesWallet-iOS/CustomViews/ContactDetailView.swift index af7085fb..ab2590e4 100644 --- a/WavesWallet-iOS/PresentationLayer/CustomViews/ContactDetailView.swift +++ b/WavesWallet-iOS/CustomViews/ContactDetailView.swift @@ -8,6 +8,7 @@ import Foundation import UIKit +import Extensions final class ContactDetailView: UIView, NibOwnerLoadable { diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/ContactDetailView.xib b/WavesWallet-iOS/CustomViews/ContactDetailView.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/ContactDetailView.xib rename to WavesWallet-iOS/CustomViews/ContactDetailView.xib diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/CopyableImageView.swift b/WavesWallet-iOS/CustomViews/CopyableImageView.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/CustomViews/CopyableImageView.swift rename to WavesWallet-iOS/CustomViews/CopyableImageView.swift index 1c95c0c5..f2f486a4 100644 --- a/WavesWallet-iOS/PresentationLayer/CustomViews/CopyableImageView.swift +++ b/WavesWallet-iOS/CustomViews/CopyableImageView.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions final class CopyableImageView: UIImageView { diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/CopyableLabel.swift b/WavesWallet-iOS/CustomViews/CopyableLabel.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/CustomViews/CopyableLabel.swift rename to WavesWallet-iOS/CustomViews/CopyableLabel.swift index 1399fe11..17ce3f43 100644 --- a/WavesWallet-iOS/PresentationLayer/CustomViews/CopyableLabel.swift +++ b/WavesWallet-iOS/CustomViews/CopyableLabel.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions final class CopyableLabel: UILabel { diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/CustomGradientView.swift b/WavesWallet-iOS/CustomViews/CustomGradientView.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/CustomGradientView.swift rename to WavesWallet-iOS/CustomViews/CustomGradientView.swift diff --git a/WavesWallet-iOS/CustomViews/CustomNavigationBar.swift b/WavesWallet-iOS/CustomViews/CustomNavigationBar.swift new file mode 100644 index 00000000..8e6373de --- /dev/null +++ b/WavesWallet-iOS/CustomViews/CustomNavigationBar.swift @@ -0,0 +1,28 @@ +// +// CustomNavigationBar.swift +// testApp +// +// Created by Pavel Gubin on 5/28/19. +// Copyright © 2019 Pavel Gubin. All rights reserved. +// + +import UIKit + +final class CustomNavigationBar: UINavigationBar { + + //TODO: need check + override func layoutSubviews() { + super.layoutSubviews() +// if let view = subviews.first { +// if let color = backgroundColor { +// view.alpha = 1 +// view.backgroundColor = color +// } +// +// if let effectView = view.subviews.last as? UIVisualEffectView { +// effectView.isHidden = backgroundColor != nil +// } +// } + } + +} diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/CustomNavigationController.swift b/WavesWallet-iOS/CustomViews/CustomNavigationController.swift similarity index 94% rename from WavesWallet-iOS/PresentationLayer/CustomViews/CustomNavigationController.swift rename to WavesWallet-iOS/CustomViews/CustomNavigationController.swift index 6ef5c6c1..d7f032ea 100644 --- a/WavesWallet-iOS/PresentationLayer/CustomViews/CustomNavigationController.swift +++ b/WavesWallet-iOS/CustomViews/CustomNavigationController.swift @@ -201,16 +201,16 @@ final class CustomNavigationController: UINavigationController { private let proxyDelegate: ProxyNavigationControllerDelegate = ProxyNavigationControllerDelegate() private weak var prevViewContoller: UIViewController? - + override var delegate: UINavigationControllerDelegate? { get { - return proxyDelegate + return super.delegate } - set { + super.delegate = proxyDelegate if let newValue = newValue { proxyDelegate.delegates.append(Weak(value: newValue)) - } + } } } @@ -253,7 +253,7 @@ final class CustomNavigationController: UINavigationController { self.viewControllers.first?.hidesBottomBarWhenPushed = true super.pushViewController(viewController, animated: animated) } - + private func apperanceNavigationItemProperties(_ viewController: UIViewController, animated: Bool = false) { if viewController != topViewController { @@ -267,18 +267,32 @@ final class CustomNavigationController: UINavigationController { navigationBar.barTintColor = viewController.navigationItem.barTintColor navigationBar.tintColor = viewController.navigationItem.tintColor navigationBar.titleTextAttributes = viewController.navigationItem.titleTextAttributes + if #available(iOS 11.0, *) { navigationBar.largeTitleTextAttributes = viewController.navigationItem.largeTitleTextAttributes - navigationBar.prefersLargeTitles = viewController.navigationItem.prefersLargeTitles + navigationBar.prefersLargeTitles = true } + if #available(iOS 13, *) { + let appereance = UINavigationBarAppearance() + appereance.configureWithTransparentBackground() + if viewController.navigationItem.backgroundImage == nil { + appereance.backgroundColor = viewController.view.backgroundColor + } + appereance.titleTextAttributes = viewController.navigationItem.titleTextAttributes ?? [:] + appereance.largeTitleTextAttributes = viewController.navigationItem.largeTitleTextAttributes ?? [:] + + navigationBar.standardAppearance = appereance + navigationBar.scrollEdgeAppearance = appereance + } + setNavigationBarHidden(viewController.navigationItem.isNavigationBarHidden, animated: animated) } override var childForStatusBarStyle: UIViewController? { return self.topViewController } - + override var preferredStatusBarStyle: UIStatusBarStyle { return self.topViewController?.preferredStatusBarStyle ?? .default } @@ -329,9 +343,8 @@ extension CustomNavigationController: UIGestureRecognizerDelegate { extension CustomNavigationController: UINavigationControllerDelegate { - func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) { - + if let prevViewContoller = prevViewContoller { prevViewContoller.navigationItem.removeObserver(self, forKeyPath: Constants.shadowImage) prevViewContoller.navigationItem.removeObserver(self, forKeyPath: Constants.backgroundImage) @@ -369,8 +382,8 @@ extension CustomNavigationController: UINavigationControllerDelegate { viewController.navigationItem.addObserver(self, forKeyPath: Constants.prefersLargeTitles, options: [.new, .old], context: nil) viewController.navigationItem.addObserver(self, forKeyPath: Constants.largeTitleTextAttributes, options: [.new, .old], context: nil) } - - self.transitionCoordinator?.notifyWhenInteractionEnds({ [weak self] context in + + self.transitionCoordinator?.notifyWhenInteractionChanges({ [weak self] context in guard let self = self else { return } guard context.isCancelled else { return } guard let fromViewController = context.viewController(forKey: .from) else { return } @@ -384,7 +397,10 @@ extension CustomNavigationController: UINavigationControllerDelegate { }) } - func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {} + func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) { + + + } } private final class Weak where T: AnyObject { diff --git a/WavesWallet-iOS/CustomViews/DebugView.swift b/WavesWallet-iOS/CustomViews/DebugView.swift new file mode 100644 index 00000000..636fbe81 --- /dev/null +++ b/WavesWallet-iOS/CustomViews/DebugView.swift @@ -0,0 +1,61 @@ +// +// DebugView.swift +// WavesWallet-iOS +// +// Created by rprokofev on 19.07.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import UIKit +import Extensions + +final class DebugView: UIView, NibOwnerLoadable { + + @IBOutlet private(set) var chainIdLabel: UILabel! + + private lazy var tapGesture: UITapGestureRecognizer = UITapGestureRecognizer(target: self, + action: #selector(handlerTapGesture(recognizer:))) + + var didTapOnView: (() -> Void)? + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + loadNibContent() + setup() + } + + override init(frame: CGRect) { + super.init(frame: frame) + loadNibContent() + setup() + } + + func setup() { + tapGesture.delegate = self + tapGesture.numberOfTapsRequired = 2 + addGestureRecognizer(tapGesture) + self.backgroundColor = .submit400 + } + + override func awakeFromNib() { + super.awakeFromNib() + } + + override func layoutSubviews() { + super.layoutSubviews() + self.cornerRadius = Float(self.frame.width * 0.5) + } + + @objc func handlerTapGesture(recognizer: UITapGestureRecognizer) { + didTapOnView?() + } +} + +extension DebugView: UIGestureRecognizerDelegate { + + override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { + return true + } + +} diff --git a/WavesWallet-iOS/CustomViews/DebugView.xib b/WavesWallet-iOS/CustomViews/DebugView.xib new file mode 100644 index 00000000..27596994 --- /dev/null +++ b/WavesWallet-iOS/CustomViews/DebugView.xib @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/DottedLineView.swift b/WavesWallet-iOS/CustomViews/DottedLineView.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/DottedLineView.swift rename to WavesWallet-iOS/CustomViews/DottedLineView.swift diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/DottedRoundView.swift b/WavesWallet-iOS/CustomViews/DottedRoundView.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/DottedRoundView.swift rename to WavesWallet-iOS/CustomViews/DottedRoundView.swift diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/DynamicHeaderTableView.swift b/WavesWallet-iOS/CustomViews/DynamicHeaderTableView.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/DynamicHeaderTableView.swift rename to WavesWallet-iOS/CustomViews/DynamicHeaderTableView.swift diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/EmptyCell.swift b/WavesWallet-iOS/CustomViews/EmptyCell.swift similarity index 87% rename from WavesWallet-iOS/PresentationLayer/CustomViews/EmptyCell.swift rename to WavesWallet-iOS/CustomViews/EmptyCell.swift index 90de4c05..ee91f044 100644 --- a/WavesWallet-iOS/PresentationLayer/CustomViews/EmptyCell.swift +++ b/WavesWallet-iOS/CustomViews/EmptyCell.swift @@ -7,6 +7,7 @@ // import Foundation -import UIKit +import UIKit +import Extensions final class EmptyCell: UITableViewCell, NibReusable { } diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/EmptyCell.xib b/WavesWallet-iOS/CustomViews/EmptyCell.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/EmptyCell.xib rename to WavesWallet-iOS/CustomViews/EmptyCell.xib diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/GlobalErrorView.swift b/WavesWallet-iOS/CustomViews/GlobalErrorView.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/CustomViews/GlobalErrorView.swift rename to WavesWallet-iOS/CustomViews/GlobalErrorView.swift index 8b76207b..d876ea49 100644 --- a/WavesWallet-iOS/PresentationLayer/CustomViews/GlobalErrorView.swift +++ b/WavesWallet-iOS/CustomViews/GlobalErrorView.swift @@ -8,7 +8,8 @@ import UIKit import Reachability -import WavesSDKExtension +import WavesSDKExtensions +import Extensions final class GlobalErrorView: UIView, NibOwnerLoadable { @@ -27,6 +28,7 @@ final class GlobalErrorView: UIView, NibOwnerLoadable { } @IBAction func handlerActionRetry() { + let instance = ReachabilityService.instance if instance.connection != .none { retryDidTap?() diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/GlobalErrorView.xib b/WavesWallet-iOS/CustomViews/GlobalErrorView.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/GlobalErrorView.xib rename to WavesWallet-iOS/CustomViews/GlobalErrorView.xib diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/GradientView.swift b/WavesWallet-iOS/CustomViews/GradientView.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/GradientView.swift rename to WavesWallet-iOS/CustomViews/GradientView.swift diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/HalfModalPresentationController/HalfModalInteractiveTransition.swift b/WavesWallet-iOS/CustomViews/HalfModalPresentationController/HalfModalInteractiveTransition.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/HalfModalPresentationController/HalfModalInteractiveTransition.swift rename to WavesWallet-iOS/CustomViews/HalfModalPresentationController/HalfModalInteractiveTransition.swift diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/HalfModalPresentationController/HalfModalPresentationController.swift b/WavesWallet-iOS/CustomViews/HalfModalPresentationController/HalfModalPresentationController.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/HalfModalPresentationController/HalfModalPresentationController.swift rename to WavesWallet-iOS/CustomViews/HalfModalPresentationController/HalfModalPresentationController.swift diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/HalfModalPresentationController/HalfModalTransitionAnimator.swift b/WavesWallet-iOS/CustomViews/HalfModalPresentationController/HalfModalTransitionAnimator.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/HalfModalPresentationController/HalfModalTransitionAnimator.swift rename to WavesWallet-iOS/CustomViews/HalfModalPresentationController/HalfModalTransitionAnimator.swift diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/HalfModalPresentationController/HalfModalTransitioningDelegate.swift b/WavesWallet-iOS/CustomViews/HalfModalPresentationController/HalfModalTransitioningDelegate.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/HalfModalPresentationController/HalfModalTransitioningDelegate.swift rename to WavesWallet-iOS/CustomViews/HalfModalPresentationController/HalfModalTransitioningDelegate.swift diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/InputScrollButtonsView.swift b/WavesWallet-iOS/CustomViews/InputScrollButtonsView.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/CustomViews/InputScrollButtonsView.swift rename to WavesWallet-iOS/CustomViews/InputScrollButtonsView.swift index 01a959d9..2bbfa1b6 100644 --- a/WavesWallet-iOS/PresentationLayer/CustomViews/InputScrollButtonsView.swift +++ b/WavesWallet-iOS/CustomViews/InputScrollButtonsView.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions private enum Constants { static let fontSize: CGFloat = 13 diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/NavigationAccessoryView.swift b/WavesWallet-iOS/CustomViews/NavigationAccessoryView.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/NavigationAccessoryView.swift rename to WavesWallet-iOS/CustomViews/NavigationAccessoryView.swift diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/NewSegmentedControl.swift b/WavesWallet-iOS/CustomViews/NewSegmentedControl.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/CustomViews/NewSegmentedControl.swift rename to WavesWallet-iOS/CustomViews/NewSegmentedControl.swift index 16c5f8ab..a176817b 100644 --- a/WavesWallet-iOS/PresentationLayer/CustomViews/NewSegmentedControl.swift +++ b/WavesWallet-iOS/CustomViews/NewSegmentedControl.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions private enum Constants { static let font = UIFont.systemFont(ofSize: 13) diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/Passcode/PasscodeNumberButton.swift b/WavesWallet-iOS/CustomViews/Passcode/PasscodeNumberButton.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/CustomViews/Passcode/PasscodeNumberButton.swift rename to WavesWallet-iOS/CustomViews/Passcode/PasscodeNumberButton.swift index 5c98c71b..b7d96493 100644 --- a/WavesWallet-iOS/PresentationLayer/CustomViews/Passcode/PasscodeNumberButton.swift +++ b/WavesWallet-iOS/CustomViews/Passcode/PasscodeNumberButton.swift @@ -7,6 +7,8 @@ // import UIKit +import DomainLayer +import Extensions final class PasscodeNumberButton: UIButton { diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/Passcode/PasscodeTopBarView.swift b/WavesWallet-iOS/CustomViews/Passcode/PasscodeTopBarView.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/CustomViews/Passcode/PasscodeTopBarView.swift rename to WavesWallet-iOS/CustomViews/Passcode/PasscodeTopBarView.swift index 9ba05af0..c2bdd36e 100644 --- a/WavesWallet-iOS/PresentationLayer/CustomViews/Passcode/PasscodeTopBarView.swift +++ b/WavesWallet-iOS/CustomViews/Passcode/PasscodeTopBarView.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions private enum Constants { static let durationDotsAnimation: TimeInterval = 0.6 diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/Passcode/PasscodeView.swift b/WavesWallet-iOS/CustomViews/Passcode/PasscodeView.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/CustomViews/Passcode/PasscodeView.swift rename to WavesWallet-iOS/CustomViews/Passcode/PasscodeView.swift index d314f32f..5678df72 100644 --- a/WavesWallet-iOS/PresentationLayer/CustomViews/Passcode/PasscodeView.swift +++ b/WavesWallet-iOS/CustomViews/Passcode/PasscodeView.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions private enum Constants { static let delayRemovedNumberSmall: TimeInterval = 0.15 diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/Passcode/PasscodeView.xib b/WavesWallet-iOS/CustomViews/Passcode/PasscodeView.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/Passcode/PasscodeView.xib rename to WavesWallet-iOS/CustomViews/Passcode/PasscodeView.xib diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/PasteboardButton.swift b/WavesWallet-iOS/CustomViews/PasteboardButton.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/CustomViews/PasteboardButton.swift rename to WavesWallet-iOS/CustomViews/PasteboardButton.swift index 2e078c44..a519863f 100644 --- a/WavesWallet-iOS/PresentationLayer/CustomViews/PasteboardButton.swift +++ b/WavesWallet-iOS/CustomViews/PasteboardButton.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions private enum Constants { static let duration: TimeInterval = 1 diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/PopupViewController.swift b/WavesWallet-iOS/CustomViews/PopupViewController.swift similarity index 96% rename from WavesWallet-iOS/PresentationLayer/CustomViews/PopupViewController.swift rename to WavesWallet-iOS/CustomViews/PopupViewController.swift index 3f6551dd..162853af 100644 --- a/WavesWallet-iOS/PresentationLayer/CustomViews/PopupViewController.swift +++ b/WavesWallet-iOS/CustomViews/PopupViewController.swift @@ -7,6 +7,7 @@ // import UIKit +import DomainLayer fileprivate enum Constants { @@ -58,7 +59,7 @@ final class PopupViewController: UIViewController { func present(contentViewController: UIViewController, animated: Bool = true) { - let topController = getTopController() + let topController = self.topController topController.view.addSubview(bgView) topController.addChild(self) @@ -101,6 +102,7 @@ final class PopupViewController: UIViewController { self.view.removeFromSuperview() self.willMove(toParent: nil) self.removeFromParent() + self.children.forEach { $0.removeFromParent() } } } @@ -272,7 +274,10 @@ private extension PopupViewController { } } - func getTopController() -> UIViewController { - return AppDelegate.shared().window!.rootViewController! + var topController: UIViewController { + guard let topVC = UIApplication.shared.keyWindow?.rootViewController else { + return UIViewController() + } + return topVC } } diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/ScannerCustomView.swift b/WavesWallet-iOS/CustomViews/ScannerCustomView.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/CustomViews/ScannerCustomView.swift rename to WavesWallet-iOS/CustomViews/ScannerCustomView.swift index 1ec3ec21..d7258c33 100644 --- a/WavesWallet-iOS/PresentationLayer/CustomViews/ScannerCustomView.swift +++ b/WavesWallet-iOS/CustomViews/ScannerCustomView.swift @@ -9,6 +9,7 @@ import UIKit import QRCodeReader import AVFoundation +import Extensions final class ScannerCustomView: UIView, QRCodeReaderDisplayable { diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/ScrolledContainerView.swift b/WavesWallet-iOS/CustomViews/ScrolledContainerView.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/CustomViews/ScrolledContainerView.swift rename to WavesWallet-iOS/CustomViews/ScrolledContainerView.swift index b5e01e9c..2b3f18db 100644 --- a/WavesWallet-iOS/PresentationLayer/CustomViews/ScrolledContainerView.swift +++ b/WavesWallet-iOS/CustomViews/ScrolledContainerView.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions private enum Constants { static let animationDuration: TimeInterval = 0.3 diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/SegmentedControl/SegmentedControl.swift b/WavesWallet-iOS/CustomViews/SegmentedControl/SegmentedControl.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/CustomViews/SegmentedControl/SegmentedControl.swift rename to WavesWallet-iOS/CustomViews/SegmentedControl/SegmentedControl.swift index 4d20afe9..4ab0f364 100644 --- a/WavesWallet-iOS/PresentationLayer/CustomViews/SegmentedControl/SegmentedControl.swift +++ b/WavesWallet-iOS/CustomViews/SegmentedControl/SegmentedControl.swift @@ -8,6 +8,7 @@ import Foundation import UIKit +import Extensions fileprivate enum Constants { static let imageEdgeInsetsForButtonWithIcon = UIEdgeInsets.init(top: 0, left: -8, bottom: 0, right: 8) diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/SegmentedControl/SegmentedControl.xib b/WavesWallet-iOS/CustomViews/SegmentedControl/SegmentedControl.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/SegmentedControl/SegmentedControl.xib rename to WavesWallet-iOS/CustomViews/SegmentedControl/SegmentedControl.xib diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/SegmentedControl/SegmentedControlScrollView.swift b/WavesWallet-iOS/CustomViews/SegmentedControl/SegmentedControlScrollView.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/SegmentedControl/SegmentedControlScrollView.swift rename to WavesWallet-iOS/CustomViews/SegmentedControl/SegmentedControlScrollView.swift diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/SeparatorView.swift b/WavesWallet-iOS/CustomViews/SeparatorView.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/SeparatorView.swift rename to WavesWallet-iOS/CustomViews/SeparatorView.swift diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/SideMenu.swift b/WavesWallet-iOS/CustomViews/SideMenu.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/SideMenu.swift rename to WavesWallet-iOS/CustomViews/SideMenu.swift diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/Skeleton/SkeletonCell.swift b/WavesWallet-iOS/CustomViews/Skeleton/SkeletonCell.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/Skeleton/SkeletonCell.swift rename to WavesWallet-iOS/CustomViews/Skeleton/SkeletonCell.swift diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/Skeleton/SkeletonTableCell.swift b/WavesWallet-iOS/CustomViews/Skeleton/SkeletonTableCell.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/Skeleton/SkeletonTableCell.swift rename to WavesWallet-iOS/CustomViews/Skeleton/SkeletonTableCell.swift diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/Skeleton/SkeletonTableHeaderFooterView.swift b/WavesWallet-iOS/CustomViews/Skeleton/SkeletonTableHeaderFooterView.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/Skeleton/SkeletonTableHeaderFooterView.swift rename to WavesWallet-iOS/CustomViews/Skeleton/SkeletonTableHeaderFooterView.swift diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/Skeleton/SkeletonView.swift b/WavesWallet-iOS/CustomViews/Skeleton/SkeletonView.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/Skeleton/SkeletonView.swift rename to WavesWallet-iOS/CustomViews/Skeleton/SkeletonView.swift diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/SweetSnackbar/SweetSnackBack+Factory.swift b/WavesWallet-iOS/CustomViews/SweetSnackbar/SweetSnackBack+Factory.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/CustomViews/SweetSnackbar/SweetSnackBack+Factory.swift rename to WavesWallet-iOS/CustomViews/SweetSnackbar/SweetSnackBack+Factory.swift index 81745454..4cda7104 100644 --- a/WavesWallet-iOS/PresentationLayer/CustomViews/SweetSnackbar/SweetSnackBack+Factory.swift +++ b/WavesWallet-iOS/CustomViews/SweetSnackbar/SweetSnackBack+Factory.swift @@ -7,6 +7,7 @@ // import UIKit +import WavesSDK private enum Constants { static let withoutInternetSnackAlpha: CGFloat = 0.74 @@ -38,7 +39,7 @@ extension UIViewController { case .serverError: return showErrorSnackWithoutAction(title: Localizable.Waves.General.Error.Title.notfound) - case .notFound: + case .notFound, .none: return showErrorNotFoundSnackWithoutAction() case .scriptError: diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/SweetSnackbar/SweetSnackView.swift b/WavesWallet-iOS/CustomViews/SweetSnackbar/SweetSnackView.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/CustomViews/SweetSnackbar/SweetSnackView.swift rename to WavesWallet-iOS/CustomViews/SweetSnackbar/SweetSnackView.swift index ce5314b7..b308395d 100644 --- a/WavesWallet-iOS/PresentationLayer/CustomViews/SweetSnackbar/SweetSnackView.swift +++ b/WavesWallet-iOS/CustomViews/SweetSnackbar/SweetSnackView.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions private enum Constants { static let durationAnimation: TimeInterval = 1.8 diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/SweetSnackbar/SweetSnackView.xib b/WavesWallet-iOS/CustomViews/SweetSnackbar/SweetSnackView.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/SweetSnackbar/SweetSnackView.xib rename to WavesWallet-iOS/CustomViews/SweetSnackbar/SweetSnackView.xib diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/SweetSnackbar/SweetSnackbar.swift b/WavesWallet-iOS/CustomViews/SweetSnackbar/SweetSnackbar.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/CustomViews/SweetSnackbar/SweetSnackbar.swift rename to WavesWallet-iOS/CustomViews/SweetSnackbar/SweetSnackbar.swift index cec3c496..6d0081da 100644 --- a/WavesWallet-iOS/PresentationLayer/CustomViews/SweetSnackbar/SweetSnackbar.swift +++ b/WavesWallet-iOS/CustomViews/SweetSnackbar/SweetSnackbar.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions private extension UIViewController { @@ -113,7 +114,7 @@ final class SweetSnackbar: NSObject { view.bounds = bounds viewController.view.addSubview(view) - // TODO: Need check iOS 10 version + if let tabBarVC = viewController as? UITabBarController { tabBarVC.view.bringSubviewToFront(tabBarVC.tabBar) } @@ -329,6 +330,8 @@ extension SweetSnackbar: UIGestureRecognizerDelegate { break case .failed: break + @unknown default: + break } } diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/TickerView.swift b/WavesWallet-iOS/CustomViews/TickerView.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/CustomViews/TickerView.swift rename to WavesWallet-iOS/CustomViews/TickerView.swift index 2a4de5dd..042a733c 100644 --- a/WavesWallet-iOS/PresentationLayer/CustomViews/TickerView.swift +++ b/WavesWallet-iOS/CustomViews/TickerView.swift @@ -8,6 +8,7 @@ import Foundation import UIKit +import Extensions fileprivate enum Constants { static let height: CGFloat = 16 diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/TickerView.xib b/WavesWallet-iOS/CustomViews/TickerView.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/TickerView.xib rename to WavesWallet-iOS/CustomViews/TickerView.xib diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/TransactionImageView.swift b/WavesWallet-iOS/CustomViews/TransactionImageView.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/CustomViews/TransactionImageView.swift rename to WavesWallet-iOS/CustomViews/TransactionImageView.swift index cff78622..6dfda411 100644 --- a/WavesWallet-iOS/PresentationLayer/CustomViews/TransactionImageView.swift +++ b/WavesWallet-iOS/CustomViews/TransactionImageView.swift @@ -8,6 +8,7 @@ import Foundation import UIKit +import Extensions final class TransactionImageView: UIView, NibOwnerLoadable { diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/TransactionImageView.xib b/WavesWallet-iOS/CustomViews/TransactionImageView.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/TransactionImageView.xib rename to WavesWallet-iOS/CustomViews/TransactionImageView.xib diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/UIKit/HighlightedButton.swift b/WavesWallet-iOS/CustomViews/UIKit/HighlightedButton.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/UIKit/HighlightedButton.swift rename to WavesWallet-iOS/CustomViews/UIKit/HighlightedButton.swift diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/UIKit/HighlightedView.swift b/WavesWallet-iOS/CustomViews/UIKit/HighlightedView.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/UIKit/HighlightedView.swift rename to WavesWallet-iOS/CustomViews/UIKit/HighlightedView.swift diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/UIKit/MoneyTextField.swift b/WavesWallet-iOS/CustomViews/UIKit/MoneyTextField.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/CustomViews/UIKit/MoneyTextField.swift rename to WavesWallet-iOS/CustomViews/UIKit/MoneyTextField.swift index 8638fb3c..7ba31b41 100644 --- a/WavesWallet-iOS/PresentationLayer/CustomViews/UIKit/MoneyTextField.swift +++ b/WavesWallet-iOS/CustomViews/UIKit/MoneyTextField.swift @@ -8,6 +8,7 @@ import UIKit import AudioToolbox +import Extensions private enum Constants { static let locale = Locale(identifier: "en_US") diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/UIKit/SuccessSystemMessageView.swift b/WavesWallet-iOS/CustomViews/UIKit/SuccessSystemMessageView.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/UIKit/SuccessSystemMessageView.swift rename to WavesWallet-iOS/CustomViews/UIKit/SuccessSystemMessageView.swift diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/UIKit/TextFields/InputTextField.swift b/WavesWallet-iOS/CustomViews/UIKit/TextFields/InputTextField.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/CustomViews/UIKit/TextFields/InputTextField.swift rename to WavesWallet-iOS/CustomViews/UIKit/TextFields/InputTextField.swift index ba8048d0..8ee96615 100644 --- a/WavesWallet-iOS/PresentationLayer/CustomViews/UIKit/TextFields/InputTextField.swift +++ b/WavesWallet-iOS/CustomViews/UIKit/TextFields/InputTextField.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions final class InputTextField: UIView, NibOwnerLoadable { diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/UIKit/TextFields/InputTextField.xib b/WavesWallet-iOS/CustomViews/UIKit/TextFields/InputTextField.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/UIKit/TextFields/InputTextField.xib rename to WavesWallet-iOS/CustomViews/UIKit/TextFields/InputTextField.xib diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/UIKit/TextFields/MultilineTextField.swift b/WavesWallet-iOS/CustomViews/UIKit/TextFields/MultilineTextField.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/CustomViews/UIKit/TextFields/MultilineTextField.swift rename to WavesWallet-iOS/CustomViews/UIKit/TextFields/MultilineTextField.swift index 019bfb5e..249292f1 100644 --- a/WavesWallet-iOS/PresentationLayer/CustomViews/UIKit/TextFields/MultilineTextField.swift +++ b/WavesWallet-iOS/CustomViews/UIKit/TextFields/MultilineTextField.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions protocol MultilineTextFieldDelegate: class { func multilineTextField(textField: MultilineTextField, errorTextForValue value: String) -> String? diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/UIKit/TextFields/MultyTextField.swift b/WavesWallet-iOS/CustomViews/UIKit/TextFields/MultyTextField.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/CustomViews/UIKit/TextFields/MultyTextField.swift rename to WavesWallet-iOS/CustomViews/UIKit/TextFields/MultyTextField.swift index ab95c55d..3288cc89 100644 --- a/WavesWallet-iOS/PresentationLayer/CustomViews/UIKit/TextFields/MultyTextField.swift +++ b/WavesWallet-iOS/CustomViews/UIKit/TextFields/MultyTextField.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions private enum Constans { static let animationDuration: TimeInterval = 0.24 diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/UIKit/TextFields/MultyTextField.xib b/WavesWallet-iOS/CustomViews/UIKit/TextFields/MultyTextField.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/UIKit/TextFields/MultyTextField.xib rename to WavesWallet-iOS/CustomViews/UIKit/TextFields/MultyTextField.xib diff --git a/WavesWallet-iOS/PresentationLayer/CustomViews/WavesButton.swift b/WavesWallet-iOS/CustomViews/WavesButton.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/CustomViews/WavesButton.swift rename to WavesWallet-iOS/CustomViews/WavesButton.swift diff --git a/WavesWallet-iOS/DataLayer/Assisstants/Protocols/BaseTargetType.swift b/WavesWallet-iOS/DataLayer/Assisstants/Protocols/BaseTargetType.swift deleted file mode 100644 index 665604ac..00000000 --- a/WavesWallet-iOS/DataLayer/Assisstants/Protocols/BaseTargetType.swift +++ /dev/null @@ -1,43 +0,0 @@ -// -// APIType.swift -// WavesWallet-iOS -// -// Created by mefilt on 08.07.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import Moya -import WavesSDKCrypto - -protocol BaseTargetType: TargetType { - var environment: Environment { get } - } - -enum ContentType { - case applicationJson - case applicationCsv -} - -extension ContentType { - var headers: [String: String] { - switch self { - case .applicationCsv: - return ["Content-type": "application/csv"] - case .applicationJson: - return ["Content-type": "application/json"] - } - } -} - - -extension BaseTargetType { - - var sampleData: Data { - return Data() - } - - var headers: [String: String]? { - return ContentType.applicationJson.headers - } -} diff --git a/WavesWallet-iOS/DataLayer/Assisstants/Types/Signature.swift b/WavesWallet-iOS/DataLayer/Assisstants/Types/Signature.swift deleted file mode 100644 index a82ef6ef..00000000 --- a/WavesWallet-iOS/DataLayer/Assisstants/Types/Signature.swift +++ /dev/null @@ -1,55 +0,0 @@ -// -// Signature.swift -// WavesWallet-iOS -// -// Created by mefilt on 23.07.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import Base58 -import Base58 -import WavesSDKExtension -import WavesSDKCrypto - -fileprivate enum Constants { - static let senderPublicKey = "senderPublicKey" - static let signature = "signature" -} - -protocol SignatureProtocol { - associatedtype Variable: CustomStringConvertible - - var signedWallet: DomainLayer.DTO.SignedWallet { get } - - var variable: Variable { get } - var variableKey: String { get } - - var toSign: [UInt8] { get } - var parameters: [String: String] { get } - - func signature() -> [UInt8] -} - -extension SignatureProtocol { - - var publicKey: PublicKeyAccount { - return signedWallet.publicKey - } - - var toSign: [UInt8] { - let s1 = signedWallet.publicKey.publicKey - let s2 = toByteArray(variable) - return s1 + s2 - } - - func signature() -> [UInt8] { - return (try? signedWallet.sign(input: toSign, kind: [.none])) ?? [] - } - - var parameters: [String: String] { - return [Constants.senderPublicKey: Base58.encode(signedWallet.publicKey.publicKey), - variableKey: "\(variable)", - Constants.signature: Base58.encode(signature())] - } -} diff --git a/WavesWallet-iOS/DataLayer/Assisstants/Types/TimestampSignature.swift b/WavesWallet-iOS/DataLayer/Assisstants/Types/TimestampSignature.swift deleted file mode 100644 index b4a081df..00000000 --- a/WavesWallet-iOS/DataLayer/Assisstants/Types/TimestampSignature.swift +++ /dev/null @@ -1,34 +0,0 @@ -// -// TimestampSignature.swift -// WavesWallet-iOS -// -// Created by mefilt on 23.07.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import WavesSDKExtension -import WavesSDKCrypto - -fileprivate enum Constants { - static let timestamp = "timestamp" -} - -struct TimestampSignature: SignatureProtocol { - - typealias Variable = Int64 - - private(set) var signedWallet: DomainLayer.DTO.SignedWallet - private(set) var variable: Variable - - var variableKey: String { - return Constants.timestamp - } -} - -extension TimestampSignature { - init(signedWallet: DomainLayer.DTO.SignedWallet, environment: Environment) { - self.init(signedWallet: signedWallet, - variable: Date().millisecondsSince1970(timestampDiff: environment.timestampServerDiff)) - } -} diff --git a/WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/SetScriptTransaction.swift b/WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/SetScriptTransaction.swift deleted file mode 100644 index e1275378..00000000 --- a/WavesWallet-iOS/DataLayer/DataBase/Wallet/Model/Transaction/SetScriptTransaction.swift +++ /dev/null @@ -1,15 +0,0 @@ -// -// SetScriptTransaction.swift -// WavesWallet-iOS -// -// Created by mefilt on 22/01/2019. -// Copyright © 2019 Waves Platform. All rights reserved. -// - -import Foundation -import RealmSwift - -final class ScriptTransaction: Transaction { - @objc dynamic var script: String? = nil -} - diff --git a/WavesWallet-iOS/DataLayer/Mapper/DexAssetPairDomainDTO+Mapper.swift b/WavesWallet-iOS/DataLayer/Mapper/DexAssetPairDomainDTO+Mapper.swift deleted file mode 100644 index 93df09c5..00000000 --- a/WavesWallet-iOS/DataLayer/Mapper/DexAssetPairDomainDTO+Mapper.swift +++ /dev/null @@ -1,99 +0,0 @@ -// -// DexMarketDomainDTO+Mapper.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 12/27/18. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import RealmSwift - -extension DomainLayer.DTO.Dex.SmartPair { - - init(_ pair: DexAssetPair, isChecked: Bool) { - - let amountAsset = DomainLayer.DTO.Dex.Asset(id: pair.amountAsset.id, - name: pair.amountAsset.name, - shortName: pair.amountAsset.shortName, - decimals: pair.amountAsset.decimals) - - let priceAsset = DomainLayer.DTO.Dex.Asset(id: pair.priceAsset.id, - name: pair.priceAsset.name, - shortName: pair.priceAsset.shortName, - decimals: pair.priceAsset.decimals) - - - self.amountAsset = amountAsset - self.priceAsset = priceAsset - self.isChecked = isChecked - self.isGeneral = pair.isGeneral - self.sortLevel = pair.sortLevel - self.id = pair.id - - } -} - - -extension DomainLayer.DTO.Dex.SmartPair { - - init(_ market: Matcher.DTO.Market, realm: Realm) { - - var amountAssetName = market.amountAssetName - var amountAssetShortName = market.amountAssetName - - if let asset = realm.object(ofType: Asset.self, forPrimaryKey: market.amountAsset) { - amountAssetName = asset.displayName - if let ticker = asset.ticker { - amountAssetShortName = ticker - } - } - - //TODO: need remove when move on new Api - if let ticker = DexMarket.MinersRewardToken[market.amountAsset] { - amountAssetShortName = ticker - } - else if let ticker = DexMarket.WavesCommunityToken[market.amountAsset] { - amountAssetShortName = ticker - } - - var priceAssetName = market.priceAssetName - var priceAssetShortName = market.priceAssetName - - if let asset = realm.object(ofType: Asset.self, forPrimaryKey: market.priceAsset) { - priceAssetName = asset.displayName - if let ticker = asset.ticker { - priceAssetShortName = ticker - } - } - - //TODO: need remove when move on new Api - if let ticker = DexMarket.MinersRewardToken[market.priceAsset] { - priceAssetShortName = ticker - } - else if let ticker = DexMarket.WavesCommunityToken[market.priceAsset] { - priceAssetShortName = ticker - } - - amountAsset = .init(id: market.amountAsset, - name: amountAssetName, - shortName: amountAssetShortName, - decimals: market.amountAssetInfo?.decimals ?? 0) - - priceAsset = .init(id: market.priceAsset, - name: priceAssetName, - shortName: priceAssetShortName, - decimals: market.priceAssetInfo?.decimals ?? 0) - - - let isGeneralAmount = realm.objects(Asset.self) - .filter(NSPredicate(format: "id == %@ AND isGeneral == true", amountAsset.id)).count > 0 - let isGeneralPrice = realm.objects(Asset.self) - .filter(NSPredicate(format: "id == %@ AND isGeneral == true", priceAsset.id)).count > 0 - - isGeneral = isGeneralAmount && isGeneralPrice - id = market.amountAsset + market.priceAsset - isChecked = realm.object(ofType: DexAssetPair.self, forPrimaryKey: id) != nil - sortLevel = realm.object(ofType: DexAssetPair.self, forPrimaryKey: id)?.sortLevel ?? 0 - } -} diff --git a/WavesWallet-iOS/DataLayer/Mapper/DexMyOrders+Mapper.swift b/WavesWallet-iOS/DataLayer/Mapper/DexMyOrders+Mapper.swift deleted file mode 100644 index 83a8cee9..00000000 --- a/WavesWallet-iOS/DataLayer/Mapper/DexMyOrders+Mapper.swift +++ /dev/null @@ -1,48 +0,0 @@ -// -// DexMyOrders+Mapper.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 1/14/19. -// Copyright © 2019 Waves Platform. All rights reserved. -// - -import Foundation - - -extension DomainLayer.DTO.Dex.MyOrder { - - init(_ model: Matcher.DTO.Order, priceAsset: DomainLayer.DTO.Dex.Asset, amountAsset: DomainLayer.DTO.Dex.Asset) { - - id = model.id - - price = Money.price(amount: model.price, amountDecimals: amountAsset.decimals, priceDecimals: priceAsset.decimals) - - amount = Money(model.amount, amountAsset.decimals) - time = model.timestamp - filled = Money(model.filled, amountAsset.decimals) - - if model.status == .Accepted { - status = .accepted - } - else if model.status == .PartiallyFilled { - status = .partiallyFilled - } - else if model.status == .Filled { - status = .filled - } - else { - status = .cancelled - } - - if model.type == .sell { - type = .sell - } - else { - type = .buy - } - - self.amountAsset = amountAsset - self.priceAsset = priceAsset - percentFilled = status == .filled ? 100 : Int(filled.amount * 100 / amount.amount) - } -} diff --git a/WavesWallet-iOS/DataLayer/Mapper/Transactions/AliasTransaction+Mapper.swift b/WavesWallet-iOS/DataLayer/Mapper/Transactions/AliasTransaction+Mapper.swift deleted file mode 100644 index 4a17831d..00000000 --- a/WavesWallet-iOS/DataLayer/Mapper/Transactions/AliasTransaction+Mapper.swift +++ /dev/null @@ -1,70 +0,0 @@ -// -// AliasTransaction+Mapper.swift -// WavesWallet-iOS -// -// Created by mefilt on 30.08.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import WavesSDKCrypto - -extension AliasTransaction { - - convenience init(transaction: DomainLayer.DTO.AliasTransaction) { - self.init() - type = transaction.type - id = transaction.id - sender = transaction.sender - senderPublicKey = transaction.senderPublicKey - fee = transaction.fee - timestamp = transaction.timestamp - version = transaction.version - height = transaction.height ?? -1 - modified = transaction.modified - if let proofs = transaction.proofs { - self.proofs.append(objectsIn: proofs) - } - signature = transaction.signature - alias = transaction.alias - status = transaction.status.rawValue - } -} - -extension DomainLayer.DTO.AliasTransaction { - - init(transaction: Node.DTO.AliasTransaction, status: DomainLayer.DTO.TransactionStatus, environment: Environment) { - - type = transaction.type - id = transaction.id - sender = transaction.sender.normalizeAddress(environment: environment) - senderPublicKey = transaction.senderPublicKey - fee = transaction.fee - timestamp = transaction.timestamp - version = transaction.version - height = transaction.height - modified = Date() - - signature = transaction.signature - alias = transaction.alias - proofs = transaction.proofs - self.status = status - } - - init(transaction: AliasTransaction) { - type = transaction.type - id = transaction.id - sender = transaction.sender - senderPublicKey = transaction.senderPublicKey - fee = transaction.fee - timestamp = transaction.timestamp - version = transaction.version - height = transaction.height - modified = transaction.modified - - signature = transaction.signature - alias = transaction.alias - proofs = transaction.proofs.toArray() - status = DomainLayer.DTO.TransactionStatus(rawValue: transaction.status) ?? .completed - } -} diff --git a/WavesWallet-iOS/DataLayer/Mapper/Transactions/AssetScriptTransaction+Mapper.swift b/WavesWallet-iOS/DataLayer/Mapper/Transactions/AssetScriptTransaction+Mapper.swift deleted file mode 100644 index 6b076048..00000000 --- a/WavesWallet-iOS/DataLayer/Mapper/Transactions/AssetScriptTransaction+Mapper.swift +++ /dev/null @@ -1,77 +0,0 @@ -// -// AssetScriptTransaction+Mapper.swift -// WavesWallet-iOS -// -// Created by mefilt on 22/01/2019. -// Copyright © 2019 Waves Platform. All rights reserved. -// - -import Foundation -import WavesSDKExtension -import WavesSDKCrypto - -extension AssetScriptTransaction { - - convenience init(transaction: DomainLayer.DTO.AssetScriptTransaction) { - self.init() - type = transaction.type - id = transaction.id - sender = transaction.sender - senderPublicKey = transaction.sender - fee = transaction.fee - timestamp = transaction.timestamp - height = transaction.height - signature = transaction.signature - version = transaction.version - script = transaction.script - assetId = transaction.assetId - - if let proofs = transaction.proofs { - self.proofs.append(objectsIn: proofs) - } - modified = transaction.modified - status = transaction.status.rawValue - } -} - -extension DomainLayer.DTO.AssetScriptTransaction { - - init(transaction: Node.DTO.AssetScriptTransaction, status: DomainLayer.DTO.TransactionStatus, environment: Environment) { - - type = transaction.type - id = transaction.id - sender = transaction.sender.normalizeAddress(environment: environment) - senderPublicKey = transaction.senderPublicKey - fee = transaction.fee - timestamp = transaction.timestamp - height = transaction.height ?? -1 - signature = transaction.signature - proofs = transaction.proofs - chainId = transaction.chainId - version = transaction.version - script = transaction.script - assetId = transaction.assetId - modified = Date() - self.status = status - } - - init(transaction: AssetScriptTransaction) { - type = transaction.type - id = transaction.id - sender = transaction.sender - senderPublicKey = transaction.sender - fee = transaction.fee - timestamp = transaction.timestamp - height = transaction.height - signature = transaction.signature - proofs = transaction.proofs.toArray() - chainId = transaction.chainId.value - version = transaction.version - script = transaction.script - assetId = transaction.assetId - - modified = transaction.modified - status = DomainLayer.DTO.TransactionStatus(rawValue: transaction.status) ?? .completed - } -} - diff --git a/WavesWallet-iOS/DataLayer/Mapper/Transactions/BurnTransaction+Mapper.swift b/WavesWallet-iOS/DataLayer/Mapper/Transactions/BurnTransaction+Mapper.swift deleted file mode 100644 index 09bc6274..00000000 --- a/WavesWallet-iOS/DataLayer/Mapper/Transactions/BurnTransaction+Mapper.swift +++ /dev/null @@ -1,77 +0,0 @@ -// -// BurnTransaction+Mapper.swift -// WavesWallet-iOS -// -// Created by mefilt on 30.08.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import WavesSDKCrypto - -extension BurnTransaction { - - convenience init(transaction: DomainLayer.DTO.BurnTransaction) { - self.init() - type = transaction.type - id = transaction.id - sender = transaction.sender - senderPublicKey = transaction.senderPublicKey - fee = transaction.fee - timestamp = transaction.timestamp - version = transaction.version - height = transaction.height - modified = transaction.modified - - assetId = transaction.assetId - - if let proofs = transaction.proofs { - self.proofs.append(objectsIn: proofs) - } - - amount = transaction.amount - status = transaction.status.rawValue - } -} - -extension DomainLayer.DTO.BurnTransaction { - - init(transaction: Node.DTO.BurnTransaction, status: DomainLayer.DTO.TransactionStatus, environment: Environment) { - - type = transaction.type - id = transaction.id - sender = transaction.sender.normalizeAddress(environment: environment) - senderPublicKey = transaction.senderPublicKey - fee = transaction.fee - timestamp = transaction.timestamp - version = transaction.version - height = transaction.height ?? -1 - modified = Date() - - assetId = transaction.assetId - signature = transaction.signature - chainId = transaction.chainId - amount = transaction.amount - proofs = transaction.proofs - self.status = status - } - - init(transaction: BurnTransaction) { - type = transaction.type - id = transaction.id - sender = transaction.sender - senderPublicKey = transaction.senderPublicKey - fee = transaction.fee - timestamp = transaction.timestamp - version = transaction.version - height = transaction.height - modified = transaction.modified - - assetId = transaction.assetId - amount = transaction.amount - signature = transaction.signature - chainId = transaction.chainId.value - proofs = transaction.proofs.toArray() - status = DomainLayer.DTO.TransactionStatus(rawValue: transaction.status) ?? .completed - } -} diff --git a/WavesWallet-iOS/DataLayer/Mapper/Transactions/ExchangeTransaction+Mapper.swift b/WavesWallet-iOS/DataLayer/Mapper/Transactions/ExchangeTransaction+Mapper.swift deleted file mode 100644 index c4ad5170..00000000 --- a/WavesWallet-iOS/DataLayer/Mapper/Transactions/ExchangeTransaction+Mapper.swift +++ /dev/null @@ -1,171 +0,0 @@ -// -// ExchangeTransaction+Mapper.swift -// WavesWallet-iOS -// -// Created by mefilt on 30.08.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import WavesSDKCrypto - -extension ExchangeTransaction { - - convenience init(transaction: DomainLayer.DTO.ExchangeTransaction) { - self.init() - type = transaction.type - id = transaction.id - sender = transaction.sender - senderPublicKey = transaction.sender - fee = transaction.fee - timestamp = transaction.timestamp - version = 1 - height = transaction.height - modified = transaction.modified - - if let proofs = transaction.proofs { - self.proofs.append(objectsIn: proofs) - } - signature = transaction.signature - amount = transaction.amount - price = transaction.price - signature = transaction.signature - buyMatcherFee = transaction.buyMatcherFee - sellMatcherFee = transaction.sellMatcherFee - - order1 = ExchangeTransactionOrder(order: transaction.order1) - order2 = ExchangeTransactionOrder(order: transaction.order2) - status = transaction.status.rawValue - } -} - -extension DomainLayer.DTO.ExchangeTransaction { - - init(transaction: Node.DTO.ExchangeTransaction, status: DomainLayer.DTO.TransactionStatus, environment: Environment) { - - type = transaction.type - id = transaction.id - sender = transaction.sender.normalizeAddress(environment: environment) - senderPublicKey = transaction.senderPublicKey - fee = transaction.fee - timestamp = transaction.timestamp - height = transaction.height - modified = Date() - - signature = transaction.signature - amount = transaction.amount - price = transaction.price - buyMatcherFee = transaction.buyMatcherFee - sellMatcherFee = transaction.sellMatcherFee - order1 = DomainLayer.DTO.ExchangeTransaction.Order(order: transaction.order1, environment: environment) - order2 = DomainLayer.DTO.ExchangeTransaction.Order(order: transaction.order2, environment: environment) - proofs = [] - self.status = status - } - - init(transaction: ExchangeTransaction) { - type = transaction.type - id = transaction.id - sender = transaction.sender - senderPublicKey = transaction.sender - fee = transaction.fee - timestamp = transaction.timestamp - height = transaction.height - modified = transaction.modified - - amount = transaction.amount - price = transaction.price - signature = transaction.signature - proofs = transaction.proofs.toArray() - buyMatcherFee = transaction.buyMatcherFee - sellMatcherFee = transaction.sellMatcherFee - order1 = DomainLayer.DTO.ExchangeTransaction.Order(order: transaction.order1!) - order2 = DomainLayer.DTO.ExchangeTransaction.Order(order: transaction.order2!) - status = DomainLayer.DTO.TransactionStatus(rawValue: transaction.status) ?? .completed - } -} - -fileprivate extension DomainLayer.DTO.ExchangeTransaction.Order.Kind { - - init(key: String) { - if key == "sell" { - self = .sell - } else { - self = .buy - } - } - - var key: String { - switch self { - case .sell: - return "sell" - case .buy: - return "buy" - } - } -} - -extension ExchangeTransactionOrder { - - convenience init(order: DomainLayer.DTO.ExchangeTransaction.Order) { - self.init() - - id = order.id - sender = order.sender - senderPublicKey = order.sender - matcherPublicKey = order.matcherPublicKey - orderType = order.orderType.key - price = order.price - amount = order.amount - timestamp = order.timestamp - expiration = order.expiration - matcherFee = order.matcherFee - signature = order.signature - - let assetPair = ExchangeTransactionAssetPair() - assetPair.amountAsset = order.assetPair.amountAsset - assetPair.priceAsset = order.assetPair.priceAsset - self.assetPair = assetPair - } -} - -extension DomainLayer.DTO.ExchangeTransaction.Order { - - init(order: Node.DTO.ExchangeTransaction.Order, environment: Environment) { - - id = order.id - sender = order.sender.normalizeAddress(environment: environment) - senderPublicKey = order.senderPublicKey - matcherPublicKey = order.matcherPublicKey - orderType = .init(key: order.orderType) - price = order.price - amount = order.amount - timestamp = order.timestamp - expiration = order.expiration - matcherFee = order.matcherFee - signature = order.signature - assetPair = DomainLayer.DTO.ExchangeTransaction.AssetPair(amountAsset: order.assetPair.amountAsset.normalizeAssetId, - priceAsset: order.assetPair.priceAsset.normalizeAssetId) - } - - init(order: ExchangeTransactionOrder) { - id = order.id - sender = order.sender - senderPublicKey = order.sender - matcherPublicKey = order.matcherPublicKey - orderType = .init(key: order.orderType) - price = order.price - amount = order.amount - timestamp = order.timestamp - expiration = order.expiration - matcherFee = order.matcherFee - signature = order.signature - - let amountAssetId = order.assetPair?.amountAsset - let priceAssetId = order.assetPair?.priceAsset - - assetPair = DomainLayer.DTO.ExchangeTransaction.AssetPair(amountAsset: amountAssetId.normalizeAssetId, - priceAsset: priceAssetId.normalizeAssetId) - } -} - diff --git a/WavesWallet-iOS/DataLayer/Mapper/Transactions/InvokeScriptTransaction+Mapper.swift b/WavesWallet-iOS/DataLayer/Mapper/Transactions/InvokeScriptTransaction+Mapper.swift deleted file mode 100644 index 3f4cbf58..00000000 --- a/WavesWallet-iOS/DataLayer/Mapper/Transactions/InvokeScriptTransaction+Mapper.swift +++ /dev/null @@ -1,82 +0,0 @@ -// -// InvokeScriptTransaction+Mapper.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 4/9/19. -// Copyright © 2019 Waves Platform. All rights reserved. -// - -import Foundation -import WavesSDKCrypto - -extension InvokeScriptTransaction { - - convenience init(transaction: DomainLayer.DTO.InvokeScriptTransaction) { - self.init() - - type = transaction.type - id = transaction.id - sender = transaction.sender - senderPublicKey = transaction.sender - fee = transaction.fee - timestamp = transaction.timestamp - height = transaction.height - version = transaction.version - - if let proofs = transaction.proofs { - self.proofs.append(objectsIn: proofs) - } - feeAssetId = transaction.feeAssetId - dappAddress = transaction.dappAddress - - modified = transaction.modified - status = transaction.status.rawValue - - if let txPayment = transaction.payment { - payment = InvokeScriptTransactionPayment() - payment?.amount = txPayment.amount - payment?.assetId = txPayment.assetId - } - - } -} -extension DomainLayer.DTO.InvokeScriptTransaction { - - init(transaction: Node.DTO.InvokeScriptTransaction, status: DomainLayer.DTO.TransactionStatus, environment: Environment) { - type = transaction.type - id = transaction.id - sender = transaction.sender.normalizeAddress(environment: environment) - senderPublicKey = transaction.senderPublicKey - fee = transaction.fee - feeAssetId = transaction.feeAssetId - timestamp = transaction.timestamp - proofs = transaction.proofs - version = transaction.version - dappAddress = transaction.dApp - height = transaction.height - payment = transaction.payment.first.map { .init(amount: $0.amount, assetId: $0.assetId) } - - modified = Date() - self.status = status - } - - init(transaction: InvokeScriptTransaction) { - - type = transaction.type - id = transaction.id - sender = transaction.sender - senderPublicKey = transaction.senderPublicKey - fee = transaction.fee - feeAssetId = transaction.feeAssetId - timestamp = transaction.timestamp - version = transaction.version - dappAddress = transaction.dappAddress - height = transaction.height - proofs = transaction.proofs.toArray() - payment = transaction.payment.map { .init(amount: $0.amount, assetId: $0.assetId) } - - modified = transaction.modified - status = DomainLayer.DTO.TransactionStatus(rawValue: transaction.status) ?? .completed - } - -} diff --git a/WavesWallet-iOS/DataLayer/Mapper/Transactions/IssueTransaction+Mapper.swift b/WavesWallet-iOS/DataLayer/Mapper/Transactions/IssueTransaction+Mapper.swift deleted file mode 100644 index 0b68efc0..00000000 --- a/WavesWallet-iOS/DataLayer/Mapper/Transactions/IssueTransaction+Mapper.swift +++ /dev/null @@ -1,91 +0,0 @@ -// -// TransactionContainers.swift -// WavesWallet-iOS -// -// Created by mefilt on 30.08.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import WavesSDKExtension -import WavesSDKCrypto - -extension IssueTransaction { - - convenience init(transaction: DomainLayer.DTO.IssueTransaction) { - self.init() - type = transaction.type - id = transaction.id - sender = transaction.sender - senderPublicKey = transaction.senderPublicKey - fee = transaction.fee - timestamp = transaction.timestamp - version = transaction.version - height = transaction.height - signature = transaction.signature - chainId.value = transaction.chainId - if let proofs = transaction.proofs { - self.proofs.append(objectsIn: proofs) - } - assetId = transaction.assetId - name = transaction.name - quantity = transaction.quantity - reissuable = transaction.reissuable - decimals = transaction.decimals - assetDescription = transaction.description - script = transaction.script - modified = transaction.modified - status = transaction.status.rawValue - } -} - -extension DomainLayer.DTO.IssueTransaction { - - init(transaction: Node.DTO.IssueTransaction, status: DomainLayer.DTO.TransactionStatus, environment: Environment) { - - type = transaction.type - id = transaction.id - sender = transaction.sender.normalizeAddress(environment: environment) - senderPublicKey = transaction.senderPublicKey - fee = transaction.fee - timestamp = transaction.timestamp - version = transaction.version - height = transaction.height - signature = transaction.signature - assetId = transaction.assetId - name = transaction.name - chainId = nil - - quantity = transaction.quantity - reissuable = transaction.reissuable - decimals = transaction.decimals - description = transaction.description - script = transaction.script - modified = Date() - proofs = transaction.proofs - self.status = status - } - - init(transaction: IssueTransaction) { - type = transaction.type - id = transaction.id - sender = transaction.sender - senderPublicKey = transaction.senderPublicKey - fee = transaction.fee - timestamp = transaction.timestamp - version = transaction.version - height = transaction.height - signature = transaction.signature - assetId = transaction.assetId - name = transaction.name - quantity = transaction.quantity - reissuable = transaction.reissuable - decimals = transaction.decimals - description = transaction.assetDescription - script = transaction.script - modified = transaction.modified - proofs = transaction.proofs.toArray() - chainId = transaction.chainId.value - status = DomainLayer.DTO.TransactionStatus(rawValue: transaction.status) ?? .completed - } -} diff --git a/WavesWallet-iOS/DataLayer/Mapper/Transactions/LeaseCancelTransaction+Mapper.swift b/WavesWallet-iOS/DataLayer/Mapper/Transactions/LeaseCancelTransaction+Mapper.swift deleted file mode 100644 index 32de8d59..00000000 --- a/WavesWallet-iOS/DataLayer/Mapper/Transactions/LeaseCancelTransaction+Mapper.swift +++ /dev/null @@ -1,93 +0,0 @@ -// -// LeaseCancelTransaction+Mapper.swift -// WavesWallet-iOS -// -// Created by mefilt on 30.08.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import WavesSDKCrypto - -extension LeaseCancelTransaction { - - convenience init(transaction: DomainLayer.DTO.LeaseCancelTransaction) { - self.init() - type = transaction.type - id = transaction.id - sender = transaction.sender - senderPublicKey = transaction.senderPublicKey - fee = transaction.fee - timestamp = transaction.timestamp - version = transaction.version - height = transaction.height - modified = transaction.modified - - if let proofs = transaction.proofs { - self.proofs.append(objectsIn: proofs) - } - - signature = transaction.signature - chainId.value = transaction.chainId - leaseId = transaction.leaseId - if let lease = transaction.lease { - if let leaseFromBD = self.realm?.object(ofType: LeaseTransaction.self, forPrimaryKey: leaseId) { - self.lease = leaseFromBD - } else { - self.lease = LeaseTransaction(transaction: lease) - } - } - status = transaction.status.rawValue - } -} - -extension DomainLayer.DTO.LeaseCancelTransaction { - - init(transaction: Node.DTO.LeaseCancelTransaction, status: DomainLayer.DTO.TransactionStatus, environment: Environment) { - - type = transaction.type - id = transaction.id - sender = transaction.sender.normalizeAddress(environment: environment) - senderPublicKey = transaction.senderPublicKey - fee = transaction.fee - timestamp = transaction.timestamp - version = transaction.version - height = transaction.height ?? -1 - modified = Date() - - signature = transaction.signature - chainId = transaction.chainId - leaseId = transaction.leaseId - if let lease = transaction.lease { - self.lease = DomainLayer.DTO.LeaseTransaction(transaction: lease, status: .completed, environment: environment) - } else { - self.lease = nil - } - - proofs = transaction.proofs - self.status = status - } - - init(transaction: LeaseCancelTransaction) { - type = transaction.type - id = transaction.id - sender = transaction.sender - senderPublicKey = transaction.senderPublicKey - fee = transaction.fee - timestamp = transaction.timestamp - version = transaction.version - height = transaction.height - modified = transaction.modified - - signature = transaction.signature - chainId = transaction.chainId.value - leaseId = transaction.leaseId - if let lease = transaction.lease { - self.lease = DomainLayer.DTO.LeaseTransaction(transaction: lease) - } else { - self.lease = nil - } - proofs = transaction.proofs.toArray() - status = DomainLayer.DTO.TransactionStatus(rawValue: transaction.status) ?? .completed - } -} diff --git a/WavesWallet-iOS/DataLayer/Mapper/Transactions/LeaseTransaction+Mapper.swift b/WavesWallet-iOS/DataLayer/Mapper/Transactions/LeaseTransaction+Mapper.swift deleted file mode 100644 index b756f4f2..00000000 --- a/WavesWallet-iOS/DataLayer/Mapper/Transactions/LeaseTransaction+Mapper.swift +++ /dev/null @@ -1,77 +0,0 @@ -// -// LeasingTransaction+Mapper.swift -// WavesWallet-iOS -// -// Created by mefilt on 19.07.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import WavesSDKExtension -import WavesSDKCrypto - -extension LeaseTransaction { - - convenience init(transaction: DomainLayer.DTO.LeaseTransaction) { - self.init() - type = transaction.type - id = transaction.id - sender = transaction.sender - senderPublicKey = transaction.senderPublicKey - fee = transaction.fee - timestamp = transaction.timestamp - height = transaction.height - chainId.value = transaction.chainId - signature = transaction.signature - if let proofs = transaction.proofs { - self.proofs.append(objectsIn: proofs) - } - amount = transaction.amount - recipient = transaction.recipient - modified = transaction.modified - status = transaction.status.rawValue - - } -} - -extension DomainLayer.DTO.LeaseTransaction { - - init(transaction: Node.DTO.LeaseTransaction, status: DomainLayer.DTO.TransactionStatus, environment: Environment) { - type = transaction.type - id = transaction.id - sender = transaction.sender.normalizeAddress(environment: environment) - senderPublicKey = transaction.senderPublicKey - fee = transaction.fee - timestamp = transaction.timestamp - signature = transaction.signature - version = transaction.version - amount = transaction.amount - recipient = transaction.recipient.normalizeAddress(environment: environment) - - height = transaction.height ?? -1 - chainId = nil - modified = Date() - proofs = transaction.proofs - - self.status = status - } - - init(transaction: LeaseTransaction) { - - type = transaction.type - id = transaction.id - sender = transaction.sender - senderPublicKey = transaction.senderPublicKey - fee = transaction.fee - timestamp = transaction.timestamp - signature = transaction.signature - version = transaction.version - amount = transaction.amount - recipient = transaction.recipient - height = transaction.height - chainId = transaction.chainId.value - proofs = transaction.proofs.toArray() - modified = transaction.modified - status = DomainLayer.DTO.TransactionStatus(rawValue: transaction.status) ?? .completed - } -} diff --git a/WavesWallet-iOS/DataLayer/Mapper/Transactions/MassTransferTransaction+Mapper.swift b/WavesWallet-iOS/DataLayer/Mapper/Transactions/MassTransferTransaction+Mapper.swift deleted file mode 100644 index 71e4d409..00000000 --- a/WavesWallet-iOS/DataLayer/Mapper/Transactions/MassTransferTransaction+Mapper.swift +++ /dev/null @@ -1,103 +0,0 @@ -// -// MassTransferTransaction+Mapper.swift -// WavesWallet-iOS -// -// Created by mefilt on 30.08.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import WavesSDKExtension -import WavesSDKCrypto - -extension MassTransferTransaction { - - convenience init(transaction: DomainLayer.DTO.MassTransferTransaction) { - self.init() - type = transaction.type - id = transaction.id - sender = transaction.sender - senderPublicKey = transaction.senderPublicKey - fee = transaction.fee - timestamp = transaction.timestamp - version = transaction.version - height = transaction.height - modified = transaction.modified - - assetId = transaction.assetId - attachment = transaction.attachment - transferCount = transaction.transferCount - totalAmount = transaction.totalAmount - - if let proofs = transaction.proofs { - self.proofs.append(objectsIn: proofs) - } - let transfers = transaction - .transfers - .map { model -> MassTransferTransactionTransfer in - let info = MassTransferTransactionTransfer() - info.recipient = model.recipient - info.amount = model.amount - return info - } - - self.transfers.append(objectsIn: transfers) - - status = transaction.status.rawValue - } -} - -extension DomainLayer.DTO.MassTransferTransaction { - - init(transaction: Node.DTO.MassTransferTransaction, - status: DomainLayer.DTO.TransactionStatus, - environment: Environment) { - - type = transaction.type - id = transaction.id - sender = transaction.sender.normalizeAddress(environment: environment) - senderPublicKey = transaction.senderPublicKey - fee = transaction.fee - timestamp = transaction.timestamp - version = transaction.version - height = transaction.height - modified = Date() - - assetId = transaction.assetId.normalizeAssetId - attachment = transaction.attachment - transferCount = transaction.transferCount - totalAmount = transaction.totalAmount - proofs = transaction.proofs - - transfers = transaction - .transfers - .map { .init(recipient: $0.recipient.normalizeAddress(environment: environment), - amount: $0.amount) } - - self.status = status - } - - init(transaction: MassTransferTransaction) { - type = transaction.type - id = transaction.id - sender = transaction.sender - senderPublicKey = transaction.sender - fee = transaction.fee - timestamp = transaction.timestamp - version = transaction.version - height = transaction.height - modified = transaction.modified - - assetId = transaction.assetId.normalizeAssetId - attachment = transaction.attachment - transferCount = transaction.transferCount - totalAmount = transaction.totalAmount - proofs = transaction.proofs.toArray() - - transfers = transaction - .transfers - .map { .init(recipient: $0.recipient, - amount: $0.amount) } - status = DomainLayer.DTO.TransactionStatus(rawValue: transaction.status) ?? .completed - } -} diff --git a/WavesWallet-iOS/DataLayer/Mapper/Transactions/ReissueTransaction+Mapper.swift b/WavesWallet-iOS/DataLayer/Mapper/Transactions/ReissueTransaction+Mapper.swift deleted file mode 100644 index 40390869..00000000 --- a/WavesWallet-iOS/DataLayer/Mapper/Transactions/ReissueTransaction+Mapper.swift +++ /dev/null @@ -1,79 +0,0 @@ -// -// ReissueTransaction+Mapper.swift -// WavesWallet-iOS -// -// Created by mefilt on 30.08.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import WavesSDKCrypto - -extension ReissueTransaction { - - convenience init(transaction: DomainLayer.DTO.ReissueTransaction) { - self.init() - type = transaction.type - id = transaction.id - sender = transaction.sender - senderPublicKey = transaction.senderPublicKey - fee = transaction.fee - timestamp = transaction.timestamp - version = transaction.version - height = transaction.height - modified = transaction.modified - if let proofs = transaction.proofs { - self.proofs.append(objectsIn: proofs) - } - signature = transaction.signature - assetId = transaction.assetId - chainId.value = transaction.chainId - quantity = transaction.quantity - reissuable = transaction.reissuable - status = transaction.status.rawValue - } -} - -extension DomainLayer.DTO.ReissueTransaction { - - init(transaction: Node.DTO.ReissueTransaction, status: DomainLayer.DTO.TransactionStatus, environment: Environment) { - - type = transaction.type - id = transaction.id - sender = transaction.sender.normalizeAddress(environment: environment) - senderPublicKey = transaction.senderPublicKey - fee = transaction.fee - timestamp = transaction.timestamp - version = transaction.version - height = transaction.height - modified = Date() - - signature = transaction.signature - assetId = transaction.assetId - chainId = transaction.chainId - quantity = transaction.quantity - reissuable = transaction.reissuable - proofs = transaction.proofs - self.status = status - } - - init(transaction: ReissueTransaction) { - type = transaction.type - id = transaction.id - sender = transaction.sender - senderPublicKey = transaction.senderPublicKey - fee = transaction.fee - timestamp = transaction.timestamp - version = transaction.version - height = transaction.height - modified = transaction.modified - - signature = transaction.signature - assetId = transaction.assetId - chainId = transaction.chainId.value - quantity = transaction.quantity - reissuable = transaction.reissuable - proofs = transaction.proofs.toArray() - status = DomainLayer.DTO.TransactionStatus(rawValue: transaction.status) ?? .completed - } -} diff --git a/WavesWallet-iOS/DataLayer/Mapper/Transactions/ScriptTransaction+Mapper.swift b/WavesWallet-iOS/DataLayer/Mapper/Transactions/ScriptTransaction+Mapper.swift deleted file mode 100644 index fca1b31d..00000000 --- a/WavesWallet-iOS/DataLayer/Mapper/Transactions/ScriptTransaction+Mapper.swift +++ /dev/null @@ -1,72 +0,0 @@ -// -// ScriptTransaction+Mapper.swift -// WavesWallet-iOS -// -// Created by mefilt on 22/01/2019. -// Copyright © 2019 Waves Platform. All rights reserved. -// - -import Foundation -import WavesSDKExtension -import WavesSDKCrypto - -extension ScriptTransaction { - - convenience init(transaction: DomainLayer.DTO.ScriptTransaction) { - self.init() - type = transaction.type - id = transaction.id - sender = transaction.sender - senderPublicKey = transaction.sender - fee = transaction.fee - timestamp = transaction.timestamp - version = 1 - height = transaction.height ?? -1 - chainId.value = transaction.chainId - signature = transaction.signature - if let proofs = transaction.proofs { - self.proofs.append(objectsIn: proofs) - } - script = transaction.script - modified = transaction.modified - status = transaction.status.rawValue - } -} - -extension DomainLayer.DTO.ScriptTransaction { - - init(transaction: Node.DTO.ScriptTransaction, status: DomainLayer.DTO.TransactionStatus, environment: Environment) { - - type = transaction.type - id = transaction.id - sender = transaction.sender.normalizeAddress(environment: environment) - senderPublicKey = transaction.senderPublicKey - fee = transaction.fee - timestamp = transaction.timestamp - version = transaction.version - height = transaction.height - chainId = transaction.chainId - signature = transaction.signature - proofs = transaction.proofs - script = transaction.script - modified = Date() - self.status = status - } - - init(transaction: ScriptTransaction) { - type = transaction.type - id = transaction.id - sender = transaction.sender - senderPublicKey = transaction.sender - fee = transaction.fee - timestamp = transaction.timestamp - modified = transaction.modified - height = transaction.height - chainId = transaction.chainId.value - signature = transaction.signature - proofs = transaction.proofs.toArray() - script = transaction.script - version = transaction.version - status = DomainLayer.DTO.TransactionStatus(rawValue: transaction.status) ?? .completed - } -} diff --git a/WavesWallet-iOS/DataLayer/Mapper/Transactions/SponsorshipTransaction+Mapper.swift b/WavesWallet-iOS/DataLayer/Mapper/Transactions/SponsorshipTransaction+Mapper.swift deleted file mode 100644 index 2be9ad06..00000000 --- a/WavesWallet-iOS/DataLayer/Mapper/Transactions/SponsorshipTransaction+Mapper.swift +++ /dev/null @@ -1,79 +0,0 @@ -// -// SponsorshipTransaction+Mapper.swift -// WavesWallet-iOS -// -// Created by Prokofev Ruslan on 05/02/2019. -// Copyright © 2019 Waves Platform. All rights reserved. -// - -import Foundation -import WavesSDKExtension -import WavesSDKCrypto - -extension SponsorshipTransaction { - - convenience init(transaction: DomainLayer.DTO.SponsorshipTransaction) { - self.init() - type = transaction.type - id = transaction.id - sender = transaction.sender - senderPublicKey = transaction.sender - fee = transaction.fee - timestamp = transaction.timestamp - height = transaction.height ?? -1 - signature = transaction.signature - version = transaction.version - minSponsoredAssetFee.value = transaction.minSponsoredAssetFee - assetId = transaction.assetId - - if let proofs = transaction.proofs { - self.proofs.append(objectsIn: proofs) - } - modified = transaction.modified - status = transaction.status.rawValue - } -} - -extension DomainLayer.DTO.SponsorshipTransaction { - - init(transaction: Node.DTO.SponsorshipTransaction, status: DomainLayer.DTO.TransactionStatus, environment: Environment) { - - type = transaction.type - id = transaction.id - sender = transaction.sender.normalizeAddress(environment: environment) - senderPublicKey = transaction.senderPublicKey - fee = transaction.fee - timestamp = transaction.timestamp - height = transaction.height ?? -1 - signature = transaction.signature - proofs = transaction.proofs - assetId = transaction.assetId - version = transaction.version - minSponsoredAssetFee = transaction.minSponsoredAssetFee - self.assetId = transaction.assetId - modified = Date() - self.status = status - } - - init(transaction: SponsorshipTransaction) { - type = transaction.type - id = transaction.id - sender = transaction.sender - senderPublicKey = transaction.sender - fee = transaction.fee - timestamp = transaction.timestamp - height = transaction.height - signature = transaction.signature - proofs = transaction.proofs.toArray() - assetId = transaction.assetId - version = transaction.version - minSponsoredAssetFee = transaction.minSponsoredAssetFee.value - self.assetId = transaction.assetId - - modified = transaction.modified - status = DomainLayer.DTO.TransactionStatus(rawValue: transaction.status) ?? .completed - } -} - - - diff --git a/WavesWallet-iOS/DataLayer/Mapper/Transactions/TransferTransaction+Mapper.swift b/WavesWallet-iOS/DataLayer/Mapper/Transactions/TransferTransaction+Mapper.swift deleted file mode 100644 index eef020c5..00000000 --- a/WavesWallet-iOS/DataLayer/Mapper/Transactions/TransferTransaction+Mapper.swift +++ /dev/null @@ -1,87 +0,0 @@ -// -// TransferTransaction+Mapper.swift -// WavesWallet-iOS -// -// Created by mefilt on 30.08.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import WavesSDKExtension -import WavesSDKCrypto - -extension TransferTransaction { - - convenience init(transaction: DomainLayer.DTO.TransferTransaction) { - self.init() - type = transaction.type - id = transaction.id - sender = transaction.sender - senderPublicKey = transaction.senderPublicKey - fee = transaction.fee - timestamp = transaction.timestamp - version = transaction.version - height = transaction.height - signature = transaction.signature - if let proofs = transaction.proofs { - self.proofs.append(objectsIn: proofs) - } - assetId = transaction.assetId - modified = transaction.modified - - recipient = transaction.recipient - feeAssetId = transaction.feeAssetId - feeAsset = transaction.feeAsset - amount = transaction.amount - attachment = transaction.attachment - status = transaction.status.rawValue - } -} - -extension DomainLayer.DTO.TransferTransaction { - - init(transaction: Node.DTO.TransferTransaction, status: DomainLayer.DTO.TransactionStatus, environment: Environment) { - - type = transaction.type - id = transaction.id - sender = transaction.sender.normalizeAddress(environment: environment) - senderPublicKey = transaction.senderPublicKey - fee = transaction.fee - timestamp = transaction.timestamp - version = transaction.version - height = transaction.height ?? -1 - signature = transaction.signature - assetId = transaction.assetId.normalizeAssetId - modified = Date() - - recipient = transaction.recipient.normalizeAddress(environment: environment) - feeAssetId = transaction.feeAssetId.normalizeAssetId - feeAsset = transaction.feeAsset - amount = transaction.amount - attachment = transaction.attachment - proofs = transaction.proofs - self.status = status - } - - init(transaction: TransferTransaction) { - type = transaction.type - id = transaction.id - sender = transaction.sender - senderPublicKey = transaction.senderPublicKey - fee = transaction.fee - timestamp = transaction.timestamp - version = transaction.version - height = transaction.height - assetId = transaction.assetId.normalizeAssetId - modified = transaction.modified - - recipient = transaction.recipient - feeAssetId = transaction.feeAssetId.normalizeAssetId - feeAsset = transaction.feeAsset - amount = transaction.amount - attachment = transaction.attachment - proofs = transaction.proofs.toArray() - status = DomainLayer.DTO.TransactionStatus(rawValue: transaction.status) ?? .completed - signature = transaction.signature - } -} diff --git a/WavesWallet-iOS/DataLayer/Mapper/Transactions/UnrecognisedTransaction+Mapper.swift b/WavesWallet-iOS/DataLayer/Mapper/Transactions/UnrecognisedTransaction+Mapper.swift deleted file mode 100644 index 751401ba..00000000 --- a/WavesWallet-iOS/DataLayer/Mapper/Transactions/UnrecognisedTransaction+Mapper.swift +++ /dev/null @@ -1,55 +0,0 @@ -// -// UnrecognisedTransaction+Mapper.swift -// WavesWallet-iOS -// -// Created by mefilt on 31.08.2018.1 -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import WavesSDKCrypto - -extension UnrecognisedTransaction { - - convenience init(transaction: DomainLayer.DTO.UnrecognisedTransaction) { - self.init() - type = transaction.type - id = transaction.id - sender = transaction.sender - senderPublicKey = transaction.sender - fee = transaction.fee - timestamp = transaction.timestamp - version = 1 - height = transaction.height - modified = transaction.modified - status = transaction.status.rawValue - } -} - -extension DomainLayer.DTO.UnrecognisedTransaction { - - init(transaction: Node.DTO.UnrecognisedTransaction, status: DomainLayer.DTO.TransactionStatus, environment: Environment) { - - type = transaction.type - id = transaction.id - sender = transaction.sender.normalizeAddress(environment: environment) - senderPublicKey = transaction.senderPublicKey - fee = transaction.fee - timestamp = transaction.timestamp - height = transaction.height - modified = Date() - self.status = status - } - - init(transaction: UnrecognisedTransaction) { - type = transaction.type - id = transaction.id - sender = transaction.sender - senderPublicKey = transaction.sender - fee = transaction.fee - timestamp = transaction.timestamp - modified = transaction.modified - height = transaction.height - status = DomainLayer.DTO.TransactionStatus(rawValue: transaction.status) ?? .completed - } -} diff --git a/WavesWallet-iOS/DataLayer/Repositories/AccountBalance/AccountBalanceRepositoryRemote.swift b/WavesWallet-iOS/DataLayer/Repositories/AccountBalance/AccountBalanceRepositoryRemote.swift deleted file mode 100644 index 0bd7d168..00000000 --- a/WavesWallet-iOS/DataLayer/Repositories/AccountBalance/AccountBalanceRepositoryRemote.swift +++ /dev/null @@ -1,305 +0,0 @@ -// -// AccountBalanceRepositoryRemote.swift -// WavesWallet-iOS -// -// Created by Prokofev Ruslan on 05/08/2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import Moya -import RxSwift -import WavesSDKExtension -import WavesSDKCrypto - -private struct SponsoredAssetDetail { - let minSponsoredAssetFee: Int64? - let sponsoredBalance: Int64 -} - -final class AccountBalanceRepositoryRemote: AccountBalanceRepositoryProtocol { - - private let assetsProvider: MoyaProvider = .nodeMoyaProvider() - private let addressesProvider: MoyaProvider = .nodeMoyaProvider() - private let matcherBalanceProvider: MoyaProvider = .nodeMoyaProvider() - - private let environmentRepository: EnvironmentRepositoryProtocol - - init(environmentRepository: EnvironmentRepositoryProtocol) { - self.environmentRepository = environmentRepository - } - - func balances(by wallet: DomainLayer.DTO.SignedWallet) -> Observable<[DomainLayer.DTO.AssetBalance]> { - - let walletAddress = wallet.address - let assetsBalance = self.assetsBalance(by: walletAddress) - let accountBalance = self.accountBalance(by: walletAddress) - let matcherBalances = self.matcherBalances(by: walletAddress, wallet: wallet) - - return Observable - .zip(assetsBalance, - accountBalance, - matcherBalances) - .map { DomainLayer.DTO.AssetBalance.map(assets: $0.0, - account: $0.1, - matcherBalances: $0.2) } - } - - func balance(by assetId: String, wallet: DomainLayer.DTO.SignedWallet) -> Observable { - - let matcherBalances = self.matcherBalances(by: wallet.address, wallet: wallet) - - if assetId == WavesSDKCryptoConstants.wavesAssetId { - let accountBalance = self.accountBalance(by: wallet.address) - - return Observable - .zip(accountBalance, - matcherBalances) - .map({ (accountBalance, matcher) -> DomainLayer.DTO.AssetBalance in - let inOrderBalance = matcher[WavesSDKCryptoConstants.wavesAssetId] ?? 0 - return DomainLayer.DTO.AssetBalance(accountBalance: accountBalance, inOrderBalance: inOrderBalance) - }) - } else { - let assetBalance = self.assetBalance(by: wallet.address, assetId: assetId) - let sponsorBalance = self.sponsorBalance(assetId: assetId, walletAddress: wallet.address) - - return Observable - .zip(assetBalance, - matcherBalances, - sponsorBalance) - .map({ (assetBalance, matcher, sponsorBalance) -> DomainLayer.DTO.AssetBalance in - let inOrderBalance = matcher[WavesSDKCryptoConstants.wavesAssetId] ?? 0 - return DomainLayer.DTO.AssetBalance(model: assetBalance, - inOrderBalance: inOrderBalance, - sponsoredAssetDetail: sponsorBalance) - }) - } - } - - func deleteBalances(_ balances:[DomainLayer.DTO.AssetBalance], accountAddress: String) -> Observable { - assertMethodDontSupported() - return Observable.never() - } - - func saveBalances(_ balances: [DomainLayer.DTO.AssetBalance], accountAddress: String) -> Observable { - assertMethodDontSupported() - return Observable.never() - } - - func saveBalance(_ balance: DomainLayer.DTO.AssetBalance, accountAddress: String) -> Observable { - assertMethodDontSupported() - return Observable.never() - } - - func listenerOfUpdatedBalances(by accountAddress: String) -> Observable<[DomainLayer.DTO.AssetBalance]> { - assertMethodDontSupported() - return Observable.never() - } -} - -private extension AccountBalanceRepositoryRemote { - - func matcherBalances(by walletAddress: String, wallet: DomainLayer.DTO.SignedWallet) -> Observable<[String: Int64]> { - - return environmentRepository - .accountEnvironment(accountAddress: wallet.address) - .flatMap { [weak self] environment -> Single in - - guard let self = self else { return Single.never() } - - let signature = TimestampSignature(signedWallet: wallet, - environment: environment) - - return self - .matcherBalanceProvider - .rx - .request(.init(kind: .getReservedBalances(signature), - environment: environment), - callbackQueue: DispatchQueue.global(qos: .userInteractive)) - } - .filterSuccessfulStatusAndRedirectCodes() - .catchError({ (error) -> Observable in - return Observable.error(NetworkError.error(by: error)) - }) - .map([String: Int64].self) - } - - func assetBalance(by walletAddress: String, - assetId: String) -> Observable { - - return environmentRepository - .accountEnvironment(accountAddress: walletAddress) - .flatMap { [weak self] environment -> Single in - - guard let self = self else { return Single.never() } - return self - .assetsProvider - .rx - .request(.init(kind: .getAssetsBalance(address: walletAddress, assetId: assetId), - environment: environment), - callbackQueue: DispatchQueue.global(qos: .userInteractive)) - } - .filterSuccessfulStatusAndRedirectCodes() - .catchError({ (error) -> Observable in - return Observable.error(NetworkError.error(by: error)) - }) - .map(Node.DTO.AccountAssetBalance.self) - .asObservable() - } - - //TODO: https://wavesplatform.atlassian.net/browse/NODE-1488 - - func sponsorBalance(assetId: String, walletAddress: String) -> Observable { - return assetDetail(assetId: assetId, - walletAddress: walletAddress) - .flatMap { [weak self] (detail) -> Observable in - - guard let self = self else { return Observable.never() } - - return self.balance(for: detail.issuer, - myWalletAddress: walletAddress) - .map({ (balance) -> SponsoredAssetDetail in - return SponsoredAssetDetail(minSponsoredAssetFee: detail.minSponsoredAssetFee, - sponsoredBalance: balance.balance) - }) - } - } - - func assetDetail(assetId: String, walletAddress: String) -> Observable { - - return environmentRepository - .accountEnvironment(accountAddress: walletAddress) - .flatMap { [weak self] environment -> Single in - - guard let self = self else { return Single.never() } - return self - .assetsProvider - .rx - .request(.init(kind: .details(assetId: assetId), - environment: environment), - callbackQueue: DispatchQueue.global(qos: .userInteractive)) - } - .filterSuccessfulStatusAndRedirectCodes() - .catchError({ (error) -> Observable in - return Observable.error(NetworkError.error(by: error)) - }) - .map(Node.DTO.AssetDetail.self) - .asObservable() - } - - func balance(for walletAddress: String, myWalletAddress: String) -> Observable { - - return environmentRepository - .accountEnvironment(accountAddress: myWalletAddress) - .flatMap { [weak self] environment -> Single in - - guard let self = self else { return Single.never() } - return self - .addressesProvider - .rx - .request(.init(kind: .getAccountBalance(id: walletAddress), - environment: environment), - callbackQueue: DispatchQueue.global(qos: .userInteractive)) - } - .filterSuccessfulStatusAndRedirectCodes() - .catchError({ (error) -> Observable in - return Observable.error(NetworkError.error(by: error)) - }) - .map(Node.DTO.AccountBalance.self) - .asObservable() - } - - func assetsBalance(by walletAddress: String) -> Observable { - - return environmentRepository.accountEnvironment(accountAddress: walletAddress) - .flatMap({ [weak self] (environment) -> Observable in - guard let self = self else { return Observable.empty() } - - let decoder = JSONDecoder() - decoder.dateDecodingStrategy = .custom({ (decoder) -> Date in - return Date(timestampDecoder: decoder, timestampDiff: environment.timestampServerDiff) - }) - - return self - .assetsProvider - .rx - .request(.init(kind: .getAssetsBalances(walletAddress: walletAddress), - environment: environment), - callbackQueue: DispatchQueue.global(qos: .userInteractive)) - .filterSuccessfulStatusAndRedirectCodes() - .asObservable() - .catchError({ (error) -> Observable in - return Observable.error(NetworkError.error(by: error)) - }) - .map(Node.DTO.AccountAssetsBalance.self, atKeyPath: nil, using: decoder, failsOnEmptyData: false) - }) - } - - func accountBalance(by walletAddress: String) -> Observable { - - return environmentRepository - .accountEnvironment(accountAddress: walletAddress) - .flatMap { [weak self] environment -> Single in - guard let self = self else { return Single.never() } - return self - .addressesProvider - .rx - .request(.init(kind: .getAccountBalance(id: walletAddress), - environment: environment), - callbackQueue: DispatchQueue.global(qos: .userInteractive)) - } - .filterSuccessfulStatusAndRedirectCodes() - .catchError({ (error) -> Observable in - return Observable.error(NetworkError.error(by: error)) - }) - .map(Node.DTO.AccountBalance.self) - } -} - -private extension DomainLayer.DTO.AssetBalance { - - init(accountBalance: Node.DTO.AccountBalance, inOrderBalance: Int64) { - self.assetId = WavesSDKCryptoConstants.wavesAssetId - self.totalBalance = accountBalance.balance - self.leasedBalance = 0 - self.inOrderBalance = inOrderBalance - self.modified = Date() - self.sponsorBalance = 0 - self.minSponsoredAssetFee = 0 - } - - init(model: Node.DTO.AssetBalance, inOrderBalance: Int64) { - self.assetId = model.assetId - self.totalBalance = model.balance - self.leasedBalance = 0 - self.inOrderBalance = inOrderBalance - self.sponsorBalance = model.sponsorBalance ?? 0 - self.modified = Date() - self.minSponsoredAssetFee = model.minSponsoredAssetFee ?? 0 - } - - init(model: Node.DTO.AccountAssetBalance, inOrderBalance: Int64, sponsoredAssetDetail: SponsoredAssetDetail) { - self.assetId = model.assetId - self.totalBalance = model.balance - self.leasedBalance = 0 - self.inOrderBalance = inOrderBalance - self.sponsorBalance = sponsoredAssetDetail.sponsoredBalance - self.modified = Date() - self.minSponsoredAssetFee = sponsoredAssetDetail.minSponsoredAssetFee ?? 0 - } - - static func map(assets: Node.DTO.AccountAssetsBalance, - account: Node.DTO.AccountBalance, - matcherBalances: [String: Int64]) -> [DomainLayer.DTO.AssetBalance] { - - let assetsBalance = assets.balances.map { DomainLayer.DTO.AssetBalance(model: $0, inOrderBalance: matcherBalances[$0.assetId] ?? 0) } - let accountBalance = DomainLayer.DTO.AssetBalance(accountBalance: account, - inOrderBalance: matcherBalances[WavesSDKCryptoConstants.wavesAssetId] ?? 0) - - var list = [DomainLayer.DTO.AssetBalance]() - list.append(contentsOf: assetsBalance) - list.append(accountBalance) - - return list - } -} diff --git a/WavesWallet-iOS/DataLayer/Repositories/AccountEnvironmentRepository.swift b/WavesWallet-iOS/DataLayer/Repositories/AccountEnvironmentRepository.swift deleted file mode 100644 index 9ac515c7..00000000 --- a/WavesWallet-iOS/DataLayer/Repositories/AccountEnvironmentRepository.swift +++ /dev/null @@ -1,60 +0,0 @@ -// -// AccountEnvironmentRepository.swift -// WavesWallet-iOS -// -// Created by Prokofev Ruslan on 22/10/2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import RxSwift -import RxRealm -import RealmSwift -import WavesSDKExtension - -final class AccountSettingsRepository: AccountSettingsRepositoryProtocol { - - func accountSettings(accountAddress: String) -> Observable { - return Observable.create({ observer -> Disposable in - - //TODO: Error - let realm = try! WalletRealmFactory.realm(accountAddress: accountAddress) - let result = realm.objects(AccountSettings.self) - - if let settings = result.toArray().first { - observer.onNext(DomainLayer.DTO.AccountSettings(settings)) - observer.onCompleted() - } else { - observer.onNext(nil) - observer.onCompleted() - } - - return Disposables.create() - }) - } - - func saveAccountSettings(accountAddress: String, settings: DomainLayer.DTO.AccountSettings) -> Observable { - return Observable.create({ observer -> Disposable in - - do { - let realm = try WalletRealmFactory.realm(accountAddress: accountAddress) - try realm.write { - - let result = realm.objects(AccountSettings.self) - realm.delete(result) - - realm.add(AccountSettings(settings)) - } - - } catch let e { - SweetLogger.debug(e) - observer.onError(AccountSettingsRepositoryError.invalid) - } - - observer.onNext(settings) - observer.onCompleted() - - return Disposables.create() - }) - } -} diff --git a/WavesWallet-iOS/DataLayer/Repositories/AddressBook/AddressBookRepository.swift b/WavesWallet-iOS/DataLayer/Repositories/AddressBook/AddressBookRepository.swift deleted file mode 100644 index d5734b18..00000000 --- a/WavesWallet-iOS/DataLayer/Repositories/AddressBook/AddressBookRepository.swift +++ /dev/null @@ -1,117 +0,0 @@ -// -// AddressBookRepositoryLocal.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 9/26/18. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import RxSwift -import RxRealm -import RealmSwift - -final class AddressBookRepository: AddressBookRepositoryProtocol { - - func contact(by address: String, accountAddress: String) -> Observable { - - return Observable.create({ observer -> Disposable in - - //TODO: Remove ! - let realm = try! WalletRealmFactory.realm(accountAddress: accountAddress) - - if let object = realm.object(ofType: AddressBook.self, forPrimaryKey: address) { - observer.onNext(DomainLayer.DTO.Contact(name: object.name, address: object.address)) - } else { - observer.onNext(nil) - } - observer.onCompleted() - - return Disposables.create() - }) - } - - func listListener(by accountAddress: String) -> Observable<[DomainLayer.DTO.Contact]> { - return Observable.create({ observer -> Disposable in - //TODO: Remove ! - let realm = try! WalletRealmFactory.realm(accountAddress: accountAddress) - - let result = realm.objects(AddressBook.self) - let collection = Observable.collection(from: result) - .skip(1) - .map { $0.toArray() } - .map({ list -> [DomainLayer.DTO.Contact] in - return list.map { return DomainLayer.DTO.Contact(name: $0.name, address: $0.address) } - }) - .bind(to: observer) - - return Disposables.create([collection]) - }) - .subscribeOn(Schedulers.realmThreadScheduler) - } - - func list(by accountAddress: String) -> Observable<[DomainLayer.DTO.Contact]> { - return Observable.create({ observer -> Disposable in - - //TODO: Remove ! - let realm = try! WalletRealmFactory.realm(accountAddress: accountAddress) - - let list = realm.objects(AddressBook.self).toArray().map { - return DomainLayer.DTO.Contact(name: $0.name, address: $0.address) - } - observer.onNext(list) - observer.onCompleted() - - return Disposables.create() - }) - } - - func save(contact: DomainLayer.DTO.Contact, accountAddress: String) -> Observable { - - return Observable.create({ observer -> Disposable in - let realm = try! WalletRealmFactory.realm(accountAddress: accountAddress) - - //TODO: Remove ! - try! realm.write { - realm.add(AddressBook(contact), update: true) - } - observer.onNext(true) - observer.onCompleted() - - return Disposables.create() - }) - } - - func delete(contact: DomainLayer.DTO.Contact, accountAddress: String) -> Observable { - - return Observable.create({ observer -> Disposable in - //TODO: Remove ! - let realm = try! WalletRealmFactory.realm(accountAddress: accountAddress) - - guard let user = realm.object(ofType: AddressBook.self, - forPrimaryKey: contact.address) else { - observer.onNext(true) - observer.onCompleted() - return Disposables.create() - } - - try! realm.write { - realm.delete(user) - } - - observer.onNext(true) - observer.onCompleted() - - return Disposables.create() - }) - } -} - -private extension AddressBook { - - convenience init(_ from: DomainLayer.DTO.Contact) { - self.init() - self.address = from.address - self.name = from.name - } -} diff --git a/WavesWallet-iOS/DataLayer/Repositories/AddressRepositoryRemote.swift b/WavesWallet-iOS/DataLayer/Repositories/AddressRepositoryRemote.swift deleted file mode 100644 index 29cd3290..00000000 --- a/WavesWallet-iOS/DataLayer/Repositories/AddressRepositoryRemote.swift +++ /dev/null @@ -1,44 +0,0 @@ -// -// AddressRepositoryRemote.swift -// WavesWallet-iOS -// -// Created by mefilt on 21/01/2019. -// Copyright © 2019 Waves Platform. All rights reserved. -// - -import Foundation -import RxSwift -import Moya - -final class AddressRepositoryRemote: AddressRepositoryProtocol { - - private let environmentRepository: EnvironmentRepositoryProtocol - - private let addressesProvider: MoyaProvider = .nodeMoyaProvider() - - init(environmentRepository: EnvironmentRepositoryProtocol) { - self.environmentRepository = environmentRepository - } - - func isSmartAddress(accountAddress: String) -> Observable { - - let environment = environmentRepository.accountEnvironment(accountAddress: accountAddress) - - return environment - .flatMap { [weak self] environment -> Single in - - guard let self = self else { return Single.never() } - return self - .addressesProvider - .rx - .request(.init(kind: .scriptInfo(id: accountAddress), environment: environment), - callbackQueue: DispatchQueue.global(qos: .userInteractive)) - } - .filterSuccessfulStatusAndRedirectCodes() - .catchError({ (error) -> Observable in - return Observable.error(NetworkError.error(by: error)) - }) - .map(Node.DTO.AddressScriptInfo.self) - .map { ($0.extraFee ?? 0) > 0 } - } -} diff --git a/WavesWallet-iOS/DataLayer/Repositories/Aliases/AliasesRepository.swift b/WavesWallet-iOS/DataLayer/Repositories/Aliases/AliasesRepository.swift deleted file mode 100644 index 2dfa5ea4..00000000 --- a/WavesWallet-iOS/DataLayer/Repositories/Aliases/AliasesRepository.swift +++ /dev/null @@ -1,90 +0,0 @@ -// -// AliasRepositoryRemote.swift -// WavesWallet-iOS -// -// Created by Prokofev Ruslan on 27/10/2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import RxSwift -import Moya -import WavesSDKExtension -import WavesSDKCrypto - -private enum Constants { - static var notFoundCode = 404 -} - -final class AliasesRepository: AliasesRepositoryProtocol { - - private let environmentRepository: EnvironmentRepositoryProtocol - private let aliasApi: MoyaProvider = .nodeMoyaProvider() - - init(environmentRepository: EnvironmentRepositoryProtocol) { - self.environmentRepository = environmentRepository - } - - func aliases(accountAddress: String) -> Observable<[DomainLayer.DTO.Alias]> { - - return environmentRepository - .accountEnvironment(accountAddress: accountAddress) - .flatMap({ [weak self] environment -> Observable<(aliases: [API.DTO.Alias], environment: Environment)> in - guard let self = self else { return Observable.never() } - return self - .aliasApi - .rx - .request(API.Service.Alias(environment: environment, - kind: .list(accountAddress: accountAddress)), - callbackQueue: DispatchQueue.global(qos: .userInteractive)) - .filterSuccessfulStatusAndRedirectCodes() - .asObservable() - .catchError({ (error) -> Observable in - return Observable.error(NetworkError.error(by: error)) - }) - .map(API.Response<[API.Response]>.self) - .map { (aliases: $0.data.map{ $0.data }, environment: environment) } - }) - .map({ data -> [DomainLayer.DTO.Alias] in - - let list = data.aliases - let aliasScheme = data.environment.aliasScheme - - return list.map({ alias -> DomainLayer.DTO.Alias? in - - let name = alias.alias - let originalName = aliasScheme + name - return DomainLayer.DTO.Alias(name: name, originalName: originalName) - }) - .compactMap { $0 } - }) - } - - func alias(by name: String, accountAddress: String) -> Observable { - return environmentRepository.accountEnvironment(accountAddress: accountAddress) - .flatMap({ [weak self] (environment) -> Observable in - guard let self = self else { return Observable.empty() } - return self.aliasApi.rx.request(API.Service.Alias(environment: environment, - kind: .alias(name: name))) - .filterSuccessfulStatusAndRedirectCodes() - .map(API.Response.self) - .map({ (response) -> String in - return response.data.address - }) - .asObservable() - .catchError({ (e) -> Observable in - guard let error = e as? MoyaError else { - return Observable.error(NetworkError.error(by: e)) - } - guard let response = error.response else { return Observable.error(NetworkError.error(by: e)) } - guard response.statusCode == Constants.notFoundCode else { return Observable.error(NetworkError.error(by: e)) } - return Observable.error(AliasesRepositoryError.dontExist) - }) - }) - } - - func saveAliases(by accountAddress: String, aliases: [DomainLayer.DTO.Alias]) -> Observable { - assertMethodDontSupported() - return Observable.never() - } -} diff --git a/WavesWallet-iOS/DataLayer/Repositories/ApplicationVersionRepository.swift b/WavesWallet-iOS/DataLayer/Repositories/ApplicationVersionRepository.swift deleted file mode 100644 index 41a35761..00000000 --- a/WavesWallet-iOS/DataLayer/Repositories/ApplicationVersionRepository.swift +++ /dev/null @@ -1,42 +0,0 @@ -// -// ApplicationVersionRepository.swift -// WavesWallet-iOS -// -// Created by rprokofev on 30/05/2019. -// Copyright © 2019 Waves Platform. All rights reserved. -// - -import Foundation -import RxSwift -import RxSwiftExt -import Moya - -private struct Constants { - static let lastVersion: String = "last_version" -} - -final class ApplicationVersionRepository: ApplicationVersionRepositoryProtocol { - - private let applicationVersionService: MoyaProvider = .nodeMoyaProvider() - - func version() -> Observable { - return applicationVersionService - .rx - .request(.get(hasProxy: true)) - .catchError({ [weak self] (_) -> PrimitiveSequence in - guard let self = self else { return Single.never() } - return self - .applicationVersionService - .rx - .request(.get(hasProxy: false)) - }) - .map([String: String].self) - .map { $0[Constants.lastVersion] } - .asObservable() - .flatMap({ (version) -> Observable in - guard let version = version else { return Observable.error(RepositoryError.fail) } - - return Observable.just(version) - }) - } -} diff --git a/WavesWallet-iOS/DataLayer/Repositories/Assets/AssetsRepositoryRemote.swift b/WavesWallet-iOS/DataLayer/Repositories/Assets/AssetsRepositoryRemote.swift deleted file mode 100644 index 76a5a1fb..00000000 --- a/WavesWallet-iOS/DataLayer/Repositories/Assets/AssetsRepositoryRemote.swift +++ /dev/null @@ -1,194 +0,0 @@ -// -// AssetsRepositoryRemote.swift -// WavesWallet-iOS -// -// Created by Prokofev Ruslan on 04/08/2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import RxSwift -import Moya -import CSV -import WavesSDKExtension -import WavesSDKCrypto - -final class AssetsRepositoryRemote: AssetsRepositoryProtocol { - - private let apiProvider: MoyaProvider = .nodeMoyaProvider() - private let assetNodeProvider: MoyaProvider = .nodeMoyaProvider() - private let spamProvider: MoyaProvider = .nodeMoyaProvider() - - private let environmentRepository: EnvironmentRepositoryProtocol - - init(environmentRepository: EnvironmentRepositoryProtocol) { - self.environmentRepository = environmentRepository - } - - func assets(by ids: [String], accountAddress: String) -> Observable<[DomainLayer.DTO.Asset]> { - - return environmentRepository.accountEnvironment(accountAddress: accountAddress) - .flatMap({ [weak self] (environment) -> Observable<[DomainLayer.DTO.Asset]> in - guard let self = self else { return Observable.empty() } - - let spamAssets = self.spamProvider.rx - .request(.getSpamList(hasProxy: true), - callbackQueue: DispatchQueue.global(qos: .userInteractive)) - .catchError({ [weak self] (_) -> PrimitiveSequence in - guard let self = self else { return Single.never() } - return self.spamProvider - .rx - .request(.getSpamList(hasProxy: false)) - }) - .filterSuccessfulStatusAndRedirectCodes() - .asObservable() - .catchError({ (error) -> Observable in - return Observable.error(NetworkError.error(by: error)) - }) - .map { response -> [String] in - return (try? SpamCVC.addresses(from: response.data)) ?? [] - } - - let decoder = JSONDecoder() - decoder.dateDecodingStrategy = .custom { decoder in - return Date(isoDecoder: decoder, timestampDiff: environment.timestampServerDiff) - } - - let assetsList = self.apiProvider.rx - .request(.init(kind: .getAssets(ids: ids), environment: environment), - callbackQueue: DispatchQueue.global(qos: .userInteractive)) - .filterSuccessfulStatusAndRedirectCodes() - .asObservable() - .catchError({ (error) -> Observable in - return Observable.error(NetworkError.error(by: error)) - }) - .map(API.Response<[API.Response]>.self, atKeyPath: nil, using: decoder, failsOnEmptyData: false) - .map { $0.data.map { $0.data } } - - - return Observable.zip(assetsList, spamAssets) - .map({ (assets, spamAssets) -> [DomainLayer.DTO.Asset] in - - let map = environment.hashMapAssets() - let mapGeneralAssets = environment.hashMapGeneralAssets() - - let spamIds = spamAssets.reduce(into: [String: Bool](), {$0[$1] = true }) - - return assets.map { DomainLayer.DTO.Asset(asset: $0, - info: map[$0.id], - isSpam: spamIds[$0.id] == true, - isMyWavesToken: $0.sender == accountAddress, - isGeneral: mapGeneralAssets[$0.id] != nil) } - }) - }) - } - - func saveAssets(_ assets:[DomainLayer.DTO.Asset], by accountAddress: String) -> Observable { - assertMethodDontSupported() - return Observable.never() - } - - func saveAsset(_ asset: DomainLayer.DTO.Asset, by accountAddress: String) -> Observable { - assertMethodDontSupported() - return Observable.never() - } - - func isSmartAsset(_ assetId: String, by accountAddress: String) -> Observable { - - if assetId == WavesSDKCryptoConstants.wavesAssetId { - return Observable.just(false) - } - - let environment = environmentRepository.accountEnvironment(accountAddress: accountAddress) - - return environment - .flatMap { [weak self] environment -> Single in - - guard let self = self else { return Single.never() } - return self - .assetNodeProvider - .rx - .request(.init(kind: .details(assetId: assetId), environment: environment), - callbackQueue: DispatchQueue.global(qos: .userInteractive)) - } - .filterSuccessfulStatusAndRedirectCodes() - .catchError({ (error) -> Observable in - return Observable.error(NetworkError.error(by: error)) - }) - .map(Node.DTO.AssetDetail.self) - .map { $0.scripted == true } - } -} - -fileprivate extension Environment { - - func hashMapAssets() -> [String: Environment.AssetInfo] { - - var allAssets = generalAssets - if let additionalAssets = assets { - allAssets.append(contentsOf: additionalAssets) - } - - return allAssets.reduce([String: Environment.AssetInfo](), { map, info -> [String: Environment.AssetInfo] in - var new = map - new[info.assetId] = info - return new - }) - } - - func hashMapGeneralAssets() -> [String: Environment.AssetInfo] { - - var allAssets = generalAssets - - return allAssets.reduce([String: Environment.AssetInfo](), { map, info -> [String: Environment.AssetInfo] in - var new = map - new[info.assetId] = info - return new - }) - } -} - -fileprivate extension DomainLayer.DTO.Asset { - - init(asset: API.DTO.Asset, info: Environment.AssetInfo?, isSpam: Bool, isMyWavesToken: Bool, isGeneral: Bool) { - self.ticker = asset.ticker - self.id = asset.id - self.wavesId = info?.wavesId - self.gatewayId = info?.gatewayId - self.precision = asset.precision - self.description = asset.description - self.height = asset.height - self.timestamp = asset.timestamp - self.sender = asset.sender - self.quantity = asset.quantity - self.isReusable = asset.reissuable - self.isSpam = isSpam - self.isMyWavesToken = isMyWavesToken - self.modified = Date() - var isWaves = false - var isFiat = false - let isGateway = info?.isGateway ?? false - var name = asset.name - - //TODO: Current code need move to AssetsInteractor! - if let info = info { - if info.assetId == WavesSDKCryptoConstants.wavesAssetId { - isWaves = true - } - - name = info.displayName - isFiat = info.isFiat - } - - self.isWavesToken = isFiat == false && isGateway == false && isWaves == false - self.isGeneral = isGeneral - self.isWaves = isWaves - self.isFiat = isFiat - self.isGateway = isGateway - self.displayName = name - self.addressRegEx = info?.addressRegEx ?? "" - self.iconLogoUrl = info?.iconUrls?.default - self.hasScript = asset.hasScript - self.minSponsoredFee = asset.minSponsoredFee ?? 0 - } -} diff --git a/WavesWallet-iOS/DataLayer/Repositories/BlockRepositoryRemote.swift b/WavesWallet-iOS/DataLayer/Repositories/BlockRepositoryRemote.swift deleted file mode 100644 index 76f79c4e..00000000 --- a/WavesWallet-iOS/DataLayer/Repositories/BlockRepositoryRemote.swift +++ /dev/null @@ -1,41 +0,0 @@ -// -// BlockRepositoryRemote.swift -// WavesWallet-iOS -// -// Created by mefilt on 10.09.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import RxSwift -import Moya - -final class BlockRepositoryRemote: BlockRepositoryProtocol { - - private let environmentRepository: EnvironmentRepositoryProtocol - private let blockNode: MoyaProvider = .nodeMoyaProvider() - - init(environmentRepository: EnvironmentRepositoryProtocol) { - self.environmentRepository = environmentRepository - } - - func height(accountAddress: String) -> Observable { - - return environmentRepository - .accountEnvironment(accountAddress: accountAddress) - .flatMap({ [weak self] environment -> Single in - guard let self = self else { return Single.never() } - return self - .blockNode - .rx - .request(Node.Service.Blocks(environment: environment, - kind: .height)) - }) - .filterSuccessfulStatusAndRedirectCodes() - .catchError({ (error) -> Observable in - return Observable.error(NetworkError.error(by: error)) - }) - .map(Node.DTO.Block.self) - .map { $0.height } - } -} diff --git a/WavesWallet-iOS/DataLayer/Repositories/Dex/CandlesRepositoryRemote.swift b/WavesWallet-iOS/DataLayer/Repositories/Dex/CandlesRepositoryRemote.swift deleted file mode 100644 index ff317015..00000000 --- a/WavesWallet-iOS/DataLayer/Repositories/Dex/CandlesRepositoryRemote.swift +++ /dev/null @@ -1,83 +0,0 @@ -// -// CandlesRepositoryProtocol.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 12/5/18. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import RxSwift -import Moya - -final class CandlesRepositoryRemote: CandlesRepositoryProtocol { - - private let apiProvider: MoyaProvider = .nodeMoyaProvider() - private let environmentRepository: EnvironmentRepositoryProtocol - - init(environmentRepository: EnvironmentRepositoryProtocol) { - self.environmentRepository = environmentRepository - } - - func candles(accountAddress: String, amountAsset: String, priceAsset: String, timeStart: Date, timeEnd: Date, timeFrame: DomainLayer.DTO.Candle.TimeFrameType) -> Observable<[DomainLayer.DTO.Candle]> { - - return environmentRepository.accountEnvironment(accountAddress: accountAddress) - .flatMap({ [weak self] (environment) -> Observable<[DomainLayer.DTO.Candle]> in - - guard let self = self else { return Observable.empty() } - - let filters = API.Query.CandleFilters(timeStart: timeStart.millisecondsSince1970(timestampDiff: environment.timestampServerDiff), - timeEnd: timeEnd.millisecondsSince1970(timestampDiff: environment.timestampServerDiff), - interval: String(timeFrame.rawValue) + "m") - - let candles = API.Service.Candles(amountAsset: amountAsset, - priceAsset: priceAsset, - params: filters, - environment: environment) - - return self.apiProvider.rx - .request(candles, callbackQueue: DispatchQueue.global(qos: .userInteractive)) - .filterSuccessfulStatusAndRedirectCodes() - .map(API.DTO.Chart.self) - .asObservable() - .map({ (chart) -> [DomainLayer.DTO.Candle] in - - var models: [DomainLayer.DTO.Candle] = [] - - for model in chart.candles { - - guard let volume = model.volume, - let high = model.high, - let low = model.low, - let open = model.open, - let close = model.close else { - continue - } - - if volume > 0 { - let timestamp = self.convertTimestamp(model.time, timeFrame: timeFrame) - - let model = DomainLayer.DTO.Candle(close: close, - high: high, - low: low, - open: open, - timestamp: timestamp, - volume: volume) - models.append(model) - } - } - - return models - }) - }) - } -} - -private extension CandlesRepositoryRemote { - - func convertTimestamp(_ timestamp: Int64, timeFrame: DomainLayer.DTO.Candle.TimeFrameType) -> Double { - return Double(timestamp / Int64(1000 * 60 * timeFrame.rawValue)) - } -} - - diff --git a/WavesWallet-iOS/DataLayer/Repositories/Dex/DexOrderBookRepositoryRemote.swift b/WavesWallet-iOS/DataLayer/Repositories/Dex/DexOrderBookRepositoryRemote.swift deleted file mode 100644 index 9858ef60..00000000 --- a/WavesWallet-iOS/DataLayer/Repositories/Dex/DexOrderBookRepositoryRemote.swift +++ /dev/null @@ -1,247 +0,0 @@ -// -// DexOrderBookRepositoryRemote.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 12/17/18. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import RxSwift -import Moya -import RealmSwift - -final class DexOrderBookRepositoryRemote: DexOrderBookRepositoryProtocol { - - private let matcherProvider: MoyaProvider = .nodeMoyaProvider() - private let spamProvider: MoyaProvider = .nodeMoyaProvider() - private let environmentRepository: EnvironmentRepositoryProtocol - - init(environmentRepository: EnvironmentRepositoryProtocol) { - self.environmentRepository = environmentRepository - } - - func orderBook(wallet: DomainLayer.DTO.SignedWallet, amountAsset: String, priceAsset: String) -> Observable { - - return environmentRepository.accountEnvironment(accountAddress: wallet.address) - .flatMap({ [weak self] (environment) -> Observable in - guard let self = self else { return Observable.empty() } - - let decoder = JSONDecoder() - decoder.dateDecodingStrategy = .custom { decoder in - return Date(timestampDecoder: decoder, timestampDiff: environment.timestampServerDiff) - } - - - return self.matcherProvider.rx - .request(.init(kind: .getOrderBook(amountAsset: amountAsset, priceAsset: priceAsset), - environment: environment), - callbackQueue: DispatchQueue.global(qos: .userInteractive)) - .filterSuccessfulStatusAndRedirectCodes() - .map(Matcher.DTO.OrderBook.self, atKeyPath: nil, using: decoder, failsOnEmptyData: false) - .asObservable() - .flatMap({ (orderBook) -> Observable in - - let bids = orderBook.bids.map { DomainLayer.DTO.Dex.OrderBook.Value(amount: $0.amount, - price: $0.price)} - - let asks = orderBook.asks.map { DomainLayer.DTO.Dex.OrderBook.Value(amount: $0.amount, - price: $0.price)} - - return Observable.just(DomainLayer.DTO.Dex.OrderBook(bids: bids, asks: asks)) - }) - }) - } - - func markets(wallet: DomainLayer.DTO.SignedWallet) -> Observable<[DomainLayer.DTO.Dex.SmartPair]> { - - return environmentRepository.accountEnvironment(accountAddress: wallet.address) - .flatMap({ [weak self] (environment) -> Observable<[Matcher.DTO.Market]> in - guard let self = self else { return Observable.empty() } - - let markets = self.matcherProvider.rx - .request(.init(kind: .getMarket, environment: environment), - callbackQueue: DispatchQueue.global(qos: .userInteractive)) - .filterSuccessfulStatusAndRedirectCodes() - .map(Matcher.DTO.MarketResponse.self) - .asObservable() - .map { $0.markets } - - return Observable.zip(markets, self.spamList(accountAddress: wallet.address)) - .map({ (markets, spamList) -> [Matcher.DTO.Market] in - - var filterMarkets: [Matcher.DTO.Market] = [] - let spamListKeys = spamList.reduce(into: [String : String](), { $0[$1] = $1}) - - for market in markets { - if spamListKeys[market.amountAsset] == nil && - spamListKeys[market.priceAsset] == nil { - filterMarkets.append(market) - } - } - - return filterMarkets - }) - }) - .map({ [weak self] (markets) -> [DomainLayer.DTO.Dex.SmartPair] in - guard let self = self else { return [] } - - //TODO: Remove Realm from remote repository - guard let realm = try? WalletRealmFactory.realm(accountAddress: wallet.address) else { - return [] - } - - var pairs: [DomainLayer.DTO.Dex.SmartPair] = [] - for market in markets { - pairs.append(DomainLayer.DTO.Dex.SmartPair(market, realm: realm)) - } - pairs = self.sort(pairs: pairs, realm: realm) - - return pairs - }) - } - - - func myOrders(wallet: DomainLayer.DTO.SignedWallet, amountAsset: DomainLayer.DTO.Dex.Asset, priceAsset: DomainLayer.DTO.Dex.Asset) -> Observable<[DomainLayer.DTO.Dex.MyOrder]> { - - return environmentRepository.accountEnvironment(accountAddress: wallet.address) - .flatMap({ [weak self] (environment) -> Observable<[DomainLayer.DTO.Dex.MyOrder]> in - guard let self = self else { return Observable.empty() } - - let decoder = JSONDecoder() - decoder.dateDecodingStrategy = .custom { decoder in - return Date(timestampDecoder: decoder, timestampDiff: environment.timestampServerDiff) - } - - return self.matcherProvider.rx - .request(.init(kind: .getMyOrders(amountAsset: amountAsset.id, - priceAsset: priceAsset.id, - signature: TimestampSignature(signedWallet: wallet, environment: environment)), - environment: environment), - callbackQueue: DispatchQueue.global(qos: .userInteractive)) - .filterSuccessfulStatusAndRedirectCodes() - .map([Matcher.DTO.Order].self, atKeyPath: nil, using: decoder, failsOnEmptyData: false) - .asObservable() - .map({ (orders) -> [DomainLayer.DTO.Dex.MyOrder] in - - var myOrders: [DomainLayer.DTO.Dex.MyOrder] = [] - - for order in orders { - myOrders.append(DomainLayer.DTO.Dex.MyOrder(order, - priceAsset: priceAsset, - amountAsset: amountAsset)) - - } - return myOrders - }) - }) - } - - func cancelOrder(wallet: DomainLayer.DTO.SignedWallet, orderId: String, amountAsset: String, priceAsset: String) -> Observable { - - return environmentRepository.accountEnvironment(accountAddress: wallet.address) - .flatMap({ [weak self] (environment) -> Observable in - guard let self = self else { return Observable.empty() } - - return self.matcherProvider.rx - .request(.init(kind: .cancelOrder(.init(wallet: wallet, - orderId: orderId, - amountAsset: amountAsset, - priceAsset: priceAsset)), - environment: environment), - callbackQueue: DispatchQueue.global(qos: .userInteractive)) - .filterSuccessfulStatusAndRedirectCodes() - .asObservable() - .catchError({ (error) -> Observable in - return Observable.error(NetworkError.error(by: error)) - }) - .map { _ in true } - }) - } - - func createOrder(wallet: DomainLayer.DTO.SignedWallet, order: DomainLayer.Query.Dex.CreateOrder) -> Observable { - - return environmentRepository.accountEnvironment(accountAddress: wallet.address) - .flatMap({ [weak self] (environment) -> Observable in - - guard let self = self else { return Observable.empty() } - - return self.matcherProvider.rx - .request(.init(kind: .createOrder(order), - environment: environment), - callbackQueue: DispatchQueue.global(qos: .userInteractive)) - .filterSuccessfulStatusAndRedirectCodes() - .asObservable() - .map { _ in true } - - }) - } -} - -//MARK: - SpamList -private extension DexOrderBookRepositoryRemote { - - func spamList(accountAddress: String) -> Observable<[String]> { - - return environmentRepository.accountEnvironment(accountAddress: accountAddress) - .flatMap({ [weak self] (environment) -> Observable<[String]> in - guard let self = self else { return Observable.empty() } - - return self.spamProvider.rx - .request(.getSpamList(hasProxy: true), - callbackQueue: DispatchQueue.global(qos: .userInteractive)) - .catchError({ [weak self] (_) -> PrimitiveSequence in - guard let self = self else { return Single.never() } - return self.spamProvider - .rx - .request(.getSpamList(hasProxy: false)) - }) - .filterSuccessfulStatusAndRedirectCodes() - .asObservable() - .map({ (response) -> [String] in - return (try? SpamCVC.addresses(from: response.data)) ?? [] - }) - .catchError({ (error) -> Observable<[String]> in - return Observable.just([]) - }) - }) - } -} - - -//MARK: - Markets Sort -private extension DexOrderBookRepositoryRemote { - - func sort(pairs: [DomainLayer.DTO.Dex.SmartPair], realm: Realm) -> [DomainLayer.DTO.Dex.SmartPair] { - - var sortedPairs: [DomainLayer.DTO.Dex.SmartPair] = [] - - let generalBalances = realm - .objects(Asset.self) - .filter(NSPredicate(format: "isGeneral == true")) - .toArray() - .reduce(into: [String: Asset](), { $0[$1.id] = $1 }) - - let settingsList = realm - .objects(AssetBalanceSettings.self) - .toArray() - .filter { (asset) -> Bool in - return generalBalances[asset.assetId]?.isGeneral == true - } - .sorted(by: { $0.sortLevel < $1.sortLevel }) - - for settings in settingsList { - sortedPairs.append(contentsOf: pairs.filter({$0.amountAsset.id == settings.assetId && $0.isGeneral == true })) - } - - var sortedIds = sortedPairs.map {$0.id} - sortedPairs.append(contentsOf: pairs.filter { $0.isGeneral == true && !sortedIds.contains($0.id) } ) - - sortedIds = sortedPairs.map {$0.id} - sortedPairs.append(contentsOf: pairs.filter { !sortedIds.contains($0.id) } ) - - return sortedPairs - } -} - - diff --git a/WavesWallet-iOS/DataLayer/Repositories/Dex/DexPairsPriceRepositoryRemote.swift b/WavesWallet-iOS/DataLayer/Repositories/Dex/DexPairsPriceRepositoryRemote.swift deleted file mode 100644 index 09ddd644..00000000 --- a/WavesWallet-iOS/DataLayer/Repositories/Dex/DexPairsPriceRepositoryRemote.swift +++ /dev/null @@ -1,56 +0,0 @@ -// -// DexListRepositoryRemote.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 12/17/18. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import RxSwift -import Moya - -final class DexPairsPriceRepositoryRemote: DexPairsPriceRepositoryProtocol { - - private let apiProvider: MoyaProvider = .nodeMoyaProvider() - private let environmentRepository: EnvironmentRepositoryProtocol - - init(environmentRepository: EnvironmentRepositoryProtocol) { - self.environmentRepository = environmentRepository - } - - func list(by accountAddress: String, pairs: [DomainLayer.DTO.Dex.Pair]) -> Observable<[DomainLayer.DTO.Dex.PairPrice]> { - - return environmentRepository.accountEnvironment(accountAddress: accountAddress) - .flatMap({ [weak self] (environment) -> Observable<[DomainLayer.DTO.Dex.PairPrice]> in - guard let self = self else { return Observable.empty() } - return self.apiProvider.rx - .request(.init(pairs: pairs, environment: environment), - callbackQueue: DispatchQueue.global(qos: .userInteractive)) - .filterSuccessfulStatusAndRedirectCodes() - .map(API.Response<[API.OptionalResponse]>.self) - .map { $0.data.map {$0.data ?? .empty}} - .map({ (list) -> [DomainLayer.DTO.Dex.PairPrice] in - - var listPairs: [DomainLayer.DTO.Dex.PairPrice] = [] - - for (index, pair) in list.enumerated() { - let localPair = pairs[index] - - let priceAsset = localPair.priceAsset - let firstPrice = Money(value: Decimal(pair.firstPrice), priceAsset.decimals) - let lastPrice = Money(value: Decimal(pair.lastPrice), priceAsset.decimals) - - let pair = DomainLayer.DTO.Dex.PairPrice(firstPrice: firstPrice, - lastPrice: lastPrice, - amountAsset: localPair.amountAsset, - priceAsset: priceAsset) - listPairs.append(pair) - } - - return listPairs - }) - .asObservable() - }) - } -} diff --git a/WavesWallet-iOS/DataLayer/Repositories/Dex/LastTradesRepositoryRemote.swift b/WavesWallet-iOS/DataLayer/Repositories/Dex/LastTradesRepositoryRemote.swift deleted file mode 100644 index 3d3e2ae2..00000000 --- a/WavesWallet-iOS/DataLayer/Repositories/Dex/LastTradesRepositoryRemote.swift +++ /dev/null @@ -1,71 +0,0 @@ -// -// LastTradesRepository.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 12/5/18. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import RxSwift -import Moya - -final class LastTradesRepositoryRemote: LastTradesRepositoryProtocol { - - private let apiProvider: MoyaProvider = .nodeMoyaProvider() - private let environmentRepository: EnvironmentRepositoryProtocol - - init(environmentRepository: EnvironmentRepositoryProtocol) { - self.environmentRepository = environmentRepository - } - - func lastTrades(accountAddress: String, amountAsset: DomainLayer.DTO.Dex.Asset, priceAsset: DomainLayer.DTO.Dex.Asset, limit: Int) -> Observable<[DomainLayer.DTO.Dex.LastTrade]> { - - return environmentRepository.accountEnvironment(accountAddress: accountAddress) - .flatMap({ [weak self] (environment) -> Observable<[DomainLayer.DTO.Dex.LastTrade]> in - guard let self = self else { return Observable.empty() } - - let decoder = JSONDecoder() - decoder.dateDecodingStrategy = .custom { decoder in - return Date(isoDecoder: decoder, timestampDiff: environment.timestampServerDiff) - } - let filters = API.Query.ExchangeFilters(matcher: nil, - sender: nil, - timeStart: nil, - timeEnd: nil, - amountAsset: amountAsset.id, - priceAsset: priceAsset.id, - after: nil, - limit: limit) - - return self - .apiProvider - .rx - .request(.init(kind: .getExchangeWithFilters(filters), - environment: environment), - callbackQueue: DispatchQueue.global(qos: .userInteractive)) - .filterSuccessfulStatusAndRedirectCodes() - .asObservable() - .map(API.Response<[API.Response]>.self, atKeyPath: nil, using: decoder, failsOnEmptyData: false) - .map { $0.data.map { $0.data } } - .flatMap({ (transactions) -> Observable<[DomainLayer.DTO.Dex.LastTrade]> in - - var trades: [DomainLayer.DTO.Dex.LastTrade] = [] - for tx in transactions { - - let sum = Money(value: Decimal(tx.price * tx.amount), priceAsset.decimals) - let orderType: DomainLayer.DTO.Dex.OrderType = tx.orderType == .sell ? .sell : .buy - - let model = DomainLayer.DTO.Dex.LastTrade(time: tx.timestamp, - price: Money(value: Decimal(tx.price), priceAsset.decimals), - amount: Money(value: Decimal(tx.amount), amountAsset.decimals), - sum: sum, - type: orderType) - trades.append(model) - } - - return Observable.just(trades) - }) - }) - } -} diff --git a/WavesWallet-iOS/DataLayer/Repositories/Dex/MatcherRepositoryRemote.swift b/WavesWallet-iOS/DataLayer/Repositories/Dex/MatcherRepositoryRemote.swift deleted file mode 100644 index 492b4872..00000000 --- a/WavesWallet-iOS/DataLayer/Repositories/Dex/MatcherRepositoryRemote.swift +++ /dev/null @@ -1,47 +0,0 @@ -// -// MatcherRepositoryRemote.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 12/26/18. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import RxSwift -import Moya -import Base58 -import WavesSDKCrypto - -final class MatcherRepositoryRemote: MatcherRepositoryProtocol { - - private let matcherProvider: MoyaProvider = .nodeMoyaProvider() - private let environmentRepository: EnvironmentRepositoryProtocol - - init(environmentRepository: EnvironmentRepositoryProtocol) { - self.environmentRepository = environmentRepository - } - - func matcherPublicKey(accountAddress: String) -> Observable { - - return environmentRepository.accountEnvironment(accountAddress: accountAddress) - .flatMap({ [weak self] (environment) -> Observable in - guard let self = self else { return Observable.empty() } - - return self.matcherProvider.rx - .request(.init(environment: environment), - callbackQueue: DispatchQueue.global(qos: .userInteractive)) - .filterSuccessfulStatusAndRedirectCodes() - .asObservable() - .flatMap({ (response) -> Observable in - - do { - let key = try JSONSerialization.jsonObject(with: response.data, options: .allowFragments) as? String ?? "" - return Observable.just(PublicKeyAccount(publicKey: Base58.decode(key))) - } - catch let error { - return Observable.error(error) - } - }) - }) - } -} diff --git a/WavesWallet-iOS/DataLayer/Repositories/EnvironmentRepository.swift b/WavesWallet-iOS/DataLayer/Repositories/EnvironmentRepository.swift deleted file mode 100644 index b2c5feba..00000000 --- a/WavesWallet-iOS/DataLayer/Repositories/EnvironmentRepository.swift +++ /dev/null @@ -1,301 +0,0 @@ -// -// EnvironmentRepositoryRemote.swift -// WavesWallet-iOS -// -// Created by mefilt on 18/10/2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import Moya -import RealmSwift -import RxRealm -import RxSwift -import WavesSDKExtension -import WavesSDKCrypto - -private enum Constants { - static let minServerTimestampDiff: Int64 = 1000 * 30 -} - -private struct EnvironmentKey: Hashable { - let accountAddress: String - let isTestNet: Bool -} - -final class EnvironmentRepository: EnvironmentRepositoryProtocol { - - private var isValidServerTimestampDiff = false - private let environmentRepository: MoyaProvider = .nodeMoyaProvider() - private let spamProvider: MoyaProvider = .nodeMoyaProvider() - - private var localEnvironments: BehaviorSubject<[EnvironmentKey: Environment]> = BehaviorSubject<[EnvironmentKey: Environment]>(value: [:]) - - private let utilsProvider: MoyaProvider = .nodeMoyaProvider() - - init() { - NotificationCenter.default.addObserver(self, selector: #selector(timeDidChange), name: UIApplication.significantTimeChangeNotification, object: nil) - } - - func deffaultEnvironment(accountAddress: String) -> Observable { - return remoteEnvironment(accountAddress: accountAddress) - } - - func accountEnvironment(accountAddress: String) -> Observable { - - var deffaultEnvironment: Observable! - - if let enviroment = localEnvironment(by: .init(accountAddress: accountAddress, isTestNet: Environment.isTestNet)), - isValidServerTimestampDiff { - deffaultEnvironment = Observable.just(enviroment) - } else { - deffaultEnvironment = remoteEnvironment(accountAddress: accountAddress) - } - - let accountEnvironment = self.localAccountEnvironment(accountAddress: accountAddress) - - return Observable - .zip(deffaultEnvironment, accountEnvironment) - .flatMap(weak: self, selector: { (owner, environments) -> Observable in - - let environment: Environment = owner.merge(environment: environments.0, with: environments.1) - return Observable.just(environment) - }) - .do(onNext: { [weak self] environment in - - guard let self = self else { - return - } - - let key = EnvironmentKey(accountAddress: accountAddress, isTestNet: Environment.isTestNet) - - if let value = try? self.localEnvironments.value() { - var newValue = value - newValue[key] = environment - self.localEnvironments.onNext(newValue) - } else { - self.localEnvironments.onNext([key: environment]) - } - }) - } - - private func remoteEnvironment(accountAddress: String) -> Observable { - - //TODO: function call 6 times, after user input passcode - return environmentRepository - .rx - .request(.get(isTestNet: Environment.isTestNet, hasProxy: true)) - .catchError({ [weak self] (_) -> PrimitiveSequence in - guard let self = self else { return Single.never() } - return self - .environmentRepository - .rx - .request(.get(isTestNet: Environment.isTestNet, hasProxy: false)) - }) - .map(Environment.self) - .catchError { error -> Single in - return Single.just(Environment.current) - } - .asObservable() - .flatMap({ [weak self] (environment) -> Observable in - guard let self = self else { return Observable.empty() } - return self.updateTimestampServerDiff(environment: environment) - }) - } - - func setSpamURL(_ url: String, by accountAddress: String) -> Observable { - return Observable.create({ [weak self] (observer) -> Disposable in - - guard let self = self else { - return Disposables.create() - } - - guard url.isValidUrl else { - observer.onError(EnvironmentRepositoryError.invalidURL) - return Disposables.create() - } - - guard let link = URL(string: url) else { - observer.onError(EnvironmentRepositoryError.invalidURL) - return Disposables.create() - } - - let disposable = self.spamProvider - .rx - .request(.getSpamList(hasProxy: true)) - .catchError({ [weak self] (_) -> PrimitiveSequence in - guard let self = self else { return Single.never() } - return self.spamProvider - .rx - .request(.getSpamListByUrl(url: link)) - }) - .flatMap({ response -> Single in - - do { - _ = try SpamCVC.addresses(from: response.data) - return Single.just(true) - } catch _ { - return Single.error(EnvironmentRepositoryError.invalidResponse) - } - }) - .asObservable() - .flatMap({ [weak self] _ -> Observable in - - guard let self = self else { - return Observable.never() - } - return self.localAccountEnvironment(accountAddress: accountAddress) - }) - .flatMap({ [weak self] account -> Observable in - - guard let self = self else { - return Observable.never() - } - - var newAccount = account ?? DomainLayer.DTO.AccountEnvironment() - newAccount.spamUrl = url - - return self.saveAccountEnvironment(newAccount, accountAddress: accountAddress) - }) - .subscribe(observer) - - return Disposables.create([disposable]) - }) - .sweetDebug("setURL") - } - - private func localEnvironment(by key: EnvironmentKey) -> Environment? { - - if let value = try? localEnvironments.value() { - return value[key] - } - - return nil - } - - private func localAccountEnvironment(accountAddress: String) -> Observable { - return Observable.create { observer -> Disposable in - - //TODO: Error - let realm = try! WalletRealmFactory.realm(accountAddress: accountAddress) - - let result = realm.objects(AccountEnvironment.self) - - guard let environment = result.toArray().first else { - observer.onNext(nil) - observer.onCompleted() - return Disposables.create() - } - - observer.onNext(.init(nodeUrl: environment.nodeUrl, - dataUrl: environment.dataUrl, - spamUrl: environment.spamUrl, - matcherUrl: environment.matcherUrl)) - observer.onCompleted() - - return Disposables.create() - } - } - - private func saveAccountEnvironment(_ accountEnvironment: DomainLayer.DTO.AccountEnvironment, accountAddress: String) -> Observable { - return Observable.create { observer -> Disposable in - - //TODO: Error - let realm = try! WalletRealmFactory.realm(accountAddress: accountAddress) - - try? realm.write { - realm - .objects(AccountEnvironment.self) - .toArray() - .forEach({ account in - account.realm?.delete(account) - }) - let environment = AccountEnvironment() - environment.dataUrl = accountEnvironment.dataUrl - environment.matcherUrl = accountEnvironment.matcherUrl - environment.nodeUrl = accountEnvironment.nodeUrl - environment.spamUrl = accountEnvironment.spamUrl - realm.add(environment, update: false) - } - observer.onNext(true) - observer.onCompleted() - - return Disposables.create() - } - } - - func merge(environment: Environment, with accountEnvironment: DomainLayer.DTO.AccountEnvironment?) -> Environment { - - var servers: Environment.Servers! - - if let accountEnvironmet = accountEnvironment { - - var dataUrl: URL! - var matcherUrl: URL! - var nodeUrl: URL! - var spamUrl: URL! - - if let data = accountEnvironmet.dataUrl { - dataUrl = URL(string: data) - } - - if let matcher = accountEnvironmet.matcherUrl { - matcherUrl = URL(string: matcher) - } - - if let node = accountEnvironmet.nodeUrl { - nodeUrl = URL(string: node) - } - - if let spam = accountEnvironmet.spamUrl { - spamUrl = URL(string: spam) - } - - dataUrl = dataUrl ?? environment.servers.dataUrl - matcherUrl = matcherUrl ?? environment.servers.matcherUrl - nodeUrl = nodeUrl ?? environment.servers.nodeUrl - spamUrl = spamUrl ?? environment.servers.spamUrl - - servers = .init(nodeUrl: nodeUrl, - dataUrl: dataUrl, - spamUrl: spamUrl, - matcherUrl: matcherUrl) - } else { - servers = environment.servers - } - - return Environment(name: environment.name, - servers: servers, - scheme: environment.scheme, - generalAssets: environment.generalAssets, - assets: environment.assets) - } -} - -private extension EnvironmentRepository { - - @objc func timeDidChange() { - isValidServerTimestampDiff = false - } - - func updateTimestampServerDiff(environment: Environment) -> Observable { - - return utilsProvider.rx.request(.init(environment: environment, kind: .time), - callbackQueue: DispatchQueue.global(qos: .userInteractive)) - .map(Node.DTO.Utils.Time.self) - .asObservable() - .flatMap({ [weak self] (time) -> Observable in - - guard let self = self else { return Observable.empty() } - self.isValidServerTimestampDiff = true - - let localTimestamp = Int64(Date().timeIntervalSince1970 * 1000) - let diff = localTimestamp - time.NTP - let timestamp = abs(diff) > Constants.minServerTimestampDiff ? diff : 0 - - Environment.updateTimestampServerDiff(timestamp) - - return Observable.just(environment) - }) - } -} diff --git a/WavesWallet-iOS/DataLayer/Repositories/Transactions/TransactionsRepositoryRemote.swift b/WavesWallet-iOS/DataLayer/Repositories/Transactions/TransactionsRepositoryRemote.swift deleted file mode 100644 index ed65374b..00000000 --- a/WavesWallet-iOS/DataLayer/Repositories/Transactions/TransactionsRepositoryRemote.swift +++ /dev/null @@ -1,549 +0,0 @@ -// -// TransactionsRepositoryRemote.swift -// WavesWallet-iOS -// -// Created by mefilt on 30.08.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import RxSwift -import Moya -import CryptoSwift -import Base58 -import WavesSDKExtension -import WavesSDKCrypto - -fileprivate enum Constants { - static let maxLimit: Int = 10000 -} - -extension TransactionSenderSpecifications { - - var version: Int { - switch self { - case .createAlias: - return 2 - - case .lease: - return 2 - - case .burn: - return 2 - - case .cancelLease: - return 2 - - case .data: - return 1 - - case .send: - return 2 - } - } - - var type: TransactionType { - switch self { - case .createAlias: - return TransactionType.alias - - case .lease: - return TransactionType.lease - - case .burn: - return TransactionType.burn - - case .cancelLease: - return TransactionType.leaseCancel - - case .data: - return TransactionType.data - - case .send: - return TransactionType.transfer - } - } -} - -final class TransactionsRepositoryRemote: TransactionsRepositoryProtocol { - - private let transactions: MoyaProvider = .nodeMoyaProvider() - private let leasingProvider: MoyaProvider = .nodeMoyaProvider() - private let transactionRules: MoyaProvider = .nodeMoyaProvider() - - private let environmentRepository: EnvironmentRepositoryProtocol - - init(environmentRepository: EnvironmentRepositoryProtocol) { - self.environmentRepository = environmentRepository - } - - func transactions(by address: DomainLayer.DTO.Address, offset: Int, limit: Int) -> Observable<[DomainLayer.DTO.AnyTransaction]> { - - return environmentRepository - .accountEnvironment(accountAddress: address.address) - .flatMap { [weak self] environment -> Observable<[DomainLayer.DTO.AnyTransaction]> in - - guard let self = self else { return Observable.never() } - - let limit = min(Constants.maxLimit, offset + limit) - - let decoder = JSONDecoder() - decoder.dateDecodingStrategy = .custom { decoder in - return Date(timestampDecoder: decoder, timestampDiff: environment.timestampServerDiff) - } - - return self - .transactions - .rx - .request(.init(kind: .list(accountAddress: address.address, - limit: limit), - environment: environment), - callbackQueue: DispatchQueue.global(qos: .userInteractive)) - .filterSuccessfulStatusAndRedirectCodes() - .catchError({ (error) -> Single in - return Single.error(NetworkError.error(by: error)) - }) - .map(Node.DTO.TransactionContainers.self, atKeyPath: nil, using: decoder, failsOnEmptyData: false) - .map { $0.anyTransactions(status: .completed, environment: environment) } - .asObservable() - } - } - - func activeLeasingTransactions(by accountAddress: String) -> Observable<[DomainLayer.DTO.LeaseTransaction]> { - - return environmentRepository - .accountEnvironment(accountAddress: accountAddress) - .flatMap { [weak self] environment -> Observable<[DomainLayer.DTO.LeaseTransaction]> in - - guard let self = self else { return Observable.never() } - - let decoder = JSONDecoder() - decoder.dateDecodingStrategy = .custom { decoder in - return Date(timestampDecoder: decoder, timestampDiff: environment.timestampServerDiff) - } - - return self - .leasingProvider - .rx - .request(.init(kind: .getActive(accountAddress: accountAddress), - environment: environment), - callbackQueue: DispatchQueue.global(qos: .userInteractive)) - .filterSuccessfulStatusAndRedirectCodes() - .catchError({ (error) -> Single in - return Single.error(NetworkError.error(by: error)) - }) - .map([Node.DTO.LeaseTransaction].self, atKeyPath: nil, using: decoder, failsOnEmptyData: false) - .map { $0.map { tx in - return DomainLayer.DTO.LeaseTransaction(transaction: tx, status: .activeNow, environment: environment) - } - } - .asObservable() - } - } - - func send(by specifications: TransactionSenderSpecifications, wallet: DomainLayer.DTO.SignedWallet) -> Observable { - - return environmentRepository - .accountEnvironment(accountAddress: wallet.address) - .flatMap { [weak self] environment -> Observable in - - let timestamp = Date().millisecondsSince1970(timestampDiff: environment.timestampServerDiff) - var signature = specifications.signature(timestamp: timestamp, - scheme: environment.scheme, - publicKey: wallet.publicKey.publicKey) - - do { - signature = try wallet.sign(input: signature, kind: [.none]) - } catch let e { - SweetLogger.error(e) - return Observable.error(TransactionsInteractorError.invalid) - } - - let proofs = [Base58.encode(signature)] - - let broadcastSpecification = specifications.broadcastSpecification(timestamp: timestamp, - environment: environment, - publicKey: wallet.publicKey.getPublicKeyStr(), - proofs: proofs) - guard let self = self else { return Observable.never() } - - let decoder = JSONDecoder() - decoder.dateDecodingStrategy = .custom { decoder in - return Date(timestampDecoder: decoder, timestampDiff: environment.timestampServerDiff) - } - - return self - .transactions - .rx - .request(.init(kind: .broadcast(broadcastSpecification), - environment: environment), - callbackQueue: DispatchQueue.global(qos: .userInteractive)) - .filterSuccessfulStatusAndRedirectCodes() - .catchError({ (error) -> Single in - return Single.error(NetworkError.error(by: error)) - }) - .map(Node.DTO.Transaction.self, atKeyPath: nil, using: decoder, failsOnEmptyData: false) - .map({ $0.anyTransaction(status: .unconfirmed, environment: environment) }) - .asObservable() - } - } - -// MARK - - Dont support - func newTransactions(by address: DomainLayer.DTO.Address, - specifications: TransactionsSpecifications) -> Observable<[DomainLayer.DTO.AnyTransaction]> { - assertMethodDontSupported() - return Observable.never() - } - - func transactions(by address: DomainLayer.DTO.Address, - specifications: TransactionsSpecifications) -> Observable<[DomainLayer.DTO.AnyTransaction]> { - assertMethodDontSupported() - return Observable.never() - } - - func saveTransactions(_ transactions: [DomainLayer.DTO.AnyTransaction], accountAddress: String) -> Observable { - assertMethodDontSupported() - return Observable.never() - } - - - func isHasTransactions(by accountAddress: String, ignoreUnconfirmed: Bool) -> Observable { - assertMethodDontSupported() - return Observable.never() - } - - func isHasTransaction(by id: String, accountAddress: String, ignoreUnconfirmed: Bool) -> Observable { - assertMethodDontSupported() - return Observable.never() - } - - func isHasTransactions(by ids: [String], accountAddress: String, ignoreUnconfirmed: Bool) -> Observable { - assertMethodDontSupported() - return Observable.never() - } - - func feeRules() -> Observable { - return transactionRules - .rx - .request(.get(hasProxy: true)) - .catchError({ [weak self] (_) -> PrimitiveSequence in - guard let self = self else { return Single.never() } - return self - .transactionRules - .rx - .request(.get(hasProxy: false)) - }) - .map(GitHub.DTO.TransactionFeeRules.self) - .asObservable() - .map({ (txRules) -> DomainLayer.DTO.TransactionFeeRules in - - let deffault = txRules.calculate_fee_rules[TransactionFeeDefaultRule] - - let rules = TransactionType - .all - .reduce(into: [TransactionType: DomainLayer.DTO.TransactionFeeRules.Rule](), { (result, type) in - - let rule = txRules.calculate_fee_rules["\(type.rawValue)"] - - let addSmartAssetFee = (rule?.add_smart_asset_fee ?? deffault?.add_smart_asset_fee) ?? false - let addSmartAccountFee = (rule?.add_smart_account_fee ?? deffault?.add_smart_account_fee) ?? false - let minPriceStep = (rule?.min_price_step ?? deffault?.min_price_step) ?? 0 - let fee = (rule?.fee ?? deffault?.fee) ?? 0 - let pricePerTransfer = (rule?.price_per_transfer ?? deffault?.price_per_transfer) ?? 0 - let pricePerKb = (rule?.price_per_kb ?? deffault?.price_per_kb) ?? 0 - - let newRule = DomainLayer.DTO.TransactionFeeRules.Rule(addSmartAssetFee: addSmartAssetFee, - addSmartAccountFee: addSmartAccountFee, - minPriceStep: minPriceStep, - fee: fee, - pricePerTransfer: pricePerTransfer, - pricePerKb: pricePerKb) - - result[type] = newRule - }) - - - let newDefaultRule = DomainLayer.DTO.TransactionFeeRules.Rule(addSmartAssetFee: deffault?.add_smart_asset_fee ?? false, - addSmartAccountFee: deffault?.add_smart_account_fee ?? false, - minPriceStep: deffault?.min_price_step ?? 0, - fee: deffault?.fee ?? 0, - pricePerTransfer: deffault?.price_per_transfer ?? 0, - pricePerKb: deffault?.price_per_kb ?? 0) - - - let newRules = DomainLayer.DTO.TransactionFeeRules(smartAssetExtraFee: txRules.smart_asset_extra_fee, - smartAccountExtraFee: txRules.smart_account_extra_fee, - defaultRule: newDefaultRule, - rules: rules) - - return newRules - }) - } -} - - - -fileprivate extension TransactionSenderSpecifications { - - func broadcastSpecification(timestamp: Int64, - environment: Environment, - publicKey: String, - proofs: [String]) -> Node.Service.Transaction.BroadcastSpecification { - - switch self { - - case .burn(let model): - - return .burn(Node.Service.Transaction.Burn(version: self.version, - type: self.type.rawValue, - scheme: environment.scheme, - fee: model.fee, - assetId: model.assetID, - quantity: model.quantity, - timestamp: timestamp, - senderPublicKey: publicKey, - proofs: proofs)) - - case .createAlias(let model): - - return .createAlias(Node.Service.Transaction.Alias(version: self.version, - name: model.alias, - fee: model.fee, - timestamp: timestamp, - type: self.type.rawValue, - senderPublicKey: publicKey, - proofs: proofs)) - case .lease(let model): - - var recipient = "" - if model.recipient.count <= WavesSDKCryptoConstants.aliasNameMaxLimitSymbols { - recipient = environment.aliasScheme + model.recipient - } else { - recipient = model.recipient - } - return .startLease(Node.Service.Transaction.Lease(version: self.version, - scheme: environment.scheme, - fee: model.fee, - recipient: recipient, - amount: model.amount, - timestamp: timestamp, - type: self.type.rawValue, - senderPublicKey: publicKey, - proofs: proofs)) - case .cancelLease(let model): - - return .cancelLease(Node.Service.Transaction.LeaseCancel(version: self.version, - scheme: environment.scheme, - fee: model.fee, - leaseId: model.leaseId, - timestamp: timestamp, - type: self.type.rawValue, - senderPublicKey: publicKey, - proofs: proofs)) - - case .data(let model): - - return .data(Node.Service.Transaction.Data.init(type: self.type.rawValue, - version: self.version, - fee: model.fee, - timestamp: timestamp, - senderPublicKey: publicKey, - proofs: proofs, - data: model.dataForNode)) - - case .send(let model): - - var recipient = "" - if model.recipient.count <= WavesSDKCryptoConstants.aliasNameMaxLimitSymbols { - recipient = environment.aliasScheme + model.recipient - } else { - recipient = model.recipient - } - - return .send(Node.Service.Transaction.Send(type: self.type.rawValue, - version: self.version, - recipient: recipient, - assetId: model.assetId, - amount: model.amount, - fee: model.fee, - attachment: Base58.encode(Array(model.attachment.utf8)), - feeAssetId: model.getFeeAssetID, - timestamp: timestamp, - senderPublicKey: publicKey, - proofs: proofs)) - } - - } - - func signature(timestamp: Int64, scheme: String, publicKey: [UInt8]) -> [UInt8] { - - switch self { - - case .data(let model): - //TODO: check size - var signature: [UInt8] = [] - signature += toByteArray(Int8(self.type.rawValue)) - signature += toByteArray(Int8(self.version)) - signature += publicKey - signature += model.bytesForSignature - signature += toByteArray(timestamp) - signature += toByteArray(model.fee) - return signature - - case .burn(let model): - - let assetId: [UInt8] = Base58.decode(model.assetID) - - var signature: [UInt8] = [] - signature += toByteArray(Int8(self.type.rawValue)) - signature += toByteArray(Int8(self.version)) - signature += scheme.utf8 - signature += publicKey - signature += assetId - signature += toByteArray(model.quantity) - signature += toByteArray(model.fee) - signature += toByteArray(timestamp) - return signature - - case .cancelLease(let model): - - let leaseId: [UInt8] = Base58.decode(model.leaseId) - - var signature: [UInt8] = [] - signature += toByteArray(Int8(self.type.rawValue)) - signature += toByteArray(Int8(self.version)) - signature += scheme.utf8 - signature += publicKey - signature += toByteArray(model.fee) - signature += toByteArray(timestamp) - signature += leaseId - return signature - - case .createAlias(let model): - - var alias: [UInt8] = toByteArray(Int8(self.version)) - alias += scheme.utf8 - alias += model.alias.arrayWithSize() - - var signature: [UInt8] = [] - signature += toByteArray(Int8(self.type.rawValue)) - signature += toByteArray(Int8(self.version)) - signature += publicKey - - signature += alias.arrayWithSize() - signature += toByteArray(model.fee) - signature += toByteArray(timestamp) - return signature - - case .lease(let model): - - var recipient: [UInt8] = [] - if model.recipient.count <= WavesSDKCryptoConstants.aliasNameMaxLimitSymbols { - recipient += toByteArray(Int8(self.version)) - recipient += scheme.utf8 - recipient += model.recipient.arrayWithSize() - } else { - recipient += Base58.decode(model.recipient) - } - - var signature: [UInt8] = [] - signature += toByteArray(Int8(self.type.rawValue)) - signature += toByteArray(Int8(self.version)) - signature += [0] - signature += publicKey - - signature += recipient - signature += toByteArray(model.amount) - signature += toByteArray(model.fee) - signature += toByteArray(timestamp) - return signature - - case .send(let model): - - var recipient: [UInt8] = [] - if model.recipient.count <= WavesSDKCryptoConstants.aliasNameMaxLimitSymbols { - recipient += toByteArray(Int8(self.version)) - recipient += scheme.utf8 - recipient += model.recipient.arrayWithSize() - } else { - recipient += Base58.decode(model.recipient) - } - - var signature: [UInt8] = [] - signature += toByteArray(Int8(self.type.rawValue)) - signature += toByteArray(Int8(self.version)) - signature += publicKey - signature += model.assetId.isEmpty ? [UInt8(0)] : ([UInt8(1)] + Base58.decode(model.assetId)) - signature += model.getFeeAssetID.isEmpty ? [UInt8(0)] : ([UInt8(1)] + Base58.decode(model.getFeeAssetID)) - signature += toByteArray(timestamp) - signature += toByteArray(model.amount) - signature += toByteArray(model.fee) - signature += recipient - signature += model.attachment.arrayWithSize() - - return signature - } - } -} - -private extension SendTransactionSender { - - var getFeeAssetID: String { - return feeAssetID == WavesSDKCryptoConstants.wavesAssetId ? "" : feeAssetID - } -} - -private extension DataTransactionSender { - - var bytesForSignature: [UInt8] { - - var signature: [UInt8] = [] - signature += toByteArray(Int16(self.data.count)) - - for value in self.data { - signature += value.key.arrayWithSize() - - switch value.value { - case .binary(let data): - signature += toByteArray(Int8(2)) - signature += data.arrayWithSize() - - case .integer(let number): - signature += toByteArray(Int8(0)) - signature += toByteArray(number) - - case .boolean(let flag): - signature += toByteArray(Int8(1)) - signature += toByteArray(flag) - - case .string(let str): - signature += toByteArray(Int8(3)) - signature += str.arrayWithSize() - } - } - return signature - } - - var dataForNode: [Node.Service.Transaction.Data.Value] { - return self.data.map { (value) -> Node.Service.Transaction.Data.Value in - - var kind: Node.Service.Transaction.Data.Value.Kind! - - switch value.value { - case .binary(let data): - kind = .binary(data.toBase64() ?? "") - - case .integer(let number): - kind = .integer(number) - - case .boolean(let flag): - kind = .boolean(flag) - - case .string(let str): - kind = .string(str) - } - - return Node.Service.Transaction.Data.Value.init(key: value.key, value: kind) - } - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Api/ApiServiceTypes.swift b/WavesWallet-iOS/DataLayer/Service/Api/ApiServiceTypes.swift deleted file mode 100644 index 193a39a5..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Api/ApiServiceTypes.swift +++ /dev/null @@ -1,32 +0,0 @@ -// -// DataService.swift -// WavesWallet-iOS -// -// Created by mefilt on 09.07.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import WavesSDKExtension - -enum API {} - -extension API { - enum Service {} - enum DTO {} - enum Query {} -} - -protocol ApiTargetType: BaseTargetType {} - -extension ApiTargetType { - private var apiVersion: String { - return "/v0" - } - - private var apiUrl: String { - return environment.servers.dataUrl.relativeString - } - - var baseURL: URL { return URL(string: "\(apiUrl)\(apiVersion)")! } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Api/Models/AliasApi.swift b/WavesWallet-iOS/DataLayer/Service/Api/Models/AliasApi.swift deleted file mode 100644 index 687b07cc..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Api/Models/AliasApi.swift +++ /dev/null @@ -1,17 +0,0 @@ -// -// AliasApi.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 1/30/19. -// Copyright © 2019 Waves Platform. All rights reserved. -// - -import Foundation - -extension API.DTO { - - struct Alias: Decodable { - let alias: String - let address: String - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Api/Models/AssetApi.swift b/WavesWallet-iOS/DataLayer/Service/Api/Models/AssetApi.swift deleted file mode 100644 index e10a61b8..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Api/Models/AssetApi.swift +++ /dev/null @@ -1,26 +0,0 @@ -// -// Asset.swift -// WavesWallet-iOS -// -// Created by mefilt on 09.07.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension API.DTO { - struct Asset: Decodable { - let ticker: String? - let id: String - let name: String - let precision: Int - let description: String - let height: Int64 - let timestamp: Date - let sender: String - let quantity: Int64 - let reissuable: Bool - let hasScript: Bool - let minSponsoredFee: Int64? - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Api/Models/CandleApi.swift b/WavesWallet-iOS/DataLayer/Service/Api/Models/CandleApi.swift deleted file mode 100644 index 0428b3b8..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Api/Models/CandleApi.swift +++ /dev/null @@ -1,25 +0,0 @@ -// -// CandleApi.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 12/23/18. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension API.DTO { - struct Chart: Decodable { - - struct Candle: Decodable { - let time: Int64 - let volume: Double? - let close: Double? - let high: Double? - let low: Double? - let open: Double? - } - - let candles: [Candle] - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Api/Models/TransactionApi.swift b/WavesWallet-iOS/DataLayer/Service/Api/Models/TransactionApi.swift deleted file mode 100644 index 7d4ed11d..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Api/Models/TransactionApi.swift +++ /dev/null @@ -1,61 +0,0 @@ -// -// Transaction.swift -// WavesWallet-iOS -// -// Created by mefilt on 09.07.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension API.DTO { - - enum OrderType: String, Decodable { - case sell - case buy - } - - struct Pair: Decodable { - let amountAsset: String - let priceAsset: String - } - - struct Order: Decodable { - let id: String - let senderPublicKey: String - let matcherPublicKey: String - let assetPair: Pair - let orderType: OrderType - let price: Double - let sender: String - let amount: Double - let timestamp: Date - let expiration: Date - let matcherFee: Double - let signature: String - } - - struct ExchangeTransaction: Decodable { - let id: String - let timestamp: Date - let height: Int64 - let type: Int - let fee: Double - let sender: String - let senderPublicKey: String - let buyMatcherFee: Double - let sellMatcherFee: Double - let price: Double - let amount: Double - let order1: Order - let order2: Order - } -} - -extension API.DTO.ExchangeTransaction { - - var orderType: API.DTO.OrderType { - let order = order1.timestamp > order2.timestamp ? order1 : order2 - return order.orderType - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Api/Queries/CandleApiFilters.swift b/WavesWallet-iOS/DataLayer/Service/Api/Queries/CandleApiFilters.swift deleted file mode 100644 index 02e9639c..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Api/Queries/CandleApiFilters.swift +++ /dev/null @@ -1,18 +0,0 @@ -// -// CandleFilters.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 12/23/18. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension API.Query { - - struct CandleFilters: Codable { - let timeStart: Int64 - let timeEnd: Int64 - let interval: String - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Api/Queries/ExchangeApiFilters.swift b/WavesWallet-iOS/DataLayer/Service/Api/Queries/ExchangeApiFilters.swift deleted file mode 100644 index a4c06aed..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Api/Queries/ExchangeApiFilters.swift +++ /dev/null @@ -1,32 +0,0 @@ -// -// ExchangeFilters.swift -// WavesWallet-iOS -// -// Created by mefilt on 09.07.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension API.Query { - struct ExchangeFilters: Codable { - // Address of a matcher which sent the transaction - let matcher: String? - // Address of a trader-participant in a transaction — an ORDER sender - let sender: String? - // Time range filter, start. Defaults to first transaction's time_stamp in db. - let timeStart: String? - // Time range filter, end. Defaults to now. - let timeEnd: String? - // Asset ID of the amount asset. - let amountAsset: String? - // Asset ID of the price asset. - let priceAsset: String? - // Cursor in base64 encoding. Holds information about timestamp, id, sort. - let after: String? - // Sort order. Gonna be rewritten by cursor's sort if present. - let sort: String = "desc" - // How many transactions to await in response. - let limit: Int - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Api/Services/AliasApiService.swift b/WavesWallet-iOS/DataLayer/Service/Api/Services/AliasApiService.swift deleted file mode 100644 index 43ec9495..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Api/Services/AliasApiService.swift +++ /dev/null @@ -1,59 +0,0 @@ -// -// AliasApiService.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 1/30/19. -// Copyright © 2019 Waves Platform. All rights reserved. -// - -import Foundation -import Moya -import WavesSDKCrypto - -extension API.Service { - - struct Alias { - enum Kind { - case alias(name: String) - case list(accountAddress: String) - } - - let environment: Environment - let kind: Kind - } -} - - - -extension API.Service.Alias: ApiTargetType { - - private enum Constants { - static let aliases = "aliases" - static let address = "address" - } - - var path: String { - switch kind { - - case .alias(let name): - return Constants.aliases + "/" + "\(name)" - - case .list: - return Constants.aliases - } - } - - var method: Moya.Method { - return .get - } - - var task: Task { - switch kind { - case .alias: - return .requestPlain - - case .list(let accountAddress): - return .requestParameters(parameters: [Constants.address : accountAddress], encoding: URLEncoding.default) - } - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Api/Services/CandlesApiService.swift b/WavesWallet-iOS/DataLayer/Service/Api/Services/CandlesApiService.swift deleted file mode 100644 index e6b7ab43..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Api/Services/CandlesApiService.swift +++ /dev/null @@ -1,42 +0,0 @@ -// -// CandlesApiService.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 12/22/18. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import Moya -import WavesSDKExtension -import WavesSDKCrypto - -extension API.Service { - - struct Candles { - let amountAsset: String - let priceAsset: String - let params: API.Query.CandleFilters - let environment: Environment - } -} - -extension API.Service.Candles: BaseTargetType { - - var path: String { - return "/candles/\(amountAsset)/\(priceAsset)" - } - - var method: Moya.Method { - return .get - } - - var task: Task { - return .requestParameters(parameters: params.dictionary, encoding: URLEncoding.default) - } - - var baseURL: URL { - return URL(string: environment.servers.dataUrl.relativeString)! - } - -} diff --git a/WavesWallet-iOS/DataLayer/Service/Api/Services/PairsPriceApiService.swift b/WavesWallet-iOS/DataLayer/Service/Api/Services/PairsPriceApiService.swift deleted file mode 100644 index ad094484..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Api/Services/PairsPriceApiService.swift +++ /dev/null @@ -1,68 +0,0 @@ -// -// DexPairsApiService.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 12/25/18. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import Moya -import WavesSDKCrypto - -extension API.Service { - - - struct PairsPrice { - let pairs: [DomainLayer.DTO.Dex.Pair] - let environment: Environment - } -} - - -extension API.Service.PairsPrice: BaseTargetType { - - private enum Constants { - static let pairsPath = "/v0/pairs" - } - - var path: String { - return "" - } - - var baseURL: URL { - return URL(string: baseUrlString + parametersString)! - } - - var method: Moya.Method { - return .get - } - - var task: Task { - return .requestPlain - } -} - -private extension API.Service.PairsPrice { - - var baseUrlString: String { - return environment.servers.dataUrl.relativeString + Constants.pairsPath - } - - var parametersString: String { - - var url = "" - - for pair in pairs { - if (url as NSString).range(of: "?").location == NSNotFound { - url.append("?") - } - if url.last != "?" { - url.append("&") - } - url.append("pairs=" + pair.amountAsset.id + "/" + pair.priceAsset.id) - } - - return url - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Matcher/BalanceMatcherService.swift b/WavesWallet-iOS/DataLayer/Service/Matcher/BalanceMatcherService.swift deleted file mode 100644 index e4dcea79..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Matcher/BalanceMatcherService.swift +++ /dev/null @@ -1,74 +0,0 @@ -// -// BalanceMatcherService.swift -// WavesWallet-iOS -// -// Created by mefilt on 23.07.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import Moya -import WavesSDKExtension -import WavesSDKCrypto - -extension Matcher.Service { - struct Balance { - enum Kind { - /** - Response: - - [AssetId: Balance] as [String: Int64] - */ - case getReservedBalances(TimestampSignature) - } - - var kind: Kind - var environment: Environment - } -} - -extension Matcher.Service.Balance: MatcherTargetType { - fileprivate enum Constants { - static let matcher = "matcher" - static let balance = "balance" - static let reserved = "reserved" - static let timestamp = "timestamp" - } - - var path: String { - switch kind { - case .getReservedBalances(let signature): - return Constants.matcher - + "/" - + Constants.balance - + "/" - + Constants.reserved - + "/" - + "\(signature.publicKey.getPublicKeyStr())".urlEscaped - } - } - - var method: Moya.Method { - switch kind { - case .getReservedBalances: - return .get - } - } - - var task: Task { - switch kind { - case .getReservedBalances: - return .requestPlain - } - } - - var headers: [String: String]? { - var headers = ContentType.applicationJson.headers - - switch kind { - case .getReservedBalances(let signature): - headers.merge(signature.parameters) { a, _ in a } - } - - return headers - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Matcher/MatcherServiceTypes.swift b/WavesWallet-iOS/DataLayer/Service/Matcher/MatcherServiceTypes.swift deleted file mode 100644 index ecec7f9b..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Matcher/MatcherServiceTypes.swift +++ /dev/null @@ -1,23 +0,0 @@ -// -// MatcherServiceTypes.swift -// WavesWallet-iOS -// -// Created by mefilt on 20.07.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - - -enum Matcher {} - -extension Matcher { - enum DTO {} - enum Service {} -} - -protocol MatcherTargetType: BaseTargetType {} - -extension MatcherTargetType { - var baseURL: URL { return environment.servers.matcherUrl } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Matcher/Models/MarketMatcher.swift b/WavesWallet-iOS/DataLayer/Service/Matcher/Models/MarketMatcher.swift deleted file mode 100644 index 687b637c..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Matcher/Models/MarketMatcher.swift +++ /dev/null @@ -1,31 +0,0 @@ -// -// MarketApi.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 12/23/18. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension Matcher.DTO { - - struct Market: Decodable { - struct AssetInfo: Decodable { - let decimals: Int - } - - let amountAsset: String - let amountAssetName: String - let amountAssetInfo: AssetInfo? - - let priceAsset: String - let priceAssetName: String - let priceAssetInfo: AssetInfo? - } - - struct MarketResponse: Decodable { - let markets: [Market] - } - -} diff --git a/WavesWallet-iOS/DataLayer/Service/Matcher/Models/OrderBookMatcher.swift b/WavesWallet-iOS/DataLayer/Service/Matcher/Models/OrderBookMatcher.swift deleted file mode 100644 index 50d0e560..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Matcher/Models/OrderBookMatcher.swift +++ /dev/null @@ -1,35 +0,0 @@ -// -// OrderBookApi.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 12/17/18. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension Matcher.DTO { - - struct OrderBook: Decodable { - - struct Pair: Decodable { - let amountAsset: String - let priceAsset: String - } - - struct Value: Decodable { - let amount: Int64 - let price: Int64 - } - - let date: Date - let pair: Pair - let bids: [Value] - let asks: [Value] - - private enum CodingKeys: String, CodingKey { - case date = "timestamp" - case pair, bids, asks - } - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Matcher/Models/OrderMatcher.swift b/WavesWallet-iOS/DataLayer/Service/Matcher/Models/OrderMatcher.swift deleted file mode 100644 index 357bed19..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Matcher/Models/OrderMatcher.swift +++ /dev/null @@ -1,35 +0,0 @@ -// -// MyOrderMatcher.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 12/26/18. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension Matcher.DTO { - - struct Order: Decodable { - - enum OrderType: String, Decodable { - case sell - case buy - } - - enum Status: String, Decodable { - case Accepted - case PartiallyFilled - case Cancelled - case Filled - } - - let id: String - let type: OrderType - let amount: Int64 - let price: Int64 - let filled: Int64 - let status: Status - let timestamp: Date - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Matcher/OrderBookMatcherService.swift b/WavesWallet-iOS/DataLayer/Service/Matcher/OrderBookMatcherService.swift deleted file mode 100644 index 52556744..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Matcher/OrderBookMatcherService.swift +++ /dev/null @@ -1,202 +0,0 @@ -// -// MatcherNodeService.swift -// WavesWallet-iOS -// -// Created by mefilt on 20.07.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import Moya -import Base58 -import WavesSDKExtension -import WavesSDKCrypto - -extension Matcher.Service { - - struct OrderBook { - - enum Kind { - case getOrderBook(amountAsset: String, priceAsset: String) - case getMarket - case getMyOrders(amountAsset: String, priceAsset: String, signature: TimestampSignature) - case cancelOrder(DomainLayer.Query.Dex.CancelOrder) - case createOrder(DomainLayer.Query.Dex.CreateOrder) - } - - var kind: Kind - var environment: Environment - } -} - -extension Matcher.Service.OrderBook: MatcherTargetType { - fileprivate enum Constants { - static let matcher = "matcher" - static let orderbook = "orderbook" - static let publicKey = "publicKey" - } - - private var orderBookPath: String { - - return Constants.matcher + "/" + Constants.orderbook - } - - var path: String { - switch kind { - - case .getOrderBook(let amountAsset, let priceAsset): - return orderBookPath + "/" + amountAsset + "/" + priceAsset - - case .getMarket: - return orderBookPath - - case .getMyOrders(let amountAsset, let priceAsset, let signature): - return orderBookPath + "/" + amountAsset + "/" + priceAsset + "/" - + Constants.publicKey + "/" + signature.publicKey.getPublicKeyStr() - - case .cancelOrder(let order): - return orderBookPath + "/" + order.amountAsset + "/" + order.priceAsset + "/" + "cancel" - - case .createOrder: - return orderBookPath - } - } - - var method: Moya.Method { - - switch kind { - case .cancelOrder, .createOrder: - return .post - - default: - return .get - } - } - - var task: Task { - - switch kind { - case .cancelOrder(let order): - return .requestParameters(parameters: order.params, encoding: JSONEncoding.default) - - case .createOrder(let order): - - return .requestParameters(parameters: order.params, encoding: JSONEncoding.default) - - default: - return .requestPlain - } - } - - var headers: [String: String]? { - var headers = ContentType.applicationJson.headers - - switch kind { - case .getMyOrders(_, _, let signature): - headers.merge(signature.parameters) { a, _ in a } - - default: - break - } - - return headers - } -} - - - -//MARK: - CancelOrder -fileprivate extension DomainLayer.Query.Dex.CancelOrder { - - private var toSign: [UInt8] { - let s1 = wallet.publicKey.publicKey - let s2 = Base58.decode(orderId) - return s1 + s2 - } - - private var signature: [UInt8] { - return Hash.sign(toSign, wallet.privateKey.privateKey) - } - - //TODO: Need we use proofs instead of signature? - - var params: [String : String] { - return ["sender" : Base58.encode(wallet.publicKey.publicKey), - "orderId" : orderId, - "signature" : Base58.encode(signature)] - } -} - - - -//MARK: - CreateOrder -fileprivate extension DomainLayer.Query.Dex.CreateOrder { - - private struct AssetPair { - let amountAssetId: String? - let priceAssetId: String? - - var json: [String : String] { - return ["amountAsset" : amountAssetId ?? "", - "priceAsset" : priceAssetId ?? ""] - } - - func assetIdBytes(_ id: String?) -> [UInt8] { - return id == nil ? [UInt8(0)] : ([UInt8(1)] + Base58.decode(id!)) - } - - var bytes: [UInt8] { - return assetIdBytes(amountAssetId) + assetIdBytes(priceAssetId) - } - } - - private var assetPair: AssetPair { - return .init(amountAssetId: amountAsset == WavesSDKCryptoConstants.wavesAssetId ? nil : amountAsset, - priceAssetId: priceAsset == WavesSDKCryptoConstants.wavesAssetId ? nil : priceAsset) - } - - private var id: [UInt8] { - return Hash.fastHash(toSign) - } - - private var signature: [UInt8] { - return Hash.sign(toSign, wallet.privateKey.privateKey) - } - - private var toSign: [UInt8] { - let s1 = toByteArray(UInt8(2)) + wallet.publicKey.publicKey + matcherPublicKey.publicKey - let s2 = assetPair.bytes + orderType.bytes - let s3 = toByteArray(price) + toByteArray(amount) - let s4 = toByteArray(timestamp) + toByteArray(expirationTimestamp) + toByteArray(matcherFee) - return s1 + s2 + s3 + s4 - } - - private var expirationTimestamp: Int64 { - return timestamp + Int64(expiration) * 60 * 1000 - } - - var params: [String : Any] { - - return ["senderPublicKey" : Base58.encode(wallet.publicKey.publicKey), - "matcherPublicKey" : Base58.encode(matcherPublicKey.publicKey), - "assetPair" : assetPair.json, - "orderType" : orderType.rawValue, - "price" : price, - "amount" : amount, - "timestamp" : timestamp, - "expiration" : expirationTimestamp, - "matcherFee" : matcherFee, - "proofs" : [Base58.encode(signature)], - "version": 2] - } -} - - -fileprivate extension DomainLayer.DTO.Dex.OrderType { - var bytes: [UInt8] { - switch self { - case .sell: return [UInt8(1)] - case .buy: return [UInt8(0)] - } - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Node/Models/AccountAssetsBalanceNode.swift b/WavesWallet-iOS/DataLayer/Service/Node/Models/AccountAssetsBalanceNode.swift deleted file mode 100644 index 2dc5c73a..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Node/Models/AccountAssetsBalanceNode.swift +++ /dev/null @@ -1,53 +0,0 @@ -// -// AssetBalanceNodeService.swift -// WavesWallet-iOS -// -// Created by mefilt on 09.07.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension Node.DTO { - - struct AccountAssetBalance: Decodable { - let address: String - let assetId: String - let balance: Int64 - } - - struct AccountAssetsBalance: Decodable { - let address: String - let balances: [AssetBalance] - } - - struct AssetBalance: Decodable { - - struct IssueTransaction: Decodable { - let type: Int64 - let id: String - let sender: String - let senderPublicKey: String - let fee: Int64 - let timestamp: Date - let signature: String? - let proofs: [String]?? - let version: Int64 - let assetId: String - let name: String - let quantity: Int64 - let reissuable: Bool - let decimals: Int64 - let description: String - let script: String? - } - - let assetId: String - let balance: Int64 - let reissuable: Bool - let minSponsoredAssetFee: Int64? - let sponsorBalance: Int64? - let quantity: Int64 - let issueTransaction: IssueTransaction - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Node/Models/AccountBalanceNode.swift b/WavesWallet-iOS/DataLayer/Service/Node/Models/AccountBalanceNode.swift deleted file mode 100644 index 61b61e70..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Node/Models/AccountBalanceNode.swift +++ /dev/null @@ -1,17 +0,0 @@ -// -// AddressBalanceNodeService.swift -// WavesWallet-iOS -// -// Created by mefilt on 09.07.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension Node.DTO { - struct AccountBalance: Decodable { - let address: String - let confirmations: Int64 - let balance: Int64 - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Node/Models/AddressScriptInfoNode.swift b/WavesWallet-iOS/DataLayer/Service/Node/Models/AddressScriptInfoNode.swift deleted file mode 100644 index b3c47ecc..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Node/Models/AddressScriptInfoNode.swift +++ /dev/null @@ -1,18 +0,0 @@ -// -// AddressScriptInfo.swift -// WavesWallet-iOS -// -// Created by mefilt on 21/01/2019. -// Copyright © 2019 Waves Platform. All rights reserved. -// - -import Foundation - -extension Node.DTO { - - struct AddressScriptInfo: Decodable { - let address: String - let complexity: Int64 - let extraFee: Int64? - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Node/Models/AssetDetailNode.swift b/WavesWallet-iOS/DataLayer/Service/Node/Models/AssetDetailNode.swift deleted file mode 100644 index 6e1b064c..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Node/Models/AssetDetailNode.swift +++ /dev/null @@ -1,26 +0,0 @@ -// -// AssetDetailNode.swift -// WavesWallet-iOS -// -// Created by mefilt on 21/01/2019. -// Copyright © 2019 Waves Platform. All rights reserved. -// - -import Foundation - -extension Node.DTO { - - struct AssetDetail: Decodable { - let assetId: String - let issueHeight: Int64 - let issueTimestamp: Int64 - let issuer: String - let name: String - let description: String - let decimals: Int64 - let reissuable: Bool - let quantity: Int64 - let scripted: Bool? - let minSponsoredAssetFee: Int64? - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Node/Models/BlockNode.swift b/WavesWallet-iOS/DataLayer/Service/Node/Models/BlockNode.swift deleted file mode 100644 index f9d6b50b..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Node/Models/BlockNode.swift +++ /dev/null @@ -1,15 +0,0 @@ -// -// BlockNode.swift -// WavesWallet-iOS -// -// Created by mefilt on 10.09.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension Node.DTO { - struct Block: Decodable { - let height: Int64 - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/AliasTransactionNode.swift b/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/AliasTransactionNode.swift deleted file mode 100644 index 27e1f31b..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/AliasTransactionNode.swift +++ /dev/null @@ -1,26 +0,0 @@ -// -// TransactionAliasNode.swift -// WavesWallet-iOS -// -// Created by Prokofev Ruslan on 07/08/2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension Node.DTO { - struct AliasTransaction: Decodable { - let type: Int - let id: String - let sender: String - let senderPublicKey: String - let fee: Int64 - let timestamp: Date - let version: Int - let height: Int64? - - let signature: String? - let proofs: [String]? - let alias: String - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/AssetScriptTransactionNode.swift b/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/AssetScriptTransactionNode.swift deleted file mode 100644 index 4f15eee8..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/AssetScriptTransactionNode.swift +++ /dev/null @@ -1,29 +0,0 @@ -// -// AssetScriptTransactionNode.swift -// WavesWallet-iOS -// -// Created by mefilt on 22/01/2019. -// Copyright © 2019 Waves Platform. All rights reserved. -// - -import Foundation - -extension Node.DTO { - - struct AssetScriptTransaction: Decodable { - - let type: Int - let id: String - let sender: String - let senderPublicKey: String - let fee: Int64 - let timestamp: Date - let height: Int64? - let signature: String? - let proofs: [String]? - let chainId: Int? - let assetId: String - let version: Int - let script: String? - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/BurnTransactionNode.swift b/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/BurnTransactionNode.swift deleted file mode 100644 index 64e5f4ea..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/BurnTransactionNode.swift +++ /dev/null @@ -1,28 +0,0 @@ -// -// TransactionBurnNode.swift -// WavesWallet-iOS -// -// Created by Prokofev Ruslan on 07/08/2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension Node.DTO { - struct BurnTransaction: Decodable { - let type: Int - let id: String - let sender: String - let senderPublicKey: String - let fee: Int64 - let timestamp: Date - let version: Int - let height: Int64? - - let signature: String? - let proofs: [String]? - let chainId: Int? - let assetId: String - let amount: Int64 - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/DataTransactionNode.swift b/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/DataTransactionNode.swift deleted file mode 100644 index 2b864e8e..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/DataTransactionNode.swift +++ /dev/null @@ -1,92 +0,0 @@ -// -// TransactionDataNode.swift -// WavesWallet-iOS -// -// Created by Prokofev Ruslan on 07/08/2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension Node.DTO { - - struct DataTransaction: Decodable { - - struct Data: Decodable { - - enum Value { - case bool(Bool) - case integer(Int) - case string(String) - case binary(String) - } - - let key: String - let type: String - let value: Value - } - - let type: Int - let id: String - let sender: String - let senderPublicKey: String - let fee: Int64 - let timestamp: Date - let height: Int64? - let version: Int - - let proofs: [String]? - let data: [Data] - } -} - -extension Node.DTO.DataTransaction.Data { - - enum CodingKeys: String, CodingKey { - case key - case type - case value - } - - enum ValueKey: String { - case boolean - case integer - case string - case binary - } - - init(from decoder: Decoder) throws { - - let container = try decoder.container(keyedBy: CodingKeys.self) - - if let value = try container.decodeIfPresent(String.self, forKey: .key) { - key = value - } else { - throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: container.codingPath, - debugDescription: "Not found key")) - } - - if let value = try container.decodeIfPresent(String.self, forKey: .type) { - type = value - } else { - throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: container.codingPath, - debugDescription: "Not found value")) - } - - if let type = ValueKey(rawValue: self.type) { - switch type { - case .boolean: - value = .bool(try container.decode(Bool.self, forKey: .value)) - case .integer: - value = .integer(try container.decode(Int.self, forKey: .value)) - case .string: - value = .string(try container.decode(String.self, forKey: .value)) - case .binary: - value = .binary(try container.decode(String.self, forKey: .value)) - } - } else { - throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: container.codingPath, - debugDescription: "Not found value")) - } - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/ExchangeTransactionNode.swift b/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/ExchangeTransactionNode.swift deleted file mode 100644 index 6907197c..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/ExchangeTransactionNode.swift +++ /dev/null @@ -1,52 +0,0 @@ -// -// TransactionExchangeNode.swift -// WavesWallet-iOS -// -// Created by Prokofev Ruslan on 07/08/2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension Node.DTO { - - struct ExchangeTransaction: Decodable { - struct Order: Decodable { - let id: String - let sender: String - let senderPublicKey: String - let matcherPublicKey: String - let assetPair: AssetPair - let orderType: String - let price: Int64 - let amount: Int64 - let timestamp: Date - let expiration: Int64 - let matcherFee: Int64 - let signature: String? - let proofs: [String]? - } - - struct AssetPair: Decodable { - let amountAsset: String? - let priceAsset: String? - } - - let type: Int - let id: String - let sender: String - let senderPublicKey: String - let fee: Int64 - let timestamp: Date - let height: Int64 - - let signature: String? - let proofs: [String]? - let order1: Order - let order2: Order - let price: Int64 - let amount: Int64 - let buyMatcherFee: Int64 - let sellMatcherFee: Int64 - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/InvokeScriptTransactionNode.swift b/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/InvokeScriptTransactionNode.swift deleted file mode 100644 index d7adecfb..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/InvokeScriptTransactionNode.swift +++ /dev/null @@ -1,96 +0,0 @@ -// -// InvokeScriptTransactionNode.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 4/9/19. -// Copyright © 2019 Waves Platform. All rights reserved. -// - -import Foundation - -extension Node.DTO { - - struct InvokeScriptTransaction: Decodable { - - struct Call: Decodable { - - struct Args: Decodable { - enum Value { - case bool(Bool) - case integer(Int) - case string(String) - case binary(String) - } - - let type: String - let value: Value - } - - let function: String - let args: [Args] - } - - struct Payment: Decodable { - let amount: Int64 - let assetId: String? - } - - let type: Int - let id: String - let sender: String - let senderPublicKey: String - let fee: Int64 - let feeAssetId: String? - let timestamp: Date - let proofs: [String]? - let version: Int - let dApp: String - let call: Call? - let payment: [Payment] - let height: Int64 - } -} - - -extension Node.DTO.InvokeScriptTransaction.Call.Args { - - enum CodingKeys: String, CodingKey { - case type - case value - } - - enum ValueKey: String { - case boolean - case integer - case string - case binary - } - - init(from decoder: Decoder) throws { - - let container = try decoder.container(keyedBy: CodingKeys.self) - - if let value = try container.decodeIfPresent(String.self, forKey: .type) { - type = value - } else { - throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: container.codingPath, - debugDescription: "Not found type")) - } - - if let type = ValueKey(rawValue: self.type) { - switch type { - case .boolean: - value = .bool(try container.decode(Bool.self, forKey: .value)) - case .integer: - value = .integer(try container.decode(Int.self, forKey: .value)) - case .string: - value = .string(try container.decode(String.self, forKey: .value)) - case .binary: - value = .binary(try container.decode(String.self, forKey: .value)) - } - } else { - throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: container.codingPath, - debugDescription: "Not found value")) - } - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/IssueTransactionNode.swift b/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/IssueTransactionNode.swift deleted file mode 100644 index d675c22c..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/IssueTransactionNode.swift +++ /dev/null @@ -1,32 +0,0 @@ -// -// TransactionIssueNode.swift -// WavesWallet-iOS -// -// Created by Prokofev Ruslan on 07/08/2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension Node.DTO { - struct IssueTransaction: Decodable { - let type: Int - let id: String - let sender: String - let senderPublicKey: String - let fee: Int64 - let timestamp: Date - let version: Int - let height: Int64 - - let signature: String? - let proofs: [String]? - let assetId: String - let name: String - let quantity: Int64 - let reissuable: Bool - let decimals: Int - let description: String - let script: String? - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/LeaseCancelTransactionNode.swift b/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/LeaseCancelTransactionNode.swift deleted file mode 100644 index e38e50f4..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/LeaseCancelTransactionNode.swift +++ /dev/null @@ -1,27 +0,0 @@ -// -// TransactionLeaseCancelNode.swift -// WavesWallet-iOS -// -// Created by Prokofev Ruslan on 07/08/2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension Node.DTO { - struct LeaseCancelTransaction: Decodable { - let type: Int - let id: String - let sender: String - let senderPublicKey: String - let fee: Int64 - let timestamp: Date - let version: Int - let height: Int64? - let signature: String? - let proofs: [String]? - let chainId: Int? - let leaseId: String - let lease: Node.DTO.LeaseTransaction? - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/LeaseTransactionNode.swift b/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/LeaseTransactionNode.swift deleted file mode 100644 index 8360efdc..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/LeaseTransactionNode.swift +++ /dev/null @@ -1,27 +0,0 @@ -// -// TransactionLeaseNode.swift -// WavesWallet-iOS -// -// Created by mefilt on 18.07.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension Node.DTO { - struct LeaseTransaction: Decodable { - let type: Int - let id: String - let sender: String - let senderPublicKey: String - let fee: Int64 - let timestamp: Date - let version: Int - let height: Int64? //I do optional variable for cancel leasing model - - let signature: String? - let proofs: [String]? - let amount: Int64 - let recipient: String - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/MassTransferTransactionNode.swift b/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/MassTransferTransactionNode.swift deleted file mode 100644 index bcc5c23b..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/MassTransferTransactionNode.swift +++ /dev/null @@ -1,35 +0,0 @@ -// -// TransactionMassTransferNode.swift -// WavesWallet-iOS -// -// Created by Prokofev Ruslan on 07/08/2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension Node.DTO { - struct MassTransferTransaction: Decodable { - - struct Transfer: Decodable { - let recipient: String - let amount: Int64 - } - - let type: Int - let id: String - let sender: String - let senderPublicKey: String - let fee: Int64 - let timestamp: Date - let version: Int - let height: Int64 - - let proofs: [String]? - let assetId: String? - let attachment: String - let transferCount: Int - let totalAmount: Int64 - let transfers: [Transfer] - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/ReissueTransactionNode.swift b/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/ReissueTransactionNode.swift deleted file mode 100644 index 34c9e986..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/ReissueTransactionNode.swift +++ /dev/null @@ -1,29 +0,0 @@ -// -// TransactionReissueNode.swift -// WavesWallet-iOS -// -// Created by Prokofev Ruslan on 07/08/2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension Node.DTO { - struct ReissueTransaction: Decodable { - let type: Int - let id: String - let sender: String - let senderPublicKey: String - let fee: Int64 - let timestamp: Date - let version: Int - let height: Int64 - - let signature: String? - let proofs: [String]? - let chainId: Int? - let assetId: String - let quantity: Int64 - let reissuable: Bool - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/ScriptTransactionNode.swift b/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/ScriptTransactionNode.swift deleted file mode 100644 index d7939c39..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/ScriptTransactionNode.swift +++ /dev/null @@ -1,28 +0,0 @@ -// -// SetScriptTransactionNode.swift -// WavesWallet-iOS -// -// Created by mefilt on 22/01/2019. -// Copyright © 2019 Waves Platform. All rights reserved. -// - -import Foundation - -extension Node.DTO { - - struct ScriptTransaction: Decodable { - - let type: Int - let id: String - let sender: String - let senderPublicKey: String - let fee: Int64 - let timestamp: Date - let height: Int64? - let signature: String? - let proofs: [String]? - let chainId: Int? - let version: Int - let script: String? - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/SponsorshipTransactionNode.swift b/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/SponsorshipTransactionNode.swift deleted file mode 100644 index 5452f989..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/SponsorshipTransactionNode.swift +++ /dev/null @@ -1,29 +0,0 @@ -// -// SponsorshipTransactionNode.swift -// WavesWallet-iOS -// -// Created by Prokofev Ruslan on 05/02/2019. -// Copyright © 2019 Waves Platform. All rights reserved. -// - -import Foundation - -extension Node.DTO { - - struct SponsorshipTransaction: Decodable { - - let type: Int - let id: String - let sender: String - let senderPublicKey: String - let fee: Int64 - let timestamp: Date - let height: Int64? - let signature: String? - let proofs: [String]? - let assetId: String - let minSponsoredAssetFee: Int64? - let version: Int - let script: String? - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/TransactionContainersNode.swift b/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/TransactionContainersNode.swift deleted file mode 100644 index 36d8e72b..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/TransactionContainersNode.swift +++ /dev/null @@ -1,214 +0,0 @@ -// -// TransactionContainers.swift -// WavesWallet-iOS -// -// Created by mefilt on 29.08.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import WavesSDKExtension - -extension Node.DTO { - - fileprivate enum TransactionType: Int, Decodable { - case issue = 3 - case transfer = 4 - case reissue = 5 - case burn = 6 - case exchange = 7 - case lease = 8 - case leaseCancel = 9 - case alias = 10 - case massTransfer = 11 - case data = 12 - case script = 13 - case sponsorship = 14 - case assetScript = 15 - case invokeScript = 16 - } - - enum TransactionError: Error { - case none - } - - enum Transaction: Decodable { - case unrecognised(Node.DTO.UnrecognisedTransaction) - case issue(Node.DTO.IssueTransaction) - case transfer(Node.DTO.TransferTransaction) - case reissue(Node.DTO.ReissueTransaction) - case burn(Node.DTO.BurnTransaction) - case exchange(Node.DTO.ExchangeTransaction) - case lease(Node.DTO.LeaseTransaction) - case leaseCancel(Node.DTO.LeaseCancelTransaction) - case alias(Node.DTO.AliasTransaction) - case massTransfer(Node.DTO.MassTransferTransaction) - case data(Node.DTO.DataTransaction) - case script(Node.DTO.ScriptTransaction) - case sponsorship(Node.DTO.SponsorshipTransaction) - case assetScript(Node.DTO.AssetScriptTransaction) - case invokeScript(Node.DTO.InvokeScriptTransaction) - - init(from decoder: Decoder) throws { - - do { - let container = try decoder.container(keyedBy: CodingKeys.self) - let type = try container.decode(TransactionType.self, forKey: .type) - - self = try Transaction.transaction(from: decoder, type: type) - } catch let e { - SweetLogger.error(e) - throw TransactionError.none - } - } - - - fileprivate static func transaction(from decode: Decoder, type: TransactionType) throws -> Transaction { - - switch type { - case .issue: - return .issue( try Node.DTO.IssueTransaction(from: decode)) - - case .transfer: - return .transfer( try Node.DTO.TransferTransaction(from: decode)) - - case .reissue: - return .reissue( try Node.DTO.ReissueTransaction(from: decode)) - - case .burn: - return .burn( try Node.DTO.BurnTransaction(from: decode)) - - case .exchange: - return .exchange( try Node.DTO.ExchangeTransaction(from: decode)) - - case .lease: - return .lease( try Node.DTO.LeaseTransaction(from: decode)) - - case .leaseCancel: - return .leaseCancel( try Node.DTO.LeaseCancelTransaction(from: decode)) - - case .alias: - return .alias( try Node.DTO.AliasTransaction(from: decode)) - - case .massTransfer: - return .massTransfer( try Node.DTO.MassTransferTransaction(from: decode)) - - case .data: - return .data(try Node.DTO.DataTransaction(from: decode)) - - case .script: - return .script(try Node.DTO.ScriptTransaction(from: decode)) - - case .assetScript: - return .assetScript(try Node.DTO.AssetScriptTransaction(from: decode)) - - case .sponsorship: - return .sponsorship(try Node.DTO.SponsorshipTransaction(from: decode)) - - case .invokeScript: - return .invokeScript(try Node.DTO.InvokeScriptTransaction(from: decode)) - } - } - } - - enum CodingKeys: String, CodingKey { - case type = "type" - } - - struct TransactionContainers: Decodable { - - let transactions: [Transaction] - - init(from decoder: Decoder) throws { - - var transactions: [Transaction] = [] - - do { - - var container = try decoder.unkeyedContainer() - var listForType = try container.nestedUnkeyedContainer() - - var listArray = listForType - while !listForType.isAtEnd { - - let objectType = try listForType.nestedContainer(keyedBy: CodingKeys.self) - - do { - let type = try objectType.decode(TransactionType.self, forKey: .type) - - switch type { - case .issue: - let tx = try listArray.decode(Node.DTO.IssueTransaction.self) - transactions.append(.issue(tx)) - - case .transfer: - let tx = try listArray.decode(Node.DTO.TransferTransaction.self) - transactions.append(.transfer(tx)) - - case .reissue: - let tx = try listArray.decode(Node.DTO.ReissueTransaction.self) - transactions.append(.reissue(tx)) - - case .burn: - let tx = try listArray.decode(Node.DTO.BurnTransaction.self) - transactions.append(.burn(tx)) - - case .exchange: - let tx = try listArray.decode(Node.DTO.ExchangeTransaction.self) - transactions.append(.exchange(tx)) - - case .lease: - let tx = try listArray.decode(Node.DTO.LeaseTransaction.self) - transactions.append(.lease(tx)) - - case .leaseCancel: - let tx = try listArray.decode(Node.DTO.LeaseCancelTransaction.self) - transactions.append(.leaseCancel(tx)) - - case .alias: - let tx = try listArray.decode(Node.DTO.AliasTransaction.self) - transactions.append(.alias(tx)) - - case .massTransfer: - let tx = try listArray.decode(Node.DTO.MassTransferTransaction.self) - transactions.append(.massTransfer(tx)) - - case .data: - let tx = try listArray.decode(Node.DTO.DataTransaction.self) - transactions.append(.data(tx)) - - case .script: - let tx = try listArray.decode(Node.DTO.ScriptTransaction.self) - transactions.append(.script(tx)) - - case .assetScript: - let tx = try listArray.decode(Node.DTO.AssetScriptTransaction.self) - transactions.append(.assetScript(tx)) - - case .sponsorship: - let tx = try listArray.decode(Node.DTO.SponsorshipTransaction.self) - transactions.append(.sponsorship(tx)) - - case .invokeScript: - let tx = try listArray.decode(Node.DTO.InvokeScriptTransaction.self) - transactions.append(.invokeScript(tx)) - } - } catch let e { - - if let tx = try? listArray.decode(Node.DTO.UnrecognisedTransaction.self) { - transactions.append(.unrecognised(tx)) - SweetLogger.error("Unrecognised \(e)") - } else { - SweetLogger.error("Not Found type \(e)") - } - } - } - - } catch let e { - SweetLogger.error("WTF \(e)") - } - - self.transactions = transactions - } - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/TransferTransactionNode.swift b/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/TransferTransactionNode.swift deleted file mode 100644 index a9dc9621..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/TransferTransactionNode.swift +++ /dev/null @@ -1,31 +0,0 @@ -// -// TransactionTransferNode.swift -// WavesWallet-iOS -// -// Created by Prokofev Ruslan on 07/08/2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension Node.DTO { - struct TransferTransaction: Decodable { - let type: Int - let id: String - let sender: String - let senderPublicKey: String - let fee: Int64 - let timestamp: Date - let version: Int - let height: Int64? - - let signature: String? - let proofs: [String]? - let recipient: String - let assetId: String? - let feeAssetId: String? - let feeAsset: String? - let amount: Int64 - let attachment: String? - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/UnrecognisedTransactionNode.swift b/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/UnrecognisedTransactionNode.swift deleted file mode 100644 index a908a68d..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Node/Models/Transactions/UnrecognisedTransactionNode.swift +++ /dev/null @@ -1,21 +0,0 @@ -// -// UnrecognisedTransactionNode.swift -// WavesWallet-iOS -// -// Created by mefilt on 31.08.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension Node.DTO { - struct UnrecognisedTransaction: Decodable { - let type: Int - let id: String - let sender: String - let senderPublicKey: String - let fee: Int64 - let timestamp: Date - let height: Int64 - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Node/Models/UtilsNode.swift b/WavesWallet-iOS/DataLayer/Service/Node/Models/UtilsNode.swift deleted file mode 100644 index 6827272b..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Node/Models/UtilsNode.swift +++ /dev/null @@ -1,21 +0,0 @@ -// -// UtilsNode.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 3/12/19. -// Copyright © 2019 Waves Platform. All rights reserved. -// - -import Foundation - -extension Node.DTO { - enum Utils {} -} - -extension Node.DTO.Utils { - - struct Time: Decodable { - let system: Int64 - let NTP: Int64 - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Node/NodeServiceTypes.swift b/WavesWallet-iOS/DataLayer/Service/Node/NodeServiceTypes.swift deleted file mode 100644 index fe438ca7..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Node/NodeServiceTypes.swift +++ /dev/null @@ -1,32 +0,0 @@ -// -// NodeTargetType.swift -// WavesWallet-iOS -// -// Created by mefilt on 09.07.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import Result -import Moya -import WavesSDKExtension - -enum Node {} - -extension Node { - enum DTO {} - enum Service {} -} - -protocol NodeTargetType: BaseTargetType {} - -extension NodeTargetType { - var baseURL: URL { return environment.servers.nodeUrl } -} - -extension MoyaProvider { - final class func nodeMoyaProvider() -> MoyaProvider { - return MoyaProvider(callbackQueue: nil, - plugins: [SentryNetworkLoggerPlugin(), NodePlugin()]) - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Node/Services/AddressesNodeService.swift b/WavesWallet-iOS/DataLayer/Service/Node/Services/AddressesNodeService.swift deleted file mode 100644 index 18e9b9dd..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Node/Services/AddressesNodeService.swift +++ /dev/null @@ -1,66 +0,0 @@ -// -// NodeAddressesService.swift -// WavesWallet-iOS -// -// Created by mefilt on 09.07.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import Moya -import WavesSDKExtension -import WavesSDKCrypto - -extension Node.Service { - - struct Addresses { - enum Kind { - /** - Response: - - Node.Model.AccountBalance.self - */ - case getAccountBalance(id: String) - - /** - Response: - - DomainLayer.DTO.AddressScriptInfo - */ - case scriptInfo(id: String) - } - - var kind: Kind - var environment: Environment - } -} - -extension Node.Service.Addresses: NodeTargetType { - fileprivate enum Constants { - static let addresses = "addresses" - static let balance = "balance" - static let scriptInfo = "scriptInfo" - } - - var path: String { - switch kind { - case .getAccountBalance(let id): - return Constants.addresses + "/" + Constants.balance + "/" + "\(id)".urlEscaped - - case .scriptInfo(let id): - return Constants.addresses + "/" + Constants.scriptInfo + "/" + "\(id)".urlEscaped - } - } - - var method: Moya.Method { - switch kind { - case .getAccountBalance, .scriptInfo: - return .get - } - } - - var task: Task { - switch kind { - case .getAccountBalance, .scriptInfo: - return .requestPlain - } - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Node/Services/AssetsNodeService.swift b/WavesWallet-iOS/DataLayer/Service/Node/Services/AssetsNodeService.swift deleted file mode 100644 index 87681596..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Node/Services/AssetsNodeService.swift +++ /dev/null @@ -1,80 +0,0 @@ -// -// NodeAssetsService.swift -// WavesWallet-iOS -// -// Created by mefilt on 09.07.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import Moya -import WavesSDKExtension -import WavesSDKCrypto - -extension Node.Service { - - struct Assets { - enum Kind { - /** - Response: - - [Node.Model.AccountAssetsBalance] - */ - case getAssetsBalances(walletAddress: String) - - /** - Response: - - [Node.Model.AccountAssetsBalance] - */ - case getAssetsBalance(address: String, assetId: String) - - /** - Response: - - Node.DTO.AssetDetail - */ - case details(assetId: String) - } - - var kind: Kind - var environment: Environment - } -} - -extension Node.Service.Assets: NodeTargetType { - var modelType: Encodable.Type { - return String.self - } - - fileprivate enum Constants { - static let assets = "assets" - static let balance = "balance" - static let details = "details" - } - - var path: String { - switch kind { - case .getAssetsBalances(let id): - return Constants.assets + "/" + Constants.balance + "/" + "\(id)".urlEscaped - - case .getAssetsBalance(let address, - let assetId): - return Constants.assets + "/" + Constants.balance + "/" + "\(address)".urlEscaped + "/" + "\(assetId)".urlEscaped - - case .details(let id): - return Constants.assets + "/" + Constants.details + "/" + "\(id)".urlEscaped - } - } - - var method: Moya.Method { - switch kind { - case .getAssetsBalances, .getAssetsBalance, .details: - return .get - } - } - - var task: Task { - switch kind { - case .getAssetsBalances, .getAssetsBalance, .details: - return .requestPlain - } - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Node/Services/BlocksNodeService.swift b/WavesWallet-iOS/DataLayer/Service/Node/Services/BlocksNodeService.swift deleted file mode 100644 index 8651fcf3..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Node/Services/BlocksNodeService.swift +++ /dev/null @@ -1,60 +0,0 @@ -// -// BlockNodeService.swift -// WavesWallet-iOS -// -// Created by mefilt on 10.09.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import Moya -import WavesSDKExtension -import WavesSDKCrypto - -extension Node.Service { - - struct Blocks { - enum Kind { - /** - Response: - - Node.DTO.Block - */ - case height - } - - let environment: Environment - let kind: Kind - } -} - -extension Node.Service.Blocks: NodeTargetType { - var modelType: Encodable.Type { - return String.self - } - - fileprivate enum Constants { - static let blocks = "blocks" - static let height = "height" - } - - var path: String { - switch kind { - case .height: - return Constants.blocks + "/" + Constants.height - } - } - - var method: Moya.Method { - switch kind { - case .height: - return .get - } - } - - var task: Task { - switch kind { - case .height: - return .requestPlain - } - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Node/Services/LeasingNodeService.swift b/WavesWallet-iOS/DataLayer/Service/Node/Services/LeasingNodeService.swift deleted file mode 100644 index 337a1e30..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Node/Services/LeasingNodeService.swift +++ /dev/null @@ -1,61 +0,0 @@ -// -// LeasingNodeService.swift -// WavesWallet-iOS -// -// Created by mefilt on 18.07.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import Moya -import WavesSDKExtension -import WavesSDKCrypto - -extension Node.Service { - - struct Leasing { - enum Kind { - /** - Response: - - [Node.Model.LeasingTransaction].self - */ - case getActive(accountAddress: String) - } - - var kind: Kind - var environment: Environment - } -} - -extension Node.Service.Leasing: NodeTargetType { - var modelType: Encodable.Type { - return String.self - } - - fileprivate enum Constants { - static let leasing = "leasing" - static let active = "active" - static let address = "address" - } - - var path: String { - switch kind { - case .getActive(let accountAddress): - return Constants.leasing + "/" + Constants.active + "/" + "\(accountAddress)".urlEscaped - } - } - - var method: Moya.Method { - switch kind { - case .getActive: - return .get - } - } - - var task: Task { - switch kind { - case .getActive: - return .requestPlain - } - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Node/Services/TransactionNodeService.swift b/WavesWallet-iOS/DataLayer/Service/Node/Services/TransactionNodeService.swift deleted file mode 100644 index 9af0a6f5..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Node/Services/TransactionNodeService.swift +++ /dev/null @@ -1,308 +0,0 @@ -// -// TransactionsService.swift -// WavesWallet-iOS -// -// Created by Prokofev Ruslan on 07/08/2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import Moya -import WavesSDKExtension -import WavesSDKCrypto - -fileprivate enum Constants { - static let transactions = "transactions" - static let limit = "limit" - static let address = "address" - static let info = "info" - static let broadcast = "broadcast" - - static let version: String = "version" - static let alias: String = "alias" - static let fee: String = "fee" - static let timestamp: String = "timestamp" - static let type: String = "type" - static let senderPublicKey: String = "senderPublicKey" - static let proofs: String = "proofs" - static let chainId: String = "chainId" - static let recipient: String = "recipient" - static let amount: String = "amount" - static let quantity: String = "quantity" - static let assetId: String = "assetId" - static let leaseId: String = "leaseId" - static let data: String = "data" - static let feeAssetId: String = "feeAssetId" - static let feeAsset: String = "feeAsset" - static let attachment: String = "attachment" -} - -extension Node.Service { - - struct Transaction { - - struct Burn { - let version: Int - let type: Int - let scheme: String - let fee: Int64 - let assetId: String - let quantity: Int64 - let timestamp: Int64 - let senderPublicKey: String - let proofs: [String] - } - - struct Alias { - let version: Int - let name: String - let fee: Int64 - let timestamp: Int64 - let type: Int - let senderPublicKey: String - let proofs: [String]? - } - - struct Lease { - let version: Int - let scheme: String - let fee: Int64 - let recipient: String - let amount: Int64 - let timestamp: Int64 - let type: Int - let senderPublicKey: String - let proofs: [String] - } - - struct LeaseCancel { - let version: Int - let scheme: String - let fee: Int64 - let leaseId: String - let timestamp: Int64 - let type: Int - let senderPublicKey: String - let proofs: [String] - } - - struct Data { - struct Value { - enum Kind { - case integer(Int64) - case boolean(Bool) - case string(String) - case binary(String) - } - - let key: String - let value: Kind - } - - let type: Int - let version: Int - let fee: Int64 - let timestamp: Int64 - let senderPublicKey: String - let proofs: [String] - let data: [Value] - } - - struct Send { - let type: Int - let version: Int - let recipient: String - let assetId: String - let amount: Int64 - let fee: Int64 - let attachment: String - let feeAssetId: String - let feeAsset: String = "" - let timestamp: Int64 - let senderPublicKey: String - let proofs: [String] - } - - enum BroadcastSpecification { - case createAlias(Alias) - case startLease(Lease) - case cancelLease(LeaseCancel) - case burn(Burn) - case data(Data) - case send(Send) - - var params: [String: Any] { - switch self { - case .burn(let burn): - return [Constants.version: burn.version, - Constants.chainId: burn.scheme, - Constants.senderPublicKey: burn.senderPublicKey, - Constants.quantity: burn.quantity, - Constants.fee: burn.fee, - Constants.timestamp: burn.timestamp, - Constants.proofs: burn.proofs, - Constants.type: burn.type, - Constants.assetId: burn.assetId] - - case .createAlias(let alias): - return [Constants.version: alias.version, - Constants.alias: alias.name, - Constants.fee: alias.fee, - Constants.timestamp: alias.timestamp, - Constants.type: alias.type, - Constants.senderPublicKey: alias.senderPublicKey, - Constants.proofs: alias.proofs ?? []] - - case .startLease(let lease): - let scheme: UInt8 = lease.scheme.utf8.last ?? UInt8(0) - return [Constants.version: lease.version, - Constants.chainId: scheme, - Constants.senderPublicKey: lease.senderPublicKey, - Constants.recipient: lease.recipient, - Constants.amount: lease.amount, - Constants.fee: lease.fee, - Constants.timestamp: lease.timestamp, - Constants.proofs: lease.proofs, - Constants.type: lease.type] - - case .cancelLease(let lease): - let scheme: UInt8 = lease.scheme.utf8.last ?? UInt8(0) - return [Constants.version: lease.version, - Constants.chainId: scheme, - Constants.senderPublicKey: lease.senderPublicKey, - Constants.fee: lease.fee, - Constants.timestamp: lease.timestamp, - Constants.proofs: lease.proofs, - Constants.type: lease.type, - Constants.leaseId: lease.leaseId] - - case .data(let data): - - return [Constants.version: data.version, - Constants.senderPublicKey: data.senderPublicKey, - Constants.fee: data.fee, - Constants.timestamp: data.timestamp, - Constants.proofs: data.proofs, - Constants.type: data.type, - Constants.data: data.data.dataByParams] - - case .send(let model): - - return [Constants.type: model.type, - Constants.senderPublicKey : model.senderPublicKey, - Constants.fee: model.fee, - Constants.timestamp: model.timestamp, - Constants.proofs: model.proofs, - Constants.version: model.version, - Constants.recipient: model.recipient, - Constants.assetId: model.assetId, - Constants.feeAssetId: model.feeAssetId, - Constants.feeAsset: model.feeAsset, - Constants.amount: model.amount, - Constants.attachment: model.attachment] - } - } - } - - enum Kind { - /** - Response: - - Node.DTO.TransactionContainers.self - */ - case list(accountAddress: String, limit: Int) - /** - Response: - - ? - */ - case info(id: String) - - case broadcast(BroadcastSpecification) - } - - var kind: Kind - var environment: Environment - } -} - -extension Node.Service.Transaction: NodeTargetType { - var modelType: Encodable.Type { - return String.self - } - - var path: String { - switch kind { - case .list(let accountAddress, let limit): - return Constants.transactions + "/" + Constants.address + "/" + "\(accountAddress)".urlEscaped + "/" + Constants.limit + "/" + "\(limit)".urlEscaped - - case .info(let id): - return Constants.transactions + "/" + Constants.info + "/" + "\(id)".urlEscaped - - case .broadcast: - return Constants.transactions + "/" + Constants.broadcast - } - } - - var method: Moya.Method { - switch kind { - case .list, .info: - return .get - case .broadcast: - return .post - } - } - - var task: Task { - switch kind { - case .list, .info: - return .requestPlain - - case .broadcast(let specification): - return .requestParameters(parameters: specification.params, encoding: JSONEncoding.default) - } - } -} - -fileprivate extension Array where Element == Node.Service.Transaction.Data.Value { - - var dataByParams: [[String: Any]] { - - var list: [[String: Any]] = .init() - - for value in self { - list.append(value.params()) - } - - return list - } -} - -fileprivate extension Node.Service.Transaction.Data.Value { - - - func params() -> [String: Any] { - - var params: [String: Any] = .init() - - params["key"] = self.key - - switch self.value { - case .integer(let number): - params["type"] = "integer" - params["value"] = number - - case .boolean(let flag): - params["type"] = "boolean" - params["value"] = flag - - case .string(let txt): - params["type"] = "string" - params["value"] = txt - - case .binary(let binary): - params["type"] = "binary" - params["value"] = binary - } - - return params - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Node/Services/UtilsNodeService.swift b/WavesWallet-iOS/DataLayer/Service/Node/Services/UtilsNodeService.swift deleted file mode 100644 index 23afb1e0..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Node/Services/UtilsNodeService.swift +++ /dev/null @@ -1,53 +0,0 @@ -// -// UtilsNodeService.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 3/12/19. -// Copyright © 2019 Waves Platform. All rights reserved. -// - -import Foundation -import Moya -import WavesSDKExtension -import WavesSDKCrypto - -extension Node.Service { - - struct Utils { - enum Kind { - case time - } - - let environment: Environment - let kind: Kind - } -} - -extension Node.Service.Utils: NodeTargetType { - - private enum Constants { - static let utils = "utils" - static let time = "time" - } - - var path: String { - switch kind { - case .time: - return Constants.utils + "/" + Constants.time - } - } - - var method: Moya.Method { - switch kind { - case .time: - return .get - } - } - - var task: Task { - switch kind { - case .time: - return .requestPlain - } - } -} diff --git a/WavesWallet-iOS/DataLayer/Service/Spam/SpamService.swift b/WavesWallet-iOS/DataLayer/Service/Spam/SpamService.swift deleted file mode 100644 index 2e2a7c8f..00000000 --- a/WavesWallet-iOS/DataLayer/Service/Spam/SpamService.swift +++ /dev/null @@ -1,15 +0,0 @@ -// -// SpamService.swift -// WavesWallet-iOS -// -// Created by mefilt on 16.07.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -enum Spam {} - -extension Spam { - enum Service {} -} diff --git a/WavesWallet-iOS/DomainLayer/Assisstants/AnalyticManager/AnalyticManager+WalletAsset.swift b/WavesWallet-iOS/DomainLayer/Assisstants/AnalyticManager/AnalyticManager+WalletAsset.swift deleted file mode 100644 index dd697270..00000000 --- a/WavesWallet-iOS/DomainLayer/Assisstants/AnalyticManager/AnalyticManager+WalletAsset.swift +++ /dev/null @@ -1,62 +0,0 @@ -// -// AnalyticManager+WalletAsset.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 3/22/19. -// Copyright © 2019 Waves Platform. All rights reserved. -// - -import Foundation - -extension AnalyticManager.Event { - - enum WalletAsset { - - private static let key = "Currency" - - /* Нажата кнопка «Continue» у любой криптовалюты или токена. */ - case sendTap(assetName: String) - - /* Нажата кнопка «Confirm» у любой криптовалюты или токена. */ - case sendConfirm(assetName: String) - - /* Нажата кнопка «Continue» у любой криптовалюты или токена. */ - case receiveTap(assetName: String) - - /* Нажата кнопка «Continue» на экране с заполненными полями карты. */ - case cardReceiveTap - - - var name: String { - switch self { - case .sendTap: - return "Wallet Assets Send Tap" - - case .sendConfirm: - return "Wallet Assets Send Confirm" - - case .receiveTap: - return "Wallet Assets Receive Tap" - - case .cardReceiveTap: - return "Wallet Assets Card Receive Tap" - } - } - - var params: [String : String] { - switch self { - case .sendTap(let assetName): - return [WalletAsset.key: assetName] - - case .sendConfirm(let assetName): - return [WalletAsset.key: assetName] - - case .receiveTap(let assetName): - return [WalletAsset.key: assetName] - - default: - return [:] - } - } - } -} diff --git a/WavesWallet-iOS/DomainLayer/Assisstants/AnalyticManager/AnalyticManager+WalletStart.swift b/WavesWallet-iOS/DomainLayer/Assisstants/AnalyticManager/AnalyticManager+WalletStart.swift deleted file mode 100644 index 9a81cc59..00000000 --- a/WavesWallet-iOS/DomainLayer/Assisstants/AnalyticManager/AnalyticManager+WalletStart.swift +++ /dev/null @@ -1,36 +0,0 @@ -// -// AnalyticManager+WalletStart.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 3/22/19. -// Copyright © 2019 Waves Platform. All rights reserved. -// - -import Foundation - -extension AnalyticManager.Event { - enum WalletStart { - - private static let key = "Currency" - - /* Необходимо запоминать нулевые балансы для нашего general листа и - при пополнении ассета любым способом отправлять событие. - Изменение баланса с нуля, считаем только 1 раз. */ - case balanceFromZero(assetName: String) - - var name: String { - switch self { - case .balanceFromZero: - return "Wallet Start Balance from Zero" - } - } - - var params: [String: String] { - switch self { - case .balanceFromZero(let assetName): - return [WalletStart.key: assetName] - } - } - } - -} diff --git a/WavesWallet-iOS/DomainLayer/Assisstants/AnalyticManager/AnalyticManager.swift b/WavesWallet-iOS/DomainLayer/Assisstants/AnalyticManager/AnalyticManager.swift deleted file mode 100644 index 0878d766..00000000 --- a/WavesWallet-iOS/DomainLayer/Assisstants/AnalyticManager/AnalyticManager.swift +++ /dev/null @@ -1,137 +0,0 @@ -// -// AnalyticManager.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 3/22/19. -// Copyright © 2019 Waves Platform. All rights reserved. -// - -import Foundation -import Amplitude_iOS -import Firebase -import FirebaseAnalytics -import AppsFlyerLib - -private protocol AnalyticManagerProtocol { - associatedtype Event - static func trackEvent(_ event: Event) -} - -final class AnalyticManager: AnalyticManagerProtocol { - - enum Event { - - case leasing(Leasing) - case createAlias(CreateAlias) - case dex(Dex) - case walletAsset(WalletAsset) - case tokenBurn(TokenBurn) - case walletStart(WalletStart) - case newUser(NewUser) - } - - - static func trackEvent(_ event: Event) { - - Amplitude.instance().logEvent(event.name, withEventProperties: event.params) - Analytics.logEvent(event.name.replacingOccurrences(of: " ", with: "_"), parameters: event.params) - AppsFlyerTracker.shared()?.trackEvent(event.name, withValues: event.params) - } -} - -//MARK - Event params -extension AnalyticManager.Event { - - var name: String { - switch self { - case .leasing(let leasing): - return leasing.rawValue - - case .createAlias(let alias): - return alias.rawValue - - case .dex(let dex): - return dex.name - - case .walletAsset(let walletAsset): - return walletAsset.name - - case .tokenBurn(let tokenBurn): - return tokenBurn.rawValue - - case .walletStart(let walletStart): - return walletStart.name - - case .newUser(let user): - return user.rawValue - } - } - - var params: [String : String] { - switch self { - - case .dex(let dex): - return dex.params - - case .walletAsset(let walletAsset): - return walletAsset.params - - case .walletStart(let walletStart): - return walletStart.params - - default: - return [:] - } - } -} - -//MARK: - Leasing -extension AnalyticManager.Event { - enum Leasing: String { - - /* Нажата кнопка «Start Lease» на экране Wallet. */ - case leasingStartTap = "Leasing Start Tap" - - /* Нажата кнопка «Start Lease» на экране с заполненными полями. */ - case leasingSendTap = "Leasing Send Tap" - - /* Нажата кнопка «Confirm» на экране подтверждения лизинга. */ - case leasingConfirmTap = "Leasing Confirm Tap" - } -} - -//MARK: - CreateAlias -extension AnalyticManager.Event { - enum CreateAlias: String { - - /* Нажата кнопка «Create a new alias» на экране профайла. */ - case createProfile = "Alias Create Profile" - - /* Нажата кнопка «Create a new alias» на экране визитки. */ - case aliasCreateVcard = "Alias Create Vcard" - } -} - -//MARK: - TokenBurn -extension AnalyticManager.Event { - enum TokenBurn: String { - - /* Нажата кнопка «Token Burn» на экране ассета. */ - case tap = "Burn Token Tap" - - /* Нажата кнопка «Burn» на экране с заполненными полями. */ - case continueTap = "Burn Token Continue Tap" - - /* Нажата кнопка «Burn» на экране подтверждения. */ - case confirmTap = "Burn Token Confirm Tap" - } -} - -//MARK: - NewUser -extension AnalyticManager.Event { - enum NewUser: String { - - /* Проставлены 3 чекбокса с условиями использования и нажата кнопка "Begin". */ - case confirm = "New User Confirm" - } -} diff --git a/WavesWallet-iOS/DomainLayer/Assisstants/ApplicationDebugSettings.swift b/WavesWallet-iOS/DomainLayer/Assisstants/ApplicationDebugSettings.swift deleted file mode 100644 index d6cb867a..00000000 --- a/WavesWallet-iOS/DomainLayer/Assisstants/ApplicationDebugSettings.swift +++ /dev/null @@ -1,46 +0,0 @@ -// -// ApplicationDebugSettings.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 3/28/19. -// Copyright © 2019 Waves Platform. All rights reserved. -// - -import Foundation -import WavesSDKExtension - -struct ApplicationDebugSettings: TSUD, Codable, Mutating { - - private static let key: String = "com.waves.debug.settings" - - private var isEnableStage: Bool = false - private var isEnableNotificationsSettingDev: Bool = false - - static var defaultValue: ApplicationDebugSettings { - return ApplicationDebugSettings(isEnableStage: false, isEnableNotificationsSettingDev: false) - } - - static var stringKey: String { - return key - } - - static var isEnableStage: Bool { - return ApplicationDebugSettings.get().isEnableStage - } - - static func setupIsEnableStage(isEnable: Bool) { - var settings = ApplicationDebugSettings.get() - settings.isEnableStage = isEnable - ApplicationDebugSettings.set(settings) - } - - static var isEnableNotificationsSettingDev: Bool { - return ApplicationDebugSettings.get().isEnableNotificationsSettingDev - } - - static func setEnableNotificationsSettingDev(isEnable: Bool) { - var settings = ApplicationDebugSettings.get() - settings.isEnableNotificationsSettingDev = isEnable - ApplicationDebugSettings.set(settings) - } -} diff --git a/WavesWallet-iOS/DomainLayer/Assisstants/Type/SentryManager.swift b/WavesWallet-iOS/DomainLayer/Assisstants/Type/SentryManager.swift deleted file mode 100644 index 188ecd7b..00000000 --- a/WavesWallet-iOS/DomainLayer/Assisstants/Type/SentryManager.swift +++ /dev/null @@ -1,65 +0,0 @@ -// -// SentryService.swift -// WavesWallet-iOS -// -// Created by rprokofev on 27/02/2019. -// Copyright © 2019 Waves Platform. All rights reserved. -// - -import Foundation -import Sentry -import WavesSDKExtension - -public class SentryManager { - - typealias Event = Sentry.Event - - typealias Level = SweetLoggerLevel - - private static var shared = SentryManager() - - private var client: Client? = nil - - init() { - if let path = Bundle.main.path(forResource: "Sentry-io-Info", ofType: "plist"), - let dsn = NSDictionary(contentsOfFile: path)?["DSN_URL"] as? String { - - do { - let client = try Client(dsn: dsn) - self.client = client - Client.shared = self.client - } catch let error { - print("Sentry Not Loading :( \(error)") - } - - do { - try Client.shared?.startCrashHandler() - } catch let error { - print("Centry startCrashHandler :( \(error)") - } - } - - Client.shared?.enableAutomaticBreadcrumbTracking() - } - - static var currentUser: Sentry.User { - - let user = Sentry.User() - user.userId = UIDevice.uuid - return user - } - - static func send(event: Event) { - - event.timestamp = Date() - event.user = currentUser - - SentryManager.shared.client?.send(event: event, completion: { error in - - if let error = error { - print("SweetLogger :( \(String(describing: error))") - } - }) - } -} - diff --git a/WavesWallet-iOS/DomainLayer/FactoryInteractors.swift b/WavesWallet-iOS/DomainLayer/FactoryInteractors.swift deleted file mode 100644 index 211cc52b..00000000 --- a/WavesWallet-iOS/DomainLayer/FactoryInteractors.swift +++ /dev/null @@ -1,118 +0,0 @@ -// -// FactoryInteractors.swift -// WavesWallet-iOS -// -// Created by mefilt on 06.08.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -private struct AuthorizationInteractorLocalizableImp: AuthorizationInteractorLocalizable { - var fallbackTitle: String { - return Localizable.Waves.Biometric.localizedFallbackTitle - } - var cancelTitle: String { - return Localizable.Waves.Biometric.localizedCancelTitle - } - var readFromkeychain: String { - return Localizable.Waves.Biometric.readfromkeychain - } - var saveInkeychain: String { - return Localizable.Waves.Biometric.saveinkeychain - } -} - -final class FactoryInteractors: FactoryInteractorsProtocol { - - static let instance: FactoryInteractors = FactoryInteractors() - - private(set) lazy var assetsInteractor: AssetsInteractorProtocol = { - - let instance = FactoryRepositories.instance - let interactor = AssetsInteractor(assetsRepositoryLocal: instance.assetsRepositoryLocal, - assetsRepositoryRemote: instance.assetsRepositoryRemote) - - return interactor - }() - - private(set) lazy var accountBalance: AccountBalanceInteractorProtocol = { - let instance = FactoryRepositories.instance - let interactor = AccountBalanceInteractor(authorizationInteractor: self.authorization, - balanceRepositoryRemote: instance.accountBalanceRepositoryRemote, - environmentRepository: instance.environmentRepository, - assetsInteractor: self.assetsInteractor, - assetsBalanceSettings: self.assetsBalanceSettings, - transactionsInteractor: self.transactions, - assetsBalanceSettingsRepository: instance.assetsBalanceSettingsRepositoryLocal) - return interactor - }() - - private(set) lazy var transactions: TransactionsInteractorProtocol = { - - let instance = FactoryRepositories.instance - - let interactor = TransactionsInteractor(transactionsRepositoryLocal: instance.transactionsRepositoryLocal, - transactionsRepositoryRemote: instance.transactionsRepositoryRemote, - assetsInteractors: self.assetsInteractor, - addressInteractors: self.address, - addressRepository: instance.addressRepository, - assetsRepositoryRemote: instance.assetsRepositoryRemote, - blockRepositoryRemote: instance.blockRemote, - accountSettingsRepository: instance.accountSettingsRepository) - return interactor - }() - - private(set) lazy var address: AddressInteractorProtocol = { - - let instance = FactoryRepositories.instance - - let interactor = AddressInteractor(addressBookRepository: instance.addressBookRepository, - aliasesInteractor: self.aliases) - return interactor - }() - - private(set) lazy var authorization: AuthorizationInteractorProtocol = { - - let instance = FactoryRepositories.instance - - let interactor = AuthorizationInteractor(localWalletRepository: instance.walletsRepositoryLocal, - localWalletSeedRepository: instance.walletSeedRepositoryLocal, - remoteAuthenticationRepository: instance.authenticationRepositoryRemote, - accountSettingsRepository: instance.accountSettingsRepository, - localizable: AuthorizationInteractorLocalizableImp()) - - return interactor - }() - - private(set) lazy var aliases: AliasesInteractorProtocol = { - - let instance = FactoryRepositories.instance - - let interactor = AliasesInteractor(aliasesRepositoryRemote: instance.aliasesRepositoryRemote, - aliasesRepositoryLocal: instance.aliasesRepositoryLocal) - - return interactor - }() - - private(set) lazy var assetsBalanceSettings: AssetsBalanceSettingsInteractorProtocol = { - - let instance = FactoryRepositories.instance - - let interactor = AssetsBalanceSettingsInteractor(assetsBalanceSettingsRepositoryLocal: instance.assetsBalanceSettingsRepositoryLocal, - environmentRepository: instance.environmentRepository, - authorizationInteractor: authorization) - - return interactor - }() - - private(set) lazy var migrationInteractor: MigrationInteractor = { - - let instance = FactoryRepositories.instance - return MigrationInteractor(walletsRepository: instance.walletsRepositoryLocal) - }() - - var applicationVersionUseCase: ApplicationVersionUseCase = ApplicationVersionUseCase() - - fileprivate init() {} -} diff --git a/WavesWallet-iOS/DomainLayer/FactoryInteractorsProtocol.swift b/WavesWallet-iOS/DomainLayer/FactoryInteractorsProtocol.swift deleted file mode 100644 index b1e6aa7e..00000000 --- a/WavesWallet-iOS/DomainLayer/FactoryInteractorsProtocol.swift +++ /dev/null @@ -1,22 +0,0 @@ -// -// FactoryInteractor.swift -// WavesWallet-iOS -// -// Created by mefilt on 06.08.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -protocol FactoryInteractorsProtocol { - var assetsInteractor: AssetsInteractorProtocol { get } - var accountBalance: AccountBalanceInteractorProtocol { get } - var transactions: TransactionsInteractorProtocol { get } - var address: AddressInteractorProtocol { get } - var authorization: AuthorizationInteractorProtocol { get } - var aliases: AliasesInteractorProtocol { get } - var assetsBalanceSettings: AssetsBalanceSettingsInteractorProtocol { get } - var migrationInteractor: MigrationInteractor { get } - - var applicationVersionUseCase: ApplicationVersionUseCase { get } -} diff --git a/WavesWallet-iOS/DomainLayer/FactoryRepositories.swift b/WavesWallet-iOS/DomainLayer/FactoryRepositories.swift deleted file mode 100644 index fdd934dd..00000000 --- a/WavesWallet-iOS/DomainLayer/FactoryRepositories.swift +++ /dev/null @@ -1,65 +0,0 @@ -// -// FactoryRepositories.swift -// WavesWallet-iOS -// -// Created by mefilt on 06.08.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -final class FactoryRepositories: FactoryRepositoriesProtocol { - - static let instance: FactoryRepositories = FactoryRepositories() - - private(set) lazy var assetsRepositoryLocal: AssetsRepositoryProtocol = AssetsRepositoryLocal() - private(set) lazy var assetsRepositoryRemote: AssetsRepositoryProtocol = AssetsRepositoryRemote(environmentRepository: self.environmentRepository) - - private(set) lazy var accountBalanceRepositoryLocal: AccountBalanceRepositoryProtocol = AccountBalanceRepositoryLocal() - private(set) lazy var accountBalanceRepositoryRemote: AccountBalanceRepositoryProtocol = AccountBalanceRepositoryRemote(environmentRepository: self.environmentRepository) - - private(set) lazy var transactionsRepositoryLocal: TransactionsRepositoryProtocol = TransactionsRepositoryLocal() - private(set) lazy var transactionsRepositoryRemote: TransactionsRepositoryProtocol = TransactionsRepositoryRemote(environmentRepository: self.environmentRepository) - - private(set) lazy var blockRemote: BlockRepositoryProtocol = BlockRepositoryRemote(environmentRepository: self.environmentRepository) - - private(set) lazy var walletsRepositoryLocal: WalletsRepositoryProtocol = WalletsRepositoryLocal() - - private(set) lazy var walletSeedRepositoryLocal: WalletSeedRepositoryProtocol = WalletSeedRepositoryLocal() - - private(set) lazy var authenticationRepositoryRemote: AuthenticationRepositoryProtocol = AuthenticationRepositoryRemote() - - private(set) lazy var environmentRepository: EnvironmentRepositoryProtocol = EnvironmentRepository() - - private(set) lazy var accountSettingsRepository: AccountSettingsRepositoryProtocol = AccountSettingsRepository() - - private(set) lazy var addressBookRepository: AddressBookRepositoryProtocol = AddressBookRepository() - - private(set) lazy var dexRealmRepository: DexRealmRepositoryProtocol = DexRealmRepositoryLocal() - - private(set) lazy var dexPairsPriceRepository: DexPairsPriceRepositoryProtocol = DexPairsPriceRepositoryRemote(environmentRepository: self.environmentRepository) - - private(set) lazy var dexOrderBookRepository: DexOrderBookRepositoryProtocol = DexOrderBookRepositoryRemote(environmentRepository: self.environmentRepository) - - private(set) lazy var aliasesRepositoryRemote: AliasesRepositoryProtocol = AliasesRepository(environmentRepository: self.environmentRepository) - - private(set) lazy var aliasesRepositoryLocal: AliasesRepositoryProtocol = AliasesRepositoryLocal() - - private(set) lazy var assetsBalanceSettingsRepositoryLocal: AssetsBalanceSettingsRepositoryProtocol = AssetsBalanceSettingsRepositoryLocal() - - private(set) lazy var candlesRepository: CandlesRepositoryProtocol = CandlesRepositoryRemote(environmentRepository: self.environmentRepository) - - private(set) lazy var lastTradesRespository: LastTradesRepositoryProtocol = LastTradesRepositoryRemote(environmentRepository: self.environmentRepository) - - private(set) lazy var coinomatRepository: CoinomatRepositoryProtocol = CoinomatRepository() - - private(set) lazy var matcherRepository: MatcherRepositoryProtocol = MatcherRepositoryRemote(environmentRepository: self.environmentRepository) - - private(set) lazy var addressRepository: AddressRepositoryProtocol = AddressRepositoryRemote(environmentRepository: self.environmentRepository) - - private(set) lazy var notificationNewsRepository: NotificationNewsRepositoryProtocol = NotificationNewsRepository() - - private(set) lazy var applicationVersionRepository: ApplicationVersionRepositoryProtocol = ApplicationVersionRepository() - - fileprivate init() {} -} diff --git a/WavesWallet-iOS/DomainLayer/Interactor/AccountsInteractor.swift b/WavesWallet-iOS/DomainLayer/Interactor/AccountsInteractor.swift deleted file mode 100644 index 02ab22d8..00000000 --- a/WavesWallet-iOS/DomainLayer/Interactor/AccountsInteractor.swift +++ /dev/null @@ -1,111 +0,0 @@ -// -// AccountsInteractorProtocol.swift -// WavesWallet-iOS -// -// Created by mefilt on 10.09.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import RxSwift -import RxCocoa - -protocol AddressInteractorProtocol { - func address(by ids: [String], myAddress: String) -> Observable<[DomainLayer.DTO.Address]> - func addressSync(by ids: [String], myAddress: String) -> SyncObservable<[DomainLayer.DTO.Address]> -} - -final class AddressInteractor: AddressInteractorProtocol { - - private let addressBookRepository: AddressBookRepositoryProtocol - private let aliasesInteractor: AliasesInteractorProtocol - - init(addressBookRepository: AddressBookRepositoryProtocol, - aliasesInteractor: AliasesInteractorProtocol) { - - self.addressBookRepository = addressBookRepository - self.aliasesInteractor = aliasesInteractor - } - - func addressSync(by ids: [String], myAddress: String) -> SyncObservable<[DomainLayer.DTO.Address]> { - return aliasesInteractor - .aliases(by: myAddress) - .flatMapLatest { [weak self] (sync) -> SyncObservable<[DomainLayer.DTO.Address]> in - - guard let owner = self else { return Observable.never() } - - if let remote = sync.remote { - - return owner - .localAddress(myAliases: remote, ids: ids, accountAddress: myAddress) - .map({ accounts -> Sync<[DomainLayer.DTO.Address]> in - return .remote(accounts) - }) - .catchError({ (localError) -> SyncObservable<[DomainLayer.DTO.Address]> in - return .error(localError) - }) - - } else if let local = sync.local { - - return owner - .localAddress(myAliases: local.result, ids: ids, accountAddress: myAddress) - .map({ accounts -> Sync<[DomainLayer.DTO.Address]> in - return .local(accounts, error: local.error) - }) - .catchError({ (localError) -> SyncObservable<[DomainLayer.DTO.Address]> in - return .error(local.error) - }) - } else if let error = sync.error { - return SyncObservable.just(.error(error)) - } - return Observable.never() - } - .share() - .subscribeOn(ConcurrentDispatchQueueScheduler(queue: DispatchQueue.global(qos: .userInteractive))) - } - - private func localAddress(myAliases: [DomainLayer.DTO.Alias], ids: [String], accountAddress: String) -> Observable<[DomainLayer.DTO.Address]> { - - return Observable.merge(addressBookRepository.listListener(by: accountAddress), - addressBookRepository.list(by: accountAddress)) - .flatMap({ (contacts) -> Observable<[DomainLayer.DTO.Address]> in - - let maps = contacts.reduce(into: [String : DomainLayer.DTO.Contact](), { (result, contact) in - result[contact.address] = contact - }) - - let accounts = ids.map({ address -> DomainLayer.DTO.Address in - - let isMyAccount = accountAddress == address || myAliases.map { $0.name }.contains(address) - return DomainLayer.DTO.Address(address: address, - contact: maps[address], - isMyAccount: isMyAccount, - aliases: isMyAccount == true ? myAliases : []) - }) - - return Observable.just(accounts) - }) - } - - func address(by ids: [String], myAddress: String) -> Observable<[DomainLayer.DTO.Address]> { - - return self.addressSync(by: ids, myAddress: myAddress) - .flatMap({ (sync) -> Observable<[DomainLayer.DTO.Address]> in - - if let remote = sync.resultIngoreError { - return Observable.just(remote) - } - - switch sync { - case .remote(let model): - return Observable.just(model) - - case .local(_, let error): - return Observable.error(error) - - case .error(let error): - return Observable.error(error) - } - }) - } -} diff --git a/WavesWallet-iOS/DomainLayer/Interactor/ApplicationVersionUseCase.swift b/WavesWallet-iOS/DomainLayer/Interactor/ApplicationVersionUseCase.swift deleted file mode 100644 index 7d0b3ce7..00000000 --- a/WavesWallet-iOS/DomainLayer/Interactor/ApplicationVersionUseCase.swift +++ /dev/null @@ -1,32 +0,0 @@ -// -// ApplicationVersionUseCase.swift -// WavesWallet-iOS -// -// Created by rprokofev on 30/05/2019. -// Copyright © 2019 Waves Platform. All rights reserved. -// - -import Foundation -import RxSwift - -final class ApplicationVersionUseCase { - - private let repository: ApplicationVersionRepositoryProtocol = FactoryRepositories.instance.applicationVersionRepository - - func isHasNewVersion() -> Observable { - - return repository - .version() - .flatMap { (version) -> Observable in - let currentVersion = Bundle.main.version.versionToInt() - return Observable.just(currentVersion.lexicographicallyPrecedes(version.versionToInt())) - } - } -} - -private extension String { - func versionToInt() -> [Int] { - return self.components(separatedBy: ".") - .map { Int.init($0) ?? 0 } - } -} diff --git a/WavesWallet-iOS/DomainLayer/Models/DTO/AccountEnvironmentDomainDTO.swift b/WavesWallet-iOS/DomainLayer/Models/DTO/AccountEnvironmentDomainDTO.swift deleted file mode 100644 index 4ebfdb3d..00000000 --- a/WavesWallet-iOS/DomainLayer/Models/DTO/AccountEnvironmentDomainDTO.swift +++ /dev/null @@ -1,19 +0,0 @@ -// -// AccountEnvironmentDomainDTO.swift -// WavesWallet-iOS -// -// Created by mefilt on 24/10/2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension DomainLayer.DTO { - - struct AccountEnvironment: Equatable, Mutating { - var nodeUrl: String? - var dataUrl: String? - var spamUrl: String? - var matcherUrl: String? - } -} diff --git a/WavesWallet-iOS/DomainLayer/Models/DTO/AssetBalanceDomainDTO.swift b/WavesWallet-iOS/DomainLayer/Models/DTO/AssetBalanceDomainDTO.swift deleted file mode 100644 index 9ed984f7..00000000 --- a/WavesWallet-iOS/DomainLayer/Models/DTO/AssetBalanceDomainDTO.swift +++ /dev/null @@ -1,49 +0,0 @@ -// -// AssetBalanceDomainDTO.swift -// WavesWallet-iOS -// -// Created by Prokofev Ruslan on 05/08/2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import WavesSDKExtension - -extension DomainLayer.DTO { - - struct SmartAssetBalance: Mutating { - let assetId: String - var totalBalance: Int64 - var leasedBalance: Int64 - var inOrderBalance: Int64 - var settings: DomainLayer.DTO.AssetBalanceSettings - var asset: DomainLayer.DTO.Asset - var modified: Date - let sponsorBalance: Int64 - } - - struct AssetBalance: Mutating { - - let assetId: String - var totalBalance: Int64 - var leasedBalance: Int64 - var inOrderBalance: Int64 - var modified: Date - let sponsorBalance: Int64 - let minSponsoredAssetFee: Int64 - } - - struct AssetBalanceSettings: Mutating { - let assetId: String - var sortLevel: Float - var isHidden: Bool - var isFavorite: Bool - } -} - -extension DomainLayer.DTO.SmartAssetBalance { - - var availableBalance: Int64 { - return max(totalBalance - leasedBalance - inOrderBalance, 0) - } -} diff --git a/WavesWallet-iOS/DomainLayer/Models/DTO/AssetDomainDTO.swift b/WavesWallet-iOS/DomainLayer/Models/DTO/AssetDomainDTO.swift deleted file mode 100644 index 023dd92c..00000000 --- a/WavesWallet-iOS/DomainLayer/Models/DTO/AssetDomainDTO.swift +++ /dev/null @@ -1,74 +0,0 @@ -// -// File.swift -// WavesWallet-iOS -// -// Created by Prokofev Ruslan on 04/08/2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension DomainLayer.DTO { - - struct Asset: Mutating, Equatable { - - struct Icon: Equatable { - let assetId: String - let name: String - let url: String? - } - - let id: String - let gatewayId: String? - let wavesId: String? - let displayName: String - let precision: Int - let description: String - let height: Int64 - let timestamp: Date - let sender: String - let quantity: Int64 - let ticker: String? - let isReusable: Bool - var isSpam: Bool - let isFiat: Bool - let isGeneral: Bool - let isMyWavesToken: Bool - let isWavesToken: Bool - let isGateway: Bool - let isWaves: Bool - let modified: Date - let addressRegEx: String - let iconLogoUrl: String? - let hasScript: Bool - var minSponsoredFee: Int64 - } -} - -extension DomainLayer.DTO.Asset { - - var iconLogo: DomainLayer.DTO.Asset.Icon { - return DomainLayer.DTO.Asset.Icon(assetId: id, name: icon, url: iconLogoUrl) - } - - var icon: String { - - if let gatewayId = gatewayId, gatewayId.count > 0 { - return gatewayId - } - - return displayName - } - - var isMonero: Bool { - return gatewayId == "XMR" - } - - var isEthereum: Bool { - return gatewayId == "ETH" - } - - var isSponsored: Bool { - return minSponsoredFee > 0 - } -} diff --git a/WavesWallet-iOS/DomainLayer/Models/DTO/CandleDomainDTO.swift b/WavesWallet-iOS/DomainLayer/Models/DTO/CandleDomainDTO.swift deleted file mode 100644 index b6b81a26..00000000 --- a/WavesWallet-iOS/DomainLayer/Models/DTO/CandleDomainDTO.swift +++ /dev/null @@ -1,43 +0,0 @@ -// -// CandleDomainDTO.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 12/5/18. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension DomainLayer.DTO { - - struct Candle { - let close: Double - let high: Double - let low: Double - let open: Double - let timestamp: Double - let volume: Double - } -} - -extension DomainLayer.DTO.Candle { - enum TimeFrameType: Int { - case m5 = 5 - case m15 = 15 - case m30 = 30 - case h1 = 60 - case h4 = 240 - case h24 = 1440 - } -} - -extension DomainLayer.DTO.Candle: Equatable { - static func == (lhs: DomainLayer.DTO.Candle, rhs: DomainLayer.DTO.Candle) -> Bool { - return lhs.close == rhs.close && - lhs.high == rhs.high && - lhs.low == rhs.low && - lhs.open == rhs.open && - lhs.timestamp == rhs.timestamp && - lhs.volume == rhs.volume - } -} diff --git a/WavesWallet-iOS/DomainLayer/Models/DTO/CoinomatDomainDTO.swift b/WavesWallet-iOS/DomainLayer/Models/DTO/CoinomatDomainDTO.swift deleted file mode 100644 index 80db10e5..00000000 --- a/WavesWallet-iOS/DomainLayer/Models/DTO/CoinomatDomainDTO.swift +++ /dev/null @@ -1,31 +0,0 @@ -// -// CoinomatDomainDTO.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 12/14/18. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension DomainLayer.DTO { - enum Coinomat { - - struct TunnelInfo { - let address: String - let attachment: String - let min: Money - } - - struct Rate { - let fee: Money - let min: Money - let max: Money - } - - struct CardLimit { - let min: Money - let max: Money - } - } -} diff --git a/WavesWallet-iOS/DomainLayer/Models/DTO/ContactDomainDTO.swift b/WavesWallet-iOS/DomainLayer/Models/DTO/ContactDomainDTO.swift deleted file mode 100644 index a259ae4c..00000000 --- a/WavesWallet-iOS/DomainLayer/Models/DTO/ContactDomainDTO.swift +++ /dev/null @@ -1,16 +0,0 @@ -// -// AddressBookDomainDTO.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 9/25/18. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension DomainLayer.DTO { - struct Contact: Hashable { - let name: String - let address: String - } -} diff --git a/WavesWallet-iOS/DomainLayer/Models/DTO/DexDomainDTO.swift b/WavesWallet-iOS/DomainLayer/Models/DTO/DexDomainDTO.swift deleted file mode 100644 index 8d39b29a..00000000 --- a/WavesWallet-iOS/DomainLayer/Models/DTO/DexDomainDTO.swift +++ /dev/null @@ -1,114 +0,0 @@ -// -// DexTypes.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 9/12/18. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension DomainLayer.DTO { - enum Dex {} -} - -//MARK: Asset -extension DomainLayer.DTO.Dex { - - struct Asset { - let id: String - let name: String - let shortName: String - let decimals: Int - } - - enum OrderType: String { - case sell - case buy - } -} - -//MARK: LastTrade -extension DomainLayer.DTO.Dex { - - struct LastTrade { - let time: Date - let price: Money - let amount: Money - let sum: Money - let type: OrderType - } -} - -//MARK: - SmartPair -extension DomainLayer.DTO.Dex { - - struct SmartPair: Mutating { - let id: String - let amountAsset: Asset - let priceAsset: Asset - var isChecked: Bool - let isGeneral: Bool - var sortLevel: Int - } -} - -//MARK: - Pair -extension DomainLayer.DTO.Dex { - - struct Pair { - let amountAsset: Asset - let priceAsset: Asset - } -} - -//MARK: - PairPrice -extension DomainLayer.DTO.Dex { - struct PairPrice { - let firstPrice: Money - let lastPrice: Money - let amountAsset: Asset - let priceAsset: Asset - } -} - -//MARK: - MyOrder - -extension DomainLayer.DTO.Dex { - - struct MyOrder { - - enum Status { - case accepted - case partiallyFilled - case cancelled - case filled - } - - let id: String - let time: Date - var status: Status - let price: Money - let amount: Money - let filled: Money - let type: OrderType - let amountAsset: Asset - let priceAsset: Asset - let percentFilled: Int - } -} - -//MARK: - OrderBook -extension DomainLayer.DTO.Dex { - - struct OrderBook { - - struct Value { - let amount: Int64 - let price: Int64 - } - - let bids: [Value] - let asks: [Value] - } -} diff --git a/WavesWallet-iOS/DomainLayer/Models/DTO/NotificationNewsDomainDTO.swift b/WavesWallet-iOS/DomainLayer/Models/DTO/NotificationNewsDomainDTO.swift deleted file mode 100644 index 56364060..00000000 --- a/WavesWallet-iOS/DomainLayer/Models/DTO/NotificationNewsDomainDTO.swift +++ /dev/null @@ -1,21 +0,0 @@ -// -// NotificationNewsDomainDTO.swift -// WavesWallet-iOS -// -// Created by mefilt on 15/02/2019. -// Copyright © 2019 Waves Platform. All rights reserved. -// - -import Foundation - -extension DomainLayer.DTO { - struct NotificationNews { - let startDate: Date - let endDate: Date - let logoUrl: String - let id: String - let title: [String: String] - let subTitle: [String: String] - } -} - diff --git a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/AddressDomainDTO.swift b/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/AddressDomainDTO.swift deleted file mode 100644 index 20d93a91..00000000 --- a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/AddressDomainDTO.swift +++ /dev/null @@ -1,19 +0,0 @@ -// -// AccountDomainDTO.swift -// WavesWallet-iOS -// -// Created by mefilt on 10.09.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension DomainLayer.DTO { - struct Address: Hashable { - - let address: String - let contact: DomainLayer.DTO.Contact? - let isMyAccount: Bool - let aliases: [DomainLayer.DTO.Alias] - } -} diff --git a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/AliasTransactionDomainDTO.swift b/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/AliasTransactionDomainDTO.swift deleted file mode 100644 index 950b51f2..00000000 --- a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/AliasTransactionDomainDTO.swift +++ /dev/null @@ -1,27 +0,0 @@ -// -// TransactionAliasNode.swift -// WavesWallet-iOS -// -// Created by Prokofev Ruslan on 07/08/2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension DomainLayer.DTO { - struct AliasTransaction: Decodable { - let type: Int - let id: String - let sender: String - let senderPublicKey: String - let fee: Int64 - let timestamp: Date - let version: Int - let height: Int64? - let signature: String? - let proofs: [String]? - let alias: String - var modified: Date - var status: TransactionStatus - } -} diff --git a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/AssetScriptTransactionDomainDTO.swift b/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/AssetScriptTransactionDomainDTO.swift deleted file mode 100644 index 53f9417c..00000000 --- a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/AssetScriptTransactionDomainDTO.swift +++ /dev/null @@ -1,32 +0,0 @@ -// -// AssetScriptTransactionDomainDTO.swift -// WavesWallet-iOS -// -// Created by mefilt on 22/01/2019. -// Copyright © 2019 Waves Platform. All rights reserved. -// - -import Foundation - -extension DomainLayer.DTO { - - struct AssetScriptTransaction { - - let type: Int - let id: String - let sender: String - let senderPublicKey: String - let fee: Int64 - let timestamp: Date - let height: Int64 - let signature: String? - let proofs: [String]? - let chainId: Int? - let version: Int - let script: String? - let assetId: String - - let modified: Date - var status: TransactionStatus - } -} diff --git a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/BurnTransactionDomainDTO.swift b/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/BurnTransactionDomainDTO.swift deleted file mode 100644 index 0bc72764..00000000 --- a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/BurnTransactionDomainDTO.swift +++ /dev/null @@ -1,30 +0,0 @@ -// -// TransactionBurnNode.swift -// WavesWallet-iOS -// -// Created by Prokofev Ruslan on 07/08/2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension DomainLayer.DTO { - struct BurnTransaction: Decodable { - let type: Int - let id: String - let sender: String - let senderPublicKey: String - let fee: Int64 - let timestamp: Date - let version: Int - let height: Int64 - - let signature: String? - let proofs: [String]? - let chainId: Int? - let assetId: String - let amount: Int64 - var modified: Date - var status: TransactionStatus - } -} diff --git a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/DataTransactionDomainDTO.swift b/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/DataTransactionDomainDTO.swift deleted file mode 100644 index b5ded742..00000000 --- a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/DataTransactionDomainDTO.swift +++ /dev/null @@ -1,40 +0,0 @@ -// -// TransactionDataNode.swift -// WavesWallet-iOS -// -// Created by Prokofev Ruslan on 07/08/2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension DomainLayer.DTO { - - struct DataTransaction { - struct Data { - enum Value { - case bool(Bool) - case integer(Int) - case string(String) - case binary(String) - } - let key: String - let value: Value - let type: String - } - - let type: Int - let id: String - let sender: String - let senderPublicKey: String - let fee: Int64 - let timestamp: Date - let height: Int64? - let version: Int - - let proofs: [String]? - let data: [Data] - var modified: Date - var status: TransactionStatus - } -} diff --git a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/ExchangeTransactionDomainDTO.swift b/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/ExchangeTransactionDomainDTO.swift deleted file mode 100644 index 4e1a7ec4..00000000 --- a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/ExchangeTransactionDomainDTO.swift +++ /dev/null @@ -1,60 +0,0 @@ -// -// TransactionExchangeNode.swift -// WavesWallet-iOS -// -// Created by Prokofev Ruslan on 07/08/2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension DomainLayer.DTO { - - struct ExchangeTransaction: Mutating { - - struct Order: Mutating { - - enum Kind { - case sell - case buy - } - - let id: String - let sender: String - let senderPublicKey: String - let matcherPublicKey: String - var assetPair: AssetPair - let orderType: Kind - let price: Int64 - let amount: Int64 - let timestamp: Date - let expiration: Int64 - let matcherFee: Int64 - let signature: String? - } - - struct AssetPair: Decodable, Mutating { - var amountAsset: String - var priceAsset: String - } - - let type: Int - let id: String - let sender: String - let senderPublicKey: String - let fee: Int64 - let timestamp: Date - let height: Int64 - - let signature: String? - let proofs: [String]? - var order1: Order - var order2: Order - let price: Int64 - let amount: Int64 - let buyMatcherFee: Int64 - let sellMatcherFee: Int64 - var modified: Date - var status: TransactionStatus - } -} diff --git a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/InvokeScriptTransactionDomainDTO.swift b/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/InvokeScriptTransactionDomainDTO.swift deleted file mode 100644 index 328ed831..00000000 --- a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/InvokeScriptTransactionDomainDTO.swift +++ /dev/null @@ -1,36 +0,0 @@ -// -// InvokeScriptTransactionDomainDTO.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 4/9/19. -// Copyright © 2019 Waves Platform. All rights reserved. -// - -import Foundation - -extension DomainLayer.DTO { - - struct InvokeScriptTransaction { - - struct Payment { - let amount: Int64 - let assetId: String? - } - - let type: Int - let id: String - let sender: String - let senderPublicKey: String - let fee: Int64 - let feeAssetId: String? - let timestamp: Date - let proofs: [String]? - let version: Int - let dappAddress: String - let payment: Payment? - let height: Int64 - - var modified: Date - var status: TransactionStatus - } -} diff --git a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/IssueTransactionDomainDTO.swift b/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/IssueTransactionDomainDTO.swift deleted file mode 100644 index 15fcfb7f..00000000 --- a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/IssueTransactionDomainDTO.swift +++ /dev/null @@ -1,35 +0,0 @@ -// -// TransactionIssueNode.swift -// WavesWallet-iOS -// -// Created by Prokofev Ruslan on 07/08/2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension DomainLayer.DTO { - struct IssueTransaction { - let type: Int - let id: String - let sender: String - let senderPublicKey: String - let fee: Int64 - let timestamp: Date - let version: Int - let height: Int64 - - let chainId: Int? - let signature: String? - let proofs: [String]? - let assetId: String - let name: String - let quantity: Int64 - let reissuable: Bool - let decimals: Int - let description: String - let script: String? - var modified: Date - var status: TransactionStatus - } -} diff --git a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/LeaseCancelTransactionDomainDTO.swift b/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/LeaseCancelTransactionDomainDTO.swift deleted file mode 100644 index ef5523dd..00000000 --- a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/LeaseCancelTransactionDomainDTO.swift +++ /dev/null @@ -1,30 +0,0 @@ -// -// TransactionLeaseCancelNode.swift -// WavesWallet-iOS -// -// Created by Prokofev Ruslan on 07/08/2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension DomainLayer.DTO { - struct LeaseCancelTransaction { - let type: Int - let id: String - let sender: String - let senderPublicKey: String - let fee: Int64 - let timestamp: Date - let version: Int - let height: Int64 - - let signature: String? - let proofs: [String]? - let chainId: Int? - let leaseId: String - var lease: DomainLayer.DTO.LeaseTransaction? - var modified: Date - var status: TransactionStatus - } -} diff --git a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/LeaseTransactionDomainDTO.swift b/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/LeaseTransactionDomainDTO.swift deleted file mode 100644 index a30ac1e3..00000000 --- a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/LeaseTransactionDomainDTO.swift +++ /dev/null @@ -1,30 +0,0 @@ -// -// TransactionLeaseNode.swift -// WavesWallet-iOS -// -// Created by mefilt on 18.07.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension DomainLayer.DTO { - struct LeaseTransaction { - let type: Int - let id: String - let sender: String - let senderPublicKey: String - let fee: Int64 - let timestamp: Date - let version: Int - let height: Int64 - - let chainId: Int? - let signature: String? - let proofs: [String]? - let amount: Int64 - let recipient: String - var modified: Date - var status: TransactionStatus - } -} diff --git a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/MassTransferTransactionDomainDTO.swift b/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/MassTransferTransactionDomainDTO.swift deleted file mode 100644 index 7869a22c..00000000 --- a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/MassTransferTransactionDomainDTO.swift +++ /dev/null @@ -1,37 +0,0 @@ -// -// TransactionMassTransferNode.swift -// WavesWallet-iOS -// -// Created by Prokofev Ruslan on 07/08/2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension DomainLayer.DTO { - struct MassTransferTransaction: Mutating { - - struct Transfer { - let recipient: String - let amount: Int64 - } - - let type: Int - let id: String - let sender: String - let senderPublicKey: String - let fee: Int64 - let timestamp: Date - let version: Int - let height: Int64 - - let proofs: [String]? - var assetId: String - let attachment: String - let transferCount: Int - let totalAmount: Int64 - let transfers: [Transfer] - var modified: Date - var status: TransactionStatus - } -} diff --git a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/ReissueTransactionDomainDTO.swift b/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/ReissueTransactionDomainDTO.swift deleted file mode 100644 index d8629f77..00000000 --- a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/ReissueTransactionDomainDTO.swift +++ /dev/null @@ -1,31 +0,0 @@ -// -// TransactionReissueNode.swift -// WavesWallet-iOS -// -// Created by Prokofev Ruslan on 07/08/2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension DomainLayer.DTO { - struct ReissueTransaction { - let type: Int - let id: String - let sender: String - let senderPublicKey: String - let fee: Int64 - let timestamp: Date - let version: Int - let height: Int64 - - let signature: String? - let proofs: [String]? - let chainId: Int? - let assetId: String - let quantity: Int64 - let reissuable: Bool - var modified: Date - var status: TransactionStatus - } -} diff --git a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/ScriptTransactionDomainDTO.swift b/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/ScriptTransactionDomainDTO.swift deleted file mode 100644 index 3d238fc2..00000000 --- a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/ScriptTransactionDomainDTO.swift +++ /dev/null @@ -1,30 +0,0 @@ -// -// SetScriptTransactionDomainDTO.swift -// WavesWallet-iOS -// -// Created by mefilt on 22/01/2019. -// Copyright © 2019 Waves Platform. All rights reserved. -// - -import Foundation - -extension DomainLayer.DTO { - struct ScriptTransaction { - - let type: Int - let id: String - let sender: String - let senderPublicKey: String - let fee: Int64 - let timestamp: Date - let version: Int - let height: Int64? - let chainId: Int? - - let signature: String? - let proofs: [String]? - var script: String? - var modified: Date - var status: TransactionStatus - } -} diff --git a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/SmartTransactionDomainDTO.swift b/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/SmartTransactionDomainDTO.swift deleted file mode 100644 index b5ef2c43..00000000 --- a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/SmartTransactionDomainDTO.swift +++ /dev/null @@ -1,165 +0,0 @@ -// -// TransactionDomainDTO.swift -// WavesWallet-iOS -// -// Created by Prokofev Ruslan on 07/09/2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -private typealias CoinomatService = Coinomat - -extension DomainLayer.DTO { - - struct AssetPair: Equatable { - var amountAsset: Asset - var priceAsset: Asset - } - - struct SmartTransaction: Equatable { - - typealias Asset = DomainLayer.DTO.Asset - typealias Account = DomainLayer.DTO.Address - - enum Status: Equatable { - case activeNow - case completed - case unconfirmed - } - - struct Transfer: Equatable { - let balance: Balance - let asset: Asset - - //It is for sent too (sender) - let recipient: Account - let attachment: String? - let hasSponsorship: Bool - var isGatewayAddress: Bool { - return CoinomatService.addresses.contains(recipient.address) - } - let myAccount: Account - } - - struct Exchange: Equatable { - - struct Order: Equatable { - enum Kind: Equatable { - case buy - case sell - } - - let timestamp: Date - let expiration: Date - let sender: Account - let kind: Kind - let pair: AssetPair - let price: Balance - let amount: Balance - let total: Balance - } - - let price: Balance - let amount: Balance - let total: Balance - let buyMatcherFee: Balance - let sellMatcherFee: Balance - let order1: Order - let order2: Order - } - - struct Leasing: Equatable { - let asset: Asset - let balance: Balance - let account: Account - let myAccount: Account - } - - struct Issue: Equatable { - let asset: Asset - let balance: Balance - let description: String? - } - - struct MassTransfer: Equatable { - struct Transfer: Equatable { - let amount: Money - let recipient: Account - } - let total: Balance - let asset: Asset - let attachment: String? - let transfers: [Transfer] - } - - struct MassReceive: Equatable { - struct Transfer: Equatable { - let amount: Money - let recipient: Account - } - let total: Balance - let myTotal: Balance - let asset: Asset - let attachment: String? - let transfers: [Transfer] - } - - struct Data: Equatable { - let prettyJSON: String - } - - struct InvokeScript: Equatable { - struct Payment: Equatable { - let amount: Money - let asset: Asset? - } - let payment: Payment? - let scriptAddress: String - } - - enum Kind: Equatable { - case receive(Transfer) - case sent(Transfer) - case spamReceive(Transfer) - case selfTransfer(Transfer) - case massSent(MassTransfer) - case massReceived(MassReceive) - case spamMassReceived(MassReceive) - - case startedLeasing(Leasing) - case canceledLeasing(Leasing) - case incomingLeasing(Leasing) - - case exchange(Exchange) - - case tokenGeneration(Issue) - case tokenBurn(Issue) - case tokenReissue(Issue) - - case createdAlias(String) - - case unrecognisedTransaction - - case data(Data) - - case script(isHasScript: Bool) - case assetScript(Asset) - case sponsorship(isEnabled: Bool, asset: Asset) - case invokeScript(InvokeScript) - } - - let id: String - let type: Int - let kind: Kind - let timestamp: Date - let totalFee: Balance - let feeAsset: Asset - let height: Int64? - let confirmationHeight: Int64 - let sender: Account - let status: Status - } -} - - diff --git a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/SponsorshipTransactionDomainDTO.swift b/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/SponsorshipTransactionDomainDTO.swift deleted file mode 100644 index 346c77f4..00000000 --- a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/SponsorshipTransactionDomainDTO.swift +++ /dev/null @@ -1,32 +0,0 @@ -// -// SponsorshipTransaction.swift -// WavesWallet-iOS -// -// Created by Prokofev Ruslan on 05/02/2019. -// Copyright © 2019 Waves Platform. All rights reserved. -// - -import Foundation - -extension DomainLayer.DTO { - struct SponsorshipTransaction { - - let type: Int - let id: String - let sender: String - let senderPublicKey: String - let fee: Int64 - let timestamp: Date - let version: Int - let height: Int64? - - let signature: String? - let proofs: [String]? - - var assetId: String - let minSponsoredAssetFee: Int64? - - var modified: Date - var status: TransactionStatus - } -} diff --git a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/TransferTransactionDomainDTO.swift b/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/TransferTransactionDomainDTO.swift deleted file mode 100644 index ee726a98..00000000 --- a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/TransferTransactionDomainDTO.swift +++ /dev/null @@ -1,33 +0,0 @@ -// -// TransactionTransferNode.swift -// WavesWallet-iOS -// -// Created by Prokofev Ruslan on 07/08/2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension DomainLayer.DTO { - struct TransferTransaction: Decodable, Mutating { - let type: Int - let id: String - let sender: String - let senderPublicKey: String - let fee: Int64 - let timestamp: Date - let version: Int - let height: Int64 - - let signature: String? - let proofs: [String]? - let recipient: String - var assetId: String - let feeAssetId: String - let feeAsset: String? - let amount: Int64 - let attachment: String? - var modified: Date - var status: TransactionStatus - } -} diff --git a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/UnrecognisedTransactionDomainDTO.swift b/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/UnrecognisedTransactionDomainDTO.swift deleted file mode 100644 index 4b7c2483..00000000 --- a/WavesWallet-iOS/DomainLayer/Models/DTO/Transactions/UnrecognisedTransactionDomainDTO.swift +++ /dev/null @@ -1,23 +0,0 @@ -// -// UnrecognisedTransactionDomainDTO.swift -// WavesWallet-iOS -// -// Created by mefilt on 31.08.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -extension DomainLayer.DTO { - struct UnrecognisedTransaction { - let type: Int - let id: String - let sender: String - let senderPublicKey: String - let fee: Int64 - let timestamp: Date - let height: Int64 - let modified: Date - var status: TransactionStatus - } -} diff --git a/WavesWallet-iOS/DomainLayer/Models/DTO/WalletDomainDTO.swift b/WavesWallet-iOS/DomainLayer/Models/DTO/WalletDomainDTO.swift deleted file mode 100644 index 346476d7..00000000 --- a/WavesWallet-iOS/DomainLayer/Models/DTO/WalletDomainDTO.swift +++ /dev/null @@ -1,91 +0,0 @@ -// -// WalletDomainDTO.swift -// WavesWallet-iOS -// -// Created by mefilt on 21.09.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import WavesSDKExtension -import WavesSDKCrypto - -extension DomainLayer.DTO { - - struct Wallet: Mutating, Hashable { - var name: String - let address: String - let publicKey: String - var isLoggedIn: Bool - var isBackedUp: Bool - var hasBiometricEntrance: Bool - let id: String - var isNeedShowWalletCleanBanner: Bool - } - - struct WalletEncryption: Mutating { - - enum Kind { - case passcode(secret: String) - case none - - var secret: String? { - switch self { - case .passcode(let secret): - return secret - default: - return nil - } - } - } - - let publicKey: String - var kind: Kind - var seedId: String - } - - struct WalletSeed { - let publicKey: String - let seed: String - let address: String - } - - struct WalletRegistation { - let name: String - let address: String - let privateKey: PrivateKeyAccount - let isBackedUp: Bool - let password: String - let passcode: String - } - - final class SignedWallet { - - let wallet: DomainLayer.DTO.Wallet - let publicKey: PublicKeyAccount - let privateKey: PrivateKeyAccount - let seed: WalletSeed - - var address: String { - return wallet.address - } - - init(wallet: Wallet, - seed: WalletSeed) { - - self.seed = seed - self.wallet = wallet - self.publicKey = PublicKeyAccount(publicKey: seed.publicKey) - self.privateKey = PrivateKeyAccount(seedStr: seed.seed) - } - - func sign(input: [UInt8], kind: [SigningKind]) throws -> [UInt8] { - let privateKey = PrivateKeyAccount(seedStr: seed.seed) - return Hash.sign(input, privateKey.privateKey) - } - - var seedWords: [String] { - return seed.seed.split(separator: " ").map { "\($0)" } - } - } -} diff --git a/WavesWallet-iOS/DomainLayer/Models/NetworkError.swift b/WavesWallet-iOS/DomainLayer/Models/NetworkError.swift deleted file mode 100644 index d2cfb8d7..00000000 --- a/WavesWallet-iOS/DomainLayer/Models/NetworkError.swift +++ /dev/null @@ -1,166 +0,0 @@ -// -// NetworkError.swift -// WavesWallet-iOS -// -// Created by mefilt on 23/11/2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import Moya - -private enum Constants { - static let scriptErrorCode = 307 - static let assetScriptErrorCode = 308 -} - -enum NetworkError: Error, Equatable { - - case message(String) - case notFound - case internetNotWorking - case serverError - case scriptError - - var isInternetNotWorking: Bool { - switch self { - case .internetNotWorking: - return true - - default: - return false - } - } - - var isServerError: Bool { - switch self { - case .serverError: - return true - - default: - return false - } - } - - var text: String { - switch self { - case .message(let message): - return message - - case .internetNotWorking: - return Localizable.Waves.General.Error.Title.noconnectiontotheinternet - - default: - return Localizable.Waves.General.Error.Title.notfound - } - } -} - -extension MoyaError { - - var error: Error? { - switch self { - case .underlying(let error, _): - return error - - case .objectMapping(let error, _): - return error - - case .encodableMapping(let error): - return error - - case .parameterEncoding(let error): - return error - - default: - return nil - } - } -} - -extension NetworkError { - - static func error(by error: Error) -> NetworkError { - - switch error { - - case let moyaError as MoyaError: - guard let response = moyaError.response else { - - if let error = moyaError.error { - return NetworkError.error(by: error) - } else { - return NetworkError.notFound - } - } - return NetworkError.error(data: response.data) - - case let urlError as NSError where urlError.domain == NSURLErrorDomain: - - switch urlError.code { - case NSURLErrorBadURL: - return NetworkError.serverError - - case NSURLErrorTimedOut: - return NetworkError.internetNotWorking - - case NSURLErrorUnsupportedURL: - return NetworkError.serverError - - case NSURLErrorCannotFindHost: - return NetworkError.serverError - - case NSURLErrorCannotConnectToHost: - return NetworkError.serverError - - case NSURLErrorNetworkConnectionLost: - return NetworkError.serverError - - case NSURLErrorDNSLookupFailed: - return NetworkError.serverError - - case NSURLErrorHTTPTooManyRedirects: - return NetworkError.serverError - - case NSURLErrorResourceUnavailable: - return NetworkError.serverError - - case NSURLErrorNotConnectedToInternet: - return NetworkError.internetNotWorking - - case NSURLErrorBadServerResponse: - return NetworkError.serverError - - default: - return NetworkError.notFound - } - - default: - return NetworkError.notFound - } - } - - static func error(data: Data) -> NetworkError { - - var message: String? = nil - let anyObject = try? JSONSerialization.jsonObject(with: data, options: []) - - if let anyObject = anyObject as? [String: Any] { - - if anyObject["error"] as? Int == Constants.scriptErrorCode { - return NetworkError.scriptError - } - message = anyObject["message"] as? String - - if message == nil { - message = anyObject["error"] as? String - } - } - - if let message = message { - return NetworkError.message(message) - } - - return NetworkError.notFound - } -} diff --git a/WavesWallet-iOS/DomainLayer/Queries/DomainDexQueries.swift b/WavesWallet-iOS/DomainLayer/Queries/DomainDexQueries.swift deleted file mode 100644 index ac569cdf..00000000 --- a/WavesWallet-iOS/DomainLayer/Queries/DomainDexQueries.swift +++ /dev/null @@ -1,37 +0,0 @@ -// -// OrderMatcherQueries.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 12/26/18. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import WavesSDKExtension -import WavesSDKCrypto - -extension DomainLayer.Query { - - enum Dex { - - struct CreateOrder { - let wallet: DomainLayer.DTO.SignedWallet - let matcherPublicKey: PublicKeyAccount - let amountAsset: String - let priceAsset: String - let amount: Int64 - let price: Int64 - let orderType: DomainLayer.DTO.Dex.OrderType - let matcherFee: Int64 - let timestamp: Int64 - let expiration: Int64 - } - - struct CancelOrder { - let wallet: DomainLayer.DTO.SignedWallet - let orderId: String - let amountAsset: String - let priceAsset: String - } - } -} diff --git a/WavesWallet-iOS/DomainLayer/Repositories/Dex/CandlesRepositoryProtocol.swift b/WavesWallet-iOS/DomainLayer/Repositories/Dex/CandlesRepositoryProtocol.swift deleted file mode 100644 index b52adea4..00000000 --- a/WavesWallet-iOS/DomainLayer/Repositories/Dex/CandlesRepositoryProtocol.swift +++ /dev/null @@ -1,14 +0,0 @@ -// -// CandlesRepositoryProtocol.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 12/5/18. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import RxSwift - -protocol CandlesRepositoryProtocol { - func candles(accountAddress: String, amountAsset: String, priceAsset: String, timeStart: Date, timeEnd: Date, timeFrame: DomainLayer.DTO.Candle.TimeFrameType) -> Observable<[DomainLayer.DTO.Candle]> -} diff --git a/WavesWallet-iOS/DomainLayer/Repositories/Dex/DexPairsPriceRepositoryProtocol.swift b/WavesWallet-iOS/DomainLayer/Repositories/Dex/DexPairsPriceRepositoryProtocol.swift deleted file mode 100644 index c02e9577..00000000 --- a/WavesWallet-iOS/DomainLayer/Repositories/Dex/DexPairsPriceRepositoryProtocol.swift +++ /dev/null @@ -1,15 +0,0 @@ -// -// DexListRepositoryRemote.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 12/17/18. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import RxSwift - -protocol DexPairsPriceRepositoryProtocol { - - func list(by accountAddress: String, pairs: [DomainLayer.DTO.Dex.Pair]) -> Observable<[DomainLayer.DTO.Dex.PairPrice]> -} diff --git a/WavesWallet-iOS/DomainLayer/Repositories/Dex/LastTradesRepositoryProtocol.swift b/WavesWallet-iOS/DomainLayer/Repositories/Dex/LastTradesRepositoryProtocol.swift deleted file mode 100644 index aff59f89..00000000 --- a/WavesWallet-iOS/DomainLayer/Repositories/Dex/LastTradesRepositoryProtocol.swift +++ /dev/null @@ -1,14 +0,0 @@ -// -// LastTradesRepositoryProtocol.swift -// WavesWallet-iOS -// -// Created by Pavel Gubin on 12/5/18. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import RxSwift - -protocol LastTradesRepositoryProtocol { - func lastTrades(accountAddress: String, amountAsset: DomainLayer.DTO.Dex.Asset, priceAsset: DomainLayer.DTO.Dex.Asset, limit: Int) -> Observable<[DomainLayer.DTO.Dex.LastTrade]> -} diff --git a/WavesWallet-iOS/DomainLayer/Repositories/EnvironmentRepositoryProtocol.swift b/WavesWallet-iOS/DomainLayer/Repositories/EnvironmentRepositoryProtocol.swift deleted file mode 100644 index b38cbdc4..00000000 --- a/WavesWallet-iOS/DomainLayer/Repositories/EnvironmentRepositoryProtocol.swift +++ /dev/null @@ -1,23 +0,0 @@ -// -// EnvironmentsInteractor.swift -// WavesWallet-iOS -// -// Created by mefilt on 18/10/2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import RxSwift -import WavesSDKExtension -import WavesSDKCrypto - -enum EnvironmentRepositoryError: Error { - case invalidURL - case invalidResponse -} - -protocol EnvironmentRepositoryProtocol { - func accountEnvironment(accountAddress: String) -> Observable - func deffaultEnvironment(accountAddress: String) -> Observable - func setSpamURL(_ url: String, by accountAddress: String) -> Observable -} diff --git a/WavesWallet-iOS/DomainLayer/Repositories/Transactions/TransactionsRepositoryProtocol.swift b/WavesWallet-iOS/DomainLayer/Repositories/Transactions/TransactionsRepositoryProtocol.swift deleted file mode 100644 index 2043d1c8..00000000 --- a/WavesWallet-iOS/DomainLayer/Repositories/Transactions/TransactionsRepositoryProtocol.swift +++ /dev/null @@ -1,176 +0,0 @@ -// -// Transactions.swift -// WavesWallet-iOS -// -// Created by mefilt on 29.08.2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import RxSwift - -enum TransactionsRepositoryError: Error { - case fail -} - -enum TransactionStatus: Int, Decodable { - case activeNow - case completed - case unconfirmed -} - -enum TransactionType: Int { - case issue = 3 - case transfer = 4 - case reissue = 5 - case burn = 6 - case exchange = 7 - case lease = 8 - case leaseCancel = 9 - case alias = 10 - case massTransfer = 11 - case data = 12 - case script = 13 - case sponsorship = 14 - case assetScript = 15 - case invokeScript = 16 - case any_17 = 17 - case any_18 = 18 - case any_19 = 19 - case any_20 = 20 - case any_21 = 21 - - static var all: [TransactionType] { - return [.issue, - .transfer, - .reissue, - .burn, - .exchange, - .lease, - .leaseCancel, - .alias, - .massTransfer, - .data, - .script, - .sponsorship, - .assetScript, - .invokeScript, - .any_17, - .any_18, - .any_19, - .any_20, - .any_21] - } -} - -struct TransactionsSpecifications { - - struct Page { - let offset: Int - let limit: Int - } - - let page: Page? - let assets: [String] - let senders: [String] - let types: [TransactionType] -} - - -struct AliasTransactionSender { - let alias: String - let fee: Int64 -} - -struct LeaseTransactionSender { - let recipient: String - let amount: Int64 - let fee: Int64 -} - -struct BurnTransactionSender { - let assetID: String - let quantity: Int64 - let fee: Int64 -} - -struct CancelLeaseTransactionSender { - let leaseId: String - let fee: Int64 -} - -struct DataTransactionSender { - struct Value { - enum Kind { - case integer(Int64) - case boolean(Bool) - case string(String) - case binary([UInt8]) - } - - let key: String - let value: Kind - } - - let fee: Int64 - let data: [Value] -} - -struct SendTransactionSender { - let recipient: String - let assetId: String - let amount: Int64 - let fee: Int64 - let attachment: String - let feeAssetID: String -} - -enum TransactionSenderSpecifications { - case createAlias(AliasTransactionSender) - case lease(LeaseTransactionSender) - case burn(BurnTransactionSender) - case cancelLease(CancelLeaseTransactionSender) - case data(DataTransactionSender) - case send(SendTransactionSender) -} - -protocol TransactionsRepositoryProtocol { - - func transactions(by address: DomainLayer.DTO.Address, offset: Int, limit: Int) -> Observable<[DomainLayer.DTO.AnyTransaction]> - func transactions(by address: DomainLayer.DTO.Address, specifications: TransactionsSpecifications) -> Observable<[DomainLayer.DTO.AnyTransaction]> - func newTransactions(by address: DomainLayer.DTO.Address, - specifications: TransactionsSpecifications) -> Observable<[DomainLayer.DTO.AnyTransaction]> - - func activeLeasingTransactions(by accountAddress: String) -> Observable<[DomainLayer.DTO.LeaseTransaction]> - - func saveTransactions(_ transactions: [DomainLayer.DTO.AnyTransaction], accountAddress: String) -> Observable - - func isHasTransaction(by id: String, accountAddress: String, ignoreUnconfirmed: Bool) -> Observable - func isHasTransactions(by ids: [String], accountAddress: String, ignoreUnconfirmed: Bool) -> Observable - func isHasTransactions(by accountAddress: String, ignoreUnconfirmed: Bool) -> Observable - - func send(by specifications: TransactionSenderSpecifications, wallet: DomainLayer.DTO.SignedWallet) -> Observable - - func feeRules() -> Observable -} - -extension DomainLayer.DTO { - - struct TransactionFeeRules { - struct Rule { - let addSmartAssetFee: Bool - let addSmartAccountFee: Bool - let minPriceStep: Int64 - let fee: Int64 - let pricePerTransfer: Int64 - let pricePerKb: Int64 - } - - let smartAssetExtraFee: Int64 - let smartAccountExtraFee: Int64 - - let defaultRule: TransactionFeeRules.Rule - let rules: [TransactionType: TransactionFeeRules.Rule] - } -} - diff --git a/WavesWallet-iOS/Extensions/Analytics/NewUserWithoutBackupStorageTrack.swift b/WavesWallet-iOS/Extensions/Analytics/NewUserWithoutBackupStorageTrack.swift new file mode 100644 index 00000000..83a392ef --- /dev/null +++ b/WavesWallet-iOS/Extensions/Analytics/NewUserWithoutBackupStorageTrack.swift @@ -0,0 +1,42 @@ +// +// NewUserWithoutBackupStorageTrack.swift +// WavesWallet-iOS +// +// Created by rprokofev on 26.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import WavesSDKExtensions +import DomainLayer + +struct NewUserWithoutBackupStorageTrack { + + struct MetaData: Codable, TSUD { + private static let key: String = "com.waves.analytics.event.newUserWithoutBackupStorage" + + var count: UInt = 0 + + init() { } + + static var defaultValue: MetaData { + return MetaData() + } + + static var stringKey: String { + return key + } + } + + static func sendEvent() { + + var metaData = MetaData.get() + metaData.count = metaData.count + 1 + MetaData.set(metaData) + + UseCasesFactory + .instance + .analyticManager + .trackEvent(.createANewAccount(.newUserWithoutBackup(count: metaData.count))) + } +} diff --git a/WavesWallet-iOS/Extensions/AssetLogo+Styles.swift b/WavesWallet-iOS/Extensions/AssetLogo+Styles.swift new file mode 100644 index 00000000..54cd8895 --- /dev/null +++ b/WavesWallet-iOS/Extensions/AssetLogo+Styles.swift @@ -0,0 +1,38 @@ +// +// AssetLogo+Styles.swift +// WavesWallet-iOS +// +// Created by rprokofev on 09.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import Extensions + +extension AssetLogo.Style { + + static var litle: AssetLogo.Style = { + return AssetLogo.Style.init(size: CGSize(width: 24, height: 24), + font: UIFont.systemFont(ofSize: 15), + specs: .init(sponsoredImage: Images.sponsoritem18White.image, + scriptImage: Images.scriptasset18White.image, + size: CGSize(width: 10, + height: 10))) + }() + + static var medium: AssetLogo.Style = { + return AssetLogo.Style.init(size: CGSize(width: 28, height: 28), + font: UIFont.systemFont(ofSize: 15), + specs: .init(sponsoredImage: Images.sponsoritem18White.image, + scriptImage: Images.scriptasset18White.image, + size: CGSize(width: 12, height: 12))) + }() + + static var large: AssetLogo.Style = { + return AssetLogo.Style.init(size: CGSize(width: 48, height: 48), + font: UIFont.systemFont(ofSize: 15), + specs: .init(sponsoredImage: Images.sponsoritem18White.image, + scriptImage: Images.scriptasset18White.image, + size: CGSize(width: 18, height: 18))) + }() +} diff --git a/WavesWallet-iOS/Extensions/AuthorizationInteractorLocalizableImp.swift b/WavesWallet-iOS/Extensions/AuthorizationInteractorLocalizableImp.swift new file mode 100644 index 00000000..94cd87ba --- /dev/null +++ b/WavesWallet-iOS/Extensions/AuthorizationInteractorLocalizableImp.swift @@ -0,0 +1,30 @@ + +// AuthorizationInteractorLocalizableImp.swift +// WavesWallet-iOS +// +// Created by rprokofev on 20.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + + +import Foundation +import DomainLayer + +struct AuthorizationInteractorLocalizableImp: AuthorizationInteractorLocalizableProtocol { + + var fallbackTitle: String { + return Localizable.Waves.Biometric.localizedFallbackTitle + } + + var cancelTitle: String { + return Localizable.Waves.Biometric.localizedCancelTitle + } + + var readFromkeychain: String { + return Localizable.Waves.Biometric.readfromkeychain + } + + var saveInkeychain: String { + return Localizable.Waves.Biometric.saveinkeychain + } +} diff --git a/WavesWallet-iOS/Extensions/BiometricManager+String.swift b/WavesWallet-iOS/Extensions/BiometricManager+String.swift new file mode 100644 index 00000000..0fb59cfd --- /dev/null +++ b/WavesWallet-iOS/Extensions/BiometricManager+String.swift @@ -0,0 +1,17 @@ +// +// BiometricManager+String.swift +// WavesWallet-iOS +// +// Created by rprokofev on 20.06.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import DomainLayer + +extension BiometricManager { + public static var touchIDTypeText: String { + return type == .faceID ? Localizable.Waves.General.Biometric.Faceid.title : Localizable.Waves.General.Biometric.Touchid.title + } +} + diff --git a/WavesWallet-iOS/Extensions/DateFormatter+UI.swift b/WavesWallet-iOS/Extensions/DateFormatter+UI.swift index 0686a478..b1bf9338 100644 --- a/WavesWallet-iOS/Extensions/DateFormatter+UI.swift +++ b/WavesWallet-iOS/Extensions/DateFormatter+UI.swift @@ -15,7 +15,7 @@ public extension DateFormatter { .threadSharedObject(key: key, create: { return DateFormatter() }) - formatter.locale = Localizable.current.locale + formatter.locale = Localizable.locale return formatter } } diff --git a/WavesWallet-iOS/Extensions/Language+List.swift b/WavesWallet-iOS/Extensions/Language+List.swift new file mode 100644 index 00000000..54897901 --- /dev/null +++ b/WavesWallet-iOS/Extensions/Language+List.swift @@ -0,0 +1,18 @@ +// +// Language+List.swift +// WavesWallet-iOS +// +// Created by rprokofev on 14.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import Extensions + +extension Language { + + static var list: [Language] { + let list: [Language] = JSONDecoder.decode(json: "Languages") ?? [] + return list + } +} diff --git a/WavesWallet-iOS/Extensions/Mock/AssetsRepositoryMock.swift b/WavesWallet-iOS/Extensions/Mock/AssetsRepositoryMock.swift new file mode 100644 index 00000000..5ca38199 --- /dev/null +++ b/WavesWallet-iOS/Extensions/Mock/AssetsRepositoryMock.swift @@ -0,0 +1,95 @@ +// +// AssetsRepositoryMock.swift +// WavesWallet-iOS +// +// Created by rprokofev on 29.07.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import DomainLayer +import RxSwift + +final class AssetsRepositoryMock: AssetsRepositoryProtocol { + + func assets(by ids: [String], accountAddress: String) -> Observable<[DomainLayer.DTO.Asset]> { + + return Observable.never() + } + + func saveAssets(_ assets:[DomainLayer.DTO.Asset], by accountAddress: String) -> Observable { + return Observable.never() + } + + func saveAsset(_ asset: DomainLayer.DTO.Asset, by accountAddress: String) -> Observable { + return Observable.never() + } + + func isSmartAsset(_ assetId: String, by accountAddress: String) -> Observable { + return Observable.never() + } + + func searchAssets(search: String) -> Observable<[DomainLayer.DTO.Asset]> { + return Observable.never() + } +} + + +extension DomainLayer.DTO.Asset { + + static func mockWaves() -> DomainLayer.DTO.Asset { + return .init(id: "WAVES", + gatewayId: nil, + wavesId: "WAVES", + displayName: "Waves", + precision: 8, + description: "Waves platform", + height: 0, + timestamp: Date(), + sender: "Waves", + quantity: 10, + ticker: "Waves", + isReusable: true, + isSpam: false, + isFiat: false, + isGeneral: true, + isMyWavesToken: false, + isWavesToken: false, + isGateway: false, + isWaves: true, + modified: Date(), + addressRegEx: "", + iconLogoUrl: "", + hasScript: false, + minSponsoredFee: 0, + gatewayType: nil) + } + + static func mockBTC() -> DomainLayer.DTO.Asset { + return .init(id: "BTC", + gatewayId: nil, + wavesId: "BTC", + displayName: "Bitcoin", + precision: 8, + description: "Bitcoin block", + height: 0, + timestamp: Date(), + sender: "BTC", + quantity: 10, + ticker: "BTC", + isReusable: true, + isSpam: false, + isFiat: false, + isGeneral: true, + isMyWavesToken: false, + isWavesToken: false, + isGateway: true, + isWaves: false, + modified: Date(), + addressRegEx: "", + iconLogoUrl: "", + hasScript: false, + minSponsoredFee: 0, + gatewayType: nil) + } +} diff --git a/WavesWallet-iOS/Extensions/NSAttributedString+Styles.swift b/WavesWallet-iOS/Extensions/NSAttributedString+Styles.swift new file mode 100644 index 00000000..c470d801 --- /dev/null +++ b/WavesWallet-iOS/Extensions/NSAttributedString+Styles.swift @@ -0,0 +1,39 @@ +// +// NSAttributedString+Styles.swift +// WavesWallet-iOS +// +// Created by mefilt on 19.07.2018. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import UIKit + +public extension NSAttributedString { + public class func styleForBalance(text: String, font: UIFont) -> NSAttributedString { + let range = (text as NSString).range(of: ".") + let attrString = NSMutableAttributedString(string: text, attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: font.pointSize, weight: .semibold)]) + + if range.location != NSNotFound { + let length = text.count - range.location + attrString.addAttributes([NSAttributedString.Key.font: UIFont.systemFont(ofSize: font.pointSize, weight: .regular)], range: NSRange(location: range.location, length: length)) + } + return attrString + } + + public class func styleForMyAssetName(assetName: String, isMyAsset: Bool) -> NSAttributedString { + + var fullName = assetName + let myAssetString = " / \(Localizable.Waves.Wallet.Label.myAssets)" + + if isMyAsset { + fullName.append(myAssetString) + } + + let attrString = NSMutableAttributedString(string: fullName) + attrString.setAttributes([NSAttributedString.Key.foregroundColor : UIColor.info500, + NSAttributedString.Key.font : UIFont.systemFont(ofSize: 10)], + range: (fullName as NSString).range(of: myAssetString)) + return attrString + } +} diff --git a/WavesWallet-iOS/Extensions/NetworkError+Title.swift b/WavesWallet-iOS/Extensions/NetworkError+Title.swift new file mode 100644 index 00000000..e7b9c3ac --- /dev/null +++ b/WavesWallet-iOS/Extensions/NetworkError+Title.swift @@ -0,0 +1,25 @@ +// +// NetworkError.swift +// WavesWallet-iOS +// +// Created by rprokofev on 02.09.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import WavesSDK + +extension NetworkError { + public var text: String { + switch self { + case .message(let message): + return message + + case .internetNotWorking: + return Localizable.Waves.General.Error.Title.noconnectiontotheinternet + + default: + return Localizable.Waves.General.Error.Title.notfound + } + } +} diff --git a/WavesWallet-iOS/Extensions/UIKit/SmartTransactionDTO+EncodingToString.swift b/WavesWallet-iOS/Extensions/SmartTransactionDTO+EncodingToString.swift similarity index 99% rename from WavesWallet-iOS/Extensions/UIKit/SmartTransactionDTO+EncodingToString.swift rename to WavesWallet-iOS/Extensions/SmartTransactionDTO+EncodingToString.swift index 75261aa9..60370eef 100644 --- a/WavesWallet-iOS/Extensions/UIKit/SmartTransactionDTO+EncodingToString.swift +++ b/WavesWallet-iOS/Extensions/SmartTransactionDTO+EncodingToString.swift @@ -7,7 +7,9 @@ // import Foundation -import WavesSDKExtension +import WavesSDKExtensions +import Extensions +import DomainLayer extension DomainLayer.DTO.SmartTransaction { diff --git a/WavesWallet-iOS/Extensions/UIKit/SmartTransactionKind+UIImage.swift b/WavesWallet-iOS/Extensions/SmartTransactionKind+UIImage.swift similarity index 99% rename from WavesWallet-iOS/Extensions/UIKit/SmartTransactionKind+UIImage.swift rename to WavesWallet-iOS/Extensions/SmartTransactionKind+UIImage.swift index 75e738eb..d481ebc9 100644 --- a/WavesWallet-iOS/Extensions/UIKit/SmartTransactionKind+UIImage.swift +++ b/WavesWallet-iOS/Extensions/SmartTransactionKind+UIImage.swift @@ -8,6 +8,7 @@ import Foundation import UIKit +import DomainLayer extension DomainLayer.DTO.SmartTransaction.Kind { diff --git a/WavesWallet-iOS/Extensions/String+Size.swift b/WavesWallet-iOS/Extensions/String+Size.swift new file mode 100644 index 00000000..d6ead7f7 --- /dev/null +++ b/WavesWallet-iOS/Extensions/String+Size.swift @@ -0,0 +1,44 @@ +// +// String+Size.swift +// WavesWallet-iOS +// +// Created by rprokofev on 24/05/2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import UIKit + +public extension String { + + func maxHeight(font: UIFont, forWidth: CGFloat) -> CGFloat { + let text = self as NSString + return ceil(text.boundingRect(with: CGSize(width: forWidth, height: CGFloat.greatestFiniteMagnitude), options: .usesLineFragmentOrigin, attributes: [.font: font], context: nil).size.height) + } + + func maxHeightMultiline(font: UIFont, forWidth: CGFloat) -> CGFloat { + let style = NSMutableParagraphStyle() + style.lineBreakMode = .byWordWrapping + + let rect = NSAttributedString(string: self, attributes: [.font: font, + .paragraphStyle: style]) + .boundingRect(with: CGSize(width: forWidth, + height: CGFloat.greatestFiniteMagnitude), + options: [.usesLineFragmentOrigin, .usesFontLeading], + context: nil) + + return ceil(rect.height) + } + + func maxWidth(font: UIFont) -> CGFloat { + let text = self as NSString + return ceil(text.boundingRect(with: CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude), options: .usesLineFragmentOrigin, attributes: [.font: font], context: nil).size.width) + } +} + +public extension NSAttributedString { + + func boundingRect(with size: CGSize) -> CGRect { + return boundingRect(with: size, options: [.usesLineFragmentOrigin, .usesFontLeading], context: nil) + } +} diff --git a/WavesWallet-iOS/Extensions/Type/AppSettings.swift b/WavesWallet-iOS/Extensions/Type/AppSettings.swift deleted file mode 100644 index 67cd8d17..00000000 --- a/WavesWallet-iOS/Extensions/Type/AppSettings.swift +++ /dev/null @@ -1,39 +0,0 @@ -import UIKit -import DeviceKit - -struct Platform { - - static let ScreenWidth = UIScreen.main.bounds.width - - private static let device = Device() - - static let isIphone5: Bool = { - return device.isOneOf([.iPhone5, .simulator(.iPhone5), - .iPhone5c, .simulator(.iPhone5c), - .iPhone5s, .simulator(.iPhone5s), - .iPhoneSE, .simulator(.iPhoneSE)]) - }() - - static let isIphone7: Bool = { - - return device.isOneOf([.iPhone6, .simulator(.iPhone6), - .iPhone6s, .simulator(.iPhone6s), - .iPhone7, .simulator(.iPhone7), - .iPhone8, .simulator(.iPhone8)]) - }() - - static let isIphoneXSeries: Bool = { - return device.isOneOf([.iPhoneX, .simulator(.iPhoneX), - .iPhoneXr, .simulator(.iPhoneXr), - .iPhoneXs, .simulator(.iPhoneXs), - .iPhoneXsMax, .simulator(.iPhoneXsMax)]) - }() - - static let isSupportFaceID: Bool = { - - let realDevices = Device.allFaceIDCapableDevices - let simulators: [Device] = realDevices.map {.simulator($0)} - - return device.isOneOf(realDevices + simulators) - }() -} diff --git a/WavesWallet-iOS/Extensions/Type/Language.swift b/WavesWallet-iOS/Extensions/Type/Language.swift index e753ec07..c8f9d637 100644 --- a/WavesWallet-iOS/Extensions/Type/Language.swift +++ b/WavesWallet-iOS/Extensions/Type/Language.swift @@ -6,7 +6,7 @@ // Copyright © 2018 Waves Platform. All rights reserved. // import Foundation -import WavesSDKExtension +import WavesSDKExtensions struct Language: Codable { let title: String diff --git a/WavesWallet-iOS/Extensions/Type/QRCodeParser.swift b/WavesWallet-iOS/Extensions/Type/QRCodeParser.swift index 8ed2d149..77c2550d 100644 --- a/WavesWallet-iOS/Extensions/Type/QRCodeParser.swift +++ b/WavesWallet-iOS/Extensions/Type/QRCodeParser.swift @@ -13,21 +13,23 @@ private enum Constants { static let addressKeyScan = "recipient" static let amountKeyScan = "amount" - static let sendStartUrl = "client.wavesplatform.com/#send/" + static let sendStartUrl = "send/" } final class QRCodeParser { static func parseAssetID(_ string: String) -> String? { - let rangeStart = (string.lowercased() as NSString).range(of: Constants.sendStartUrl) - if rangeStart.location != NSNotFound && (string as NSString).range(of: "?").location != NSNotFound { - let start = (string as NSString).substring(from: rangeStart.location + rangeStart.length) - return (start as NSString).substring(to: (start as NSString).range(of: "?").location) + let isValidAssetIdQuery = (string as NSString).range(of: "?").location != NSNotFound + let range = (string.lowercased() as NSString).range(of: Constants.sendStartUrl) + + if range.location != NSNotFound && isValidAssetIdQuery { + return parseAssetIDFromStartRange(startRange: range, assetId: string) } + return nil } - + static func parseAddress(_ string: String) -> String { if let address = urlValues(string)[Constants.addressKeyScan] { return address @@ -55,7 +57,12 @@ final class QRCodeParser { } private extension QRCodeParser { - + + static func parseAssetIDFromStartRange(startRange: NSRange, assetId: String) -> String? { + let start = (assetId as NSString).substring(from: startRange.location + startRange.length) + return (start as NSString).substring(to: (start as NSString).range(of: "?").location) + } + static func urlValues(_ string: String) -> [String : String] { var values: [String : String] = [:] diff --git a/WavesWallet-iOS/Extensions/System.swift b/WavesWallet-iOS/Extensions/Type/System.swift similarity index 98% rename from WavesWallet-iOS/Extensions/System.swift rename to WavesWallet-iOS/Extensions/Type/System.swift index cfe457aa..1c5e5f52 100644 --- a/WavesWallet-iOS/Extensions/System.swift +++ b/WavesWallet-iOS/Extensions/Type/System.swift @@ -10,7 +10,7 @@ import Foundation import RxSwift import RxCocoa import RxFeedback -import WavesSDKExtension +import WavesSDKExtensions class System { diff --git a/WavesWallet-iOS/Extensions/UIKit/ActivityIndicator+Rx.swift b/WavesWallet-iOS/Extensions/UIKit/ActivityIndicator+Rx.swift deleted file mode 100644 index 63dea176..00000000 --- a/WavesWallet-iOS/Extensions/UIKit/ActivityIndicator+Rx.swift +++ /dev/null @@ -1,84 +0,0 @@ -// -// ActivityIndicator.swift -// RxSwiftUtilities -// -// Created by Jesse Farless on 11/21/16. -// Copyright © 2016 RxSwiftCommunity. All rights reserved. -// -// This file was copied from RxSwift's example app: -// https://github.com/ReactiveX/RxSwift/blob/d6dfcfa/RxExample/RxExample/Services/ActivityIndicator.swift -// - -import Foundation -import RxSwift -import RxCocoa - -private struct ActivityToken : ObservableConvertibleType, Disposable { - private let _source: Observable - private let _dispose: Cancelable - - init(source: Observable, disposeAction: @escaping () -> ()) { - _source = source - _dispose = Disposables.create(with: disposeAction) - } - - func dispose() { - _dispose.dispose() - } - - func asObservable() -> Observable { - return _source - } -} - -/** - Enables monitoring of sequence computation. - - If there is at least one sequence computation in progress, `true` will be sent. - When all activities complete `false` will be sent. - */ -public class ActivityIndicator : SharedSequenceConvertibleType { - public typealias E = Bool - public typealias SharingStrategy = DriverSharingStrategy - - private let _lock = NSRecursiveLock() - private let _variable = Variable(0) - private let _loading: SharedSequence - - public init() { - _loading = _variable.asDriver() - .map { $0 > 0 } - .distinctUntilChanged() - } - - fileprivate func trackActivityOfObservable(_ source: O) -> Observable { - return Observable.using({ () -> ActivityToken in - self.increment() - return ActivityToken(source: source.asObservable(), disposeAction: self.decrement) - }) { t in - return t.asObservable() - } - } - - private func increment() { - _lock.lock() - _variable.value = _variable.value + 1 - _lock.unlock() - } - - private func decrement() { - _lock.lock() - _variable.value = _variable.value - 1 - _lock.unlock() - } - - public func asSharedSequence() -> SharedSequence { - return _loading - } -} - -extension ObservableConvertibleType { - public func trackActivity(_ activityIndicator: ActivityIndicator) -> Observable { - return activityIndicator.trackActivityOfObservable(self) - } -} diff --git a/WavesWallet-iOS/Extensions/UIKit/Type/BiometricType.swift b/WavesWallet-iOS/Extensions/UIKit/BiometricType.swift similarity index 93% rename from WavesWallet-iOS/Extensions/UIKit/Type/BiometricType.swift rename to WavesWallet-iOS/Extensions/UIKit/BiometricType.swift index d4e7fe40..26d353b2 100644 --- a/WavesWallet-iOS/Extensions/UIKit/Type/BiometricType.swift +++ b/WavesWallet-iOS/Extensions/UIKit/BiometricType.swift @@ -6,8 +6,9 @@ // Copyright © 2018 Waves Platform. All rights reserved. // import UIKit +import DomainLayer -extension BiometricType { +public extension BiometricType { var title: String? { switch self { diff --git a/WavesWallet-iOS/Extensions/UIKit/ControlEvent+Signal.swift b/WavesWallet-iOS/Extensions/UIKit/ControlEvent+Signal.swift deleted file mode 100644 index b4ef252b..00000000 --- a/WavesWallet-iOS/Extensions/UIKit/ControlEvent+Signal.swift +++ /dev/null @@ -1,17 +0,0 @@ -// -// ControlEvent+Signal.swift -// WavesWallet-iOS -// -// Created by Prokofev Ruslan on 16/07/2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation -import RxSwift -import RxCocoa - -extension ControlEvent { - func asSignal() -> Signal { - return self.asObservable().asSignal(onErrorSignalWith: .empty()) - } -} diff --git a/WavesWallet-iOS/Extensions/UIKit/Type/DisplayError.swift b/WavesWallet-iOS/Extensions/UIKit/DisplayError.swift similarity index 90% rename from WavesWallet-iOS/Extensions/UIKit/Type/DisplayError.swift rename to WavesWallet-iOS/Extensions/UIKit/DisplayError.swift index d04a4cc3..fa218d37 100644 --- a/WavesWallet-iOS/Extensions/UIKit/Type/DisplayError.swift +++ b/WavesWallet-iOS/Extensions/UIKit/DisplayError.swift @@ -7,11 +7,12 @@ // import Foundation +import WavesSDK enum DisplayError: Equatable { case globalError(isInternetNotWorking: Bool) case internetNotWorking - case notFound + case none case message(String) case scriptError } @@ -32,11 +33,11 @@ extension DisplayError { case .internetNotWorking: self = .internetNotWorking - case .notFound: - self = .notFound + case .notFound, .none: + self = .none case .serverError: - self = .notFound + self = .none case .message(let message): self = .message(message) @@ -46,7 +47,7 @@ extension DisplayError { } default: - self = .notFound + self = .none } } } diff --git a/WavesWallet-iOS/Extensions/UIKit/Type/GlobalConstants.swift b/WavesWallet-iOS/Extensions/UIKit/GlobalConstants.swift similarity index 70% rename from WavesWallet-iOS/Extensions/UIKit/Type/GlobalConstants.swift rename to WavesWallet-iOS/Extensions/UIKit/GlobalConstants.swift index f70596d6..32dd6c77 100644 --- a/WavesWallet-iOS/Extensions/UIKit/Type/GlobalConstants.swift +++ b/WavesWallet-iOS/Extensions/UIKit/GlobalConstants.swift @@ -7,13 +7,17 @@ // import Foundation -import WavesSDKCrypto +import WavesSDK +import Extensions enum UIGlobalConstants { - static let WavesTransactionFee = Money(WavesSDKCryptoConstants.WavesTransactionFeeAmount, - WavesSDKCryptoConstants.WavesDecimals) + static let WavesTransactionFee = Money(WavesSDKConstants.WavesTransactionFeeAmount, + WavesSDKConstants.WavesDecimals) + + static let limitPriceOrderPercent: Int = 5 + #if DEBUG static let accountNameMinLimitSymbols: Int = 2 static let accountNameMaxLimitSymbols: Int = 24 @@ -26,3 +30,4 @@ enum UIGlobalConstants { static let minimumSeedLength = 25 #endif } + diff --git a/WavesWallet-iOS/Extensions/UIKit/Type/MailCompose+Support.swift b/WavesWallet-iOS/Extensions/UIKit/MailCompose+Support.swift similarity index 96% rename from WavesWallet-iOS/Extensions/UIKit/Type/MailCompose+Support.swift rename to WavesWallet-iOS/Extensions/UIKit/MailCompose+Support.swift index e7fabf09..dc5534ff 100644 --- a/WavesWallet-iOS/Extensions/UIKit/Type/MailCompose+Support.swift +++ b/WavesWallet-iOS/Extensions/UIKit/MailCompose+Support.swift @@ -29,6 +29,7 @@ final class MailComposeCoordinator: NSObject, Coordinator, MFMailComposeViewCont vc.setMessageBody(UIDevice.current.deviceDescription(), isHTML: false) vc.setToRecipients([email]) vc.mailComposeDelegate = self + vc.modalPresentationStyle = .fullScreen viewController.present(vc, animated: true, completion: nil) } else { let body = UIDevice.current.deviceDescription() diff --git a/WavesWallet-iOS/Extensions/UIKit/Type/Modal/ModalPresentationAnimator.swift b/WavesWallet-iOS/Extensions/UIKit/Modal/ModalPresentationAnimator.swift similarity index 100% rename from WavesWallet-iOS/Extensions/UIKit/Type/Modal/ModalPresentationAnimator.swift rename to WavesWallet-iOS/Extensions/UIKit/Modal/ModalPresentationAnimator.swift diff --git a/WavesWallet-iOS/Extensions/UIKit/Type/Modal/ModalPresentationAnimatorContext.swift b/WavesWallet-iOS/Extensions/UIKit/Modal/ModalPresentationAnimatorContext.swift similarity index 100% rename from WavesWallet-iOS/Extensions/UIKit/Type/Modal/ModalPresentationAnimatorContext.swift rename to WavesWallet-iOS/Extensions/UIKit/Modal/ModalPresentationAnimatorContext.swift diff --git a/WavesWallet-iOS/Extensions/UIKit/Type/Modal/ModalPresentationController.swift b/WavesWallet-iOS/Extensions/UIKit/Modal/ModalPresentationController.swift similarity index 100% rename from WavesWallet-iOS/Extensions/UIKit/Type/Modal/ModalPresentationController.swift rename to WavesWallet-iOS/Extensions/UIKit/Modal/ModalPresentationController.swift diff --git a/WavesWallet-iOS/Extensions/UIKit/Type/Modal/ModalRootView.swift b/WavesWallet-iOS/Extensions/UIKit/Modal/ModalRootView.swift similarity index 99% rename from WavesWallet-iOS/Extensions/UIKit/Type/Modal/ModalRootView.swift rename to WavesWallet-iOS/Extensions/UIKit/Modal/ModalRootView.swift index 5d89ba7b..c76d8ba4 100644 --- a/WavesWallet-iOS/Extensions/UIKit/Type/Modal/ModalRootView.swift +++ b/WavesWallet-iOS/Extensions/UIKit/Modal/ModalRootView.swift @@ -81,5 +81,4 @@ class ModalRootView: UIView, ModalScrollViewRootView { func scrollViewDidScroll(_ scrollView: UIScrollView) { setNeedsLayout() } - } diff --git a/WavesWallet-iOS/Extensions/UIKit/Type/Modal/ModalScrollViewController.swift b/WavesWallet-iOS/Extensions/UIKit/Modal/ModalScrollViewController.swift similarity index 91% rename from WavesWallet-iOS/Extensions/UIKit/Type/Modal/ModalScrollViewController.swift rename to WavesWallet-iOS/Extensions/UIKit/Modal/ModalScrollViewController.swift index 180fd205..9d011a81 100644 --- a/WavesWallet-iOS/Extensions/UIKit/Type/Modal/ModalScrollViewController.swift +++ b/WavesWallet-iOS/Extensions/UIKit/Modal/ModalScrollViewController.swift @@ -8,7 +8,7 @@ import Foundation import UIKit -import WavesSDKExtension +import WavesSDKExtensions private struct Constants { static let offsetDistanceForDismiss: CGFloat = 48 @@ -55,18 +55,19 @@ class ModalScrollViewController: UIViewController, ModalScrollViewContext { super.viewWillDisappear(animated) } - //MARK: Need overriding + // MARK: Need overriding var scrollView: UIScrollView { assertMethodNeedOverriding() return UIScrollView() } - //MARK: Need overriding + // MARK: Need overriding func visibleScrollViewHeight(for size: CGSize) -> CGFloat { assertMethodNeedOverriding() return 0.0 } + // MARK: Need overriding func bottomScrollInset(for size: CGSize) -> CGFloat { return 0.0 } @@ -85,11 +86,13 @@ extension ModalScrollViewController { private func setupInsets() { + let bottom = bottomScrollInset(for: scrollView.frame.size) let top = scrollView.frame.height - visibleScrollViewHeight(for: scrollView.frame.size) - scrollView.contentInset.bottom = bottomScrollInset(for: scrollView.frame.size) + let contentOffset = top + scrollView.contentInset.bottom = bottom scrollView.contentInset.top = top - scrollView.scrollIndicatorInsets.top = top - scrollView.contentOffset.y = -top + scrollView.scrollIndicatorInsets.top = contentOffset + scrollView.contentOffset.y = -(contentOffset) } private func setupScrollView() { diff --git a/WavesWallet-iOS/Extensions/UIKit/Type/Modal/ModalTableView.swift b/WavesWallet-iOS/Extensions/UIKit/Modal/ModalTableView.swift similarity index 77% rename from WavesWallet-iOS/Extensions/UIKit/Type/Modal/ModalTableView.swift rename to WavesWallet-iOS/Extensions/UIKit/Modal/ModalTableView.swift index 809c8324..5a9cd4af 100644 --- a/WavesWallet-iOS/Extensions/UIKit/Type/Modal/ModalTableView.swift +++ b/WavesWallet-iOS/Extensions/UIKit/Modal/ModalTableView.swift @@ -20,6 +20,7 @@ class ModalTableView: UITableView { override func layoutSubviews() { super.layoutSubviews() + backgroundModalView.isUserInteractionEnabled = false backgroundModalView.frame = CGRect(x: 0, y: contentSize.height, width: bounds.width, @@ -33,10 +34,16 @@ class ModalTableView: UITableView { if let tableHeaderView = tableHeaderView { let headerViewFrame = tableHeaderView.convert(tableHeaderView.frame, to: self) - if headerViewFrame.contains(point) { + if headerViewFrame.contains(point) { return self } } + + let backgroundModalFrame = backgroundModalView.convert(backgroundModalView.frame, to: self) + + if backgroundModalFrame.contains(point) { + return self + } return super.hitTest(point, with: event) } diff --git a/WavesWallet-iOS/Extensions/UIKit/Type/Modal/ModalViewControllerTransitioning.swift b/WavesWallet-iOS/Extensions/UIKit/Modal/ModalViewControllerTransitioning.swift similarity index 100% rename from WavesWallet-iOS/Extensions/UIKit/Type/Modal/ModalViewControllerTransitioning.swift rename to WavesWallet-iOS/Extensions/UIKit/Modal/ModalViewControllerTransitioning.swift diff --git a/WavesWallet-iOS/Extensions/UIKit/Type/Notifications.swift b/WavesWallet-iOS/Extensions/UIKit/Notifications.swift similarity index 74% rename from WavesWallet-iOS/Extensions/UIKit/Type/Notifications.swift rename to WavesWallet-iOS/Extensions/UIKit/Notifications.swift index 212ff461..26446556 100644 --- a/WavesWallet-iOS/Extensions/UIKit/Type/Notifications.swift +++ b/WavesWallet-iOS/Extensions/UIKit/Notifications.swift @@ -12,6 +12,5 @@ extension Notification.Name { public static let changedSpamList = Notification.Name(rawValue: "com.waves.language.notification.changedSpamList") /** The notification object contained current Language - */ - static let changedLanguage: Notification.Name = Notification.Name.init("com.waves.language.notification.changedLanguage") + */ } diff --git a/WavesWallet-iOS/Extensions/UIKit/Protocols/SectionDisplayCollection.swift b/WavesWallet-iOS/Extensions/UIKit/Protocols/SectionDisplayCollection.swift deleted file mode 100644 index b1f9c4f0..00000000 --- a/WavesWallet-iOS/Extensions/UIKit/Protocols/SectionDisplayCollection.swift +++ /dev/null @@ -1,38 +0,0 @@ -// -// SectionDisplayCollection.swift -// WavesWallet-iOS -// -// Created by Prokofev Ruslan on 15/08/2018. -// Copyright © 2018 Waves Platform. All rights reserved. -// - -import Foundation - -protocol SectionProtocol { - associatedtype Row - var rows: [Row] { get set } -} - -protocol DataSourceProtocol { - associatedtype Section: SectionProtocol - var sections: [Section] { get set } -} - -extension DataSourceProtocol { - subscript(indexPath: IndexPath) -> Section.Row { - return sections[indexPath.section].rows[indexPath.row] - } -} - -extension SectionProtocol { - subscript(index: Int) -> Row { - return rows[index] - } -} - -extension Array where Element: SectionProtocol { - - subscript(indexPath: IndexPath) -> Element.Row { - return self[indexPath.section][indexPath.row] - } -} diff --git a/WavesWallet-iOS/Extensions/UIKit/Type/QRCodeReader+Factory.swift b/WavesWallet-iOS/Extensions/UIKit/QRCodeReader+Factory.swift similarity index 83% rename from WavesWallet-iOS/Extensions/UIKit/Type/QRCodeReader+Factory.swift rename to WavesWallet-iOS/Extensions/UIKit/QRCodeReader+Factory.swift index 579057f1..951e2ef8 100644 --- a/WavesWallet-iOS/Extensions/UIKit/Type/QRCodeReader+Factory.swift +++ b/WavesWallet-iOS/Extensions/UIKit/QRCodeReader+Factory.swift @@ -20,6 +20,8 @@ enum QRCodeReaderFactory { $0.preferredStatusBarStyle = .lightContent } - return QRCodeReaderViewController(builder: builder) + let vc = QRCodeReaderViewController(builder: builder) + vc.modalPresentationStyle = .fullScreen + return vc }() } diff --git a/WavesWallet-iOS/Extensions/UIKit/Type/RateApp.swift b/WavesWallet-iOS/Extensions/UIKit/RateApp.swift similarity index 56% rename from WavesWallet-iOS/Extensions/UIKit/Type/RateApp.swift rename to WavesWallet-iOS/Extensions/UIKit/RateApp.swift index 3b4820da..95814bf1 100644 --- a/WavesWallet-iOS/Extensions/UIKit/Type/RateApp.swift +++ b/WavesWallet-iOS/Extensions/UIKit/RateApp.swift @@ -9,10 +9,7 @@ import Foundation import UIKit import StoreKit - -private enum Constants { - static let appURL: String = "https://itunes.apple.com/us/app/waves-wallet/id1233158971?mt=8" -} +import WavesSDK enum RateApp { @@ -21,8 +18,7 @@ enum RateApp { } private static func showItunes() { - guard let url = URL(string: Constants.appURL) else { return } - UIApplication.shared.openURLAsync(url) + UIApplication.shared.openURLAsync(WavesSDKConstants.appstoreURL) } } diff --git a/WavesWallet-iOS/Extensions/UIKit/Protocols/Skeleton/SkeletonAnimatable.swift b/WavesWallet-iOS/Extensions/UIKit/Skeleton/SkeletonAnimatable.swift similarity index 96% rename from WavesWallet-iOS/Extensions/UIKit/Protocols/Skeleton/SkeletonAnimatable.swift rename to WavesWallet-iOS/Extensions/UIKit/Skeleton/SkeletonAnimatable.swift index 52e92358..90556c13 100644 --- a/WavesWallet-iOS/Extensions/UIKit/Protocols/Skeleton/SkeletonAnimatable.swift +++ b/WavesWallet-iOS/Extensions/UIKit/Skeleton/SkeletonAnimatable.swift @@ -83,13 +83,13 @@ extension SkeletonAnimatable where Self: UIView { } fileprivate extension UIView { - @objc fileprivate func didBecomeActive() { + @objc func didBecomeActive() { if let skeleton = self as? (UIView & SkeletonAnimatable) { skeleton.startAnimation(to: skeleton.direction) } } - @objc fileprivate func didEnterBackground() { + @objc func didEnterBackground() { if let skeleton = self as? (UIView & SkeletonAnimatable) { skeleton.stopAnimation() } diff --git a/WavesWallet-iOS/Extensions/UIKit/Protocols/Skeleton/UITableView+Skeleton.swift b/WavesWallet-iOS/Extensions/UIKit/Skeleton/UITableView+Skeleton.swift similarity index 100% rename from WavesWallet-iOS/Extensions/UIKit/Protocols/Skeleton/UITableView+Skeleton.swift rename to WavesWallet-iOS/Extensions/UIKit/Skeleton/UITableView+Skeleton.swift diff --git a/WavesWallet-iOS/Extensions/UIKit/Type/UIAlertController+Factory.swift b/WavesWallet-iOS/Extensions/UIKit/UIAlertController+Factory.swift similarity index 100% rename from WavesWallet-iOS/Extensions/UIKit/Type/UIAlertController+Factory.swift rename to WavesWallet-iOS/Extensions/UIKit/UIAlertController+Factory.swift diff --git a/WavesWallet-iOS/Extensions/UIKit/UIResponder+Rx.swift b/WavesWallet-iOS/Extensions/UIKit/UIResponder+Rx.swift deleted file mode 100644 index 8b05237d..00000000 --- a/WavesWallet-iOS/Extensions/UIKit/UIResponder+Rx.swift +++ /dev/null @@ -1,15 +0,0 @@ -// -// UITextFieldExtension.swift -// WavesWallet-iOS -// -// Created by Alexey Koloskov on 11/04/2017. -// Copyright © 2017 Waves Platform. All rights reserved. -// - -import Foundation -import RxSwift -import RxCocoa - -extension Reactive where Base: UIResponder { - -} diff --git a/WavesWallet-iOS/Extensions/UIKit/UIViewController+Alert.swift b/WavesWallet-iOS/Extensions/UIKit/UIViewController+Alert.swift deleted file mode 100755 index e93e214c..00000000 --- a/WavesWallet-iOS/Extensions/UIKit/UIViewController+Alert.swift +++ /dev/null @@ -1,40 +0,0 @@ -import Foundation -import UIKit - -extension UIViewController { - //TODO remove - public func presentBasicAlertWithTitle(title: String, message: String? = nil, - completion: (() -> Void)? = nil) { - if presentedViewController == nil { - let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) - alert.addAction(UIAlertAction(title: "Ok", style: UIAlertAction.Style.default, handler: { (UIAlertAction) in - - if let completion = completion { - completion() - } - })) - self.present(alert, animated: true, completion: nil) - } - } - - public func presentAskAlert(title: String, message: String? = nil, yesCompletion: (() -> Void)? = nil, noCompletion: (() -> Void)? = nil) { - if presentedViewController == nil { - let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) - alert.addAction(UIAlertAction(title: "Confirm", style: UIAlertAction.Style.default, handler: { (UIAlertAction) in - - if let completion = yesCompletion { - completion() - } - })) - alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertAction.Style.cancel, handler: { (UIAlertAction) in - - if let completion = noCompletion { - completion() - } - })) - self.present(alert, animated: true, completion: nil) - } - } - - -} diff --git a/WavesWallet-iOS/Extensions/UIKit/UIViewController+Additionals.swift b/WavesWallet-iOS/Extensions/UIViewController+Additionals.swift similarity index 70% rename from WavesWallet-iOS/Extensions/UIKit/UIViewController+Additionals.swift rename to WavesWallet-iOS/Extensions/UIViewController+Additionals.swift index 133ef88f..363c2b67 100644 --- a/WavesWallet-iOS/Extensions/UIKit/UIViewController+Additionals.swift +++ b/WavesWallet-iOS/Extensions/UIViewController+Additionals.swift @@ -8,6 +8,8 @@ import Foundation import UIKit +import DomainLayer +import Extensions private enum Constants { static let smallNavBarHeight: CGFloat = 44 @@ -29,13 +31,19 @@ extension UIViewController { let item = UIBarButtonItem(image: UIImage(named: "icon_menu"), style: .done, target: self, action: #selector(menuTapped)) if isWhite { - item.tintColor = .white + item.tintColor = UIColor.white } navigationItem.leftBarButtonItem = item } @objc func menuTapped() { + + UseCasesFactory + .instance + .analyticManager + .trackEvent(.menu(.wavesMenuPage)) + let menu = AppDelegate.shared().menuController menu.presentLeftMenuViewController() } @@ -44,9 +52,15 @@ extension UIViewController { navigationController?.popViewController(animated: true) } - func hideTopBarLine() { + func removeTopBarLine() { navigationItem.shadowImage = UIImage() } + + func hideTopBarLineForIOS12() { + if !Platform.isIOS13orGreater { + navigationItem.shadowImage = UIImage() + } + } func showTopBarLine() { navigationItem.shadowImage = UIViewController.shadowImage @@ -66,24 +80,26 @@ extension UIViewController { func setupTopBarLine() { - if isSmallNavigationBar { - navigationItem.shadowImage = UIViewController.shadowImage - } - else { - navigationItem.shadowImage = UIViewController.cleanShadowImage + if !Platform.isIOS13orGreater { + if isSmallNavigationBar { + navigationItem.shadowImage = UIViewController.shadowImage + } + else { + navigationItem.shadowImage = UIViewController.cleanShadowImage + } } } func setupSmallNavigationBar() { if #available(iOS 11.0, *) { - navigationItem.prefersLargeTitles = false + navigationItem.largeTitleDisplayMode = .never } } func setupBigNavigationBar() { if #available(iOS 11.0, *) { + navigationItem.largeTitleDisplayMode = .always navigationItem.prefersLargeTitles = true - navigationItem.largeTitleDisplayMode = .automatic } } @@ -97,9 +113,23 @@ extension UIViewController { func tableViewTopOffsetForBigNavBar(_ tableView: UITableView) -> CGPoint { - //TODO: check if IOS 10 will be support let navBarY = (navigationController?.navigationBar.frame.origin.y ?? 0) let offset = -(Constants.bigNavBarHeight + navBarY + tableView.contentInset.top) return CGPoint(x: 0, y: offset) } + + func findNavigationController() -> UINavigationController? { + var current: UIResponder? = self + + while (current != nil) { + + if let nav = current as? UINavigationController { + return nav + } + + current = current?.next + } + + return nil + } } diff --git a/WavesWallet-iOS/Generated/AccessibilityIdentifiers.swift b/WavesWallet-iOS/Generated/AccessibilityIdentifiers.swift index 3d593131..2194e187 100644 --- a/WavesWallet-iOS/Generated/AccessibilityIdentifiers.swift +++ b/WavesWallet-iOS/Generated/AccessibilityIdentifiers.swift @@ -1,6 +1,7 @@ // Generated using SwiftGen, by O.Halligon — https://github.com/SwiftGen/SwiftGen import Foundation +import Extensions // swiftlint:disable superfluous_disable_command // swiftlint:disable file_length @@ -43,7 +44,7 @@ internal enum AccessibilityIdentifiers { } // swiftlint:enable explicit_type_interface identifier_name line_length nesting type_body_length type_name -extension AccessibilityIdentifiers { +extension AccessibilityIdentifiers: LocalizableProtocol { struct Current { var locale: Locale @@ -52,12 +53,13 @@ extension AccessibilityIdentifiers { private static let english: Localizable.Current = Localizable.Current(locale: Locale(identifier: "en"), bundle: Bundle(for: BundleToken.self)) - static var current: Localizable.Current = Localizable.Current(locale: Locale.current, bundle: Bundle(for: BundleToken.self)) + static var locale: Locale = Locale.current + static var bundle: Bundle = Bundle(for: BundleToken.self) private static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String { - let format = NSLocalizedString(key, tableName: table, bundle: current.bundle, comment: "") + let format = NSLocalizedString(key, tableName: table, bundle: bundle, comment: "") - let value = String(format: format, locale: current.locale, arguments: args) + let value = String(format: format, locale: locale, arguments: args) if value.localizedLowercase == key.localizedLowercase { let format = NSLocalizedString(key, tableName: table, bundle: english.bundle, comment: "") diff --git a/WavesWallet-iOS/Generated/Images.swift b/WavesWallet-iOS/Generated/Images.swift index a7a8ea97..c7f44bf6 100644 --- a/WavesWallet-iOS/Generated/Images.swift +++ b/WavesWallet-iOS/Generated/Images.swift @@ -44,7 +44,6 @@ internal struct ColorAsset { // swiftlint:disable identifier_name line_length nesting type_body_length type_name internal enum Images { - internal static let image = ImageAsset(name: "Image") internal static let addAddressIcon = ImageAsset(name: "add_address_icon") internal static let addaddress24Submit200 = ImageAsset(name: "addaddress24Submit200") internal static let addaddress24Submit300 = ImageAsset(name: "addaddress24Submit300") @@ -69,6 +68,7 @@ internal enum Images { internal static let bgIphonex = ImageAsset(name: "bg-iphonex") internal static let bgIphonexr = ImageAsset(name: "bg-iphonexr") internal static let bgIphonexsmax = ImageAsset(name: "bg-iphonexsmax") + internal static let bigwarning48 = ImageAsset(name: "bigwarning48") internal static let blockchain80 = ImageAsset(name: "blockchain80") internal static let btnBack = ImageAsset(name: "btn_back") internal static let btnBars = ImageAsset(name: "btn_bars") @@ -107,6 +107,7 @@ internal enum Images { internal static let editAddressIcon = ImageAsset(name: "edit_address_icon") internal static let editaddress24Submit200 = ImageAsset(name: "editaddress24Submit200") internal static let editaddress24Submit300 = ImageAsset(name: "editaddress24Submit300") + internal static let error80Error500 = ImageAsset(name: "error80Error500") internal static let eyeclsoe24Basic500 = ImageAsset(name: "eyeclsoe24Basic500") internal static let eyeopen24Basic500 = ImageAsset(name: "eyeopen24Basic500") internal static let faceid48Submit300 = ImageAsset(name: "faceid48Submit300") @@ -132,6 +133,7 @@ internal enum Images { internal static let flag18Turkey = ImageAsset(name: "flag18Turkey") internal static let forwardChevron = ImageAsset(name: "forward-chevron") internal static let hide = ImageAsset(name: "hide") + internal static let hidekeyboard24Multy = ImageAsset(name: "hidekeyboard24Multy") internal static let history = ImageAsset(name: "history") internal static let iAnonim42Submit400 = ImageAsset(name: "iAnonim42Submit400") internal static let iBackup42Submit400 = ImageAsset(name: "iBackup42Submit400") @@ -157,6 +159,7 @@ internal enum Images { internal static let info18Error500 = ImageAsset(name: "info18Error500") internal static let info18Warning600 = ImageAsset(name: "info18Warning600") internal static let information22Multy = ImageAsset(name: "information22Multy") + internal static let information24Multy = ImageAsset(name: "information24Multy") internal static let launcher34 = ImageAsset(name: "launcher34") internal static let logoBitcoin48 = ImageAsset(name: "logoBitcoin48") internal static let logoBitcoincash48 = ImageAsset(name: "logoBitcoincash48") @@ -259,6 +262,7 @@ internal enum Images { internal static let tabbarWavesActive = ImageAsset(name: "tabbarWavesActive") internal static let tabbarWavesDefault = ImageAsset(name: "tabbarWavesDefault") internal static let token80 = ImageAsset(name: "token80") + internal static let topbarAdd = ImageAsset(name: "topbarAdd") internal static let topbarAddaddress = ImageAsset(name: "topbarAddaddress") internal static let topbarAddmarkets = ImageAsset(name: "topbarAddmarkets") internal static let topbarBackwhite = ImageAsset(name: "topbarBackwhite") @@ -276,6 +280,8 @@ internal enum Images { internal static let touchid48Submit300 = ImageAsset(name: "touchid48Submit300") internal static let unhide = ImageAsset(name: "unhide") internal static let upChevron = ImageAsset(name: "up-chevron@") + internal static let userimgUpdate = ImageAsset(name: "userimg-Update") + internal static let userimgPush = ImageAsset(name: "userimg-push") internal static let userimgBackup100 = ImageAsset(name: "userimgBackup100") internal static let userimgBlockchain80 = ImageAsset(name: "userimgBlockchain80") internal static let userimgBlockchain80White = ImageAsset(name: "userimgBlockchain80White") @@ -312,12 +318,15 @@ internal enum Images { internal static let warning18White = ImageAsset(name: "warning18White") internal static let warningAddress = ImageAsset(name: "warning_address") internal static let wavesLogo = ImageAsset(name: "waves_logo") + internal static let widgetAddtoken22 = ImageAsset(name: "widgetAddtoken22") + internal static let widgetInterval22 = ImageAsset(name: "widgetInterval22") + internal static let widgetMaxtoken22 = ImageAsset(name: "widgetMaxtoken22") + internal static let widgetStyle22 = ImageAsset(name: "widgetStyle22") // swiftlint:disable trailing_comma internal static let allColors: [ColorAsset] = [ ] internal static let allImages: [ImageAsset] = [ - image, addAddressIcon, addaddress24Submit200, addaddress24Submit300, @@ -342,6 +351,7 @@ internal enum Images { bgIphonex, bgIphonexr, bgIphonexsmax, + bigwarning48, blockchain80, btnBack, btnBars, @@ -380,6 +390,7 @@ internal enum Images { editAddressIcon, editaddress24Submit200, editaddress24Submit300, + error80Error500, eyeclsoe24Basic500, eyeopen24Basic500, faceid48Submit300, @@ -405,6 +416,7 @@ internal enum Images { flag18Turkey, forwardChevron, hide, + hidekeyboard24Multy, history, iAnonim42Submit400, iBackup42Submit400, @@ -430,6 +442,7 @@ internal enum Images { info18Error500, info18Warning600, information22Multy, + information24Multy, launcher34, logoBitcoin48, logoBitcoincash48, @@ -532,6 +545,7 @@ internal enum Images { tabbarWavesActive, tabbarWavesDefault, token80, + topbarAdd, topbarAddaddress, topbarAddmarkets, topbarBackwhite, @@ -549,6 +563,8 @@ internal enum Images { touchid48Submit300, unhide, upChevron, + userimgUpdate, + userimgPush, userimgBackup100, userimgBlockchain80, userimgBlockchain80White, @@ -585,6 +601,10 @@ internal enum Images { warning18White, warningAddress, wavesLogo, + widgetAddtoken22, + widgetInterval22, + widgetMaxtoken22, + widgetStyle22, ] // swiftlint:enable trailing_comma @available(*, deprecated, renamed: "allImages") diff --git a/WavesWallet-iOS/Generated/Localizable.swift b/WavesWallet-iOS/Generated/Localizable.swift index 9c1d145d..07475a6e 100644 --- a/WavesWallet-iOS/Generated/Localizable.swift +++ b/WavesWallet-iOS/Generated/Localizable.swift @@ -1,6 +1,7 @@ // Generated using SwiftGen, by O.Halligon — https://github.com/SwiftGen/SwiftGen import Foundation +import Extensions // swiftlint:disable superfluous_disable_command // swiftlint:disable file_length @@ -384,6 +385,18 @@ internal enum Localizable { } } + internal enum Assetsearch { + + internal enum Cell { + + internal enum Empty { + /// No tokens matching your search + internal static var title: String { return Localizable.tr("Waves", "assetsearch.cell.empty.title") } + internal static var titleKey: String { return "assetsearch.cell.empty.title" } + } + } + } + internal enum Backup { internal enum Backup { @@ -580,6 +593,9 @@ internal enum Localizable { internal enum Chooseaccount { internal enum Alert { + /// Please select + internal static var pleaseSelect: String { return Localizable.tr("Waves", "chooseaccount.alert.pleaseSelect") } + internal static var pleaseSelectKey: String { return "chooseaccount.alert.pleaseSelect" } internal enum Button { /// Cancel @@ -614,7 +630,7 @@ internal enum Localizable { } internal enum Coinomat { - /// Service Coinomat temporarily unavailable + /// Service temporarily unavailable internal static var temporarilyUnavailable: String { return Localizable.tr("Waves", "coinomat.temporarilyUnavailable") } internal static var temporarilyUnavailableKey: String { return "coinomat.temporarilyUnavailable" } /// Try again later @@ -786,6 +802,32 @@ internal enum Localizable { internal static var weekKey: String { return "dexcreateorder.button.week" } } + internal enum Invalidpricepopup { + /// Do you want to proceed? + internal static var subtitle: String { return Localizable.tr("Waves", "dexcreateorder.invalidPricePopup.subtitle") } + internal static var subtitleKey: String { return "dexcreateorder.invalidPricePopup.subtitle" } + + internal enum Button { + /// Cancel + internal static var cancel: String { return Localizable.tr("Waves", "dexcreateorder.invalidPricePopup.button.cancel") } + internal static var cancelKey: String { return "dexcreateorder.invalidPricePopup.button.cancel" } + /// Place Order + internal static var placeOrder: String { return Localizable.tr("Waves", "dexcreateorder.invalidPricePopup.button.placeOrder") } + internal static var placeOrderKey: String { return "dexcreateorder.invalidPricePopup.button.placeOrder" } + } + + internal enum Title { + /// You order price is %d%% higher than the latest market price + internal static func higherPrice(_ p1: Int) -> String { + return Localizable.tr("Waves", "dexcreateorder.invalidPricePopup.title.higherPrice", p1) + } + /// Your order price is %d%% lower than the latest market price + internal static func loverPrice(_ p1: Int) -> String { + return Localizable.tr("Waves", "dexcreateorder.invalidPricePopup.title.loverPrice", p1) + } + } + } + internal enum Label { /// Amount in internal static var amountIn: String { return Localizable.tr("Waves", "dexcreateorder.label.amountIn") } @@ -1177,6 +1219,25 @@ internal enum Localizable { } } + internal enum Forceupdate { + + internal enum Button { + /// Update + internal static var update: String { return Localizable.tr("Waves", "forceupdate.button.update") } + internal static var updateKey: String { return "forceupdate.button.update" } + } + + internal enum Label { + /// To continue using the app, you will need to upgrade to version %@. Availability of the new version in the App Store may take a few hours.\nYou can use the web version to access your Waves account for now. + internal static func subtitle(_ p1: String) -> String { + return Localizable.tr("Waves", "forceupdate.label.subtitle", p1) + } + /// It is time to update your Waves app! + internal static var title: String { return Localizable.tr("Waves", "forceupdate.label.title") } + internal static var titleKey: String { return "forceupdate.label.title" } + } + } + internal enum General { internal enum Biometric { @@ -1710,6 +1771,42 @@ internal enum Localizable { } } + internal enum Keeper { + + internal enum Button { + /// Approve + internal static var approve: String { return Localizable.tr("Waves", "keeper.button.approve") } + internal static var approveKey: String { return "keeper.button.approve" } + /// Reject + internal static var reject: String { return Localizable.tr("Waves", "keeper.button.reject") } + internal static var rejectKey: String { return "keeper.button.reject" } + } + + internal enum Label { + /// Confirm request + internal static var confirmRequest: String { return Localizable.tr("Waves", "keeper.label.confirmRequest") } + internal static var confirmRequestKey: String { return "keeper.label.confirmRequest" } + /// Function + internal static var function: String { return Localizable.tr("Waves", "keeper.label.function") } + internal static var functionKey: String { return "keeper.label.function" } + /// To + internal static var to: String { return Localizable.tr("Waves", "keeper.label.to") } + internal static var toKey: String { return "keeper.label.to" } + /// TX time + internal static var txTime: String { return Localizable.tr("Waves", "keeper.label.txTime") } + internal static var txTimeKey: String { return "keeper.label.txTime" } + } + + internal enum Transaction { + /// Your transaction is confirmed! + internal static var confirmed: String { return Localizable.tr("Waves", "keeper.transaction.confirmed") } + internal static var confirmedKey: String { return "keeper.transaction.confirmed" } + /// Your transaction failed + internal static var failed: String { return Localizable.tr("Waves", "keeper.transaction.failed") } + internal static var failedKey: String { return "keeper.transaction.failed" } + } + } + internal enum Menu { internal enum Button { @@ -2171,6 +2268,27 @@ internal enum Localizable { } } + internal enum Pushnotificationsalert { + + internal enum Button { + /// Yes, notify me + internal static var activatePush: String { return Localizable.tr("Waves", "pushNotificationsAlert.button.activatePush") } + internal static var activatePushKey: String { return "pushNotificationsAlert.button.activatePush" } + /// Maybe later + internal static var later: String { return Localizable.tr("Waves", "pushNotificationsAlert.button.later") } + internal static var laterKey: String { return "pushNotificationsAlert.button.later" } + } + + internal enum Label { + /// We'd like to show you notifications for the latest news and updates. + internal static var subtitle: String { return Localizable.tr("Waves", "pushNotificationsAlert.label.subtitle") } + internal static var subtitleKey: String { return "pushNotificationsAlert.label.subtitle" } + /// Get important notifications + internal static var title: String { return Localizable.tr("Waves", "pushNotificationsAlert.label.title") } + internal static var titleKey: String { return "pushNotificationsAlert.label.title" } + } + } + internal enum Receive { internal enum Button { @@ -2428,7 +2546,7 @@ internal enum Localizable { internal static func description(_ p1: String) -> String { return Localizable.tr("Waves", "Send.Label.Warning.description", p1) } - /// We detected %@ address and will send your money through Coinomat gateway to that address. Minimum amount is %@, maximum amount is %@. + /// We detected %@ address and will send your money through gateway to that address. Minimum amount is %@, maximum amount is %@. internal static func subtitle(_ p1: String, _ p2: String, _ p3: String) -> String { return Localizable.tr("Waves", "Send.Label.Warning.subtitle", p1, p2, p3) } @@ -2487,6 +2605,9 @@ internal enum Localizable { /// Fee internal static var fee: String { return Localizable.tr("Waves", "sendconfirmation.label.fee") } internal static var feeKey: String { return "sendconfirmation.label.fee" } + /// Gateway Fee + internal static var gatewayFee: String { return Localizable.tr("Waves", "sendconfirmation.label.gatewayFee") } + internal static var gatewayFeeKey: String { return "sendconfirmation.label.gatewayFee" } /// Write an optional message internal static var optionalMessage: String { return Localizable.tr("Waves", "sendconfirmation.label.optionalMessage") } internal static var optionalMessageKey: String { return "sendconfirmation.label.optionalMessage" } @@ -3262,11 +3383,98 @@ internal enum Localizable { internal static var comingsoonKey: String { return "wavespopup.label.comingsoon" } } } + + internal enum Widgetsettings { + + internal enum Actionsheet { + + internal enum Changeinterval { + /// Update interval + internal static var title: String { return Localizable.tr("Waves", "widgetsettings.actionsheet.changeinterval.title") } + internal static var titleKey: String { return "widgetsettings.actionsheet.changeinterval.title" } + + internal enum Element { + /// 1 minute + internal static var m1: String { return Localizable.tr("Waves", "widgetsettings.actionsheet.changeinterval.element.m1") } + internal static var m1Key: String { return "widgetsettings.actionsheet.changeinterval.element.m1" } + /// 10 minute + internal static var m10: String { return Localizable.tr("Waves", "widgetsettings.actionsheet.changeinterval.element.m10") } + internal static var m10Key: String { return "widgetsettings.actionsheet.changeinterval.element.m10" } + /// 5 minute + internal static var m5: String { return Localizable.tr("Waves", "widgetsettings.actionsheet.changeinterval.element.m5") } + internal static var m5Key: String { return "widgetsettings.actionsheet.changeinterval.element.m5" } + /// Update manually + internal static var manually: String { return Localizable.tr("Waves", "widgetsettings.actionsheet.changeinterval.element.manually") } + internal static var manuallyKey: String { return "widgetsettings.actionsheet.changeinterval.element.manually" } + } + } + + internal enum Changestyle { + /// Widget style + internal static var title: String { return Localizable.tr("Waves", "widgetsettings.actionsheet.changestyle.title") } + internal static var titleKey: String { return "widgetsettings.actionsheet.changestyle.title" } + + internal enum Element { + /// Classic + internal static var classic: String { return Localizable.tr("Waves", "widgetsettings.actionsheet.changestyle.element.classic") } + internal static var classicKey: String { return "widgetsettings.actionsheet.changestyle.element.classic" } + /// Dark + internal static var dark: String { return Localizable.tr("Waves", "widgetsettings.actionsheet.changestyle.element.dark") } + internal static var darkKey: String { return "widgetsettings.actionsheet.changestyle.element.dark" } + } + } + } + + internal enum Button { + /// Add token + internal static var addToken: String { return Localizable.tr("Waves", "widgetsettings.button.addToken") } + internal static var addTokenKey: String { return "widgetsettings.button.addToken" } + } + + internal enum Changeinterval { + + internal enum Button { + /// 1 minute + internal static var m1: String { return Localizable.tr("Waves", "widgetsettings.changeinterval.button.m1") } + internal static var m1Key: String { return "widgetsettings.changeinterval.button.m1" } + /// 10 minute + internal static var m10: String { return Localizable.tr("Waves", "widgetsettings.changeinterval.button.m10") } + internal static var m10Key: String { return "widgetsettings.changeinterval.button.m10" } + /// 5 minute + internal static var m5: String { return Localizable.tr("Waves", "widgetsettings.changeinterval.button.m5") } + internal static var m5Key: String { return "widgetsettings.changeinterval.button.m5" } + /// Update manually + internal static var manually: String { return Localizable.tr("Waves", "widgetsettings.changeinterval.button.manually") } + internal static var manuallyKey: String { return "widgetsettings.changeinterval.button.manually" } + } + } + + internal enum Label { + /// Added + internal static var added: String { return Localizable.tr("Waves", "widgetsettings.label.added") } + internal static var addedKey: String { return "widgetsettings.label.added" } + } + + internal enum Navigation { + /// Market pulse + internal static var title: String { return Localizable.tr("Waves", "widgetsettings.navigation.title") } + internal static var titleKey: String { return "widgetsettings.navigation.title" } + } + + internal enum Tableview { + + internal enum Editmode { + /// Delete + internal static var delete: String { return Localizable.tr("Waves", "widgetsettings.tableview.editmode.delete") } + internal static var deleteKey: String { return "widgetsettings.tableview.editmode.delete" } + } + } + } } } // swiftlint:enable explicit_type_interface identifier_name line_length nesting type_body_length type_name -extension Localizable { +extension Localizable: LocalizableProtocol { struct Current { var locale: Locale @@ -3275,12 +3483,13 @@ extension Localizable { private static let english: Localizable.Current = Localizable.Current(locale: Locale(identifier: "en"), bundle: Bundle(for: BundleToken.self)) - static var current: Localizable.Current = Localizable.Current(locale: Locale.current, bundle: Bundle(for: BundleToken.self)) + static var locale: Locale = Locale.current + static var bundle: Bundle = Bundle(for: BundleToken.self) private static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String { - let format = NSLocalizedString(key, tableName: table, bundle: current.bundle, comment: "") + let format = NSLocalizedString(key, tableName: table, bundle: bundle, comment: "") - let value = String(format: format, locale: current.locale, arguments: args) + let value = String(format: format, locale: locale, arguments: args) if value.localizedLowercase == key.localizedLowercase { let format = NSLocalizedString(key, tableName: table, bundle: english.bundle, comment: "") diff --git a/WavesWallet-iOS/Generated/Storyboards.swift b/WavesWallet-iOS/Generated/Storyboards.swift index 581feb44..0c7d2263 100644 --- a/WavesWallet-iOS/Generated/Storyboards.swift +++ b/WavesWallet-iOS/Generated/Storyboards.swift @@ -58,6 +58,11 @@ internal enum StoryboardScene { internal static let accountPasswordViewController = SceneType(storyboard: AccountPassword.self, identifier: "AccountPasswordViewController") } + internal enum ActionSheet: StoryboardType { + internal static let storyboardName = "ActionSheet" + + internal static let actionSheetViewController = SceneType(storyboard: ActionSheet.self, identifier: "ActionSheetViewController") + } internal enum AddressBook: StoryboardType { internal static let storyboardName = "AddressBook" @@ -83,6 +88,11 @@ internal enum StoryboardScene { internal static let assetListViewController = SceneType(storyboard: AssetList.self, identifier: "AssetListViewController") } + internal enum AssetsSearch: StoryboardType { + internal static let storyboardName = "AssetsSearch" + + internal static let assetsSearchViewController = SceneType(storyboard: AssetsSearch.self, identifier: "AssetsSearchViewController") + } internal enum Backup: StoryboardType { internal static let storyboardName = "Backup" @@ -111,6 +121,8 @@ internal enum StoryboardScene { internal static let dexCreateOrderViewController = SceneType(storyboard: Dex.self, identifier: "DexCreateOrderViewController") + internal static let dexDeepLinkLoadingViewController = SceneType(storyboard: Dex.self, identifier: "DexDeepLinkLoadingViewController") + internal static let dexInfoViewController = SceneType(storyboard: Dex.self, identifier: "DexInfoViewController") internal static let dexLastTradesViewController = SceneType(storyboard: Dex.self, identifier: "DexLastTradesViewController") @@ -141,6 +153,11 @@ internal enum StoryboardScene { internal static let languageViewController = SceneType(storyboard: Enter.self, identifier: "LanguageViewController") } + internal enum ForceUpdateApp: StoryboardType { + internal static let storyboardName = "ForceUpdateApp" + + internal static let forceUpdateAppViewController = SceneType(storyboard: ForceUpdateApp.self, identifier: "ForceUpdateAppViewController") + } internal enum Hello: StoryboardType { internal static let storyboardName = "Hello" @@ -183,6 +200,15 @@ internal enum StoryboardScene { internal static let menuViewController = SceneType(storyboard: Main.self, identifier: "MenuViewController") } + internal enum MobileKeeper: StoryboardType { + internal static let storyboardName = "MobileKeeper" + + internal static let confirmRequestCompleteViewController = SceneType(storyboard: MobileKeeper.self, identifier: "ConfirmRequestCompleteViewController") + + internal static let confirmRequestLoadingViewController = SceneType(storyboard: MobileKeeper.self, identifier: "ConfirmRequestLoadingViewController") + + internal static let confirmRequestViewController = SceneType(storyboard: MobileKeeper.self, identifier: "ConfirmRequestViewController") + } internal enum MyAddress: StoryboardType { internal static let storyboardName = "MyAddress" @@ -261,7 +287,7 @@ internal enum StoryboardScene { internal enum Support: StoryboardType { internal static let storyboardName = "Support" - internal static let supportViewController = SceneType(storyboard: Support.self, identifier: "SupportViewController") + internal static let debugViewController = SceneType(storyboard: Support.self, identifier: "DebugViewController") internal static let testViewController = SceneType(storyboard: Support.self, identifier: "TestViewController") } @@ -289,6 +315,11 @@ internal enum StoryboardScene { internal static let wavesPopupViewController = SceneType(storyboard: Waves.self, identifier: "WavesPopupViewController") } + internal enum WidgetSettings: StoryboardType { + internal static let storyboardName = "WidgetSettings" + + internal static let widgetSettingsViewController = SceneType(storyboard: WidgetSettings.self, identifier: "WidgetSettingsViewController") + } } internal enum StoryboardSegue { diff --git a/WavesWallet-iOS/Info.plist b/WavesWallet-iOS/Info.plist index 7649e1fb..34697ceb 100644 --- a/WavesWallet-iOS/Info.plist +++ b/WavesWallet-iOS/Info.plist @@ -17,22 +17,42 @@ CFBundlePackageType APPL CFBundleShortVersionString - 2.4.0 + $(MARKETING_VERSION) CFBundleURLTypes CFBundleTypeRole Editor CFBundleURLName - com.wavesplatform.WavesWallet-iOS + com.wavesplatform.waveswallet CFBundleURLSchemes waves + + CFBundleTypeRole + Editor + CFBundleURLName + com.wavesplatform.waveswallet.dev + CFBundleURLSchemes + + waves-dev + + + + CFBundleTypeRole + Editor + CFBundleURLName + com.wavesplatform.waveswallet.test + CFBundleURLSchemes + + waves-test + + CFBundleVersion - 3857 + 3920 Fabric APIKey @@ -68,6 +88,8 @@ UIRequiresFullScreen + UIStatusBarStyle + UIStatusBarStyleDefault UIStatusBarTintParameters UINavigationBar @@ -82,6 +104,8 @@ UIInterfaceOrientationPortrait + UIUserInterfaceStyle + Light UIViewControllerBasedStatusBarAppearance diff --git a/WavesWallet-iOS/PresentationLayer/Modules/AccountPassword/AccountPassword.storyboard b/WavesWallet-iOS/Modules/AccountPassword/AccountPassword.storyboard similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/AccountPassword/AccountPassword.storyboard rename to WavesWallet-iOS/Modules/AccountPassword/AccountPassword.storyboard diff --git a/WavesWallet-iOS/PresentationLayer/Modules/AccountPassword/AccountPassword.swift b/WavesWallet-iOS/Modules/AccountPassword/AccountPassword.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/AccountPassword/AccountPassword.swift rename to WavesWallet-iOS/Modules/AccountPassword/AccountPassword.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/AccountPassword/AccountPasswordInteractor.swift b/WavesWallet-iOS/Modules/AccountPassword/AccountPasswordInteractor.swift similarity index 94% rename from WavesWallet-iOS/PresentationLayer/Modules/AccountPassword/AccountPasswordInteractor.swift rename to WavesWallet-iOS/Modules/AccountPassword/AccountPasswordInteractor.swift index 19e18291..2768167c 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/AccountPassword/AccountPasswordInteractor.swift +++ b/WavesWallet-iOS/Modules/AccountPassword/AccountPasswordInteractor.swift @@ -10,6 +10,7 @@ import Foundation import RxSwift import RxCocoa import RxFeedback +import DomainLayer enum AccountPasswordInteractorError: Error { case fail @@ -24,7 +25,7 @@ protocol AccountPasswordInteractorProtocol { final class AccountPasswordInteractor: AccountPasswordInteractorProtocol { - private let authorizationInteractor: AuthorizationInteractorProtocol = FactoryInteractors.instance.authorization + private let authorizationInteractor: AuthorizationUseCaseProtocol = UseCasesFactory.instance.authorization func logIn(wallet: DomainLayer.DTO.Wallet, password: String) -> Observable { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/AccountPassword/AccountPasswordModuleBuilder.swift b/WavesWallet-iOS/Modules/AccountPassword/AccountPasswordModuleBuilder.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/AccountPassword/AccountPasswordModuleBuilder.swift rename to WavesWallet-iOS/Modules/AccountPassword/AccountPasswordModuleBuilder.swift index ec3a485a..60f57c85 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/AccountPassword/AccountPasswordModuleBuilder.swift +++ b/WavesWallet-iOS/Modules/AccountPassword/AccountPasswordModuleBuilder.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions struct AccountPasswordModuleBuilder: ModuleBuilderOutput { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/AccountPassword/AccountPasswordPresenter.swift b/WavesWallet-iOS/Modules/AccountPassword/AccountPasswordPresenter.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/AccountPassword/AccountPasswordPresenter.swift rename to WavesWallet-iOS/Modules/AccountPassword/AccountPasswordPresenter.swift index 66938eac..dbe49434 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/AccountPassword/AccountPasswordPresenter.swift +++ b/WavesWallet-iOS/Modules/AccountPassword/AccountPasswordPresenter.swift @@ -11,6 +11,7 @@ import RxCocoa import RxFeedback import RxSwift import RxOptional +import DomainLayer protocol AccountPasswordModuleInput { var kind: AccountPasswordTypes.DTO.Kind { get } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/AccountPassword/AccountPasswordTypes.swift b/WavesWallet-iOS/Modules/AccountPassword/AccountPasswordTypes.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/AccountPassword/AccountPasswordTypes.swift rename to WavesWallet-iOS/Modules/AccountPassword/AccountPasswordTypes.swift index c2b04100..8710db99 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/AccountPassword/AccountPasswordTypes.swift +++ b/WavesWallet-iOS/Modules/AccountPassword/AccountPasswordTypes.swift @@ -7,6 +7,8 @@ // import Foundation +import DomainLayer +import Extensions enum AccountPasswordTypes { enum DTO { } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/AccountPassword/AccountPasswordViewController.swift b/WavesWallet-iOS/Modules/AccountPassword/AccountPasswordViewController.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/AccountPassword/AccountPasswordViewController.swift rename to WavesWallet-iOS/Modules/AccountPassword/AccountPasswordViewController.swift index 9dd9bc5f..91538c3b 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/AccountPassword/AccountPasswordViewController.swift +++ b/WavesWallet-iOS/Modules/AccountPassword/AccountPasswordViewController.swift @@ -38,7 +38,7 @@ final class AccountPasswordViewController: UIViewController { createBackButton() setupSmallNavigationBar() - hideTopBarLine() + removeTopBarLine() navigationItem.backgroundImage = UIImage() navigationItem.shadowImage = UIImage() diff --git a/WavesWallet-iOS/Modules/ActionSheet/ActionSheet.storyboard b/WavesWallet-iOS/Modules/ActionSheet/ActionSheet.storyboard new file mode 100644 index 00000000..e56178db --- /dev/null +++ b/WavesWallet-iOS/Modules/ActionSheet/ActionSheet.storyboard @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/WavesWallet-iOS/Modules/ActionSheet/ActionSheet.swift b/WavesWallet-iOS/Modules/ActionSheet/ActionSheet.swift new file mode 100644 index 00000000..e44dcd32 --- /dev/null +++ b/WavesWallet-iOS/Modules/ActionSheet/ActionSheet.swift @@ -0,0 +1,25 @@ +// +// ActionSheet.swift +// WavesWallet-iOS +// +// Created by rprokofev on 02.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation + +enum ActionSheet { + enum DTO {} +} + +extension ActionSheet.DTO { + struct Element { + let title: String + } + + struct Data { + let title: String + let elements: [Element] + let selectedElement: Element? + } +} diff --git a/WavesWallet-iOS/Modules/ActionSheet/ActionSheetViewBuilder.swift b/WavesWallet-iOS/Modules/ActionSheet/ActionSheetViewBuilder.swift new file mode 100644 index 00000000..1d5fe228 --- /dev/null +++ b/WavesWallet-iOS/Modules/ActionSheet/ActionSheetViewBuilder.swift @@ -0,0 +1,25 @@ +// +// WidgetSettingsIntervalViewBuilder.swift +// WavesWallet-iOS +// +// Created by rprokofev on 02.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import UIKit +import Extensions + +struct ActionSheetViewBuilder: ModuleBuilderOutput { + + typealias Input = ActionSheet.DTO.Data + + var output: ((ActionSheet.DTO.Element) -> Void) + + func build(input: Input) -> UIViewController { + let vc = StoryboardScene.ActionSheet.actionSheetViewController.instantiate() + vc.data = input + vc.elementDidSelect = output + return vc + } +} + diff --git a/WavesWallet-iOS/Modules/ActionSheet/ActionSheetViewController.swift b/WavesWallet-iOS/Modules/ActionSheet/ActionSheetViewController.swift new file mode 100644 index 00000000..48ae4445 --- /dev/null +++ b/WavesWallet-iOS/Modules/ActionSheet/ActionSheetViewController.swift @@ -0,0 +1,125 @@ +// +// WidgetSettingsIntervalViewController.swift +// WavesWallet-iOS +// +// Created by rprokofev on 01.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import UIKit + +private enum Constants { + static let headerHeight: CGFloat = 74 + static let cellHeight: CGFloat = 64 + static let bottomInset: CGFloat = 16 +} + +final class ActionSheetViewController: ModalScrollViewController { + + @IBOutlet var tableView: ModalTableView! + + override var scrollView: UIScrollView { + return tableView + } + + private var rootView: ModalRootView { + return view as! ModalRootView + } + + private var headerView: ActionSheetHeaderView = ActionSheetHeaderView.loadView() + + var data: ActionSheet.DTO.Data! { + + didSet { + if let selectedElement = data.selectedElement { + selectedElementsMap[selectedElement.title] = selectedElement + } + headerView.update(with: .init(title: data.title)) + tableView?.reloadData() + } + } + + private var selectedElementsMap: [String: ActionSheet.DTO.Element] = .init() + + var elementDidSelect: ((ActionSheet.DTO.Element) -> Void)? + + override func viewDidLoad() { + super.viewDidLoad() + rootView.delegate = self + } + + override func visibleScrollViewHeight(for size: CGSize) -> CGFloat { + + let height = CGFloat((data?.elements.count ?? 0)) * Constants.cellHeight + Constants.headerHeight + return min(height, size.height * 0.5) + } + + override func bottomScrollInset(for size: CGSize) -> CGFloat { + return Constants.bottomInset + } +} + +// MARK: ModalRootViewDelegate + +extension ActionSheetViewController: ModalRootViewDelegate { + + func modalHeaderView() -> UIView { + return headerView + } + + func modalHeaderHeight() -> CGFloat { + return Constants.headerHeight + } +} + +// MARK: UITableViewDataSource + +extension ActionSheetViewController: UITableViewDataSource { + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + + let cell: ActionSheetElementCell = tableView.dequeueCell() + + let element = data.elements[indexPath.row] + + cell.update(with: .init(title: element.title, isSelected: selectedElementsMap[element.title] != nil)) + return cell + } + + func numberOfSections(in tableView: UITableView) -> Int { + return 1 + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return data?.elements.count ?? 0 + } +} + +// MARK: UITableViewDelegate + +extension ActionSheetViewController: UITableViewDelegate { + + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + + let element = data.elements [indexPath.row] + elementDidSelect?(element) + + + selectedElementsMap.removeAll() + selectedElementsMap[element.title] = element + tableView.reloadData() + } + + override func scrollViewDidScroll(_ scrollView: UIScrollView) { + rootView.scrollViewDidScroll(scrollView) + + let yOffset = scrollView.contentOffset.y + scrollView.contentInset.top + + if yOffset > scrollView.contentInset.top { + headerView.isHiddenSepatator = false + } else { + headerView.isHiddenSepatator = true + } + } +} diff --git a/WavesWallet-iOS/Modules/ActionSheet/View/ActionSheetElementCell.swift b/WavesWallet-iOS/Modules/ActionSheet/View/ActionSheetElementCell.swift new file mode 100644 index 00000000..5f03ecfa --- /dev/null +++ b/WavesWallet-iOS/Modules/ActionSheet/View/ActionSheetElementCell.swift @@ -0,0 +1,34 @@ +// +// ActionSheetElementCell.swift +// WavesWallet-iOS +// +// Created by rprokofev on 02.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import UIKit +import Extensions + +final class ActionSheetElementCell: UITableViewCell, Reusable { + + struct Model { + let title: String + let isSelected: Bool + } + + @IBOutlet private var titleLabel: UILabel! + @IBOutlet private var iconImageView: UIImageView! +} + +extension ActionSheetElementCell: ViewConfiguration { + + func update(with model: ActionSheetElementCell.Model) { + titleLabel.text = model.title + + if model.isSelected { + iconImageView.image = Images.on.image + } else { + iconImageView.image = Images.off.image + } + } +} diff --git a/WavesWallet-iOS/Modules/ActionSheet/View/ActionSheetHeaderView.swift b/WavesWallet-iOS/Modules/ActionSheet/View/ActionSheetHeaderView.swift new file mode 100644 index 00000000..49ad5361 --- /dev/null +++ b/WavesWallet-iOS/Modules/ActionSheet/View/ActionSheetHeaderView.swift @@ -0,0 +1,52 @@ +// +// TransactionCardHeaderView.swift +// WavesWallet-iOS +// +// Created by rprokofev on 13/03/2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import UIKit +import Extensions + +private struct Constants { + static let cornerRadius: CGFloat = 12 + static let startPoint: CGPoint = CGPoint(x: 0.0, y: 0.5) + static let endPoint: CGPoint = CGPoint(x: 0.0, y: 1) +} + +final class ActionSheetHeaderView: UIView, NibLoadable { + + struct Model { + let title: String + } + + @IBOutlet private weak var labelTitle: UILabel! + @IBOutlet private weak var gradientView: UIView! + @IBOutlet private weak var topBackgroundView: UIView! + @IBOutlet private weak var separatorView: UIView! + + var isHiddenSepatator: Bool = true { + didSet { + self.separatorView.isHidden = self.isHiddenSepatator + } + } + + override func awakeFromNib() { + super.awakeFromNib() + separatorView.isHidden = true + isUserInteractionEnabled = false + backgroundColor = .clear + layer.cornerRadius = Constants.cornerRadius + layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner] + topBackgroundView.layer.cornerRadius = Constants.cornerRadius + topBackgroundView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner] + } +} + +extension ActionSheetHeaderView: ViewConfiguration { + + func update(with model: ActionSheetHeaderView.Model) { + self.labelTitle.text = model.title + } +} diff --git a/WavesWallet-iOS/Modules/ActionSheet/View/ActionSheetHeaderView.xib b/WavesWallet-iOS/Modules/ActionSheet/View/ActionSheetHeaderView.xib new file mode 100644 index 00000000..ddd8d27b --- /dev/null +++ b/WavesWallet-iOS/Modules/ActionSheet/View/ActionSheetHeaderView.xib @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddAddressBook/AddAddressBookModuleBuilder.swift b/WavesWallet-iOS/Modules/AddressBook/AddAddressBook/AddAddressBookModuleBuilder.swift similarity index 96% rename from WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddAddressBook/AddAddressBookModuleBuilder.swift rename to WavesWallet-iOS/Modules/AddressBook/AddAddressBook/AddAddressBookModuleBuilder.swift index 46db2e5a..b9f79f61 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddAddressBook/AddAddressBookModuleBuilder.swift +++ b/WavesWallet-iOS/Modules/AddressBook/AddAddressBook/AddAddressBookModuleBuilder.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions struct AddAddressBookModuleBuilder: ModuleBuilderOutput { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddAddressBook/AddAddressBookModuleOutput.swift b/WavesWallet-iOS/Modules/AddressBook/AddAddressBook/AddAddressBookModuleOutput.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddAddressBook/AddAddressBookModuleOutput.swift rename to WavesWallet-iOS/Modules/AddressBook/AddAddressBook/AddAddressBookModuleOutput.swift index c435e377..6eafb6a4 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddAddressBook/AddAddressBookModuleOutput.swift +++ b/WavesWallet-iOS/Modules/AddressBook/AddAddressBook/AddAddressBookModuleOutput.swift @@ -7,6 +7,7 @@ // import Foundation +import DomainLayer protocol AddAddressBookModuleOutput: AnyObject { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddAddressBook/AddAddressBookTypes.swift b/WavesWallet-iOS/Modules/AddressBook/AddAddressBook/AddAddressBookTypes.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddAddressBook/AddAddressBookTypes.swift rename to WavesWallet-iOS/Modules/AddressBook/AddAddressBook/AddAddressBookTypes.swift index 01bdfb45..69d18665 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddAddressBook/AddAddressBookTypes.swift +++ b/WavesWallet-iOS/Modules/AddressBook/AddAddressBook/AddAddressBookTypes.swift @@ -7,6 +7,7 @@ // import Foundation +import DomainLayer enum AddAddressBook { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddAddressBook/AddAddressBookViewController.swift b/WavesWallet-iOS/Modules/AddressBook/AddAddressBook/AddAddressBookViewController.swift similarity index 95% rename from WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddAddressBook/AddAddressBookViewController.swift rename to WavesWallet-iOS/Modules/AddressBook/AddAddressBook/AddAddressBookViewController.swift index 268ed2dd..645dadbe 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddAddressBook/AddAddressBookViewController.swift +++ b/WavesWallet-iOS/Modules/AddressBook/AddAddressBook/AddAddressBookViewController.swift @@ -8,6 +8,7 @@ import UIKit import RxSwift +import DomainLayer private enum AddAddressError: Error { case addressExists @@ -27,8 +28,8 @@ final class AddAddressBookViewController: UIViewController { @IBOutlet private weak var buttonDelete: UIButton! @IBOutlet private weak var buttonSaveBottomOffset: NSLayoutConstraint! - private let repository = FactoryRepositories.instance.addressBookRepository - private let authorizationInteractor = FactoryInteractors.instance.authorization + private let repository = UseCasesFactory.instance.repositories.addressBookRepository + private let authorizationInteractor = UseCasesFactory.instance.authorization private let disposeBag: DisposeBag = DisposeBag() weak var delegate: AddAddressBookModuleOutput? @@ -97,6 +98,11 @@ private extension AddAddressBookViewController { .subscribe() .disposed(by: self.disposeBag) + UseCasesFactory + .instance + .analyticManager + .trackEvent(.addressBook(.profileAddressBookDelete)) + self.delegate?.addAddressBookDidDelete(contact: contact) //TODO: Move code to coordinator self.navigationController?.popViewController(animated: true) @@ -233,7 +239,7 @@ private extension AddAddressBookViewController { func setupNavBarUI() { navigationItem.backgroundImage = UIImage() setupBigNavigationBar() - hideTopBarLine() + removeTopBarLine() } func setupEditUserMode() { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddAddressBook/Views/AddAddressTextField.swift b/WavesWallet-iOS/Modules/AddressBook/AddAddressBook/Views/AddAddressTextField.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddAddressBook/Views/AddAddressTextField.swift rename to WavesWallet-iOS/Modules/AddressBook/AddAddressBook/Views/AddAddressTextField.swift index 90b5fed8..8580209e 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddAddressBook/Views/AddAddressTextField.swift +++ b/WavesWallet-iOS/Modules/AddressBook/AddAddressBook/Views/AddAddressTextField.swift @@ -8,7 +8,7 @@ import UIKit import QRCodeReader - +import Extensions private enum Constansts { static let rightButtonOffset: CGFloat = 45 @@ -167,9 +167,6 @@ private extension AddAddressTextField { self.firstAvailableViewController().dismiss(animated: true, completion: nil) } - - // Presents the readerVC as modal form sheet - readerVC.modalPresentationStyle = .formSheet firstAvailableViewController().present(readerVC, animated: true) } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddAddressBook/Views/AddAddressTextField.xib b/WavesWallet-iOS/Modules/AddressBook/AddAddressBook/Views/AddAddressTextField.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddAddressBook/Views/AddAddressTextField.xib rename to WavesWallet-iOS/Modules/AddressBook/AddAddressBook/Views/AddAddressTextField.xib diff --git a/WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddressBook.storyboard b/WavesWallet-iOS/Modules/AddressBook/AddressBook.storyboard similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddressBook.storyboard rename to WavesWallet-iOS/Modules/AddressBook/AddressBook.storyboard index 60da0bde..db7882f3 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddressBook.storyboard +++ b/WavesWallet-iOS/Modules/AddressBook/AddressBook.storyboard @@ -83,7 +83,7 @@ - + @@ -118,13 +118,13 @@ You can create new address - + - + diff --git a/WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddressBook/AddressBookModuleBuilder.swift b/WavesWallet-iOS/Modules/AddressBook/AddressBook/AddressBookModuleBuilder.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddressBook/AddressBookModuleBuilder.swift rename to WavesWallet-iOS/Modules/AddressBook/AddressBook/AddressBookModuleBuilder.swift index 7dfa3ede..01d24941 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddressBook/AddressBookModuleBuilder.swift +++ b/WavesWallet-iOS/Modules/AddressBook/AddressBook/AddressBookModuleBuilder.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions struct AddressBookModuleBuilder: ModuleBuilderOutput { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddressBook/AddressBookModuleOutput.swift b/WavesWallet-iOS/Modules/AddressBook/AddressBook/AddressBookModuleOutput.swift similarity index 94% rename from WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddressBook/AddressBookModuleOutput.swift rename to WavesWallet-iOS/Modules/AddressBook/AddressBook/AddressBookModuleOutput.swift index 05b1f16f..0282c885 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddressBook/AddressBookModuleOutput.swift +++ b/WavesWallet-iOS/Modules/AddressBook/AddressBook/AddressBookModuleOutput.swift @@ -7,6 +7,7 @@ // import Foundation +import DomainLayer protocol AddressBookModuleOutput: AnyObject { func addressBookDidSelectContact(_ contact: DomainLayer.DTO.Contact) diff --git a/WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddressBook/AddressBookTypes.swift b/WavesWallet-iOS/Modules/AddressBook/AddressBook/AddressBookTypes.swift similarity index 96% rename from WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddressBook/AddressBookTypes.swift rename to WavesWallet-iOS/Modules/AddressBook/AddressBook/AddressBookTypes.swift index 1b7793ae..368fb263 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddressBook/AddressBookTypes.swift +++ b/WavesWallet-iOS/Modules/AddressBook/AddressBook/AddressBookTypes.swift @@ -7,6 +7,8 @@ // import Foundation +import DomainLayer +import Extensions enum AddressBookTypes { enum ViewModel {} diff --git a/WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddressBook/AddressBookViewController.swift b/WavesWallet-iOS/Modules/AddressBook/AddressBook/AddressBookViewController.swift similarity index 93% rename from WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddressBook/AddressBookViewController.swift rename to WavesWallet-iOS/Modules/AddressBook/AddressBook/AddressBookViewController.swift index 7172043f..06e44012 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddressBook/AddressBookViewController.swift +++ b/WavesWallet-iOS/Modules/AddressBook/AddressBook/AddressBookViewController.swift @@ -10,6 +10,8 @@ import UIKit import RxSwift import RxCocoa import RxFeedback +import DomainLayer +import Extensions final class AddressBookViewController: UIViewController { @@ -40,7 +42,7 @@ final class AddressBookViewController: UIViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) setupSmallNavigationBar() - hideTopBarLine() + removeTopBarLine() navigationItem.backgroundImage = UIImage() } @@ -78,6 +80,12 @@ private extension AddressBookViewController { @objc func addUserTapped() { + UseCasesFactory + .instance + .analyticManager + .trackEvent(.addressBook(.profileAddressBookAdd)) + + //TODO: Move to Coordinator let controller = AddAddressBookModuleBuilder(output: self).build(input: .init(kind: .add(nil, isMutable: true))) navigationController?.pushViewController(controller, animated: true) } @@ -170,6 +178,11 @@ extension AddressBookViewController: AddressBookCellDelegate { if let indexPath = tableView.indexPath(for: cell) { + UseCasesFactory + .instance + .analyticManager + .trackEvent(.addressBook(.profileAddressBookEdit)) + let contact = modelSection.items[indexPath.row].contact showEditContact(contact) } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddressBook/Interactor/AddressBookInteractor.swift b/WavesWallet-iOS/Modules/AddressBook/AddressBook/Interactor/AddressBookInteractor.swift similarity index 90% rename from WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddressBook/Interactor/AddressBookInteractor.swift rename to WavesWallet-iOS/Modules/AddressBook/AddressBook/Interactor/AddressBookInteractor.swift index 96744933..4bc549f2 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddressBook/Interactor/AddressBookInteractor.swift +++ b/WavesWallet-iOS/Modules/AddressBook/AddressBook/Interactor/AddressBookInteractor.swift @@ -8,14 +8,16 @@ import Foundation import RxSwift +import Extensions +import DomainLayer final class AddressBookInteractor: AddressBookInteractorProtocol { - private let authorizationInteractor: AuthorizationInteractorProtocol = FactoryInteractors.instance.authorization + private let authorizationInteractor: AuthorizationUseCaseProtocol = UseCasesFactory.instance.authorization private let searchString: BehaviorSubject = BehaviorSubject(value: "") private var _users: [DomainLayer.DTO.Contact] = [] - private let repository = AddressBookRepository() + private let repository: AddressBookRepositoryProtocol = UseCasesFactory.instance.repositories.addressBookRepository func users() -> Observable<[DomainLayer.DTO.Contact]> { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddressBook/Interactor/AddressBookInteractorProtocol.swift b/WavesWallet-iOS/Modules/AddressBook/AddressBook/Interactor/AddressBookInteractorProtocol.swift similarity index 94% rename from WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddressBook/Interactor/AddressBookInteractorProtocol.swift rename to WavesWallet-iOS/Modules/AddressBook/AddressBook/Interactor/AddressBookInteractorProtocol.swift index 6e44c52c..50ff496d 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddressBook/Interactor/AddressBookInteractorProtocol.swift +++ b/WavesWallet-iOS/Modules/AddressBook/AddressBook/Interactor/AddressBookInteractorProtocol.swift @@ -8,6 +8,7 @@ import Foundation import RxSwift +import DomainLayer protocol AddressBookInteractorProtocol { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddressBook/Presenter/AddressBookPresenter.swift b/WavesWallet-iOS/Modules/AddressBook/AddressBook/Presenter/AddressBookPresenter.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddressBook/Presenter/AddressBookPresenter.swift rename to WavesWallet-iOS/Modules/AddressBook/AddressBook/Presenter/AddressBookPresenter.swift index 93909708..eb176a03 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddressBook/Presenter/AddressBookPresenter.swift +++ b/WavesWallet-iOS/Modules/AddressBook/AddressBook/Presenter/AddressBookPresenter.swift @@ -10,6 +10,7 @@ import Foundation import RxSwift import RxFeedback import RxCocoa +import Extensions final class AddressBookPresenter: AddressBookPresenterProtocol { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddressBook/Presenter/AddressBookPresenterProtocol.swift b/WavesWallet-iOS/Modules/AddressBook/AddressBook/Presenter/AddressBookPresenterProtocol.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddressBook/Presenter/AddressBookPresenterProtocol.swift rename to WavesWallet-iOS/Modules/AddressBook/AddressBook/Presenter/AddressBookPresenterProtocol.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddressBook/Views/AddressBookCell.swift b/WavesWallet-iOS/Modules/AddressBook/AddressBook/Views/AddressBookCell.swift similarity index 96% rename from WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddressBook/Views/AddressBookCell.swift rename to WavesWallet-iOS/Modules/AddressBook/AddressBook/Views/AddressBookCell.swift index 1d371cee..df25791f 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/AddressBook/AddressBook/Views/AddressBookCell.swift +++ b/WavesWallet-iOS/Modules/AddressBook/AddressBook/Views/AddressBookCell.swift @@ -7,6 +7,8 @@ // import UIKit +import DomainLayer +import Extensions protocol AddressBookCellDelegate: AnyObject { func addressBookCellDidTapEdit(_ cell: AddressBookCell) diff --git a/WavesWallet-iOS/Modules/AppNews/AppNewsView.swift b/WavesWallet-iOS/Modules/AppNews/AppNewsView.swift new file mode 100644 index 00000000..f611698b --- /dev/null +++ b/WavesWallet-iOS/Modules/AppNews/AppNewsView.swift @@ -0,0 +1,112 @@ +// +// AppNewsView.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 2/15/19. +// Copyright © 2019 Waves Platform. All rights reserved. +// +import Foundation +import UIKit +import Down +import TTTAttributedLabel + +private struct AppNewsFontCollection: FontCollection { + + public var heading1 = DownFont.boldSystemFont(ofSize: 25) + public var heading2 = DownFont.boldSystemFont(ofSize: 21) + public var heading3 = DownFont.boldSystemFont(ofSize: 17) + public var body = DownFont.systemFont(ofSize: 13) + public var code = DownFont(name: "menlo", size: 13) ?? .systemFont(ofSize: 13) + public var listItemPrefix = DownFont.monospacedDigitSystemFont(ofSize: 13, weight: .regular) +} + +private struct AppNewsColorCollection: ColorCollection { + + public var heading1 = DownColor.black + public var heading2 = DownColor.black + public var heading3 = DownColor.black + public var body = DownColor.black + public var code = DownColor.black + public var link = UIColor.submit400 + public var quote = DownColor.darkGray + public var quoteStripe = DownColor.darkGray + public var thematicBreak = DownColor(white: 0.9, alpha: 1) + public var listItemPrefix = DownColor.lightGray + public var codeBlockBackground = DownColor(red: 0.96, green: 0.97, blue: 0.98, alpha: 1) +} + + +final class AppNewsView: PopupActionView { + + struct Model { + let title: String + let subtitle: String + let image: UIImage + } + + @IBOutlet private weak var imageView: UIImageView! + @IBOutlet private weak var labelTitle: UILabel! + @IBOutlet private weak var labelSubtitle: TTTAttributedLabel! + @IBOutlet private weak var buttonOkey: HighlightedButton! + + var tapDismiss: (() -> Void)? + var didSelectLinkWith: ((URL) -> Void)? + + override func awakeFromNib() { + super.awakeFromNib() + labelSubtitle.delegate = self + buttonOkey.setTitle(Localizable.Waves.Appnews.Button.okey, for: .normal) + + } + + @IBAction private func okeyTapped(_ sender: Any) { + tapDismiss?() + dismiss() + } + + override func update(with model: Model) { + + labelTitle.text = model.title + + var downStyler = DownStylerConfiguration() + downStyler.colors = AppNewsColorCollection() + downStyler.fonts = AppNewsFontCollection() + + if let subtitle = try? Down.init(markdownString: model.subtitle).toAttributedString(.default, + styler: DownStyler(configuration: downStyler)) { + labelSubtitle.attributedText = subtitle + + subtitle.enumerateAttributes(in: NSMakeRange(0, subtitle.length), + options: .longestEffectiveRangeNotRequired) + { (attributes, range, _) in + + if let subAttribute = attributes.first(where: { $0.key == NSAttributedString.Key.link }) { + + if let url = subAttribute.value as? URL { + labelSubtitle.addLink(to: url, with: range) + } else if let string = subAttribute.value as? String, + let url = URL(string: string) { + labelSubtitle.addLink(to: url, with: range) + } + } + } + + } else { + labelSubtitle.text = model.subtitle + } + + imageView.image = model.image + } +} + +extension AppNewsView: TTTAttributedLabelDelegate { + + func attributedLabel(_ label: TTTAttributedLabel!, didSelectLinkWith url: URL!) { + + guard let url = url else { return } + + self.didSelectLinkWith?(url) + } +} + + diff --git a/WavesWallet-iOS/PresentationLayer/Modules/AppNews/AppNewsView.xib b/WavesWallet-iOS/Modules/AppNews/AppNewsView.xib similarity index 94% rename from WavesWallet-iOS/PresentationLayer/Modules/AppNews/AppNewsView.xib rename to WavesWallet-iOS/Modules/AppNews/AppNewsView.xib index 9c0a7688..b0a6498f 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/AppNews/AppNewsView.xib +++ b/WavesWallet-iOS/Modules/AppNews/AppNewsView.xib @@ -1,11 +1,9 @@ - - - - + + - + @@ -30,13 +28,13 @@ - diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Asset/Asset.storyboard b/WavesWallet-iOS/Modules/Asset/Asset.storyboard similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/Asset/Asset.storyboard rename to WavesWallet-iOS/Modules/Asset/Asset.storyboard index 56a6f375..985c1b00 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Asset/Asset.storyboard +++ b/WavesWallet-iOS/Modules/Asset/Asset.storyboard @@ -1,11 +1,11 @@ - + - + @@ -26,7 +26,7 @@ - + @@ -225,7 +225,7 @@ - + @@ -260,7 +260,7 @@ - + @@ -277,7 +277,7 @@ - + @@ -306,7 +306,7 @@ - + @@ -339,16 +339,16 @@ - + diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Backup/Backup.storyboard b/WavesWallet-iOS/Modules/Backup/Backup.storyboard similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Backup/Backup.storyboard rename to WavesWallet-iOS/Modules/Backup/Backup.storyboard diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Backup/ConfirmBackupViewController.swift b/WavesWallet-iOS/Modules/Backup/ConfirmBackupViewController.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/Backup/ConfirmBackupViewController.swift rename to WavesWallet-iOS/Modules/Backup/ConfirmBackupViewController.swift index 8ac73b49..286d2b6f 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Backup/ConfirmBackupViewController.swift +++ b/WavesWallet-iOS/Modules/Backup/ConfirmBackupViewController.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions protocol ConfirmBackupOutput: AnyObject { func userConfirmBackup() @@ -45,7 +46,7 @@ final class ConfirmBackupViewController: UIViewController, ConfirmBackupStackLis createBackButton() setupBigNavigationBar() - hideTopBarLine() + removeTopBarLine() navigationController?.navigationBar.barTintColor = .white buttonConfirm.alpha = 0 labelError.alpha = 0 diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Backup/NeedBackupViewController.swift b/WavesWallet-iOS/Modules/Backup/NeedBackupViewController.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Backup/NeedBackupViewController.swift rename to WavesWallet-iOS/Modules/Backup/NeedBackupViewController.swift index e8a20c31..add4f7fc 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Backup/NeedBackupViewController.swift +++ b/WavesWallet-iOS/Modules/Backup/NeedBackupViewController.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions private enum Constants { static let topLogoOffset: CGFloat = 118 diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Backup/SaveBackupPhraseViewController.swift b/WavesWallet-iOS/Modules/Backup/SaveBackupPhraseViewController.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Backup/SaveBackupPhraseViewController.swift rename to WavesWallet-iOS/Modules/Backup/SaveBackupPhraseViewController.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Backup/View/ConfirmBackupStackBaseView.swift b/WavesWallet-iOS/Modules/Backup/View/ConfirmBackupStackBaseView.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Backup/View/ConfirmBackupStackBaseView.swift rename to WavesWallet-iOS/Modules/Backup/View/ConfirmBackupStackBaseView.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Backup/View/ConfirmBackupStackInputView.swift b/WavesWallet-iOS/Modules/Backup/View/ConfirmBackupStackInputView.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Backup/View/ConfirmBackupStackInputView.swift rename to WavesWallet-iOS/Modules/Backup/View/ConfirmBackupStackInputView.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Backup/View/ConfirmBackupStackListView.swift b/WavesWallet-iOS/Modules/Backup/View/ConfirmBackupStackListView.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Backup/View/ConfirmBackupStackListView.swift rename to WavesWallet-iOS/Modules/Backup/View/ConfirmBackupStackListView.swift index 3fa9ac3c..92a6db5b 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Backup/View/ConfirmBackupStackListView.swift +++ b/WavesWallet-iOS/Modules/Backup/View/ConfirmBackupStackListView.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions protocol ConfirmBackupStackListViewDelegate: class { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/ChangePassword/ChangePassword.storyboard b/WavesWallet-iOS/Modules/ChangePassword/ChangePassword.storyboard similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/ChangePassword/ChangePassword.storyboard rename to WavesWallet-iOS/Modules/ChangePassword/ChangePassword.storyboard diff --git a/WavesWallet-iOS/PresentationLayer/Modules/ChangePassword/ChangePasswordModuleBuilder.swift b/WavesWallet-iOS/Modules/ChangePassword/ChangePasswordModuleBuilder.swift similarity index 94% rename from WavesWallet-iOS/PresentationLayer/Modules/ChangePassword/ChangePasswordModuleBuilder.swift rename to WavesWallet-iOS/Modules/ChangePassword/ChangePasswordModuleBuilder.swift index 1fce1700..4084f242 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/ChangePassword/ChangePasswordModuleBuilder.swift +++ b/WavesWallet-iOS/Modules/ChangePassword/ChangePasswordModuleBuilder.swift @@ -7,6 +7,8 @@ // import UIKit +import DomainLayer +import Extensions struct ChangePasswordModuleBuilder: ModuleBuilderOutput { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/ChangePassword/ChangePasswordPresenter.swift b/WavesWallet-iOS/Modules/ChangePassword/ChangePasswordPresenter.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/ChangePassword/ChangePasswordPresenter.swift rename to WavesWallet-iOS/Modules/ChangePassword/ChangePasswordPresenter.swift index 30e1c4a0..00c547ff 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/ChangePassword/ChangePasswordPresenter.swift +++ b/WavesWallet-iOS/Modules/ChangePassword/ChangePasswordPresenter.swift @@ -10,6 +10,7 @@ import Foundation import RxCocoa import RxFeedback import RxSwift +import DomainLayer protocol ChangePasswordModuleOutput: AnyObject { func changePasswordCompleted(wallet: DomainLayer.DTO.Wallet, newPassword: String, oldPassword: String) @@ -38,7 +39,7 @@ final class ChangePasswordPresenter: ChangePasswordPresenterProtocol { weak var moduleOutput: ChangePasswordModuleOutput? var input: ChangePasswordModuleInput! - private let authorizationInteractor: AuthorizationInteractorProtocol = FactoryInteractors.instance.authorization + private let authorizationInteractor: AuthorizationUseCaseProtocol = UseCasesFactory.instance.authorization private let disposeBag: DisposeBag = DisposeBag() init(input: ChangePasswordModuleInput) { @@ -90,7 +91,7 @@ final class ChangePasswordPresenter: ChangePasswordPresenterProtocol { }) .map { _ in Types.Event.successOldPassword } .asSignal(onErrorRecover: { error -> Signal in - guard let error = error as? AuthorizationInteractorError else { + guard let error = error as? AuthorizationUseCaseError else { return Signal.empty() } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/ChangePassword/ChangePasswordTypes.swift b/WavesWallet-iOS/Modules/ChangePassword/ChangePasswordTypes.swift similarity index 92% rename from WavesWallet-iOS/PresentationLayer/Modules/ChangePassword/ChangePasswordTypes.swift rename to WavesWallet-iOS/Modules/ChangePassword/ChangePasswordTypes.swift index 1f84b4d4..c52f75c2 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/ChangePassword/ChangePasswordTypes.swift +++ b/WavesWallet-iOS/Modules/ChangePassword/ChangePasswordTypes.swift @@ -6,6 +6,8 @@ // import Foundation +import DomainLayer +import Extensions enum ChangePasswordTypes { enum DTO { } @@ -36,7 +38,7 @@ extension ChangePasswordTypes { enum Event { case readyView case input(FieldKind, String?) - case handlerError(AuthorizationInteractorError) + case handlerError(AuthorizationUseCaseError) case successOldPassword case tapContinue case completedQuery diff --git a/WavesWallet-iOS/PresentationLayer/Modules/ChangePassword/ChangePasswordViewController.swift b/WavesWallet-iOS/Modules/ChangePassword/ChangePasswordViewController.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/ChangePassword/ChangePasswordViewController.swift rename to WavesWallet-iOS/Modules/ChangePassword/ChangePasswordViewController.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/ChooseAccount/ChooseAccount.storyboard b/WavesWallet-iOS/Modules/ChooseAccount/ChooseAccount.storyboard similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/ChooseAccount/ChooseAccount.storyboard rename to WavesWallet-iOS/Modules/ChooseAccount/ChooseAccount.storyboard index b21d8fb5..4d691da9 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/ChooseAccount/ChooseAccount.storyboard +++ b/WavesWallet-iOS/Modules/ChooseAccount/ChooseAccount.storyboard @@ -25,7 +25,7 @@ - + diff --git a/WavesWallet-iOS/PresentationLayer/Modules/ChooseAccount/ChooseAccountModuleBuilder.swift b/WavesWallet-iOS/Modules/ChooseAccount/ChooseAccountModuleBuilder.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/ChooseAccount/ChooseAccountModuleBuilder.swift rename to WavesWallet-iOS/Modules/ChooseAccount/ChooseAccountModuleBuilder.swift index c5fdcd5d..defd1dc6 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/ChooseAccount/ChooseAccountModuleBuilder.swift +++ b/WavesWallet-iOS/Modules/ChooseAccount/ChooseAccountModuleBuilder.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions struct ChooseAccountModuleBuilder: ModuleBuilderOutput { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/ChooseAccount/ChooseAccountPresenter.swift b/WavesWallet-iOS/Modules/ChooseAccount/ChooseAccountPresenter.swift similarity index 90% rename from WavesWallet-iOS/PresentationLayer/Modules/ChooseAccount/ChooseAccountPresenter.swift rename to WavesWallet-iOS/Modules/ChooseAccount/ChooseAccountPresenter.swift index 6897363d..846b9965 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/ChooseAccount/ChooseAccountPresenter.swift +++ b/WavesWallet-iOS/Modules/ChooseAccount/ChooseAccountPresenter.swift @@ -10,10 +10,13 @@ import Foundation import RxCocoa import RxFeedback import RxSwift +import DomainLayer protocol ChooseAccountModuleOutput: AnyObject { func userChooseAccount(wallet: DomainLayer.DTO.Wallet, passcodeNotCreated: Bool) -> Void func userEditAccount(wallet: DomainLayer.DTO.Wallet) -> Void + func chooseAccountDidTapBack() + func chooseAccountDidTapAddAccount() } protocol ChooseAccountModuleInput { @@ -40,7 +43,7 @@ final class ChooseAccountPresenter: ChooseAccountPresenterProtocol { var input: ChooseAccountModuleInput! weak var moduleOutput: ChooseAccountModuleOutput? - private let authorizationInteractor: AuthorizationInteractorProtocol = FactoryInteractors.instance.authorization + private let authorizationInteractor: AuthorizationUseCaseProtocol = UseCasesFactory.instance.authorization private let disposeBag: DisposeBag = DisposeBag() @@ -109,7 +112,7 @@ final class ChooseAccountPresenter: ChooseAccountPresenterProtocol { .hasPermissionToLoggedIn(wallet) .map { _ in Types.Event.openWallet(wallet, passcodeNotCreated: false) } .asSignal(onErrorRecover: { error -> Signal in - if case AuthorizationInteractorError.passcodeNotCreated? = error as? AuthorizationInteractorError { + if case AuthorizationUseCaseError.passcodeNotCreated? = error as? AuthorizationUseCaseError { return Signal.just(Types.Event.openWallet(wallet, passcodeNotCreated: true)) } return Signal.never() @@ -150,6 +153,16 @@ private extension ChooseAccountPresenter { state.displayState.action = .none state.action = .removeWallet(wallet, indexPath: indexPath) + case .tapAddAccount: + state.action = nil + state.displayState.action = .none + moduleOutput?.chooseAccountDidTapAddAccount() + + case .tapBack: + state.action = nil + state.displayState.action = .none + moduleOutput?.chooseAccountDidTapBack() + case .openWallet(let wallet, let passcodeNotCreated): state.action = nil state.displayState.action = .none diff --git a/WavesWallet-iOS/PresentationLayer/Modules/ChooseAccount/ChooseAccountTypes.swift b/WavesWallet-iOS/Modules/ChooseAccount/ChooseAccountTypes.swift similarity index 93% rename from WavesWallet-iOS/PresentationLayer/Modules/ChooseAccount/ChooseAccountTypes.swift rename to WavesWallet-iOS/Modules/ChooseAccount/ChooseAccountTypes.swift index 72e69873..32d82551 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/ChooseAccount/ChooseAccountTypes.swift +++ b/WavesWallet-iOS/Modules/ChooseAccount/ChooseAccountTypes.swift @@ -7,6 +7,8 @@ // import Foundation +import DomainLayer +import Extensions enum ChooseAccountTypes { enum DTO { } @@ -34,6 +36,8 @@ extension ChooseAccountTypes { case tapRemoveButton(DomainLayer.DTO.Wallet, indexPath: IndexPath) case tapWallet(DomainLayer.DTO.Wallet) case setWallets([DomainLayer.DTO.Wallet]) + case tapBack + case tapAddAccount case viewDidDisappear } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/ChooseAccount/ChooseAccountViewController.swift b/WavesWallet-iOS/Modules/ChooseAccount/ChooseAccountViewController.swift similarity index 88% rename from WavesWallet-iOS/PresentationLayer/Modules/ChooseAccount/ChooseAccountViewController.swift rename to WavesWallet-iOS/Modules/ChooseAccount/ChooseAccountViewController.swift index 5aeb9264..de8b580a 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/ChooseAccount/ChooseAccountViewController.swift +++ b/WavesWallet-iOS/Modules/ChooseAccount/ChooseAccountViewController.swift @@ -12,6 +12,7 @@ import RxCocoa import RxSwift import RxFeedback import MGSwipeTableCell +import DomainLayer private enum Constants { static let swipeButtonWidth: CGFloat = 72 @@ -48,8 +49,18 @@ final class ChooseAccountViewController: UIViewController { navigationItem.title = Localizable.Waves.Chooseaccount.Navigation.title setupBigNavigationBar() - createBackButton() - hideTopBarLine() + navigationItem.leftBarButtonItem = UIBarButtonItem(image: Images.btnBack.image.withRenderingMode(.alwaysOriginal), style: .plain, target: self, action: #selector(backTapped)) + + navigationItem.rightBarButtonItem = UIBarButtonItem(image: Images.topbarAdd.image.withRenderingMode(.alwaysOriginal), style: .plain, target: self, action: #selector(tapAddAccount)) + removeTopBarLine() + } + + @objc override func backTapped() { + self.eventInput.onNext(.tapBack) + } + + @objc func tapAddAccount() { + self.eventInput.onNext(.tapAddAccount) } // MARK: - Content @@ -117,6 +128,11 @@ final class ChooseAccountViewController: UIViewController { guard let cell = tableView.cellForRow(at: indexPath) as? ChooseAccountCell else { return } + UseCasesFactory + .instance + .analyticManager + .trackEvent(.singIn(.startAccountDelete)) + let wallet = wallets[indexPath.row] let alert = UIAlertController(title: Localizable.Waves.Chooseaccount.Alert.Delete.title, @@ -146,6 +162,10 @@ final class ChooseAccountViewController: UIViewController { eventInput.onNext(.tapEditButton(wallet, indexPath: indexPath)) + UseCasesFactory + .instance + .analyticManager + .trackEvent(.singIn(.startAccountEdit)) } // MARK: Empty @@ -221,12 +241,21 @@ private extension ChooseAccountViewController { func updateView(with state: Types.DisplayState) { + if self.wallets.count != state.wallets.count { + UseCasesFactory + .instance + .analyticManager + .trackEvent(.singIn(.startAccountCounter(state.wallets.count))) + } + self.wallets = state.wallets switch state.action { case .reload: reloadTableView() + + case .remove(let indexPath): diff --git a/WavesWallet-iOS/PresentationLayer/Modules/ChooseAccount/Views/ChooseAccountCell.swift b/WavesWallet-iOS/Modules/ChooseAccount/Views/ChooseAccountCell.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/ChooseAccount/Views/ChooseAccountCell.swift rename to WavesWallet-iOS/Modules/ChooseAccount/Views/ChooseAccountCell.swift index 88f2b0a7..35a28542 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/ChooseAccount/Views/ChooseAccountCell.swift +++ b/WavesWallet-iOS/Modules/ChooseAccount/Views/ChooseAccountCell.swift @@ -8,6 +8,7 @@ import UIKit import MGSwipeTableCell +import Extensions final class ChooseAccountCell: MGSwipeTableCell, NibReusable { diff --git a/WavesWallet-iOS/Modules/Debug/DebugViewController.swift b/WavesWallet-iOS/Modules/Debug/DebugViewController.swift new file mode 100644 index 00000000..cb15bf66 --- /dev/null +++ b/WavesWallet-iOS/Modules/Debug/DebugViewController.swift @@ -0,0 +1,335 @@ +// +// SupportViewControllerV2.swift +// WavesWallet-iOS +// +// Created by rprokofev on 22.07.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import UIKit +import DomainLayer +import Extensions + +enum Debug { + + struct DisplayState: DataSourceProtocol { + var sections: [Section] + } +} + +extension Debug { + + struct Enviroment { + let name: String + let chainId: String + } + + enum Row { + case enviroments(_ enviroments: [Enviroment], _ current: Enviroment) + case stageSwitch(_ isOn: Bool) + case notificationDevSwitch(_ isOn: Bool) + case versionTestSwitch(_ isOn: Bool) + case enviromentTestSwitch(_ isOn: Bool) + case info(_ version: String, _ deviceId: String) + } + + struct Section: SectionProtocol { + + enum Kind { + case enviroment + case other + } + + var rows: [Row] + var kind: Kind + } +} + +protocol DebugViewControllerDelegate: AnyObject { + + func dissmissDebugVC(isNeedRelaunchApp: Bool) + + func relaunchApplication() +} + +final class DebugViewController: UIViewController { + + @IBOutlet private var tableView: UITableView! + + private lazy var displayState: Debug.DisplayState = createDisplaState() + + private var isNeedRelaunchApp: Bool = false + + private var environmentRepository: EnvironmentRepositoryProtocol = UseCasesFactory.instance.repositories.environmentRepository + + var delegate: DebugViewControllerDelegate? + + override func viewDidLoad() { + super.viewDidLoad() + self.title = "Debug" + setupBigNavigationBar() + removeTopBarLine() + + self.navigationItem.rightBarButtonItem = UIBarButtonItem.init(barButtonSystemItem: .done, + target: self, + action: #selector(handlerDoneButton)) + } + + @objc private func handlerDoneButton() { + self.delegate?.dissmissDebugVC(isNeedRelaunchApp: isNeedRelaunchApp) + } +} + +// MARK: UITableViewDelegate + +extension DebugViewController: UITableViewDelegate { + + + func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { + return ProfileHeaderView.viewHeight() + } + + func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { + + let view: ProfileHeaderView = tableView.dequeueAndRegisterHeaderFooter() + + let section = displayState[section] + + switch section.kind { + case .enviroment: + view.update(with: "Enviroment") + + case .other: + view.update(with: "Other") + + } + + return view + } + + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + + let row = displayState[indexPath] + + switch row { + case .enviroments: + return DebugEnviromentsCell.cellHeight() + + case .stageSwitch, + .notificationDevSwitch, + .versionTestSwitch, + .enviromentTestSwitch: + return DebugSwitchCell.cellHeight() + + case .info: + return DebugInfoCell.cellHeight() + } + } +} + +// MARK: UITableViewDataSource + +extension DebugViewController: UITableViewDataSource { + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + + let row = displayState[indexPath] + + switch row { + case .stageSwitch(let isOn): + + let cell: DebugSwitchCell = tableView.dequeueCell() + cell.update(with: .init(title: "Enable Stage", + isOn: isOn)) + + cell.switchChangedValue = { isOn in + ApplicationDebugSettings.setupIsEnableStage(isEnable: isOn) + } + return cell + + case .notificationDevSwitch(let isOn): + + let cell: DebugSwitchCell = tableView.dequeueCell() + cell.update(with: .init(title: "Notification Test", + isOn: isOn)) + + cell.switchChangedValue = { isOn in + ApplicationDebugSettings.setEnableNotificationsSettingTest(isEnable: isOn) + } + return cell + + case .enviromentTestSwitch(let isOn): + + let cell: DebugSwitchCell = tableView.dequeueCell() + cell.update(with: .init(title: "Enviroment Test", + isOn: isOn)) + + cell.switchChangedValue = { isOn in + ApplicationDebugSettings.setEnableEnviromentTest(isEnable: isOn) + } + return cell + + case .versionTestSwitch(let isOn): + + let cell: DebugSwitchCell = tableView.dequeueCell() + cell.update(with: .init(title: "Version Test", + isOn: isOn)) + + cell.switchChangedValue = { isOn in + ApplicationDebugSettings.setEnableVersionUpdateTest(isEnable: isOn) + } + return cell + + case .enviroments(let envriroments, let current): + + let cell: DebugEnviromentsCell = tableView.dequeueCell() + cell.update(with: DebugEnviromentsCell.Model(chainId: current.chainId, name: current.name)) + + cell.buttonDidTap = { [weak self] in + self?.pickEnvriroments(envriroments, current: current) + } + return cell + + case .info(let version, let deviceId): + let cell: DebugInfoCell = tableView.dequeueCell() + + cell.update(with: DebugInfoCell.Model.init(version: version, + deviceId: deviceId)) + cell.deleteButtonDidTap = { [weak self] in + self?.deleteAllData() + } + + return cell + } + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return displayState[section].rows.count + } + + func numberOfSections(in tableView: UITableView) -> Int { + return displayState.sections.count + } +} + +private extension DebugViewController { + + func pickEnvriroments(_ envriroments: [Debug.Enviroment], current: Debug.Enviroment) { + + let controller = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) + let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil) + controller.addAction(cancel) + + for value in envriroments { + + let action = UIAlertAction(title: value.name, style: .default) { [weak self] (action) in + self?.changeEnviroment(value) + } + + action.isEnabled = current.chainId != value.chainId + controller.addAction(action) + } + + self.present(controller, animated: true, completion: nil) + } + + func changeEnviroment(_ enviroment: Debug.Enviroment) { + + let kind = WalletEnvironment.Kind.init(rawValue: enviroment.chainId) ?? .mainnet + + environmentRepository.environmentKind = kind + + self.isNeedRelaunchApp = true + self.displayState = createDisplaState() + self.tableView.reloadData() + } + + func createDisplaState() -> Debug.DisplayState { + + let version = Bundle.main.versionAndBuild + + let isEnableStage = ApplicationDebugSettings.isEnableStage + let isEnableNotificationsSettingDev = ApplicationDebugSettings.isEnableNotificationsSettingTest + let isEnableEnviromentTest = ApplicationDebugSettings.isEnableEnviromentTest + let isEnableVersionUpdateTest = ApplicationDebugSettings.isEnableVersionUpdateTest + + + let mainNet: Debug.Enviroment = .init(name: "Mainnet", + chainId: "W") + + let testNet: Debug.Enviroment = .init(name: "Testnet", + chainId: "T") + + let stageNet: Debug.Enviroment = .init(name: "Stagenet", + chainId: "S") + + var current: Debug.Enviroment! = nil + + switch environmentRepository.environmentKind { + + case .mainnet: + current = mainNet + + case .stagenet: + current = stageNet + + case .testnet: + current = testNet + } + + let sections: [Debug.Section] = [.init(rows: [Debug.Row.enviroments([mainNet, + testNet, + stageNet], + current)], + kind: .enviroment), + .init(rows: [.stageSwitch(isEnableStage), + .notificationDevSwitch(isEnableNotificationsSettingDev), + .versionTestSwitch(isEnableVersionUpdateTest), + .enviromentTestSwitch(isEnableEnviromentTest), + .info(version, UIDevice.uuid)], + kind: .other)] + + let state = Debug.DisplayState(sections: sections) + + + return state + } + + func deleteAllData() { + + self.delegate?.relaunchApplication() + + let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) + let cachesDirectory = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true) + let trashDirectory = NSSearchPathForDirectoriesInDomains(.trashDirectory, .userDomainMask, true) + let userDirectory = NSSearchPathForDirectoriesInDomains(.userDirectory, .userDomainMask, true) + + var paths: [String] = [] + + paths.append(contentsOf: documentDirectory) + paths.append(contentsOf: cachesDirectory) + paths.append(contentsOf: trashDirectory) + paths.append(contentsOf: userDirectory) + + paths.forEach { (file) in + clearFolder(tempFolderPath: file) + } + } + + func clearFolder(tempFolderPath: String) { + let fileManager = FileManager.default + do { + let filePaths = try fileManager.contentsOfDirectory(atPath: tempFolderPath) + for filePath in filePaths { + do { + try fileManager.removeItem(atPath: tempFolderPath + "/" + filePath) + } catch { + print("remove item: \(error)") + } + } + } catch { + print("Could not clear temp folder: \(error)") + } + } +} diff --git a/WavesWallet-iOS/Modules/Debug/Support.storyboard b/WavesWallet-iOS/Modules/Debug/Support.storyboard new file mode 100644 index 00000000..947cac71 --- /dev/null +++ b/WavesWallet-iOS/Modules/Debug/Support.storyboard @@ -0,0 +1,373 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Support/TestViewController.swift b/WavesWallet-iOS/Modules/Debug/TestViewController.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Support/TestViewController.swift rename to WavesWallet-iOS/Modules/Debug/TestViewController.swift index 11d2c047..c48bb6c2 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Support/TestViewController.swift +++ b/WavesWallet-iOS/Modules/Debug/TestViewController.swift @@ -7,6 +7,7 @@ import Foundation import UIKit +import Extensions final class TestViewController: ModalScrollViewController { diff --git a/WavesWallet-iOS/Modules/Debug/View/DebugEnviromentsCell.swift b/WavesWallet-iOS/Modules/Debug/View/DebugEnviromentsCell.swift new file mode 100644 index 00000000..dceb85b8 --- /dev/null +++ b/WavesWallet-iOS/Modules/Debug/View/DebugEnviromentsCell.swift @@ -0,0 +1,94 @@ +// +// DebugEnviromentsCell.swift +// WavesWallet-iOS +// +// Created by rprokofev on 22.07.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import UIKit +import Extensions + +private enum Constants { + static let height: CGFloat = 56 +} + +final class DebugEnviromentsCell: UITableViewCell, Reusable { + + struct Model { + let chainId: String + let name: String + } + + @IBOutlet private weak var containerView: UIView! + @IBOutlet private weak var button: UIButton! + + var buttonDidTap: (() -> Void)? + + class func cellHeight() -> CGFloat { + return Constants.height + } + + override func awakeFromNib() { + super.awakeFromNib() + containerView.addTableCellShadowStyle() + } + + @IBAction func handlerTapButton() { + buttonDidTap?() + } + + private func createLogo(chainId: String) -> UIImage? { + + let size = CGSize(width: 28, height: 28) + + UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale) + guard let context = UIGraphicsGetCurrentContext() else { return nil } + context.saveGState() + + let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height) + context.addPath(UIBezierPath(roundedRect: rect, cornerRadius: rect.height * 0.5).cgPath) + context.clip() + + + context.setFillColor(UIColor.submit400.cgColor) + context.fill(rect) + + if let first = chainId.first { + let font = UIFont.systemFont(ofSize: 17, weight: .semibold) + let symbol = String(first).uppercased() + let style = NSMutableParagraphStyle() + style.alignment = .center + let attributedString = NSAttributedString(string: symbol, + attributes: [.foregroundColor: UIColor.white, + .font: font, + .paragraphStyle: style]) + let sizeStr = attributedString.size() + + attributedString.draw(with: CGRect(x: (size.width - sizeStr.width) * 0.5, + y: (size.height - sizeStr.height) * 0.5, + width: sizeStr.width, + height: sizeStr.height), + options: [.usesLineFragmentOrigin], + context: nil) + } + + + let image = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + return image + } +} + +// MARK: ViewConfiguration + +extension DebugEnviromentsCell: ViewConfiguration { + + func update(with model: DebugEnviromentsCell.Model) { + button.setImage(createLogo(chainId: model.chainId), for: .normal) + button.setTitle(model.name, for: .normal) + } +} + + diff --git a/WavesWallet-iOS/Modules/Debug/View/DebugHeaderView.swift b/WavesWallet-iOS/Modules/Debug/View/DebugHeaderView.swift new file mode 100644 index 00000000..fe013f18 --- /dev/null +++ b/WavesWallet-iOS/Modules/Debug/View/DebugHeaderView.swift @@ -0,0 +1,32 @@ +// +// DebugHeaderView.swift +// WavesWallet-iOS +// +// Created by rprokofev on 22.07.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import UIKit +import Extensions + +private enum Constants { + static let height: CGFloat = 44 +} + +final class DebugHeaderView: UITableViewHeaderFooterView, NibReusable { + + @IBOutlet private var labelTitle: UILabel! + + class func viewHeight() -> CGFloat { + return Constants.height + } +} + +// MARK: ViewConfiguration + +extension DebugHeaderView: ViewConfiguration { + func update(with model: String) { + labelTitle.text = model + } +} + diff --git a/WavesWallet-iOS/Modules/Debug/View/DebugHeaderView.xib b/WavesWallet-iOS/Modules/Debug/View/DebugHeaderView.xib new file mode 100644 index 00000000..73714dd4 --- /dev/null +++ b/WavesWallet-iOS/Modules/Debug/View/DebugHeaderView.xib @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/WavesWallet-iOS/Modules/Debug/View/DebugInfoCell.swift b/WavesWallet-iOS/Modules/Debug/View/DebugInfoCell.swift new file mode 100644 index 00000000..49500d0b --- /dev/null +++ b/WavesWallet-iOS/Modules/Debug/View/DebugInfoCell.swift @@ -0,0 +1,71 @@ +// +// DebugInfoCell.swift +// WavesWallet-iOS +// +// Created by rprokofev on 22.07.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import UIKit +import Extensions + +private enum Constants { + static let height: CGFloat = 246 +} + +final class DebugInfoCell: UITableViewCell, Reusable { + + struct Model { + let version: String + let deviceId: String + } + + @IBOutlet private weak var deleteButton: UIButton! + + @IBOutlet private weak var secondTitleLabel: UILabel! + @IBOutlet private weak var versionTitleLabel: UILabel! + + @IBOutlet private weak var secondValueLabel: UILabel! + @IBOutlet private weak var versionValueLabel: UILabel! + + var deleteButtonDidTap: (() -> Void)? + + class func cellHeight() -> CGFloat { + return Constants.height + } + + override func awakeFromNib() { + super.awakeFromNib() + + deleteButton.setBackgroundImage(UIColor.error400.image, for: .normal) + deleteButton.setBackgroundImage(UIColor.error200.image, for: .highlighted) + deleteButton.setBackgroundImage(UIColor.error100.image, for: .disabled) + } +} + +// MARK: Action + +private extension DebugInfoCell { + + @IBAction func deleteAccount(sender: UIButton) { + deleteButtonDidTap?() + } +} + +// MARK: ViewConfiguration + +extension DebugInfoCell: ViewConfiguration { + + func update(with model: DebugInfoCell.Model) { + + deleteButton.setTitle("Delete all data", for: .normal) + + secondTitleLabel.text = "Device ID" + versionTitleLabel.text = "Version" + + secondValueLabel.text = model.deviceId + versionValueLabel.text = model.version + } +} + + diff --git a/WavesWallet-iOS/Modules/Debug/View/DebugSwitchCell.swift b/WavesWallet-iOS/Modules/Debug/View/DebugSwitchCell.swift new file mode 100644 index 00000000..fd8fd2c1 --- /dev/null +++ b/WavesWallet-iOS/Modules/Debug/View/DebugSwitchCell.swift @@ -0,0 +1,57 @@ +// +// DebugSwitchCell.swift +// WavesWallet-iOS +// +// Created by rprokofev on 22.07.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import UIKit +import Extensions + +private enum Constants { + static let height: CGFloat = 56 +} + +final class DebugSwitchCell: UITableViewCell, Reusable { + + struct Model { + let title: String + let isOn: Bool + } + + @IBOutlet private weak var labelTitle: UILabel! + @IBOutlet private weak var containerView: UIView! + @IBOutlet private weak var switchControl: UISwitch! + + var switchChangedValue: ((Bool) -> Void)? + + override func awakeFromNib() { + super.awakeFromNib() + containerView.addTableCellShadowStyle() + } + + class func cellHeight() -> CGFloat { + return Constants.height + } +} + +// MARK: Action + +private extension DebugSwitchCell { + + @IBAction func changedValue(sender: UISwitch) { + switchChangedValue?(sender.isOn) + } +} + +// MARK: ViewConfiguration + +extension DebugSwitchCell: ViewConfiguration { + + func update(with model: DebugSwitchCell.Model) { + labelTitle.text = model.title + switchControl.isOn = model.isOn + } +} + diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/Dex.storyboard b/WavesWallet-iOS/Modules/Dex/Dex.storyboard similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/Dex.storyboard rename to WavesWallet-iOS/Modules/Dex/Dex.storyboard index 162df995..53b4c8ed 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/Dex.storyboard +++ b/WavesWallet-iOS/Modules/Dex/Dex.storyboard @@ -1,11 +1,9 @@ - - - - + + - + @@ -336,14 +334,14 @@ - + - + @@ -417,6 +415,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -430,14 +455,14 @@ - + - + @@ -476,7 +501,7 @@ - + @@ -691,7 +716,7 @@ - + @@ -802,7 +827,7 @@ The order book is empty - + @@ -812,7 +837,7 @@ The order book is empty - + - + - + @@ -852,7 +877,7 @@ The order book is empty - + @@ -959,7 +984,7 @@ The order book is empty - + @@ -1054,7 +1079,7 @@ The trading history is empty - + @@ -1197,7 +1222,7 @@ The trading history is empty - + @@ -1252,11 +1277,11 @@ The trading history is empty - + - + @@ -1444,7 +1469,7 @@ You do not have any orders - + @@ -1548,13 +1573,13 @@ You do not have any orders - + @@ -1589,12 +1614,12 @@ You do not have any orders - + - + @@ -1806,10 +1831,10 @@ You do not have any orders - + - + @@ -1900,7 +1925,7 @@ We do not recommend you perform operations with smart assets if you are an inexp - + @@ -1998,10 +2023,10 @@ We do not recommend you perform operations with smart assets if you are an inexp - + - + @@ -2082,6 +2107,15 @@ We do not recommend you perform operations with smart assets if you are an inexp + + + + @@ -2092,23 +2126,29 @@ We do not recommend you perform operations with smart assets if you are an inexp + + + + + + @@ -2217,6 +2257,7 @@ We do not recommend you perform operations with smart assets if you are an inexp + @@ -2251,7 +2292,7 @@ We do not recommend you perform operations with smart assets if you are an inexp - + diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/DexChartConstants.swift b/WavesWallet-iOS/Modules/Dex/DexChart/DexChartConstants.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/DexChartConstants.swift rename to WavesWallet-iOS/Modules/Dex/DexChart/DexChartConstants.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/DexChartHelper.swift b/WavesWallet-iOS/Modules/Dex/DexChart/DexChartHelper.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/DexChartHelper.swift rename to WavesWallet-iOS/Modules/Dex/DexChart/DexChartHelper.swift index cd95396d..1bfeafc8 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/DexChartHelper.swift +++ b/WavesWallet-iOS/Modules/Dex/DexChart/DexChartHelper.swift @@ -8,6 +8,7 @@ import Foundation import Charts +import DomainLayer private enum Constants { typealias ChartContants = DexChart.ChartConstants @@ -58,7 +59,7 @@ extension DexChartHelper { barYVals.append(BarChartDataEntry(x: model.timestamp, y: model.volume)) } - let candleSet = CandleChartDataSet(values: candleYVals, label: nil) + let candleSet = CandleChartDataSet(entries: candleYVals, label: nil) candleSet.axisDependency = .right candleSet.drawIconsEnabled = false candleSet.drawValuesEnabled = false @@ -79,7 +80,7 @@ extension DexChartHelper { candleChartView.notifyDataSetChanged() } - let barSet = BarChartDataSet(values: barYVals, label: nil) + let barSet = BarChartDataSet(entries: barYVals, label: nil) barSet.axisDependency = .right barSet.drawIconsEnabled = false barSet.drawValuesEnabled = false diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/DexChartModuleBuilder.swift b/WavesWallet-iOS/Modules/Dex/DexChart/DexChartModuleBuilder.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/DexChartModuleBuilder.swift rename to WavesWallet-iOS/Modules/Dex/DexChart/DexChartModuleBuilder.swift index 47a39b3d..a5de931e 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/DexChartModuleBuilder.swift +++ b/WavesWallet-iOS/Modules/Dex/DexChart/DexChartModuleBuilder.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions struct DexChartModuleBuilder: ModuleBuilder { diff --git a/WavesWallet-iOS/Modules/Dex/DexChart/DexChartSettings.swift b/WavesWallet-iOS/Modules/Dex/DexChart/DexChartSettings.swift new file mode 100644 index 00000000..c0b018d5 --- /dev/null +++ b/WavesWallet-iOS/Modules/Dex/DexChart/DexChartSettings.swift @@ -0,0 +1,41 @@ +// +// DexChartSettings.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 07.08.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import WavesSDKExtensions +import DomainLayer +import Extensions + +struct DexChartSettings: TSUD { + + struct Settings: Codable { + let timeFrame: Int + } + + private static let key: String = "com.waves.dexChart.settings" + + static var defaultValue: Settings { + return Settings(timeFrame: DomainLayer.DTO.Candle.TimeFrameType.m15.rawValue) + } + + static var stringKey: String { + return key + } + + static var timeFrame: DomainLayer.DTO.Candle.TimeFrameType { + guard let value = DomainLayer.DTO.Candle.TimeFrameType(rawValue: get().timeFrame) else { + return .m15 + } + + return value + } + + static func setTimeFrame(timeFrame: DomainLayer.DTO.Candle.TimeFrameType) { + set(.init(timeFrame: timeFrame.rawValue)) + } +} diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/DexChartTypes.swift b/WavesWallet-iOS/Modules/Dex/DexChart/DexChartTypes.swift similarity index 94% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/DexChartTypes.swift rename to WavesWallet-iOS/Modules/Dex/DexChart/DexChartTypes.swift index a73cbd96..51116f08 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/DexChartTypes.swift +++ b/WavesWallet-iOS/Modules/Dex/DexChart/DexChartTypes.swift @@ -7,6 +7,8 @@ // import Foundation +import DomainLayer +import Extensions enum DexChart { enum ViewModel {} @@ -90,8 +92,8 @@ extension DomainLayer.DTO.Candle.TimeFrameType { case .h1: return "1" + " " + Localizable.Waves.Dexchart.Label.hour - case .h4: - return "4" + " " + Localizable.Waves.Dexchart.Label.hours + case .h3: + return "3" + " " + Localizable.Waves.Dexchart.Label.hours case .h24: return "24" + " " + Localizable.Waves.Dexchart.Label.hours @@ -112,8 +114,8 @@ extension DomainLayer.DTO.Candle.TimeFrameType { case .h1: return "H1" - case .h4: - return "H4" + case .h3: + return "H3" case .h24: return "H24" @@ -135,7 +137,7 @@ extension DexChart.State { static var initialState: DexChart.State { - let timeFrame = DomainLayer.DTO.Candle.TimeFrameType.m15 + let timeFrame: DomainLayer.DTO.Candle.TimeFrameType = DexChartSettings.timeFrame let dateTo = initialDateTo() let dateFrom = additionalDate(start: dateTo, timeFrame: timeFrame) diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/DexChartViewController.swift b/WavesWallet-iOS/Modules/Dex/DexChart/DexChartViewController.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/DexChartViewController.swift rename to WavesWallet-iOS/Modules/Dex/DexChart/DexChartViewController.swift index 2b000263..2646ea54 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/DexChartViewController.swift +++ b/WavesWallet-iOS/Modules/Dex/DexChart/DexChartViewController.swift @@ -11,6 +11,8 @@ import Charts import RxSwift import RxCocoa import RxFeedback +import Extensions +import DomainLayer private enum Constants { static let cornerRadius: CGFloat = 3 diff --git a/WavesWallet-iOS/Modules/Dex/DexChart/Interactor/DexChartInteractor.swift b/WavesWallet-iOS/Modules/Dex/DexChart/Interactor/DexChartInteractor.swift new file mode 100644 index 00000000..32127b31 --- /dev/null +++ b/WavesWallet-iOS/Modules/Dex/DexChart/Interactor/DexChartInteractor.swift @@ -0,0 +1,37 @@ +// +// DexChartInteractorMock.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 8/28/18. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import Extensions +import DomainLayer + +private enum Constants { + static let timeStart = "timeStart" + static let timeEnd = "timeEnd" + static let interval = "interval" +} + +final class DexChartInteractor: DexChartInteractorProtocol { + + private let candlesReposotiry = UseCasesFactory.instance.repositories.candlesRepository + + var pair: DexTraderContainer.DTO.Pair! + + func candles(timeFrame: DomainLayer.DTO.Candle.TimeFrameType, timeStart: Date, timeEnd: Date) -> Observable<[DomainLayer.DTO.Candle]> { + + return candlesReposotiry.candles(amountAsset: pair.amountAsset.id, + priceAsset: pair.priceAsset.id, + timeStart: timeStart, + timeEnd: timeEnd, + timeFrame: timeFrame) + .catchError({ (error) -> Observable<[DomainLayer.DTO.Candle]> in + return Observable.just([]) + }) + } +} diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/Interactor/DexChartInteractorMock.swift b/WavesWallet-iOS/Modules/Dex/DexChart/Interactor/DexChartInteractorMock.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/Interactor/DexChartInteractorMock.swift rename to WavesWallet-iOS/Modules/Dex/DexChart/Interactor/DexChartInteractorMock.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/Interactor/DexChartInteractorProtocol.swift b/WavesWallet-iOS/Modules/Dex/DexChart/Interactor/DexChartInteractorProtocol.swift similarity index 95% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/Interactor/DexChartInteractorProtocol.swift rename to WavesWallet-iOS/Modules/Dex/DexChart/Interactor/DexChartInteractorProtocol.swift index 90a9b1f9..2fecc5d4 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/Interactor/DexChartInteractorProtocol.swift +++ b/WavesWallet-iOS/Modules/Dex/DexChart/Interactor/DexChartInteractorProtocol.swift @@ -8,6 +8,7 @@ import Foundation import RxSwift +import DomainLayer protocol DexChartInteractorProtocol { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/Models/DexChartAxisFormatters.swift b/WavesWallet-iOS/Modules/Dex/DexChart/Models/DexChartAxisFormatters.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/Models/DexChartAxisFormatters.swift rename to WavesWallet-iOS/Modules/Dex/DexChart/Models/DexChartAxisFormatters.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/Presenter/DexChartPresenter.swift b/WavesWallet-iOS/Modules/Dex/DexChart/Presenter/DexChartPresenter.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/Presenter/DexChartPresenter.swift rename to WavesWallet-iOS/Modules/Dex/DexChart/Presenter/DexChartPresenter.swift index 2d28329f..579db7af 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/Presenter/DexChartPresenter.swift +++ b/WavesWallet-iOS/Modules/Dex/DexChart/Presenter/DexChartPresenter.swift @@ -10,7 +10,7 @@ import Foundation import RxSwift import RxFeedback import RxCocoa - +import Extensions final class DexChartPresenter: DexChartPresenterProtocol { @@ -77,6 +77,8 @@ final class DexChartPresenter: DexChartPresenterProtocol { $0.timeEnd = DexChart.State.initialDateTo() $0.timeStart = DexChart.State.additionalDate(start:$0.timeEnd, timeFrame: timeFrame) + DexChartSettings.setTimeFrame(timeFrame: timeFrame) + }.changeAction(.changeTimeFrame) case .preloading: diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/Presenter/DexChartPresenterProtocol.swift b/WavesWallet-iOS/Modules/Dex/DexChart/Presenter/DexChartPresenterProtocol.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/Presenter/DexChartPresenterProtocol.swift rename to WavesWallet-iOS/Modules/Dex/DexChart/Presenter/DexChartPresenterProtocol.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/Views/DexChartCandlePriceView.swift b/WavesWallet-iOS/Modules/Dex/DexChart/Views/DexChartCandlePriceView.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/Views/DexChartCandlePriceView.swift rename to WavesWallet-iOS/Modules/Dex/DexChart/Views/DexChartCandlePriceView.swift index aaef0c52..5969f421 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/Views/DexChartCandlePriceView.swift +++ b/WavesWallet-iOS/Modules/Dex/DexChart/Views/DexChartCandlePriceView.swift @@ -7,6 +7,8 @@ // import UIKit +import DomainLayer +import Extensions private enum Constants { static let additionalDeltaWidth: CGFloat = 7 diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/Views/DexChartCandlePriceView.xib b/WavesWallet-iOS/Modules/Dex/DexChart/Views/DexChartCandlePriceView.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/Views/DexChartCandlePriceView.xib rename to WavesWallet-iOS/Modules/Dex/DexChart/Views/DexChartCandlePriceView.xib diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/Views/DexChartHeaderView.swift b/WavesWallet-iOS/Modules/Dex/DexChart/Views/DexChartHeaderView.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/Views/DexChartHeaderView.swift rename to WavesWallet-iOS/Modules/Dex/DexChart/Views/DexChartHeaderView.swift index e42ca6db..b142d34f 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/Views/DexChartHeaderView.swift +++ b/WavesWallet-iOS/Modules/Dex/DexChart/Views/DexChartHeaderView.swift @@ -7,6 +7,8 @@ // import UIKit +import DomainLayer +import Extensions protocol DexChartHeaderViewDelegate: AnyObject { @@ -68,7 +70,7 @@ private extension DexChartHeaderView { let cancel = UIAlertAction(title: Localizable.Waves.Dexchart.Button.cancel, style: .cancel, handler: nil) controller.addAction(cancel) - let types: [DomainLayer.DTO.Candle.TimeFrameType] = [.m5, .m15, .m30, .h1, .h4, .h24] + let types: [DomainLayer.DTO.Candle.TimeFrameType] = [.m5, .m15, .m30, .h1, .h3, .h24] for type in types { let action = UIAlertAction(title: type.text, style: .default) { (action) in diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/Views/DexChartHeaderView.xib b/WavesWallet-iOS/Modules/Dex/DexChart/Views/DexChartHeaderView.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexChart/Views/DexChartHeaderView.xib rename to WavesWallet-iOS/Modules/Dex/DexChart/Views/DexChartHeaderView.xib diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCompleteOrder/DexCompleteOrderModuleBuilder.swift b/WavesWallet-iOS/Modules/Dex/DexCompleteOrder/DexCompleteOrderModuleBuilder.swift similarity index 96% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCompleteOrder/DexCompleteOrderModuleBuilder.swift rename to WavesWallet-iOS/Modules/Dex/DexCompleteOrder/DexCompleteOrderModuleBuilder.swift index cff08498..11ea3d4c 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCompleteOrder/DexCompleteOrderModuleBuilder.swift +++ b/WavesWallet-iOS/Modules/Dex/DexCompleteOrder/DexCompleteOrderModuleBuilder.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions final class DexCompleteOrderModuleBuilder: ModuleBuilder { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCompleteOrder/DexCompleteOrderViewController.swift b/WavesWallet-iOS/Modules/Dex/DexCompleteOrder/DexCompleteOrderViewController.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCompleteOrder/DexCompleteOrderViewController.swift rename to WavesWallet-iOS/Modules/Dex/DexCompleteOrder/DexCompleteOrderViewController.swift index 4e306535..80104468 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCompleteOrder/DexCompleteOrderViewController.swift +++ b/WavesWallet-iOS/Modules/Dex/DexCompleteOrder/DexCompleteOrderViewController.swift @@ -31,7 +31,7 @@ final class DexCompleteOrderViewController: UIViewController { setupInfo() navigationItem.backgroundImage = UIImage() - hideTopBarLine() + removeTopBarLine() navigationItem.hidesBackButton = true } diff --git a/WavesWallet-iOS/Modules/Dex/DexCreateOrder/DexCreateOrderInvalidPriceView.swift b/WavesWallet-iOS/Modules/Dex/DexCreateOrder/DexCreateOrderInvalidPriceView.swift new file mode 100644 index 00000000..b34602ec --- /dev/null +++ b/WavesWallet-iOS/Modules/Dex/DexCreateOrder/DexCreateOrderInvalidPriceView.swift @@ -0,0 +1,59 @@ +// +// DexCreateOrderInvalidPriceView.swift +// WavesWallet-iOS +// +// Created by rprokofev on 10.07.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import Foundation +import UIKit + +final class DexCreateOrderInvalidPriceView: PopupActionView { + + struct Model { + let pricePercent: Int + let isPriceHigherMarket: Bool + } + + @IBOutlet private weak var titleLabel: UILabel! + @IBOutlet private weak var subtitleTitleLabel: UILabel! + @IBOutlet private weak var placeOrderButton: HighlightedButton! + @IBOutlet private weak var buttonCancel: HighlightedButton! + + var buttonDidTap: ((_ success: Bool) -> Void)? = nil + + override func awakeFromNib() { + super.awakeFromNib() + setupLocalization() + } + + @IBAction private func successButtonAction(_ sender: Any) { + self.buttonDidTap?(true) + dismiss() + } + + @IBAction private func cancelButtonAction(_ sender: Any) { + self.buttonDidTap?(false) + dismiss() + } + + private func setupLocalization() { + + subtitleTitleLabel.text = Localizable.Waves.Dexcreateorder.Invalidpricepopup.subtitle + placeOrderButton.setTitle(Localizable.Waves.Dexcreateorder.Invalidpricepopup.Button.placeOrder, + for: .normal) + + buttonCancel.setTitle(Localizable.Waves.Dexcreateorder.Invalidpricepopup.Button.cancel, + for: .normal) + } + + override func update(with model: Model) { + + if model.isPriceHigherMarket == true { + titleLabel.text = Localizable.Waves.Dexcreateorder.Invalidpricepopup.Title.higherPrice(model.pricePercent) + } else { + titleLabel.text = Localizable.Waves.Dexcreateorder.Invalidpricepopup.Title.loverPrice(model.pricePercent) + } + } +} diff --git a/WavesWallet-iOS/Modules/Dex/DexCreateOrder/DexCreateOrderInvalidPriceView.xib b/WavesWallet-iOS/Modules/Dex/DexCreateOrder/DexCreateOrderInvalidPriceView.xib new file mode 100644 index 00000000..3b6e2e58 --- /dev/null +++ b/WavesWallet-iOS/Modules/Dex/DexCreateOrder/DexCreateOrderInvalidPriceView.xib @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCreateOrder/DexCreateOrderModuleBuilder.swift b/WavesWallet-iOS/Modules/Dex/DexCreateOrder/DexCreateOrderModuleBuilder.swift similarity index 92% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCreateOrder/DexCreateOrderModuleBuilder.swift rename to WavesWallet-iOS/Modules/Dex/DexCreateOrder/DexCreateOrderModuleBuilder.swift index c5db8fb4..6db0e438 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCreateOrder/DexCreateOrderModuleBuilder.swift +++ b/WavesWallet-iOS/Modules/Dex/DexCreateOrder/DexCreateOrderModuleBuilder.swift @@ -7,7 +7,9 @@ // import UIKit - +import DomainLayer +import Extensions + struct DexCreateOrderModuleBuilder: ModuleBuilderOutput { weak var output: DexCreateOrderModuleOutput? @@ -18,13 +20,13 @@ struct DexCreateOrderModuleBuilder: ModuleBuilderOutput { var presenter: DexCreateOrderPresenterProtocol = DexCreateOrderPresenter() presenter.interactor = interactor - presenter.moduleOutput = output presenter.pair = DomainLayer.DTO.Dex.Pair(amountAsset: input.amountAsset, priceAsset: input.priceAsset) let vc = StoryboardScene.Dex.dexCreateOrderViewController.instantiate() vc.input = input vc.presenter = presenter + vc.moduleOutput = output return vc } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCreateOrder/DexCreateOrderModuleOutput.swift b/WavesWallet-iOS/Modules/Dex/DexCreateOrder/DexCreateOrderModuleOutput.swift similarity index 77% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCreateOrder/DexCreateOrderModuleOutput.swift rename to WavesWallet-iOS/Modules/Dex/DexCreateOrder/DexCreateOrderModuleOutput.swift index fd495448..15709805 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCreateOrder/DexCreateOrderModuleOutput.swift +++ b/WavesWallet-iOS/Modules/Dex/DexCreateOrder/DexCreateOrderModuleOutput.swift @@ -9,7 +9,10 @@ import Foundation protocol DexCreateOrderModuleOutput: AnyObject { + func dexCreateOrderDidCreate(output: DexCreateOrder.DTO.Output) + + func dexCreateOrderWarningForPrice(isPriceHigherMarket: Bool, callback: @escaping ((_ isSuccess: Bool) -> Void)) } protocol DexCreateOrderProtocol { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCreateOrder/DexCreateOrderTypes.swift b/WavesWallet-iOS/Modules/Dex/DexCreateOrder/DexCreateOrderTypes.swift similarity index 80% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCreateOrder/DexCreateOrderTypes.swift rename to WavesWallet-iOS/Modules/Dex/DexCreateOrder/DexCreateOrderTypes.swift index 222d1f9d..675091a9 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCreateOrder/DexCreateOrderTypes.swift +++ b/WavesWallet-iOS/Modules/Dex/DexCreateOrder/DexCreateOrderTypes.swift @@ -7,6 +7,9 @@ // import Foundation +import WavesSDK +import Extensions +import DomainLayer enum DexCreateOrder { enum DTO {} @@ -14,28 +17,42 @@ enum DexCreateOrder { enum Event { case createOrder + case sendOrder + case cancelCreateOrder case orderDidCreate(ResponseType) case updateInputOrder(DTO.Order) - case didGetFee(Money) + case didGetFee(DTO.FeeSettings) + case orderNotValid(DexCreateOrder.CreateOrderError) case handlerFeeError(Error) case refreshFee + case feeAssetNeedUpdate(String) + } + + enum CreateOrderError: Error { + case invalid + case priceLowerMarket + case priceHigherMarket } struct State: Mutating { enum Action { case none + case showDeffaultOrderState case showCreatingOrderState case orderDidFailCreate(NetworkError) - case orderDidCreate - case didGetFee(Money) + case orderNotValid(DexCreateOrder.CreateOrderError) + case orderDidCreate(DexCreateOrder.DTO.Output) + case didGetFee(DTO.FeeSettings) } var isNeedCreateOrder: Bool + var isNeedCheckValidOrder: Bool var isNeedGetFee: Bool var order: DTO.Order? var action: Action var displayFeeErrorState: DisplayErrorState var isDisabledSellBuyButton: Bool + var feeAssetId: String } } @@ -73,8 +90,9 @@ extension DexCreateOrder.DTO { var total: Money var expiration: Expiration var fee: Int64 + var feeAssetId: String - init(amountAsset: DomainLayer.DTO.Dex.Asset, priceAsset: DomainLayer.DTO.Dex.Asset, type: DomainLayer.DTO.Dex.OrderType, amount: Money, price: Money, total: Money, expiration: Expiration, fee: Int64) { + init(amountAsset: DomainLayer.DTO.Dex.Asset, priceAsset: DomainLayer.DTO.Dex.Asset, type: DomainLayer.DTO.Dex.OrderType, amount: Money, price: Money, total: Money, expiration: Expiration, fee: Int64, feeAssetId: String) { self.amountAsset = amountAsset self.priceAsset = priceAsset @@ -84,6 +102,7 @@ extension DexCreateOrder.DTO { self.total = total self.expiration = expiration self.fee = fee + self.feeAssetId = feeAssetId } } @@ -93,6 +112,11 @@ extension DexCreateOrder.DTO { let price: Money let amount: Money } + + struct FeeSettings { + let fee: Money + let feeAssets: [DomainLayer.DTO.Dex.SmartSettingsOrderFee.Asset] + } } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCreateOrder/DexCreateOrderViewController.swift b/WavesWallet-iOS/Modules/Dex/DexCreateOrder/DexCreateOrderViewController.swift similarity index 82% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCreateOrder/DexCreateOrderViewController.swift rename to WavesWallet-iOS/Modules/Dex/DexCreateOrder/DexCreateOrderViewController.swift index 8d19298b..1f250012 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCreateOrder/DexCreateOrderViewController.swift +++ b/WavesWallet-iOS/Modules/Dex/DexCreateOrder/DexCreateOrderViewController.swift @@ -10,7 +10,10 @@ import UIKit import RxSwift import RxCocoa import RxFeedback -import WavesSDKCrypto +import WavesSDKExtensions +import WavesSDK +import Extensions +import DomainLayer private enum Constants { static let percent50 = 50 @@ -31,7 +34,13 @@ final class DexCreateOrderViewController: UIViewController { price: input.price ?? Money(0, input.priceAsset.decimals), total: Money(0, input.priceAsset.decimals), expiration: DexCreateOrder.DTO.Expiration.expiration29d, - fee: 0) + fee: 0, + feeAssetId: WavesSDKConstants.wavesAssetId) + + feeAssets = [DomainLayer.DTO.Dex.Asset(id: WavesSDKConstants.wavesAssetId, + name: WavesSDKConstants.wavesAssetId, + shortName: WavesSDKConstants.wavesAssetId, + decimals: WavesSDKConstants.WavesDecimals)] } } @@ -55,13 +64,17 @@ final class DexCreateOrderViewController: UIViewController { @IBOutlet private weak var labelErrorFee: UILabel! @IBOutlet private weak var labelFee: UILabel! @IBOutlet private weak var activityIndicatorViewFee: UIActivityIndicatorView! + @IBOutlet private weak var iconArrowCustomFee: UIImageView! private var order: DexCreateOrder.DTO.Order! private var isCreatingOrderState: Bool = false private var isDisabledBuySellButton: Bool = false private var errorSnackKey: String? + private var feeAssets: [DomainLayer.DTO.Dex.Asset] = [] var presenter: DexCreateOrderPresenterProtocol! + weak var moduleOutput: DexCreateOrderModuleOutput? + private let sendEvent: PublishRelay = PublishRelay() override func viewDidLoad() { @@ -74,7 +87,9 @@ final class DexCreateOrderViewController: UIViewController { setupButtonSellBuy() setupUIForIPhone5IfNeed() labelFee.isHidden = true + iconArrowCustomFee.isHidden = true } + } //MARK: - UI State @@ -83,7 +98,10 @@ private extension DexCreateOrderViewController { func showFee(fee: Money) { activityIndicatorViewFee.stopAnimating() labelFee.isHidden = false - labelFee.text = fee.displayText + " " + "WAVES" + + let feeAssetName = feeAssets.first(where: {$0.id == order.feeAssetId})?.shortName ?? "" + labelFee.text = fee.displayText + " " + feeAssetName + iconArrowCustomFee.isHidden = feeAssets.count <= 1 } func setupCreatingOrderState() { @@ -112,7 +130,7 @@ private extension DexCreateOrderViewController { return Bindings(subscriptions: owner.subscriptions(state: state), events: owner.events()) } - presenter.system(feedbacks: [feedback]) + presenter.system(feedbacks: [feedback], feeAssetId: order.feeAssetId) } func events() -> [Signal] { @@ -124,50 +142,82 @@ private extension DexCreateOrderViewController { .drive(onNext: { [weak self] state in guard let self = self else { return } + self.updateState(state) + }) + + return [subscriptionSections] + } + + func updateState(_ state: DexCreateOrder.State) { + + self.isDisabledBuySellButton = state.isDisabledSellBuyButton + self.setupFeeError(error: state.displayFeeErrorState) + + switch state.action { + case .none: + return + default: + break + } + + switch state.action { + case .showCreatingOrderState: + self.setupCreatingOrderState() + + case .orderDidFailCreate(let error): + + self.showNetworkErrorSnack(error: error) + self.setupDefaultState() + + case .orderDidCreate(let output): + + moduleOutput?.dexCreateOrderDidCreate(output: output) - self.isDisabledBuySellButton = state.isDisabledSellBuyButton - self.setupFeeError(error: state.displayFeeErrorState) - - switch state.action { - case .none: - return - default: - break + case .orderNotValid(let error): + + let callback: ((_ isSuccess: Bool) -> Void) = { [weak self] isSuccess in + if isSuccess { + self?.sendEvent.accept(.sendOrder) + } else { + self?.sendEvent.accept(.cancelCreateOrder) } + } + + switch error { + case .invalid: + break - switch state.action { - case .showCreatingOrderState: - self.setupCreatingOrderState() - - case .orderDidFailCreate(let error): - - self.showNetworkErrorSnack(error: error) - self.setupDefaultState() - - case .orderDidCreate: - self.dismissController() - - case .didGetFee(let fee): - - self.showFee(fee: fee) - self.order.fee = fee.amount - self.updateInputDataFields() - self.sendEvent.accept(.updateInputOrder(self.order)) - self.setupValidationErrors() - self.setupButtonSellBuy() - self.setupInputAmountData() - self.setupInputTotalData() - - default: - break - } - }) + case .priceHigherMarket: + moduleOutput?.dexCreateOrderWarningForPrice(isPriceHigherMarket: true, callback: callback) + + case .priceLowerMarket: + moduleOutput?.dexCreateOrderWarningForPrice(isPriceHigherMarket: false, callback: callback) + } + + case .didGetFee(let feeSettings): + + self.feeAssets = feeSettings.feeAssets.map{ $0.asset } + self.showFee(fee: feeSettings.fee) + self.order.fee = feeSettings.fee.amount + self.updateInputDataFields() + self.sendEvent.accept(.updateInputOrder(self.order)) + self.setupValidationErrors() + self.setupButtonSellBuy() + self.setupInputAmountData() + self.setupInputTotalData() + + case .showDeffaultOrderState: + setupDefaultState() - return [subscriptionSections] + case .none: + break + } } + } -//MARK: - Validation +// MARK: - Validation + private extension DexCreateOrderViewController { var isValidWavesFee: Bool { @@ -175,14 +225,14 @@ private extension DexCreateOrderViewController { return true } - if order.amountAsset.id == WavesSDKCryptoConstants.wavesAssetId && order.type == .buy { + if order.amountAsset.id == WavesSDKConstants.wavesAssetId && order.type == .buy { if order.amount.isZero { return isValidPriceAssetBalance } return order.amount.amount > order.fee } - else if order.priceAsset.id == WavesSDKCryptoConstants.wavesAssetId && order.type == .sell { + else if order.priceAsset.id == WavesSDKConstants.wavesAssetId && order.type == .sell { if order.total.isZero { return isValidAmountAssetBalance } @@ -203,7 +253,7 @@ private extension DexCreateOrderViewController { } var availableAmountAssetBalance: Money { - if order.amountAsset.id == WavesSDKCryptoConstants.wavesAssetId { + if order.amountAsset.id == WavesSDKConstants.wavesAssetId { let amount = input.availableAmountAssetBalance.amount - Int64(order.fee) return Money(amount < 0 ? 0 : amount, input.availableAmountAssetBalance.decimals) } @@ -211,7 +261,7 @@ private extension DexCreateOrderViewController { } var availablePriceAssetBalance: Money { - if order.priceAsset.id == WavesSDKCryptoConstants.wavesAssetId { + if order.priceAsset.id == WavesSDKConstants.wavesAssetId { let amount = input.availablePriceAssetBalance.amount - Int64(order.fee) return Money(amount < 0 ? 0 : amount, input.availablePriceAssetBalance.decimals) } @@ -237,6 +287,36 @@ private extension DexCreateOrderViewController { //MARK: - Actions private extension DexCreateOrderViewController { + @IBAction func customFeeTapped(_ sender: Any) { + + guard feeAssets.count > 1 else { return } + + let vc = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) + for asset in feeAssets { + let action = UIAlertAction(title: asset.shortName, style: .default) { (action) in + + if self.order.feeAssetId != asset.id { + self.order.feeAssetId = asset.id + self.sendEvent.accept(.feeAssetNeedUpdate(asset.id)) + + self.feeAssets = [] + self.order.fee = 0 + self.activityIndicatorViewFee.isHidden = false + self.activityIndicatorViewFee.startAnimating() + self.labelFee.isHidden = true + self.iconArrowCustomFee.isHidden = true + self.setupButtonSellBuy() + } + } + vc.addAction(action) + } + + let cancel = UIAlertAction(title: Localizable.Waves.Dexcreateorder.Button.cancel, + style: .cancel, handler: nil) + vc.addAction(cancel) + present(vc, animated: true, completion: nil) + } + func dismissController() { if let parent = self.parent as? PopupViewController { parent.dismissPopup() @@ -638,7 +718,7 @@ private extension DexCreateOrderViewController { self.sendEvent.accept(.refreshFee) }) - case .notFound, .scriptError: + case .none, .scriptError: errorSnackKey = showErrorNotFoundSnack(didTap: { [weak self] in guard let self = self else { return } self.sendEvent.accept(.refreshFee) diff --git a/WavesWallet-iOS/Modules/Dex/DexCreateOrder/Interactor/DexCreateOrderInteractor.swift b/WavesWallet-iOS/Modules/Dex/DexCreateOrder/Interactor/DexCreateOrderInteractor.swift new file mode 100644 index 00000000..abfdba0c --- /dev/null +++ b/WavesWallet-iOS/Modules/Dex/DexCreateOrder/Interactor/DexCreateOrderInteractor.swift @@ -0,0 +1,137 @@ +// +// DexCreateOrderInteractor.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 11/5/18. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import WavesSDKExtensions +import WavesSDK +import Extensions +import DomainLayer + +private enum Constants { + static let numberForConveringDecimals = 8 +} + +final class DexCreateOrderInteractor: DexCreateOrderInteractorProtocol { + + private let auth = UseCasesFactory.instance.authorization + private let matcherRepository = UseCasesFactory.instance.repositories.matcherRepository + private let orderBookRepository = UseCasesFactory.instance.repositories.dexOrderBookRepository + private let transactionInteractor = UseCasesFactory.instance.transactions + private let assetsInteractor = UseCasesFactory.instance.assets + private let orderBookInteractor = UseCasesFactory.instance.oderbook + private let lastTradesRespository = UseCasesFactory.instance.repositories.lastTradesRespository + private let environmentRepository = UseCasesFactory.instance.repositories.environmentRepository + + + func createOrder(order: DexCreateOrder.DTO.Order) -> Observable> { + + return auth.authorizedWallet().flatMap({ [weak self] (wallet) -> Observable> in + + guard let self = self else { return Observable.empty() } + + let matcher = self.matcherRepository.matcherPublicKey() + let environment = self.environmentRepository.applicationEnvironment() + + //TODO: Code move to another method + return Observable.zip(matcher, environment) + .flatMap({ [weak self] (matcherPublicKey, environment) -> Observable> in + guard let self = self else { return Observable.empty() } + + let precisionDifference = (order.priceAsset.decimals - order.amountAsset.decimals) + Constants.numberForConveringDecimals + + let price = (order.price.decimalValue * pow(10, precisionDifference)).int64Value + + let orderQuery = DomainLayer.Query.Dex.CreateOrder(wallet: wallet, + matcherPublicKey: matcherPublicKey, + amountAsset: order.amountAsset.id, + priceAsset: order.priceAsset.id, + amount: order.amount.amount, + price: price, + orderType: order.type, + matcherFee: order.fee, + timestamp: Date().millisecondsSince1970, + expiration: Int64(order.expiration.rawValue), + matcherFeeAsset: order.feeAssetId) + + + return self + .orderBookRepository + .createOrder(wallet: wallet, order: orderQuery) + .flatMap({ (success) -> Observable> in + let output = DexCreateOrder.DTO.Output(time: Date(milliseconds: orderQuery.timestamp), + orderType: order.type, + price: order.price, + amount: order.amount) + return Observable.just(ResponseType(output: output, error: nil)) + }) + }) + }) + .catchError({ (error) -> Observable> in + return Observable.just(ResponseType(output: nil, error: NetworkError.error(by: error))) + }) + } + + func getFee(amountAsset: String, priceAsset: String, feeAssetId: String) -> Observable { + + return auth.authorizedWallet().flatMap({ [weak self] (wallet) -> Observable in + guard let self = self else { return Observable.empty() } + + return self.orderBookInteractor.orderSettingsFee() + .flatMap({ [weak self] (smartSettings) -> Observable in + + guard let self = self else { return Observable.empty() } + + return self.transactionInteractor.calculateFee(by: .createOrder(amountAsset: amountAsset, + priceAsset: priceAsset, + settingsOrderFee: smartSettings, + feeAssetId: feeAssetId), + accountAddress: wallet.address) + .map({ (fee) -> DexCreateOrder.DTO.FeeSettings in + return DexCreateOrder.DTO.FeeSettings(fee: fee, feeAssets: smartSettings.feeAssets) + }) + }) + }) + } + + func isValidOrder(order: DexCreateOrder.DTO.Order) -> Observable { + + return auth + .authorizedWallet() + .flatMap({ [weak self] (wallet) -> Observable in + + guard let self = self else { return Observable.empty() } + + return self.orderBookRepository.orderBook(amountAsset: order.amountAsset.id, + priceAsset: order.priceAsset.id) + .flatMap({ (trade) -> Observable in + + let price = order.price.decimalValue + + let isBuy = order.type == .buy + + let lastPriceTrade = (isBuy == true ? trade.asks.first?.price : trade.bids.first?.price) ?? order.price.amount + let lastPrice = Money(lastPriceTrade, order.price.decimals).decimalValue + + let percent = (price / lastPrice * 100).rounded().int64Value + + if isBuy { + if lastPrice < price && percent >= (100 + UIGlobalConstants.limitPriceOrderPercent) { + return Observable.error(DexCreateOrder.CreateOrderError.priceHigherMarket) + } + } else { + if lastPrice > price && percent <= (100 - UIGlobalConstants.limitPriceOrderPercent) { + return Observable.error(DexCreateOrder.CreateOrderError.priceLowerMarket) + } + } + + return Observable.just(true) + }) + }) + } +} diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCreateOrder/Interactor/DexCreateOrderInteractorProtocol.swift b/WavesWallet-iOS/Modules/Dex/DexCreateOrder/Interactor/DexCreateOrderInteractorProtocol.swift similarity index 56% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCreateOrder/Interactor/DexCreateOrderInteractorProtocol.swift rename to WavesWallet-iOS/Modules/Dex/DexCreateOrder/Interactor/DexCreateOrderInteractorProtocol.swift index fe19043a..a10f01fa 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCreateOrder/Interactor/DexCreateOrderInteractorProtocol.swift +++ b/WavesWallet-iOS/Modules/Dex/DexCreateOrder/Interactor/DexCreateOrderInteractorProtocol.swift @@ -8,8 +8,14 @@ import Foundation import RxSwift +import DomainLayer +import Extensions protocol DexCreateOrderInteractorProtocol { + func createOrder(order: DexCreateOrder.DTO.Order) -> Observable> - func getFee(amountAsset: String, priceAsset: String) -> Observable + + func getFee(amountAsset: String, priceAsset: String, feeAssetId: String) -> Observable + // DexCreateOrder.Error + func isValidOrder(order: DexCreateOrder.DTO.Order) -> Observable } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCreateOrder/Presenter/DexCreateOrderPresenter.swift b/WavesWallet-iOS/Modules/Dex/DexCreateOrder/Presenter/DexCreateOrderPresenter.swift similarity index 60% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCreateOrder/Presenter/DexCreateOrderPresenter.swift rename to WavesWallet-iOS/Modules/Dex/DexCreateOrder/Presenter/DexCreateOrderPresenter.swift index 96507eb2..98de127c 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCreateOrder/Presenter/DexCreateOrderPresenter.swift +++ b/WavesWallet-iOS/Modules/Dex/DexCreateOrder/Presenter/DexCreateOrderPresenter.swift @@ -10,6 +10,8 @@ import Foundation import RxSwift import RxFeedback import RxCocoa +import Extensions +import DomainLayer final class DexCreateOrderPresenter: DexCreateOrderPresenterProtocol { @@ -17,16 +19,15 @@ final class DexCreateOrderPresenter: DexCreateOrderPresenterProtocol { var interactor: DexCreateOrderInteractorProtocol! private let disposeBag = DisposeBag() - weak var moduleOutput: DexCreateOrderModuleOutput? - var pair: DomainLayer.DTO.Dex.Pair! - func system(feedbacks: [DexCreateOrderPresenter.Feedback]) { + func system(feedbacks: [DexCreateOrderPresenter.Feedback], feeAssetId: String) { var newFeedbacks = feedbacks newFeedbacks.append(modelsQuery()) newFeedbacks.append(feeQuery()) + newFeedbacks.append(isValidOrderQuery()) - Driver.system(initialState: DexCreateOrder.State.initialState, + Driver.system(initialState: DexCreateOrder.State.initialState(feeAssetId: feeAssetId), reduce: { [weak self] state, event -> DexCreateOrder.State in guard let self = self else { return state } @@ -40,13 +41,13 @@ final class DexCreateOrderPresenter: DexCreateOrderPresenterProtocol { private func feeQuery() -> Feedback { return react(request: { state -> DexCreateOrder.State? in return state.isNeedGetFee ? state : nil - }, effects: { [weak self] ss -> Signal in + }, effects: { [weak self] state -> Signal in guard let self = self else { return Signal.empty() } return self .interactor - .getFee(amountAsset: self.pair.amountAsset.id, priceAsset: self.pair!.priceAsset.id) + .getFee(amountAsset: self.pair.amountAsset.id, priceAsset: self.pair.priceAsset.id, feeAssetId: state.feeAssetId) .map {.didGetFee($0)} .asSignal(onErrorRecover: { Signal.just(.handlerFeeError($0)) } ) }) @@ -65,6 +66,29 @@ final class DexCreateOrderPresenter: DexCreateOrderPresenterProtocol { }) } + private func isValidOrderQuery() -> Feedback { + + return react(request: { state -> DexCreateOrder.State? in + return state.isNeedCheckValidOrder ? state : nil + }, effects: { [weak self] ss -> Signal in + + guard let self = self else { return Signal.empty() } + guard let order = ss.order else { return Signal.empty() } + + return self + .interactor + .isValidOrder(order: order) + .map { $0 == true ? .sendOrder : .orderNotValid(.invalid) } + .asSignal(onErrorRecover: { (error) -> Signal in + if let error = error as? DexCreateOrder.CreateOrderError { + return Signal.just(.orderNotValid(error)) + } else { + return Signal.just(.orderNotValid(.invalid)) + } + }) + }) + } + private func reduce(state: DexCreateOrder.State, event: DexCreateOrder.Event) -> DexCreateOrder.State { switch event { @@ -75,12 +99,19 @@ final class DexCreateOrderPresenter: DexCreateOrderPresenterProtocol { } .changeAction(.none) + case .feeAssetNeedUpdate(let feeAssetId): + + return state.mutate { + $0.feeAssetId = feeAssetId + $0.isNeedGetFee = true + }.changeAction(.none) + case .handlerFeeError(let error): return state.mutate { $0.isNeedGetFee = false $0.isDisabledSellBuyButton = true - if let error = error as? TransactionsInteractorError, error == .commissionReceiving { + if let error = error as? TransactionsUseCaseError, error == .commissionReceiving { $0.displayFeeErrorState = .error(DisplayError.message(Localizable.Waves.Transaction.Error.Commission.receiving)) } else { $0.displayFeeErrorState = .error(DisplayError(error: error)) @@ -88,29 +119,55 @@ final class DexCreateOrderPresenter: DexCreateOrderPresenterProtocol { } .changeAction(.none) - case .didGetFee(let fee): + case .didGetFee(let feeSettings): return state.mutate { $0.isNeedGetFee = false $0.isDisabledSellBuyButton = false $0.displayFeeErrorState = .none - $0.order?.fee = fee.amount + $0.order?.fee = feeSettings.fee.amount } - .changeAction(.didGetFee(fee)) + .changeAction(.didGetFee(feeSettings)) case .createOrder: if state.order?.type == .buy { - AnalyticManager.trackEvent(.dex(.buyOrderSuccess(amountAsset: pair.amountAsset.name, + UseCasesFactory.instance.analyticManager.trackEvent(.dex(.buyOrderSuccess(amountAsset: pair.amountAsset.name, priceAsset: pair.priceAsset.name))) } else { - AnalyticManager.trackEvent(.dex(.sellOrderSuccess(amountAsset: pair.amountAsset.name, + UseCasesFactory.instance.analyticManager.trackEvent(.dex(.sellOrderSuccess(amountAsset: pair.amountAsset.name, priceAsset: pair.priceAsset.name))) } + return state.mutate { + $0.isNeedCreateOrder = false + $0.isNeedCheckValidOrder = true + } + .changeAction(.showCreatingOrderState) + + case .cancelCreateOrder: + + return state.mutate { + $0.isNeedCreateOrder = false + $0.isNeedCheckValidOrder = false + } + .changeAction(.showDeffaultOrderState) + + case .sendOrder: + return state.mutate { $0.isNeedCreateOrder = true - }.changeAction(.showCreatingOrderState) + $0.isNeedCheckValidOrder = false + } + .changeAction(.showCreatingOrderState) + + case .orderNotValid(let error): + + return state.mutate { + $0.isNeedCreateOrder = false + $0.isNeedCheckValidOrder = false + } + .changeAction(.orderNotValid(error)) case .orderDidCreate(let responce): @@ -123,8 +180,7 @@ final class DexCreateOrderPresenter: DexCreateOrderPresenterProtocol { $0.action = .orderDidFailCreate(error) case .success(let output): - moduleOutput?.dexCreateOrderDidCreate(output: output) - $0.action = .orderDidCreate + $0.action = .orderDidCreate(output) } } @@ -150,12 +206,14 @@ fileprivate extension DexCreateOrder.State { } fileprivate extension DexCreateOrder.State { - static var initialState: DexCreateOrder.State { + static func initialState(feeAssetId: String) -> DexCreateOrder.State { return DexCreateOrder.State(isNeedCreateOrder: false, + isNeedCheckValidOrder: false, isNeedGetFee: true, order: nil, action: .none, displayFeeErrorState: .none, - isDisabledSellBuyButton: false) + isDisabledSellBuyButton: false, + feeAssetId: feeAssetId) } } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCreateOrder/Presenter/DexCreateOrderPresenterProtocol.swift b/WavesWallet-iOS/Modules/Dex/DexCreateOrder/Presenter/DexCreateOrderPresenterProtocol.swift similarity index 81% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCreateOrder/Presenter/DexCreateOrderPresenterProtocol.swift rename to WavesWallet-iOS/Modules/Dex/DexCreateOrder/Presenter/DexCreateOrderPresenterProtocol.swift index 66f4d024..78be1cf1 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCreateOrder/Presenter/DexCreateOrderPresenterProtocol.swift +++ b/WavesWallet-iOS/Modules/Dex/DexCreateOrder/Presenter/DexCreateOrderPresenterProtocol.swift @@ -8,14 +8,14 @@ import Foundation import RxCocoa +import Extensions +import DomainLayer protocol DexCreateOrderPresenterProtocol { typealias Feedback = (Driver) -> Signal var interactor: DexCreateOrderInteractorProtocol! { get set } - func system(feedbacks: [Feedback]) - - var moduleOutput: DexCreateOrderModuleOutput? { get set } + func system(feedbacks: [Feedback], feeAssetId: String) var pair: DomainLayer.DTO.Dex.Pair! { get set } } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCreateOrder/Views/DexCreateOrderAmountButton.swift b/WavesWallet-iOS/Modules/Dex/DexCreateOrder/Views/DexCreateOrderAmountButton.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCreateOrder/Views/DexCreateOrderAmountButton.swift rename to WavesWallet-iOS/Modules/Dex/DexCreateOrder/Views/DexCreateOrderAmountButton.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCreateOrder/Views/DexCreateOrderInputView.swift b/WavesWallet-iOS/Modules/Dex/DexCreateOrder/Views/DexCreateOrderInputView.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCreateOrder/Views/DexCreateOrderInputView.swift rename to WavesWallet-iOS/Modules/Dex/DexCreateOrder/Views/DexCreateOrderInputView.swift index f415c0d4..170ec16c 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCreateOrder/Views/DexCreateOrderInputView.swift +++ b/WavesWallet-iOS/Modules/Dex/DexCreateOrder/Views/DexCreateOrderInputView.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions private enum Constants { static let animationFrameDuration: TimeInterval = 0.3 diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCreateOrder/Views/DexCreateOrderInputView.xib b/WavesWallet-iOS/Modules/Dex/DexCreateOrder/Views/DexCreateOrderInputView.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCreateOrder/Views/DexCreateOrderInputView.xib rename to WavesWallet-iOS/Modules/Dex/DexCreateOrder/Views/DexCreateOrderInputView.xib diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCreateOrder/Views/DexCreateOrderSegmentedControl.swift b/WavesWallet-iOS/Modules/Dex/DexCreateOrder/Views/DexCreateOrderSegmentedControl.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCreateOrder/Views/DexCreateOrderSegmentedControl.swift rename to WavesWallet-iOS/Modules/Dex/DexCreateOrder/Views/DexCreateOrderSegmentedControl.swift index 46ee1259..92f1acaa 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCreateOrder/Views/DexCreateOrderSegmentedControl.swift +++ b/WavesWallet-iOS/Modules/Dex/DexCreateOrder/Views/DexCreateOrderSegmentedControl.swift @@ -7,6 +7,8 @@ // import UIKit +import DomainLayer +import Extensions private enum Constants { static let animationDuration: TimeInterval = 0.3 diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCreateOrder/Views/DexCreateOrderSegmentedControl.xib b/WavesWallet-iOS/Modules/Dex/DexCreateOrder/Views/DexCreateOrderSegmentedControl.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexCreateOrder/Views/DexCreateOrderSegmentedControl.xib rename to WavesWallet-iOS/Modules/Dex/DexCreateOrder/Views/DexCreateOrderSegmentedControl.xib diff --git a/WavesWallet-iOS/Modules/Dex/DexDeepLinkLoading/DexDeepLinkLoadingViewController.swift b/WavesWallet-iOS/Modules/Dex/DexDeepLinkLoading/DexDeepLinkLoadingViewController.swift new file mode 100644 index 00000000..d290be66 --- /dev/null +++ b/WavesWallet-iOS/Modules/Dex/DexDeepLinkLoading/DexDeepLinkLoadingViewController.swift @@ -0,0 +1,107 @@ +// +// DexDeepLinkLoadingViewController.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 31.10.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import UIKit +import Extensions +import DomainLayer +import RxSwift + +private enum Constants { + static let amountAssetKey = "assetId1" + static let priceAssetKey = "assetId2" +} + +final class DexDeepLinkLoadingViewController: UIViewController { + + private let assets = UseCasesFactory.instance.assets + private let auth = UseCasesFactory.instance.authorization + + var deepLink: DeepLink! + var didComplete:((DexTraderContainer.DTO.Pair) -> Void)? + var didFail:(() -> Void)? + + private let disposeBag = DisposeBag() + + override func viewDidLoad() { + super.viewDidLoad() + + loadAssets() + + } + + private func loadAssets() { + if let amountAssetId = deepLink.amountAsset, let priceAssetId = deepLink.priceAsset { + auth.authorizedWallet().flatMap { [weak self] (wallet) -> Observable<[DomainLayer.DTO.Asset]> in + guard let self = self else { return Observable.empty() } + return self.assets.assets(by: [amountAssetId, priceAssetId], accountAddress: wallet.address) + } + .observeOn(MainScheduler.instance) + .subscribe(onNext: { [weak self] (assets) in + guard let self = self else { return } + if let amountAsset = assets.first(where: {$0.id == amountAssetId}), + let priceAsset = assets.first(where: {$0.id == priceAssetId}) { + + let isGeneral = amountAsset.isGeneral && priceAsset.isGeneral + let pair = DexTraderContainer.DTO.Pair(amountAsset: .init(id: amountAsset.id, + name: amountAsset.displayName, + shortName: amountAsset.ticker ?? amountAsset.displayName, + decimals: amountAsset.precision), + + priceAsset: .init(id: priceAsset.id, + name: priceAsset.displayName, + shortName: priceAsset.ticker ?? priceAsset.displayName, + decimals: priceAsset.precision), + + isGeneral: isGeneral) + self.didComplete?(pair) + } + else { + self.didFail?() + } + + }).disposed(by: disposeBag) + } + else { + didFail?() + } + } +} + + +private extension DeepLink { + + var amountAsset: String? { + return url.params.first(where: {$0.key == Constants.amountAssetKey})?.value + } + + var priceAsset: String? { + return url.params.first(where: {$0.key == Constants.priceAssetKey})?.value + } + +} + +private extension URL { + + var params: [String: String] { + + guard let query = self.query else { return [:] } + var queryStrings = [String: String]() + for pair in query.components(separatedBy: "&") { + + let key = pair.components(separatedBy: "=")[0] + + let value = pair + .components(separatedBy:"=")[1] + .replacingOccurrences(of: "+", with: " ") + .removingPercentEncoding ?? "" + + queryStrings[key] = value + } + return queryStrings + } +} diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexInfo/DexInfoModuleBuilder.swift b/WavesWallet-iOS/Modules/Dex/DexInfo/DexInfoModuleBuilder.swift similarity index 95% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexInfo/DexInfoModuleBuilder.swift rename to WavesWallet-iOS/Modules/Dex/DexInfo/DexInfoModuleBuilder.swift index 0c352b02..9a0af0b0 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexInfo/DexInfoModuleBuilder.swift +++ b/WavesWallet-iOS/Modules/Dex/DexInfo/DexInfoModuleBuilder.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions struct DexInfoModuleBuilder: ModuleBuilder { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexInfo/DexInfoTypes.swift b/WavesWallet-iOS/Modules/Dex/DexInfo/DexInfoTypes.swift similarity index 91% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexInfo/DexInfoTypes.swift rename to WavesWallet-iOS/Modules/Dex/DexInfo/DexInfoTypes.swift index 0925bc53..43c43d39 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexInfo/DexInfoTypes.swift +++ b/WavesWallet-iOS/Modules/Dex/DexInfo/DexInfoTypes.swift @@ -7,13 +7,13 @@ // import Foundation - +import DomainLayer +import Extensions enum DexInfoPair { enum DTO {} } - extension DexInfoPair.DTO { struct Pair: Mutating { @@ -22,4 +22,3 @@ extension DexInfoPair.DTO { let isGeneral: Bool } } - diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexInfo/DexInfoViewController.swift b/WavesWallet-iOS/Modules/Dex/DexInfo/DexInfoViewController.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexInfo/DexInfoViewController.swift rename to WavesWallet-iOS/Modules/Dex/DexInfo/DexInfoViewController.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexInfo/Views/SearchBarView.swift b/WavesWallet-iOS/Modules/Dex/DexInfo/Views/SearchBarView.swift similarity index 58% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexInfo/Views/SearchBarView.swift rename to WavesWallet-iOS/Modules/Dex/DexInfo/Views/SearchBarView.swift index 7e556c3b..5d37cac5 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexInfo/Views/SearchBarView.swift +++ b/WavesWallet-iOS/Modules/Dex/DexInfo/Views/SearchBarView.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions protocol SearchBarViewDelegate: AnyObject { @@ -15,7 +16,11 @@ protocol SearchBarViewDelegate: AnyObject { final class SearchBarView: UIView, NibOwnerLoadable { - @IBOutlet private weak var textField: UITextField! + @IBOutlet private(set) weak var textField: UITextField! + + @IBOutlet private weak var iconImageView: UIImageView! + + @IBOutlet private weak var indicatorView: UIActivityIndicatorView! weak var delegate: SearchBarViewDelegate? @@ -42,11 +47,40 @@ final class SearchBarView: UIView, NibOwnerLoadable { textField.attributedPlaceholder = NSAttributedString(string: Localizable.Waves.Dexmarket.Searchbar.placeholder, attributes: [NSAttributedString.Key.foregroundColor : UIColor.basic500]) } + override func becomeFirstResponder() -> Bool { + return textField.becomeFirstResponder() + } + + override func resignFirstResponder() -> Bool { + return textField.resignFirstResponder() + } + + func startLoading() { + iconImageView.isHidden = true + indicatorView.isHidden = false + indicatorView.startAnimating() + } + + func stopLoading() { + iconImageView.isHidden = false + indicatorView.stopAnimating() + indicatorView.isHidden = true + } + } //MARK: UITextFieldDelegate extension SearchBarView: UITextFieldDelegate { + + func textFieldDidBeginEditing(_ textField: UITextField) { + iconImageView.image = Images.search24Black.image + } + + func textFieldDidEndEditing(_ textField: UITextField) { + iconImageView.image = Images.search24Basic500.image + } + func textFieldShouldReturn(_ textField: UITextField) -> Bool { textField.resignFirstResponder() return true diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexInfo/Views/SearchBarView.xib b/WavesWallet-iOS/Modules/Dex/DexInfo/Views/SearchBarView.xib similarity index 79% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexInfo/Views/SearchBarView.xib rename to WavesWallet-iOS/Modules/Dex/DexInfo/Views/SearchBarView.xib index b5124477..8f3d7c05 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexInfo/Views/SearchBarView.xib +++ b/WavesWallet-iOS/Modules/Dex/DexInfo/Views/SearchBarView.xib @@ -1,17 +1,19 @@ - + - + + + @@ -21,13 +23,16 @@ - + + - + @@ -40,7 +45,9 @@ + + @@ -56,9 +63,9 @@ - + - + diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexLastTrades/DexLastTradesModuleBuilder.swift b/WavesWallet-iOS/Modules/Dex/DexLastTrades/DexLastTradesModuleBuilder.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexLastTrades/DexLastTradesModuleBuilder.swift rename to WavesWallet-iOS/Modules/Dex/DexLastTrades/DexLastTradesModuleBuilder.swift index d7d0c453..335d621e 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexLastTrades/DexLastTradesModuleBuilder.swift +++ b/WavesWallet-iOS/Modules/Dex/DexLastTrades/DexLastTradesModuleBuilder.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions struct DexLastTradesModuleBuilder: ModuleBuilderOutput { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexLastTrades/DexLastTradesModuleOutput.swift b/WavesWallet-iOS/Modules/Dex/DexLastTrades/DexLastTradesModuleOutput.swift similarity index 96% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexLastTrades/DexLastTradesModuleOutput.swift rename to WavesWallet-iOS/Modules/Dex/DexLastTrades/DexLastTradesModuleOutput.swift index 5a8d00fe..4fd9bbdb 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexLastTrades/DexLastTradesModuleOutput.swift +++ b/WavesWallet-iOS/Modules/Dex/DexLastTrades/DexLastTradesModuleOutput.swift @@ -7,6 +7,8 @@ // import Foundation +import Extensions +import DomainLayer protocol DexLastTradesModuleOutput: AnyObject { func didCreateOrder(_ trade: DexLastTrades.DTO.SellBuyTrade, diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexLastTrades/DexLastTradesTypes.swift b/WavesWallet-iOS/Modules/Dex/DexLastTrades/DexLastTradesTypes.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexLastTrades/DexLastTradesTypes.swift rename to WavesWallet-iOS/Modules/Dex/DexLastTrades/DexLastTradesTypes.swift index e8227cf0..6dad63b3 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexLastTrades/DexLastTradesTypes.swift +++ b/WavesWallet-iOS/Modules/Dex/DexLastTrades/DexLastTradesTypes.swift @@ -7,6 +7,8 @@ // import Foundation +import DomainLayer +import Extensions enum DexLastTrades { enum DTO {} diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexLastTrades/DexLastTradesViewController.swift b/WavesWallet-iOS/Modules/Dex/DexLastTrades/DexLastTradesViewController.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexLastTrades/DexLastTradesViewController.swift rename to WavesWallet-iOS/Modules/Dex/DexLastTrades/DexLastTradesViewController.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexLastTrades/Interactor/DexLastTradesInteractor.swift b/WavesWallet-iOS/Modules/Dex/DexLastTrades/Interactor/DexLastTradesInteractor.swift similarity index 62% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexLastTrades/Interactor/DexLastTradesInteractor.swift rename to WavesWallet-iOS/Modules/Dex/DexLastTrades/Interactor/DexLastTradesInteractor.swift index 60eeefcc..9315a49c 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexLastTrades/Interactor/DexLastTradesInteractor.swift +++ b/WavesWallet-iOS/Modules/Dex/DexLastTrades/Interactor/DexLastTradesInteractor.swift @@ -8,9 +8,9 @@ import Foundation import RxSwift -import Moya -import WavesSDKExtension -import WavesSDKCrypto +import WavesSDK +import Extensions +import DomainLayer private enum Constants { static let limit = 100 @@ -23,12 +23,12 @@ final class DexLastTradesInteractor: DexLastTradesInteractorProtocol { let buy: DexLastTrades.DTO.SellBuyTrade? } - private let account = FactoryInteractors.instance.accountBalance - private let lastTradesRepository = FactoryRepositories.instance.lastTradesRespository - private let orderBookRepository = FactoryRepositories.instance.dexOrderBookRepository - private let auth = FactoryInteractors.instance.authorization - private let assetsRepositoryLocal = FactoryRepositories.instance.assetsRepositoryLocal - private let assetsInteractor = FactoryInteractors.instance.assetsInteractor + private let account = UseCasesFactory.instance.accountBalance + private let lastTradesRepository = UseCasesFactory.instance.repositories.lastTradesRespository + private let orderBookRepository = UseCasesFactory.instance.repositories.dexOrderBookRepository + private let auth = UseCasesFactory.instance.authorization + private let assetsRepositoryLocal = UseCasesFactory.instance.repositories.assetsRepositoryLocal + private let assetsInteractor = UseCasesFactory.instance.assets var pair: DexTraderContainer.DTO.Pair! @@ -51,7 +51,7 @@ final class DexLastTradesInteractor: DexLastTradesInteractorProtocol { lastBuy: nil, availableAmountAssetBalance: Money(0, self.pair.amountAsset.decimals), availablePriceAssetBalance: Money(0, self.pair.priceAsset.decimals), - availableWavesBalance: Money(0, WavesSDKCryptoConstants.WavesDecimals), + availableWavesBalance: Money(0, WavesSDKConstants.WavesDecimals), scriptedAssets: []) return Observable.just(display) }) @@ -68,7 +68,7 @@ extension DexLastTradesInteractor { var amountAssetBalance = Money(0, pair.amountAsset.decimals) var priceAssetBalance = Money(0, pair.priceAsset.decimals) - var wavesBalance = Money(0, WavesSDKCryptoConstants.WavesDecimals) + var wavesBalance = Money(0, WavesSDKConstants.WavesDecimals) if let amountAsset = balances.first(where: {$0.assetId == pair.amountAsset.id}) { amountAssetBalance = Money(amountAsset.availableBalance, amountAsset.asset.precision) @@ -94,53 +94,42 @@ extension DexLastTradesInteractor { private func getLastTrades() -> Observable<[DomainLayer.DTO.Dex.LastTrade]> { - return auth.authorizedWallet().flatMap({ [weak self] (wallet) -> Observable<[DomainLayer.DTO.Dex.LastTrade]> in - guard let self = self else { return Observable.empty() } - return self.lastTradesRepository.lastTrades(accountAddress: wallet.address, - amountAsset: self.pair.amountAsset, - priceAsset: self.pair.priceAsset, - limit: Constants.limit) - }) - + return lastTradesRepository.lastTrades(amountAsset: pair.amountAsset, + priceAsset: pair.priceAsset, + limit: Constants.limit) } private func getLastSellBuy() -> Observable { - return auth.authorizedWallet().flatMap({ [weak self] (wallet) -> Observable in - guard let self = self else { return Observable.empty() } - - - return self.orderBookRepository.orderBook(wallet: wallet, - amountAsset: self.pair.amountAsset.id, - priceAsset: self.pair.priceAsset.id) - .flatMap({ [weak self] (orderbook) -> Observable in - - guard let self = self else { return Observable.empty() } + return self.orderBookRepository.orderBook(amountAsset: self.pair.amountAsset.id, + priceAsset: self.pair.priceAsset.id) + .flatMap({ [weak self] (orderbook) -> Observable in + + guard let self = self else { return Observable.empty() } + + var sell: DexLastTrades.DTO.SellBuyTrade? + var buy: DexLastTrades.DTO.SellBuyTrade? + + if let bid = orderbook.bids.first { - var sell: DexLastTrades.DTO.SellBuyTrade? - var buy: DexLastTrades.DTO.SellBuyTrade? + let price = Money.price(amount: bid.price, + amountDecimals: self.pair.amountAsset.decimals, + priceDecimals: self.pair.priceAsset.decimals) - if let bid = orderbook.bids.first { - - let price = Money.price(amount: bid.price, - amountDecimals: self.pair.amountAsset.decimals, - priceDecimals: self.pair.priceAsset.decimals) - - sell = DexLastTrades.DTO.SellBuyTrade(price: price, type: .sell) - } + sell = DexLastTrades.DTO.SellBuyTrade(price: price, type: .sell) + } + + if let ask = orderbook.asks.first { - if let ask = orderbook.asks.first { - - let price = Money.price(amount: ask.price, - amountDecimals: self.pair.amountAsset.decimals, - priceDecimals: self.pair.priceAsset.decimals) - - buy = DexLastTrades.DTO.SellBuyTrade(price: price, type: .buy) - } + let price = Money.price(amount: ask.price, + amountDecimals: self.pair.amountAsset.decimals, + priceDecimals: self.pair.priceAsset.decimals) - return Observable.just(LastSellBuy(sell: sell, buy: buy)) - }) - }) + buy = DexLastTrades.DTO.SellBuyTrade(price: price, type: .buy) + } + + return Observable.just(LastSellBuy(sell: sell, buy: buy)) + }) } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexLastTrades/Interactor/DexLastTradesInteractorMock.swift b/WavesWallet-iOS/Modules/Dex/DexLastTrades/Interactor/DexLastTradesInteractorMock.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexLastTrades/Interactor/DexLastTradesInteractorMock.swift rename to WavesWallet-iOS/Modules/Dex/DexLastTrades/Interactor/DexLastTradesInteractorMock.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexLastTrades/Interactor/DexLastTradesInteractorProtocol.swift b/WavesWallet-iOS/Modules/Dex/DexLastTrades/Interactor/DexLastTradesInteractorProtocol.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexLastTrades/Interactor/DexLastTradesInteractorProtocol.swift rename to WavesWallet-iOS/Modules/Dex/DexLastTrades/Interactor/DexLastTradesInteractorProtocol.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexLastTrades/Presenter/DexLastTradesPresenter.swift b/WavesWallet-iOS/Modules/Dex/DexLastTrades/Presenter/DexLastTradesPresenter.swift similarity index 90% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexLastTrades/Presenter/DexLastTradesPresenter.swift rename to WavesWallet-iOS/Modules/Dex/DexLastTrades/Presenter/DexLastTradesPresenter.swift index 726c587e..ded738d8 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexLastTrades/Presenter/DexLastTradesPresenter.swift +++ b/WavesWallet-iOS/Modules/Dex/DexLastTrades/Presenter/DexLastTradesPresenter.swift @@ -10,6 +10,7 @@ import Foundation import RxSwift import RxFeedback import RxCocoa +import DomainLayer final class DexLastTradesPresenter: DexLastTradesPresenterProtocol { @@ -82,7 +83,7 @@ final class DexLastTradesPresenter: DexLastTradesPresenterProtocol { }.changeAction(.update) case .didTapBuy(let buy): - AnalyticManager.trackEvent(.dex(.buyTap(amountAsset: amountAsset.name, priceAsset: priceAsset.name))) + UseCasesFactory.instance.analyticManager.trackEvent(.dex(.buyTap(amountAsset: amountAsset.name, priceAsset: priceAsset.name))) moduleOutput?.didCreateOrder(buy, amountAsset: amountAsset, priceAsset: priceAsset, availableAmountAssetBalance: state.availableAmountAssetBalance, @@ -92,7 +93,7 @@ final class DexLastTradesPresenter: DexLastTradesPresenterProtocol { return state.changeAction(.none) case .didTapEmptyBuy: - AnalyticManager.trackEvent(.dex(.buyTap(amountAsset: amountAsset.name, priceAsset: priceAsset.name))) + UseCasesFactory.instance.analyticManager.trackEvent(.dex(.buyTap(amountAsset: amountAsset.name, priceAsset: priceAsset.name))) moduleOutput?.didCreateEmptyOrder(amountAsset: amountAsset, priceAsset: priceAsset, orderType: .buy, @@ -103,7 +104,7 @@ final class DexLastTradesPresenter: DexLastTradesPresenterProtocol { return state.changeAction(.none) case .didTapSell(let sell): - AnalyticManager.trackEvent(.dex(.sellTap(amountAsset: amountAsset.name, priceAsset: priceAsset.name))) + UseCasesFactory.instance.analyticManager.trackEvent(.dex(.sellTap(amountAsset: amountAsset.name, priceAsset: priceAsset.name))) moduleOutput?.didCreateOrder(sell, amountAsset: amountAsset, priceAsset: priceAsset, availableAmountAssetBalance: state.availableAmountAssetBalance, @@ -114,7 +115,7 @@ final class DexLastTradesPresenter: DexLastTradesPresenterProtocol { return state.changeAction(.none) case .didTapEmptySell: - AnalyticManager.trackEvent(.dex(.sellTap(amountAsset: amountAsset.name, priceAsset: priceAsset.name))) + UseCasesFactory.instance.analyticManager.trackEvent(.dex(.sellTap(amountAsset: amountAsset.name, priceAsset: priceAsset.name))) moduleOutput?.didCreateEmptyOrder(amountAsset: amountAsset, priceAsset: priceAsset, orderType: .sell, diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexLastTrades/Presenter/DexLastTradesPresenterProtocol.swift b/WavesWallet-iOS/Modules/Dex/DexLastTrades/Presenter/DexLastTradesPresenterProtocol.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexLastTrades/Presenter/DexLastTradesPresenterProtocol.swift rename to WavesWallet-iOS/Modules/Dex/DexLastTrades/Presenter/DexLastTradesPresenterProtocol.swift index 850cd4c5..e5f10a9b 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexLastTrades/Presenter/DexLastTradesPresenterProtocol.swift +++ b/WavesWallet-iOS/Modules/Dex/DexLastTrades/Presenter/DexLastTradesPresenterProtocol.swift @@ -8,6 +8,7 @@ import Foundation import RxCocoa +import DomainLayer protocol DexLastTradesPresenterProtocol { typealias Feedback = (Driver) -> Signal diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexLastTrades/Views/DexLastTradesCell.swift b/WavesWallet-iOS/Modules/Dex/DexLastTrades/Views/DexLastTradesCell.swift similarity index 96% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexLastTrades/Views/DexLastTradesCell.swift rename to WavesWallet-iOS/Modules/Dex/DexLastTrades/Views/DexLastTradesCell.swift index 004bb4d1..3099389a 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexLastTrades/Views/DexLastTradesCell.swift +++ b/WavesWallet-iOS/Modules/Dex/DexLastTrades/Views/DexLastTradesCell.swift @@ -7,6 +7,8 @@ // import UIKit +import DomainLayer +import Extensions final class DexLastTradesCell: UITableViewCell, Reusable { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexLastTrades/Views/DexLastTradesHeaderView.swift b/WavesWallet-iOS/Modules/Dex/DexLastTrades/Views/DexLastTradesHeaderView.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexLastTrades/Views/DexLastTradesHeaderView.swift rename to WavesWallet-iOS/Modules/Dex/DexLastTrades/Views/DexLastTradesHeaderView.swift index 8201eb08..6c48b65e 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexLastTrades/Views/DexLastTradesHeaderView.swift +++ b/WavesWallet-iOS/Modules/Dex/DexLastTrades/Views/DexLastTradesHeaderView.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions final class DexLastTradesHeaderView: DexTraderContainerBaseHeaderView, NibOwnerLoadable { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexLastTrades/Views/DexLastTradesHeaderView.xib b/WavesWallet-iOS/Modules/Dex/DexLastTrades/Views/DexLastTradesHeaderView.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexLastTrades/Views/DexLastTradesHeaderView.xib rename to WavesWallet-iOS/Modules/Dex/DexLastTrades/Views/DexLastTradesHeaderView.xib diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexList/DexListModuleBuilder.swift b/WavesWallet-iOS/Modules/Dex/DexList/DexListModuleBuilder.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexList/DexListModuleBuilder.swift rename to WavesWallet-iOS/Modules/Dex/DexList/DexListModuleBuilder.swift index c6ee28a2..9654cce5 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexList/DexListModuleBuilder.swift +++ b/WavesWallet-iOS/Modules/Dex/DexList/DexListModuleBuilder.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions struct DexListModuleBuilder: ModuleBuilderOutput { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexList/DexListModuleOutput.swift b/WavesWallet-iOS/Modules/Dex/DexList/DexListModuleOutput.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexList/DexListModuleOutput.swift rename to WavesWallet-iOS/Modules/Dex/DexList/DexListModuleOutput.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexList/DexListTypes.swift b/WavesWallet-iOS/Modules/Dex/DexList/DexListTypes.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexList/DexListTypes.swift rename to WavesWallet-iOS/Modules/Dex/DexList/DexListTypes.swift index 25b8d444..463a3b58 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexList/DexListTypes.swift +++ b/WavesWallet-iOS/Modules/Dex/DexList/DexListTypes.swift @@ -7,6 +7,9 @@ // import Foundation +import WavesSDK +import DomainLayer +import Extensions enum DexList { enum DTO {} diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexList/DexListViewController.swift b/WavesWallet-iOS/Modules/Dex/DexList/DexListViewController.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexList/DexListViewController.swift rename to WavesWallet-iOS/Modules/Dex/DexList/DexListViewController.swift index d4358490..187a098c 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexList/DexListViewController.swift +++ b/WavesWallet-iOS/Modules/Dex/DexList/DexListViewController.swift @@ -10,7 +10,8 @@ import UIKit import RxCocoa import RxFeedback import RxSwift - +import WavesSDK +import Extensions fileprivate enum Constants { static let contentInset = UIEdgeInsets.init(top: 8, left: 0, bottom: 0, right: 0) diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexList/Interactor/DexListInteractor.swift b/WavesWallet-iOS/Modules/Dex/DexList/Interactor/DexListInteractor.swift similarity index 90% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexList/Interactor/DexListInteractor.swift rename to WavesWallet-iOS/Modules/Dex/DexList/Interactor/DexListInteractor.swift index 8b776a09..9be6931d 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexList/Interactor/DexListInteractor.swift +++ b/WavesWallet-iOS/Modules/Dex/DexList/Interactor/DexListInteractor.swift @@ -8,13 +8,14 @@ import Foundation import RxSwift - +import WavesSDK +import DomainLayer final class DexListInteractor: DexListInteractorProtocol { - private let dexRealmRepository = FactoryRepositories.instance.dexRealmRepository - private let dexListRepository = FactoryRepositories.instance.dexPairsPriceRepository - private let auth = FactoryInteractors.instance.authorization + private let dexRealmRepository = UseCasesFactory.instance.repositories.dexRealmRepository + private let dexListRepository = UseCasesFactory.instance.repositories.dexPairsPriceRepository + private let auth = UseCasesFactory.instance.authorization func localPairs() -> Observable { @@ -47,7 +48,7 @@ final class DexListInteractor: DexListInteractorProtocol { let listPairs = pairs.map { DomainLayer.DTO.Dex.Pair(amountAsset: $0.amountAsset, priceAsset: $0.priceAsset)} //TODO: Move code to other method - return self.dexListRepository.list(by: wallet.address, pairs: listPairs) + return self.dexListRepository.list(pairs: listPairs) .flatMap({ (list) -> Observable> in var listPairs: [DexList.DTO.Pair] = [] @@ -58,8 +59,8 @@ final class DexListInteractor: DexListInteractorProtocol { let pair = DexList.DTO.Pair(id: localPair.id, firstPrice: pair.firstPrice, lastPrice: pair.lastPrice, - amountAsset: pair.amountAsset, - priceAsset: pair.priceAsset, + amountAsset: localPair.amountAsset, + priceAsset: localPair.priceAsset, isGeneral: localPair.isGeneral, sortLevel: localPair.sortLevel) listPairs.append(pair) diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexList/Interactor/DexListInteractorMock.swift b/WavesWallet-iOS/Modules/Dex/DexList/Interactor/DexListInteractorMock.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexList/Interactor/DexListInteractorMock.swift rename to WavesWallet-iOS/Modules/Dex/DexList/Interactor/DexListInteractorMock.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexList/Interactor/DexListInteractorProtocol.swift b/WavesWallet-iOS/Modules/Dex/DexList/Interactor/DexListInteractorProtocol.swift similarity index 95% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexList/Interactor/DexListInteractorProtocol.swift rename to WavesWallet-iOS/Modules/Dex/DexList/Interactor/DexListInteractorProtocol.swift index 14d7f55e..e16612f8 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexList/Interactor/DexListInteractorProtocol.swift +++ b/WavesWallet-iOS/Modules/Dex/DexList/Interactor/DexListInteractorProtocol.swift @@ -8,6 +8,7 @@ import Foundation import RxSwift +import DomainLayer protocol DexListInteractorProtocol { func pairs() -> Observable> diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexList/Presenter/DexListPresenter.swift b/WavesWallet-iOS/Modules/Dex/DexList/Presenter/DexListPresenter.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexList/Presenter/DexListPresenter.swift rename to WavesWallet-iOS/Modules/Dex/DexList/Presenter/DexListPresenter.swift index e114be94..560430e9 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexList/Presenter/DexListPresenter.swift +++ b/WavesWallet-iOS/Modules/Dex/DexList/Presenter/DexListPresenter.swift @@ -10,7 +10,7 @@ import Foundation import RxFeedback import RxSwift import RxCocoa - +import DomainLayer final class DexListPresenter: DexListPresenterProtocol { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexList/Presenter/DexListPresenterProtocol.swift b/WavesWallet-iOS/Modules/Dex/DexList/Presenter/DexListPresenterProtocol.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexList/Presenter/DexListPresenterProtocol.swift rename to WavesWallet-iOS/Modules/Dex/DexList/Presenter/DexListPresenterProtocol.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexList/Views/DexListCell.swift b/WavesWallet-iOS/Modules/Dex/DexList/Views/DexListCell.swift similarity index 73% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexList/Views/DexListCell.swift rename to WavesWallet-iOS/Modules/Dex/DexList/Views/DexListCell.swift index fa8ab787..63ea9001 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexList/Views/DexListCell.swift +++ b/WavesWallet-iOS/Modules/Dex/DexList/Views/DexListCell.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions final class DexListCell: UITableViewCell, Reusable { @@ -39,21 +40,27 @@ extension DexListCell: ViewConfiguration { let lastPrice = model.lastPrice.doubleValue labelValue.text = model.lastPrice.displayText + + var deltaPercent: Double { + if firstPrice > lastPrice { + return (firstPrice - lastPrice) * 100 + } + return (lastPrice - firstPrice) * 100 + } - let deltaPercent = (lastPrice - firstPrice) * 100 - let percent = deltaPercent != 0 ? deltaPercent / lastPrice : 0 + let percent = lastPrice != 0 ? deltaPercent / lastPrice : 0 - if percent == 0 { - iconArrow.image = Images.chartarrow22Accent100.image + if lastPrice > firstPrice { + iconArrow.image = Images.chartarrow22Success400.image labelPercent.text = String(format: "%.02f", percent) + "%" } - else if percent > 0 { - iconArrow.image = Images.chartarrow22Success400.image - labelPercent.text = "+ " + String(format: "%.02f", percent) + "%" + else if firstPrice > lastPrice { + iconArrow.image = Images.chartarrow22Error500.image + labelPercent.text = String(format: "%.02f", percent * -1) + "%" } else { - iconArrow.image = Images.chartarrow22Error500.image - labelPercent.text = "- " + String(format: "%.02f", percent * -1) + "%" + iconArrow.image = Images.chartarrow22Accent100.image + labelPercent.text = String(format: "%.02f", percent) + "%" } } } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexList/Views/DexListHeaderCell.swift b/WavesWallet-iOS/Modules/Dex/DexList/Views/DexListHeaderCell.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexList/Views/DexListHeaderCell.swift rename to WavesWallet-iOS/Modules/Dex/DexList/Views/DexListHeaderCell.swift index 46f92f63..dc30ddca 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexList/Views/DexListHeaderCell.swift +++ b/WavesWallet-iOS/Modules/Dex/DexList/Views/DexListHeaderCell.swift @@ -8,7 +8,7 @@ import UIKit import SwiftDate - +import Extensions final class DexListHeaderCell: UITableViewCell, Reusable { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexList/Views/DexListSkeletonCell.swift b/WavesWallet-iOS/Modules/Dex/DexList/Views/DexListSkeletonCell.swift similarity index 96% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexList/Views/DexListSkeletonCell.swift rename to WavesWallet-iOS/Modules/Dex/DexList/Views/DexListSkeletonCell.swift index c34c3bd8..f7528480 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexList/Views/DexListSkeletonCell.swift +++ b/WavesWallet-iOS/Modules/Dex/DexList/Views/DexListSkeletonCell.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions final class DexListSkeletonCell: SkeletonTableCell, Reusable { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMarket/DexMarketModuleBuilder.swift b/WavesWallet-iOS/Modules/Dex/DexMarket/DexMarketModuleBuilder.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMarket/DexMarketModuleBuilder.swift rename to WavesWallet-iOS/Modules/Dex/DexMarket/DexMarketModuleBuilder.swift index 7c26306d..c30c0323 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMarket/DexMarketModuleBuilder.swift +++ b/WavesWallet-iOS/Modules/Dex/DexMarket/DexMarketModuleBuilder.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions struct DexMarketModuleBuilder: ModuleBuilderOutput { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMarket/DexMarketModuleOutput.swift b/WavesWallet-iOS/Modules/Dex/DexMarket/DexMarketModuleOutput.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMarket/DexMarketModuleOutput.swift rename to WavesWallet-iOS/Modules/Dex/DexMarket/DexMarketModuleOutput.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMarket/DexMarketTypes.swift b/WavesWallet-iOS/Modules/Dex/DexMarket/DexMarketTypes.swift similarity index 65% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMarket/DexMarketTypes.swift rename to WavesWallet-iOS/Modules/Dex/DexMarket/DexMarketTypes.swift index 0d6ea4ec..48cc25cc 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMarket/DexMarketTypes.swift +++ b/WavesWallet-iOS/Modules/Dex/DexMarket/DexMarketTypes.swift @@ -7,11 +7,9 @@ // import Foundation +import DomainLayer +import Extensions -private enum Constants { - static let MinersRewardToken = ["4uK8i4ThRGbehENwa6MxyLtxAjAo1Rj9fduborGExarC" : "MRT"] - static let WavesCommunityToken = ["DHgwrRvVyqJsepd32YbBqUeDH4GJ1N984X8QoekjgH8J" : "WCT"] -} enum DexMarket { enum ViewModel {} @@ -32,6 +30,9 @@ enum DexMarket { var action: Action var section: DexMarket.ViewModel.Section + var searchKey: String + var isNeedSearching: Bool + var isNeedLoadDefaultPairs: Bool } } @@ -47,12 +48,10 @@ extension DexMarket.ViewModel { } -extension DexMarket { - static var MinersRewardToken: [String : String] { - return Constants.MinersRewardToken - } - - static var WavesCommunityToken: [String : String] { - return Constants.WavesCommunityToken +extension DexMarket.State: Equatable { + static func == (lhs: DexMarket.State, rhs: DexMarket.State) -> Bool { + return lhs.isNeedSearching == rhs.isNeedSearching && + lhs.searchKey == rhs.searchKey && + lhs.isNeedLoadDefaultPairs == rhs.isNeedLoadDefaultPairs } } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMarket/DexMarketViewController.swift b/WavesWallet-iOS/Modules/Dex/DexMarket/DexMarketViewController.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMarket/DexMarketViewController.swift rename to WavesWallet-iOS/Modules/Dex/DexMarket/DexMarketViewController.swift index ef20da1c..46ac5c52 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMarket/DexMarketViewController.swift +++ b/WavesWallet-iOS/Modules/Dex/DexMarket/DexMarketViewController.swift @@ -56,7 +56,7 @@ final class DexMarketViewController: UIViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) setupSmallNavigationBar() - hideTopBarLine() + removeTopBarLine() navigationItem.isTranslucent = false } } diff --git a/WavesWallet-iOS/Modules/Dex/DexMarket/Interactor/DexMarketInteractor.swift b/WavesWallet-iOS/Modules/Dex/DexMarket/Interactor/DexMarketInteractor.swift new file mode 100644 index 00000000..67ecd0dd --- /dev/null +++ b/WavesWallet-iOS/Modules/Dex/DexMarket/Interactor/DexMarketInteractor.swift @@ -0,0 +1,258 @@ +import Foundation +import RxSwift +import DomainLayer +import DataLayer +import Extensions +import WavesSDK + +private enum Constants { + static let firstGeneralAssets = 4 + + static let liquidToken = "7FzrHF1pueRFrPEupz6oiVGTUZqe8epvC7ggWUx8n1bd" + static let wctToken = "DHgwrRvVyqJsepd32YbBqUeDH4GJ1N984X8QoekjgH8J" + static let mrtToken = "4uK8i4ThRGbehENwa6MxyLtxAjAo1Rj9fduborGExarC" +} + +final class DexMarketInteractor: DexMarketInteractorProtocol { + + private static var allPairs: [DomainLayer.DTO.Dex.SmartPair] = [] + private static var spamURL = "" + + private let disposeBag: DisposeBag = DisposeBag() + + private let dexRealmRepository: DexRealmRepositoryProtocol = UseCasesFactory.instance.repositories.dexRealmRepository + private let auth = UseCasesFactory.instance.authorization + + private let environment = UseCasesFactory.instance.repositories.environmentRepository + private let orderBookRepository = UseCasesFactory.instance.repositories.dexOrderBookRepository + + private let dexPairsPriceRepository: DexPairsPriceRepositoryProtocol = UseCasesFactory.instance.repositories.dexPairsPriceRepository + private let assetsInteractor: AssetsUseCaseProtocol = UseCasesFactory.instance.assets + private let assetsRepository: AssetsRepositoryProtocol = UseCasesFactory.instance.repositories.assetsRepositoryRemote + private let correctionPairsUseCase: CorrectionPairsUseCaseProtocol = UseCasesFactory.instance.correctionPairsUseCase + + func pairs() -> Observable<[DomainLayer.DTO.Dex.SmartPair]> { + + return auth.authorizedWallet().flatMap({ [weak self] (wallet) -> Observable<[DomainLayer.DTO.Dex.SmartPair]> in + + guard let self = self else { return Observable.empty() } + + return self.environment.walletEnvironment().flatMap({ [weak self] (environment) -> Observable<[DomainLayer.DTO.Dex.SmartPair]> in + + guard let self = self else { return Observable.empty() } + return self.defaultPairs(wallet: wallet, environment: environment) + }) + }) + } + + func searchPairs(searchWord: String) -> Observable<[DomainLayer.DTO.Dex.SmartPair]> { + + var words = searchWord.components(separatedBy: "/").filter {$0.count > 0} + .map{$0.trimmingCharacters(in: .whitespaces)} + + if words.count <= 1 { + words = searchWord.replacingOccurrences(of: "/", with: "") + .components(separatedBy: "\\").filter {$0.count > 0} + .map{$0.trimmingCharacters(in: .whitespaces)} + } + + return Observable.zip(auth.authorizedWallet(), environment.walletEnvironment()) + .flatMap{ [weak self] (wallet, environment) -> Observable<[DomainLayer.DTO.Dex.SmartPair]> in + guard let self = self else { return Observable.empty() } + + if words.count == 1 { + + var generalIds = environment.generalAssets.map { $0.assetId } + generalIds.append(Constants.wctToken) + generalIds.append(Constants.mrtToken) + generalIds.append(Constants.liquidToken) + + let generalAssetsObserver = self.assetsInteractor.assets(by: generalIds, accountAddress: wallet.address) + let assetsObserver = self.assetsRepository.searchAssets(search: words[0]) + + return self.searchPairs(firstSearchAssets: assetsObserver, secondSearchAssets: generalAssetsObserver, address: wallet.address) + } + else if words.count > 1 { + let firstAssetsObserver = self.assetsRepository.searchAssets(search: words[0]) + let secondsAssetsObserver = self.assetsRepository.searchAssets(search: words[1]) + + return self.searchPairs(firstSearchAssets: firstAssetsObserver, secondSearchAssets: secondsAssetsObserver, address: wallet.address) + } + return Observable.just([]) + } + .catchError({ (error) -> Observable<[DomainLayer.DTO.Dex.SmartPair]> in + return Observable.just([]) + }) + + } + + func checkMark(pair: DomainLayer.DTO.Dex.SmartPair) { + + var newPair = pair + newPair.isChecked = !pair.isChecked + + auth.authorizedWallet().flatMap { [weak self] wallet -> Observable in + + guard let self = self else { return Observable.never() } + + if newPair.isChecked { + return self.dexRealmRepository.save(pair: newPair, accountAddress: wallet.address) + } + return self.dexRealmRepository.delete(by: newPair.id, accountAddress: wallet.address) + + }.subscribe().disposed(by: disposeBag) + } +} + +//MARK: - Load data +private extension DexMarketInteractor { + + func searchPairs(firstSearchAssets: Observable<[DomainLayer.DTO.Asset]>, secondSearchAssets: Observable<[DomainLayer.DTO.Asset]>, address: String) -> Observable<[DomainLayer.DTO.Dex.SmartPair]> { + + return Observable.zip(firstSearchAssets, secondSearchAssets) + .flatMap{ [weak self] (firstAssets, secondAssets) -> Observable<[DomainLayer.DTO.Dex.SmartPair]> in + guard let self = self else { return Observable.empty() } + + return self.correctionAndSearchPairs(firstAssets: firstAssets.filter {$0.isSpam == false}, + secondAssets: secondAssets.filter {$0.isSpam == false}, + address: address) + } + } + + func correctionAndSearchPairs(firstAssets: [DomainLayer.DTO.Asset], secondAssets: [DomainLayer.DTO.Asset], address: String) -> Observable<[DomainLayer.DTO.Dex.SmartPair]> { + + var pairs: [DomainLayer.DTO.CorrectionPairs.Pair] = [] + let allAssets = firstAssets + secondAssets + + for asset in firstAssets { + for secondAsset in secondAssets { + if asset.id != secondAsset.id { + pairs.append(.init(amountAsset: asset.id, priceAsset: secondAsset.id)) + } + } + } + + return self.correctionPairsUseCase.correction(pairs: pairs) + .flatMap{ [weak self] correctionPairs -> Observable<[DomainLayer.DTO.Dex.SmartPair]> in + guard let self = self else { return Observable.empty() } + + let searchQueryPairs = correctionPairs.map{ DomainLayer.Query.Dex.SearchPairs.Pair(amountAsset: $0.amountAsset, + priceAsset: $0.priceAsset) } + + let searchPairsObserver = self.dexPairsPriceRepository.searchPairs(.init(kind: .pairs(searchQueryPairs))) + let localPairsObserver = self.dexRealmRepository.list(by: address) + + return Observable.zip(searchPairsObserver, localPairsObserver) + .map{ pairsSearch, localPairs -> [DomainLayer.DTO.Dex.SmartPair] in + + struct SmartVolumePair { + let smartPair: DomainLayer.DTO.Dex.SmartPair + let volume: Double + } + var smartPairs: [SmartVolumePair] = [] + + for (index, queryPair) in searchQueryPairs.enumerated() { + + guard let amountAsset = allAssets.first(where: {$0.id == queryPair.amountAsset}) else { break } + guard let priceAsset = allAssets.first(where: {$0.id == queryPair.priceAsset}) else { break } + + guard index < pairsSearch.pairs.count else { continue } + + let volume = pairsSearch.pairs[index]?.volumeWaves ?? 0 + let localPair = localPairs.first(where: {$0.amountAsset.id == amountAsset.id && + $0.priceAsset.id == priceAsset.id}) + + let isGeneralAmount = allAssets.first(where: {$0.id == amountAsset.id})?.isGeneral ?? false + let isGeneralPrice = allAssets.first(where: {$0.id == priceAsset.id})?.isGeneral ?? false + let isGeneral = isGeneralAmount && isGeneralPrice + + let dexAmountAsset = DomainLayer.DTO.Dex.Asset(id: amountAsset.id, + name: amountAsset.displayName, + shortName: amountAsset.ticker ?? amountAsset.displayName, + decimals: amountAsset.precision) + + let dexPriceAsset = DomainLayer.DTO.Dex.Asset(id: priceAsset.id, + name: priceAsset.displayName, + shortName: priceAsset.ticker ?? priceAsset.displayName, + decimals: priceAsset.precision) + + smartPairs.append(.init(smartPair: .init(amountAsset: dexAmountAsset, + priceAsset: dexPriceAsset, + isChecked: localPair?.isChecked ?? false, + isGeneral: isGeneral, + sortLevel: localPair?.sortLevel ?? 0), + volume: volume)) + + } + + + smartPairs.sort(by: {$0.volume > $1.volume}) + + return smartPairs.map {$0.smartPair} + } + } + } + + func defaultPairs(wallet: DomainLayer.DTO.SignedWallet, environment: WalletEnvironment) -> Observable<[DomainLayer.DTO.Dex.SmartPair]> { + + let spamURL = environment.servers.spamUrl.relativeString + + if DexMarketInteractor.allPairs.count > 0 && + spamURL == DexMarketInteractor.spamURL { + return dexRealmRepository.checkmark(pairs: DexMarketInteractor.allPairs, accountAddress: wallet.address) + } + + let allGeneralAssets = environment.generalAssets + let firstGeneralAssets = environment.generalAssets.prefix(Constants.firstGeneralAssets) + + var searchPairs: [DomainLayer.DTO.Dex.SimplePair] = [] + + for asset in allGeneralAssets { + for nextAsset in firstGeneralAssets { + if asset.assetId != nextAsset.assetId { + searchPairs.append(.init(amountAsset: asset.assetId, priceAsset: nextAsset.assetId)) + } + } + } + + return assetsInteractor.assets(by: allGeneralAssets.map { $0.assetId }, accountAddress: wallet.address) + .flatMap({ [weak self] (assets) -> Observable<[DomainLayer.DTO.Dex.SmartPair]> in + guard let self = self else { return Observable.empty() } + + var dexPairs: [DomainLayer.DTO.Dex.Pair] = [] + for pair in searchPairs { + + if let amountAsset = assets.first(where: {$0.id == pair.amountAsset}), + let priceAsset = assets.first(where: {$0.id == pair.priceAsset}) { + + let dexAmountAsset = DomainLayer.DTO.Dex.Asset(id: amountAsset.id, + name: amountAsset.displayName, + shortName: amountAsset.ticker ?? amountAsset.displayName, + decimals: amountAsset.precision) + + let dexPriceAsset = DomainLayer.DTO.Dex.Asset(id: priceAsset.id, + name: priceAsset.displayName, + shortName: priceAsset.ticker ?? priceAsset.displayName, + decimals: priceAsset.precision) + + + dexPairs.append(.init(amountAsset: dexAmountAsset, priceAsset: dexPriceAsset)) + } + } + + return self.orderBookRepository.markets(wallet: wallet, pairs: dexPairs) + .map({ (smartPairs) -> [DomainLayer.DTO.Dex.SmartPair] in + + DexMarketInteractor.allPairs = smartPairs + DexMarketInteractor.spamURL = spamURL + + return smartPairs + }) + }) + .catchError({ (error) -> Observable<[DomainLayer.DTO.Dex.SmartPair]> in + return Observable.just([]) + }) + } +} + + diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMarket/Interactor/DexMarketInteractorMock.swift b/WavesWallet-iOS/Modules/Dex/DexMarket/Interactor/DexMarketInteractorMock.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMarket/Interactor/DexMarketInteractorMock.swift rename to WavesWallet-iOS/Modules/Dex/DexMarket/Interactor/DexMarketInteractorMock.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMarket/Interactor/DexMarketInteractorProtocol.swift b/WavesWallet-iOS/Modules/Dex/DexMarket/Interactor/DexMarketInteractorProtocol.swift similarity index 76% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMarket/Interactor/DexMarketInteractorProtocol.swift rename to WavesWallet-iOS/Modules/Dex/DexMarket/Interactor/DexMarketInteractorProtocol.swift index 8f9062ed..ced33058 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMarket/Interactor/DexMarketInteractorProtocol.swift +++ b/WavesWallet-iOS/Modules/Dex/DexMarket/Interactor/DexMarketInteractorProtocol.swift @@ -8,11 +8,11 @@ import Foundation import RxSwift +import DomainLayer protocol DexMarketInteractorProtocol { func pairs() -> Observable<[DomainLayer.DTO.Dex.SmartPair]> - func searchPairs() -> Observable<[DomainLayer.DTO.Dex.SmartPair]> + func searchPairs(searchWord: String) -> Observable<[DomainLayer.DTO.Dex.SmartPair]> func checkMark(pair: DomainLayer.DTO.Dex.SmartPair) - func searchPair(searchText: String) } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMarket/Presenter/DexMarketPresenter.swift b/WavesWallet-iOS/Modules/Dex/DexMarket/Presenter/DexMarketPresenter.swift similarity index 76% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMarket/Presenter/DexMarketPresenter.swift rename to WavesWallet-iOS/Modules/Dex/DexMarket/Presenter/DexMarketPresenter.swift index 8ac31e0c..1cd76cf1 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMarket/Presenter/DexMarketPresenter.swift +++ b/WavesWallet-iOS/Modules/Dex/DexMarket/Presenter/DexMarketPresenter.swift @@ -10,7 +10,7 @@ import Foundation import RxSwift import RxFeedback import RxCocoa - +import DomainLayer final class DexMarketPresenter: DexMarketPresenterProtocol { @@ -34,8 +34,8 @@ final class DexMarketPresenter: DexMarketPresenterProtocol { } private func modelsQuery() -> Feedback { - return react(request: { state -> Bool? in - return true + return react(request: { state -> DexMarket.State? in + return state.isNeedLoadDefaultPairs ? state : nil }, effects: { [weak self] _ -> Signal in guard let self = self else { return Signal.empty() } @@ -44,12 +44,13 @@ final class DexMarketPresenter: DexMarketPresenterProtocol { } private func searchModelsQuery() -> Feedback { - return react(request: { state -> Bool? in - return true - }, effects: { [weak self] _ -> Signal in + return react(request: { state -> DexMarket.State? in + return state.isNeedSearching ? state : nil + }, effects: { [weak self] state -> Signal in guard let self = self else { return Signal.empty() } - return self.interactor.searchPairs().map { .setPairs($0) }.asSignal(onErrorSignalWith: Signal.empty()) + return self.interactor.searchPairs(searchWord: state.searchKey) + .map { .setPairs($0) }.asSignal(onErrorSignalWith: Signal.empty()) }) } @@ -66,7 +67,8 @@ final class DexMarketPresenter: DexMarketPresenterProtocol { let items = pairs.map { DexMarket.ViewModel.Row.pair($0) } let section = DexMarket.ViewModel.Section(items: items) state.section = section - + state.isNeedSearching = false + state.isNeedLoadDefaultPairs = false }.changeAction(.update) case .tapCheckMark(let index): @@ -91,9 +93,11 @@ final class DexMarketPresenter: DexMarketPresenterProtocol { return state.changeAction(.none) case .searchTextChange(let text): - - interactor.searchPair(searchText: text) - return state.changeAction(.none) + return state.mutate { + $0.isNeedSearching = text.count > 0 + $0.isNeedLoadDefaultPairs = text.count == 0 + $0.searchKey = text + }.changeAction(.none) } } } @@ -111,7 +115,11 @@ fileprivate extension DexMarket.ViewModel.Row { fileprivate extension DexMarket.State { static var initialState: DexMarket.State { let section = DexMarket.ViewModel.Section(items: []) - return DexMarket.State(action: .none, section: section) + return DexMarket.State(action: .none, + section: section, + searchKey: "", + isNeedSearching: false, + isNeedLoadDefaultPairs: true) } func changeAction(_ action: DexMarket.State.Action) -> DexMarket.State { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMarket/Presenter/DexMarketPresenterProtocol.swift b/WavesWallet-iOS/Modules/Dex/DexMarket/Presenter/DexMarketPresenterProtocol.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMarket/Presenter/DexMarketPresenterProtocol.swift rename to WavesWallet-iOS/Modules/Dex/DexMarket/Presenter/DexMarketPresenterProtocol.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMarket/TestDataFiles/DexMarketPairs.json b/WavesWallet-iOS/Modules/Dex/DexMarket/TestDataFiles/DexMarketPairs.json similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMarket/TestDataFiles/DexMarketPairs.json rename to WavesWallet-iOS/Modules/Dex/DexMarket/TestDataFiles/DexMarketPairs.json diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMarket/TestDataFiles/DexMarketVerifiedAssets.json b/WavesWallet-iOS/Modules/Dex/DexMarket/TestDataFiles/DexMarketVerifiedAssets.json similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMarket/TestDataFiles/DexMarketVerifiedAssets.json rename to WavesWallet-iOS/Modules/Dex/DexMarket/TestDataFiles/DexMarketVerifiedAssets.json diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMarket/Views/DexMarketCell.swift b/WavesWallet-iOS/Modules/Dex/DexMarket/Views/DexMarketCell.swift similarity index 96% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMarket/Views/DexMarketCell.swift rename to WavesWallet-iOS/Modules/Dex/DexMarket/Views/DexMarketCell.swift index 77890034..500cb51a 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMarket/Views/DexMarketCell.swift +++ b/WavesWallet-iOS/Modules/Dex/DexMarket/Views/DexMarketCell.swift @@ -7,6 +7,8 @@ // import UIKit +import DomainLayer +import Extensions final class DexMarketCell: UITableViewCell, Reusable { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMyOrders/DexMyOrdersModuleBuilder.swift b/WavesWallet-iOS/Modules/Dex/DexMyOrders/DexMyOrdersModuleBuilder.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMyOrders/DexMyOrdersModuleBuilder.swift rename to WavesWallet-iOS/Modules/Dex/DexMyOrders/DexMyOrdersModuleBuilder.swift index 5759b0d1..c1222fab 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMyOrders/DexMyOrdersModuleBuilder.swift +++ b/WavesWallet-iOS/Modules/Dex/DexMyOrders/DexMyOrdersModuleBuilder.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions struct DexMyOrdersModuleBuilder: ModuleBuilderOutput { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMyOrders/DexMyOrdersModuleOutput.swift b/WavesWallet-iOS/Modules/Dex/DexMyOrders/DexMyOrdersModuleOutput.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMyOrders/DexMyOrdersModuleOutput.swift rename to WavesWallet-iOS/Modules/Dex/DexMyOrders/DexMyOrdersModuleOutput.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMyOrders/DexMyOrdersTypes.swift b/WavesWallet-iOS/Modules/Dex/DexMyOrders/DexMyOrdersTypes.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMyOrders/DexMyOrdersTypes.swift rename to WavesWallet-iOS/Modules/Dex/DexMyOrders/DexMyOrdersTypes.swift index ba65a15a..9df38d02 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMyOrders/DexMyOrdersTypes.swift +++ b/WavesWallet-iOS/Modules/Dex/DexMyOrders/DexMyOrdersTypes.swift @@ -7,6 +7,8 @@ // import Foundation +import DomainLayer +import Extensions enum DexMyOrders { enum DTO {} diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMyOrders/DexMyOrdersViewController.swift b/WavesWallet-iOS/Modules/Dex/DexMyOrders/DexMyOrdersViewController.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMyOrders/DexMyOrdersViewController.swift rename to WavesWallet-iOS/Modules/Dex/DexMyOrders/DexMyOrdersViewController.swift index e269b595..0eff2e4d 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMyOrders/DexMyOrdersViewController.swift +++ b/WavesWallet-iOS/Modules/Dex/DexMyOrders/DexMyOrdersViewController.swift @@ -10,6 +10,7 @@ import UIKit import RxSwift import RxCocoa import RxFeedback +import DomainLayer fileprivate enum Constants { static let cornerTableRadius: CGFloat = 3 @@ -60,7 +61,7 @@ final class DexMyOrdersViewController: UIViewController { let nav = NavigationRouter(navigationController: navigationController) let coordinator = TransactionCardCoordinator(kind: .order(order), router: nav) - //TODO: Fix + //TODO: Move code to parent Coordinat self.navigationRouter = nav self.transactionCardCoordinator = coordinator coordinator.delegate = self diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMyOrders/Interactor/DexMyOrdersInteractor.swift b/WavesWallet-iOS/Modules/Dex/DexMyOrders/Interactor/DexMyOrdersInteractor.swift similarity index 85% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMyOrders/Interactor/DexMyOrdersInteractor.swift rename to WavesWallet-iOS/Modules/Dex/DexMyOrders/Interactor/DexMyOrdersInteractor.swift index fc5f74ef..ca0cef7b 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMyOrders/Interactor/DexMyOrdersInteractor.swift +++ b/WavesWallet-iOS/Modules/Dex/DexMyOrders/Interactor/DexMyOrdersInteractor.swift @@ -8,11 +8,12 @@ import Foundation import RxSwift +import DomainLayer final class DexMyOrdersInteractor: DexMyOrdersInteractorProtocol { - private let auth = FactoryInteractors.instance.authorization - private let repository = FactoryRepositories.instance.dexOrderBookRepository + private let auth = UseCasesFactory.instance.authorization + private let repository = UseCasesFactory.instance.repositories.dexOrderBookRepository var pair: DexTraderContainer.DTO.Pair! diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMyOrders/Interactor/DexMyOrdersInteractorMock.swift b/WavesWallet-iOS/Modules/Dex/DexMyOrders/Interactor/DexMyOrdersInteractorMock.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMyOrders/Interactor/DexMyOrdersInteractorMock.swift rename to WavesWallet-iOS/Modules/Dex/DexMyOrders/Interactor/DexMyOrdersInteractorMock.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMyOrders/Interactor/DexMyOrdersInteractorProtocol.swift b/WavesWallet-iOS/Modules/Dex/DexMyOrders/Interactor/DexMyOrdersInteractorProtocol.swift similarity index 95% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMyOrders/Interactor/DexMyOrdersInteractorProtocol.swift rename to WavesWallet-iOS/Modules/Dex/DexMyOrders/Interactor/DexMyOrdersInteractorProtocol.swift index 751f8feb..435e3872 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMyOrders/Interactor/DexMyOrdersInteractorProtocol.swift +++ b/WavesWallet-iOS/Modules/Dex/DexMyOrders/Interactor/DexMyOrdersInteractorProtocol.swift @@ -8,6 +8,7 @@ import Foundation import RxSwift +import DomainLayer protocol DexMyOrdersInteractorProtocol { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMyOrders/Presenter/DexMyOrdersPresenter.swift b/WavesWallet-iOS/Modules/Dex/DexMyOrders/Presenter/DexMyOrdersPresenter.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMyOrders/Presenter/DexMyOrdersPresenter.swift rename to WavesWallet-iOS/Modules/Dex/DexMyOrders/Presenter/DexMyOrdersPresenter.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMyOrders/Presenter/DexMyOrdersPresenterProtocol.swift b/WavesWallet-iOS/Modules/Dex/DexMyOrders/Presenter/DexMyOrdersPresenterProtocol.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMyOrders/Presenter/DexMyOrdersPresenterProtocol.swift rename to WavesWallet-iOS/Modules/Dex/DexMyOrders/Presenter/DexMyOrdersPresenterProtocol.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMyOrders/Views/DexMyOrdersCell.swift b/WavesWallet-iOS/Modules/Dex/DexMyOrders/Views/DexMyOrdersCell.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMyOrders/Views/DexMyOrdersCell.swift rename to WavesWallet-iOS/Modules/Dex/DexMyOrders/Views/DexMyOrdersCell.swift index bc1238ee..3edfe64e 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMyOrders/Views/DexMyOrdersCell.swift +++ b/WavesWallet-iOS/Modules/Dex/DexMyOrders/Views/DexMyOrdersCell.swift @@ -7,6 +7,8 @@ // import UIKit +import DomainLayer +import Extensions private enum Constants { static let cancelAlpha: CGFloat = 0.45 diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMyOrders/Views/DexMyOrdersHeaderView.swift b/WavesWallet-iOS/Modules/Dex/DexMyOrders/Views/DexMyOrdersHeaderView.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMyOrders/Views/DexMyOrdersHeaderView.swift rename to WavesWallet-iOS/Modules/Dex/DexMyOrders/Views/DexMyOrdersHeaderView.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMyOrders/Views/DexMyOrdersHeaderView.xib b/WavesWallet-iOS/Modules/Dex/DexMyOrders/Views/DexMyOrdersHeaderView.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexMyOrders/Views/DexMyOrdersHeaderView.xib rename to WavesWallet-iOS/Modules/Dex/DexMyOrders/Views/DexMyOrdersHeaderView.xib diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/DexOrderBookModuleBuilder.swift b/WavesWallet-iOS/Modules/Dex/DexOrderBook/DexOrderBookModuleBuilder.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/DexOrderBookModuleBuilder.swift rename to WavesWallet-iOS/Modules/Dex/DexOrderBook/DexOrderBookModuleBuilder.swift index d29caad2..7addf2ac 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/DexOrderBookModuleBuilder.swift +++ b/WavesWallet-iOS/Modules/Dex/DexOrderBook/DexOrderBookModuleBuilder.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions struct DexOrderBookModuleBuilder: ModuleBuilderOutput { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/DexOrderBookModuleOutput.swift b/WavesWallet-iOS/Modules/Dex/DexOrderBook/DexOrderBookModuleOutput.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/DexOrderBookModuleOutput.swift rename to WavesWallet-iOS/Modules/Dex/DexOrderBook/DexOrderBookModuleOutput.swift index 7ef52ab5..d3c40f15 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/DexOrderBookModuleOutput.swift +++ b/WavesWallet-iOS/Modules/Dex/DexOrderBook/DexOrderBookModuleOutput.swift @@ -7,6 +7,8 @@ // import Foundation +import Extensions +import DomainLayer protocol DexOrderBookModuleOutput: AnyObject { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/DexOrderBookTypes.swift b/WavesWallet-iOS/Modules/Dex/DexOrderBook/DexOrderBookTypes.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/DexOrderBookTypes.swift rename to WavesWallet-iOS/Modules/Dex/DexOrderBook/DexOrderBookTypes.swift index 35b8ebff..c83b449d 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/DexOrderBookTypes.swift +++ b/WavesWallet-iOS/Modules/Dex/DexOrderBook/DexOrderBookTypes.swift @@ -7,6 +7,8 @@ // import Foundation +import Extensions +import DomainLayer enum DexOrderBook { enum DTO {} @@ -169,7 +171,7 @@ extension DexOrderBook.State { } var lastPriceSection: Int? { - return sections.index(where: {$0.items.filter({$0.lastPrice != nil}).count > 0}) + return sections.firstIndex(where: {$0.items.filter({$0.lastPrice != nil}).count > 0}) } } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/DexOrderBookViewController.swift b/WavesWallet-iOS/Modules/Dex/DexOrderBook/DexOrderBookViewController.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/DexOrderBookViewController.swift rename to WavesWallet-iOS/Modules/Dex/DexOrderBook/DexOrderBookViewController.swift index 47a1395e..cb2fe18c 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/DexOrderBookViewController.swift +++ b/WavesWallet-iOS/Modules/Dex/DexOrderBook/DexOrderBookViewController.swift @@ -10,6 +10,7 @@ import UIKit import RxSwift import RxCocoa import RxFeedback +import Extensions private enum Constansts { static let emptyButtonsTitle: String = "0.000" diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/Interactor/DexOrderBookInteractor.swift b/WavesWallet-iOS/Modules/Dex/DexOrderBook/Interactor/DexOrderBookInteractor.swift similarity index 70% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/Interactor/DexOrderBookInteractor.swift rename to WavesWallet-iOS/Modules/Dex/DexOrderBook/Interactor/DexOrderBookInteractor.swift index 73be9dc5..47d47f3a 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/Interactor/DexOrderBookInteractor.swift +++ b/WavesWallet-iOS/Modules/Dex/DexOrderBook/Interactor/DexOrderBookInteractor.swift @@ -8,9 +8,10 @@ import Foundation import RxSwift -import Moya -import WavesSDKExtension -import WavesSDKCrypto +import WavesSDKExtensions +import WavesSDK +import DomainLayer +import Extensions private enum Constants { static let maxPercent: Float = 99.99 @@ -18,12 +19,12 @@ private enum Constants { final class DexOrderBookInteractor: DexOrderBookInteractorProtocol { - private let account = FactoryInteractors.instance.accountBalance - private let orderBookRepository = FactoryRepositories.instance.dexOrderBookRepository - private let lastTradesRepository = FactoryRepositories.instance.lastTradesRespository - private let auth = FactoryInteractors.instance.authorization - private let assetsInteractor = FactoryInteractors.instance.assetsInteractor - private let assetsRepositoryLocal = FactoryRepositories.instance.assetsRepositoryLocal + private let account = UseCasesFactory.instance.accountBalance + private let orderBookRepository = UseCasesFactory.instance.repositories.dexOrderBookRepository + private let lastTradesRepository = UseCasesFactory.instance.repositories.lastTradesRespository + private let auth = UseCasesFactory.instance.authorization + private let assetsInteractor = UseCasesFactory.instance.assets + private let assetsRepositoryLocal = UseCasesFactory.instance.repositories.assetsRepositoryLocal var pair: DexTraderContainer.DTO.Pair! @@ -39,39 +40,31 @@ final class DexOrderBookInteractor: DexOrderBookInteractorProtocol { header: header, availablePriceAssetBalance: Money(0, self.pair.priceAsset.decimals), availableAmountAssetBalance: Money(0, self.pair.amountAsset.decimals), - availableWavesBalance: Money(0, WavesSDKCryptoConstants.WavesDecimals), + availableWavesBalance: Money(0, WavesSDKConstants.WavesDecimals), scriptedAssets: []) - return auth.authorizedWallet().flatMap({ [weak self] (wallet) -> Observable in - guard let self = self else { return Observable.empty() } - - return Observable.zip(self.account.balances(), - self.getLastTransactionInfo(), - self.orderBookRepository.orderBook(wallet: wallet, - amountAsset: self.pair.amountAsset.id, - priceAsset: self.pair.priceAsset.id), - self.getScriptedAssets()) - .flatMap({ [weak self] ( - balances, - lastTransaction, - orderBook, - scriptedAssets) -> Observable in - - guard let self = self else { return Observable.empty() } - return Observable.just(self.getDisplayData(info: orderBook, - lastTransactionInfo: lastTransaction, - header: header, - balances: balances, - scriptedAssets: scriptedAssets)) - }) - .catchError({ (error) -> Observable in - return Observable.just(DexOrderBook.DTO.DisplayData(data: emptyData, authWalletError: false)) - }) - }) - .catchError({ (error) -> Observable in - return Observable.just(DexOrderBook.DTO.DisplayData(data: emptyData, authWalletError: true)) - }) + return Observable.zip(self.account.balances(), + self.getLastTransactionInfo(), + self.orderBookRepository.orderBook(amountAsset: self.pair.amountAsset.id, + priceAsset: self.pair.priceAsset.id), + self.getScriptedAssets()) + .flatMap({ [weak self] ( + balances, + lastTransaction, + orderBook, + scriptedAssets) -> Observable in + + guard let self = self else { return Observable.empty() } + return Observable.just(self.getDisplayData(info: orderBook, + lastTransactionInfo: lastTransaction, + header: header, + balances: balances, + scriptedAssets: scriptedAssets)) + }) + .catchError({ (error) -> Observable in + return Observable.just(DexOrderBook.DTO.DisplayData(data: emptyData, authWalletError: false)) + }) } } @@ -152,7 +145,7 @@ private extension DexOrderBookInteractor { var amountAssetBalance = Money(0, pair.amountAsset.decimals) var priceAssetBalance = Money(0, pair.priceAsset.decimals) - var wavesBalance = Money(0, WavesSDKCryptoConstants.WavesDecimals) + var wavesBalance = Money(0, WavesSDKConstants.WavesDecimals) if let amountAsset = balances.first(where: {$0.assetId == pair.amountAsset.id}) { amountAssetBalance = Money(amountAsset.availableBalance, amountAsset.asset.precision) @@ -177,16 +170,12 @@ private extension DexOrderBookInteractor { func getLastTransactionInfo() -> Observable { - return auth.authorizedWallet().flatMap({ [weak self] (wallet) -> Observable in - guard let self = self else { return Observable.empty() } - return self.lastTradesRepository.lastTrades(accountAddress: wallet.address, - amountAsset: self.pair.amountAsset, - priceAsset: self.pair.priceAsset, - limit: 1) + return lastTradesRepository.lastTrades(amountAsset: pair.amountAsset, + priceAsset: pair.priceAsset, + limit: 1) .flatMap({ (lastTrades) -> Observable in return Observable.just(lastTrades.first) }) - }) } func getScriptedAssets() -> Observable<[DomainLayer.DTO.Asset]> { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/Interactor/DexOrderBookInteractorProtocol.swift b/WavesWallet-iOS/Modules/Dex/DexOrderBook/Interactor/DexOrderBookInteractorProtocol.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/Interactor/DexOrderBookInteractorProtocol.swift rename to WavesWallet-iOS/Modules/Dex/DexOrderBook/Interactor/DexOrderBookInteractorProtocol.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/Presenter/DexOrderBookPresenter.swift b/WavesWallet-iOS/Modules/Dex/DexOrderBook/Presenter/DexOrderBookPresenter.swift similarity index 92% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/Presenter/DexOrderBookPresenter.swift rename to WavesWallet-iOS/Modules/Dex/DexOrderBook/Presenter/DexOrderBookPresenter.swift index 90e673e6..04edad40 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/Presenter/DexOrderBookPresenter.swift +++ b/WavesWallet-iOS/Modules/Dex/DexOrderBook/Presenter/DexOrderBookPresenter.swift @@ -10,7 +10,7 @@ import Foundation import RxSwift import RxFeedback import RxCocoa - +import DomainLayer final class DexOrderBookPresenter: DexOrderBookPresenterProtocol { @@ -113,7 +113,7 @@ final class DexOrderBookPresenter: DexOrderBookPresenterProtocol { case .didTapBid(let bid, let inputMaxSum): if !inputMaxSum { - AnalyticManager.trackEvent(.dex(.sellTap(amountAsset: amountAsset.name, priceAsset: priceAsset.name))) + UseCasesFactory.instance.analyticManager.trackEvent(.dex(.sellTap(amountAsset: amountAsset.name, priceAsset: priceAsset.name))) } moduleOutput?.didCreateOrder(bid, amountAsset: amountAsset, priceAsset: priceAsset, @@ -129,7 +129,7 @@ final class DexOrderBookPresenter: DexOrderBookPresenterProtocol { return state.changeAction(.none) case .didTapEmptyBid: - AnalyticManager.trackEvent(.dex(.sellTap(amountAsset: amountAsset.name, priceAsset: priceAsset.name))) + UseCasesFactory.instance.analyticManager.trackEvent(.dex(.sellTap(amountAsset: amountAsset.name, priceAsset: priceAsset.name))) moduleOutput?.didCreateEmptyOrder(amountAsset: amountAsset, priceAsset: priceAsset, orderType: .sell, @@ -146,7 +146,7 @@ final class DexOrderBookPresenter: DexOrderBookPresenterProtocol { case .didTapAsk(let ask, let inputMaxSum): if !inputMaxSum { - AnalyticManager.trackEvent(.dex(.buyTap(amountAsset: amountAsset.name, priceAsset: priceAsset.name))) + UseCasesFactory.instance.analyticManager.trackEvent(.dex(.buyTap(amountAsset: amountAsset.name, priceAsset: priceAsset.name))) } moduleOutput?.didCreateOrder(ask, amountAsset: amountAsset, priceAsset: priceAsset, @@ -162,7 +162,7 @@ final class DexOrderBookPresenter: DexOrderBookPresenterProtocol { return state.changeAction(.none) case .didTamEmptyAsk: - AnalyticManager.trackEvent(.dex(.buyTap(amountAsset: amountAsset.name, priceAsset: priceAsset.name))) + UseCasesFactory.instance.analyticManager.trackEvent(.dex(.buyTap(amountAsset: amountAsset.name, priceAsset: priceAsset.name))) moduleOutput?.didCreateEmptyOrder(amountAsset: amountAsset, priceAsset: priceAsset, orderType: .buy, diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/Presenter/DexOrderBookPresenterProtocol.swift b/WavesWallet-iOS/Modules/Dex/DexOrderBook/Presenter/DexOrderBookPresenterProtocol.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/Presenter/DexOrderBookPresenterProtocol.swift rename to WavesWallet-iOS/Modules/Dex/DexOrderBook/Presenter/DexOrderBookPresenterProtocol.swift index e04f740c..237be31e 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/Presenter/DexOrderBookPresenterProtocol.swift +++ b/WavesWallet-iOS/Modules/Dex/DexOrderBook/Presenter/DexOrderBookPresenterProtocol.swift @@ -8,6 +8,7 @@ import Foundation import RxCocoa +import DomainLayer protocol DexOrderBookPresenterProtocol { typealias Feedback = (Driver) -> Signal diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/Views/DexOrderBookCell.swift b/WavesWallet-iOS/Modules/Dex/DexOrderBook/Views/DexOrderBookCell.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/Views/DexOrderBookCell.swift rename to WavesWallet-iOS/Modules/Dex/DexOrderBook/Views/DexOrderBookCell.swift index 8256d317..c01e6a0c 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/Views/DexOrderBookCell.swift +++ b/WavesWallet-iOS/Modules/Dex/DexOrderBook/Views/DexOrderBookCell.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions final class DexOrderBookCell: UITableViewCell, Reusable { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/Views/DexOrderBookHeaderView.swift b/WavesWallet-iOS/Modules/Dex/DexOrderBook/Views/DexOrderBookHeaderView.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/Views/DexOrderBookHeaderView.swift rename to WavesWallet-iOS/Modules/Dex/DexOrderBook/Views/DexOrderBookHeaderView.swift index c69ee44f..df4069bf 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/Views/DexOrderBookHeaderView.swift +++ b/WavesWallet-iOS/Modules/Dex/DexOrderBook/Views/DexOrderBookHeaderView.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions final class DexOrderBookHeaderView: DexTraderContainerBaseHeaderView, NibOwnerLoadable { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/Views/DexOrderBookHeaderView.xib b/WavesWallet-iOS/Modules/Dex/DexOrderBook/Views/DexOrderBookHeaderView.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/Views/DexOrderBookHeaderView.xib rename to WavesWallet-iOS/Modules/Dex/DexOrderBook/Views/DexOrderBookHeaderView.xib diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/Views/DexOrderBookLastPriceCell.swift b/WavesWallet-iOS/Modules/Dex/DexOrderBook/Views/DexOrderBookLastPriceCell.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/Views/DexOrderBookLastPriceCell.swift rename to WavesWallet-iOS/Modules/Dex/DexOrderBook/Views/DexOrderBookLastPriceCell.swift index d1bbebc0..4fb2a963 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexOrderBook/Views/DexOrderBookLastPriceCell.swift +++ b/WavesWallet-iOS/Modules/Dex/DexOrderBook/Views/DexOrderBookLastPriceCell.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions final class DexOrderBookLastPriceCell: UITableViewCell, Reusable { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexScriptAssetMessage/DexScriptAssetMessageModuleBuilder.swift b/WavesWallet-iOS/Modules/Dex/DexScriptAssetMessage/DexScriptAssetMessageModuleBuilder.swift similarity index 96% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexScriptAssetMessage/DexScriptAssetMessageModuleBuilder.swift rename to WavesWallet-iOS/Modules/Dex/DexScriptAssetMessage/DexScriptAssetMessageModuleBuilder.swift index 5a81be1c..7cf17b36 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexScriptAssetMessage/DexScriptAssetMessageModuleBuilder.swift +++ b/WavesWallet-iOS/Modules/Dex/DexScriptAssetMessage/DexScriptAssetMessageModuleBuilder.swift @@ -7,6 +7,8 @@ // import UIKit +import DomainLayer +import Extensions protocol DexScriptAssetMessageModuleOutput: AnyObject { func dexScriptAssetMessageModuleOutputDidTapCheckmark(amountAsset: String, priceAsset: String, doNotShow: Bool) diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexScriptAssetMessage/DexScriptAssetMessageViewController.swift b/WavesWallet-iOS/Modules/Dex/DexScriptAssetMessage/DexScriptAssetMessageViewController.swift similarity index 87% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexScriptAssetMessage/DexScriptAssetMessageViewController.swift rename to WavesWallet-iOS/Modules/Dex/DexScriptAssetMessage/DexScriptAssetMessageViewController.swift index 1051d045..6e4cc769 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexScriptAssetMessage/DexScriptAssetMessageViewController.swift +++ b/WavesWallet-iOS/Modules/Dex/DexScriptAssetMessage/DexScriptAssetMessageViewController.swift @@ -8,12 +8,12 @@ import UIKit import RxSwift +import Extensions +import DomainLayer private enum Constants { static let buttonDeltaWidth: CGFloat = 70 static let spaceAssets: CGFloat = 24 - static let icon: CGSize = CGSize(width: 48, height: 48) - static let sponsoredIcon = CGSize(width: 18, height: 18) } final class DexScriptAssetMessageViewController: UIViewController { @@ -100,11 +100,7 @@ private extension DexScriptAssetMessageViewController { func setup(imageViewIcon: UIImageView, asset: DomainLayer.DTO.Asset) { AssetLogo.logo(icon: asset.iconLogo, - style: AssetLogo.Style(size: Constants.icon, - font: UIFont.systemFont(ofSize: 15), - specs: .init(isSponsored: asset.isSponsored, - hasScript: asset.hasScript, - size: Constants.sponsoredIcon))) + style: .large) .observeOn(MainScheduler.instance) .bind(to: imageViewIcon.rx.image) .disposed(by: disposeBag) diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexSort/DexSortModuleBuilder.swift b/WavesWallet-iOS/Modules/Dex/DexSort/DexSortModuleBuilder.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexSort/DexSortModuleBuilder.swift rename to WavesWallet-iOS/Modules/Dex/DexSort/DexSortModuleBuilder.swift index a2033f33..56e07ea7 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexSort/DexSortModuleBuilder.swift +++ b/WavesWallet-iOS/Modules/Dex/DexSort/DexSortModuleBuilder.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions struct DexSortModuleBuilder: ModuleBuilderOutput { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexSort/DexSortTypes.swift b/WavesWallet-iOS/Modules/Dex/DexSort/DexSortTypes.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexSort/DexSortTypes.swift rename to WavesWallet-iOS/Modules/Dex/DexSort/DexSortTypes.swift index f9533d8a..33b9658b 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexSort/DexSortTypes.swift +++ b/WavesWallet-iOS/Modules/Dex/DexSort/DexSortTypes.swift @@ -7,6 +7,7 @@ // import Foundation +import Extensions enum DexSort { enum DTO {} diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexSort/DexSortViewController.swift b/WavesWallet-iOS/Modules/Dex/DexSort/DexSortViewController.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexSort/DexSortViewController.swift rename to WavesWallet-iOS/Modules/Dex/DexSort/DexSortViewController.swift index a43b6b54..9ada4d74 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexSort/DexSortViewController.swift +++ b/WavesWallet-iOS/Modules/Dex/DexSort/DexSortViewController.swift @@ -10,7 +10,7 @@ import UIKit import RxCocoa import RxFeedback import RxSwift - +import Extensions fileprivate enum Constants { static let contentInset = UIEdgeInsets.init(top: 4, left: 0, bottom: 4, right: 0) diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexSort/Interactor/DexSortInteractor.swift b/WavesWallet-iOS/Modules/Dex/DexSort/Interactor/DexSortInteractor.swift similarity index 93% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexSort/Interactor/DexSortInteractor.swift rename to WavesWallet-iOS/Modules/Dex/DexSort/Interactor/DexSortInteractor.swift index eb633d3c..0b011784 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexSort/Interactor/DexSortInteractor.swift +++ b/WavesWallet-iOS/Modules/Dex/DexSort/Interactor/DexSortInteractor.swift @@ -8,12 +8,12 @@ import Foundation import RxSwift -import RealmSwift +import DomainLayer final class DexSortInteractor: DexSortInteractorProtocol { - private let reposity = FactoryRepositories.instance.dexRealmRepository - private let auth = FactoryInteractors.instance.authorization + private let reposity = UseCasesFactory.instance.repositories.dexRealmRepository + private let auth = UseCasesFactory.instance.authorization private let disposeBag = DisposeBag() func models() -> Observable<[DexSort.DTO.DexSortModel]> { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexSort/Interactor/DexSortInteractorMock.swift b/WavesWallet-iOS/Modules/Dex/DexSort/Interactor/DexSortInteractorMock.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexSort/Interactor/DexSortInteractorMock.swift rename to WavesWallet-iOS/Modules/Dex/DexSort/Interactor/DexSortInteractorMock.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexSort/Interactor/DexSortInteractorProtocol.swift b/WavesWallet-iOS/Modules/Dex/DexSort/Interactor/DexSortInteractorProtocol.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexSort/Interactor/DexSortInteractorProtocol.swift rename to WavesWallet-iOS/Modules/Dex/DexSort/Interactor/DexSortInteractorProtocol.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexSort/Presenter/DexSortPresenter.swift b/WavesWallet-iOS/Modules/Dex/DexSort/Presenter/DexSortPresenter.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexSort/Presenter/DexSortPresenter.swift rename to WavesWallet-iOS/Modules/Dex/DexSort/Presenter/DexSortPresenter.swift index aecf1e95..42cd5fe9 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexSort/Presenter/DexSortPresenter.swift +++ b/WavesWallet-iOS/Modules/Dex/DexSort/Presenter/DexSortPresenter.swift @@ -10,7 +10,7 @@ import Foundation import RxFeedback import RxSwift import RxCocoa - +import Extensions final class DexSortPresenter: DexSortPresenterProtocol { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexSort/Presenter/DexSortPresenterProtocol.swift b/WavesWallet-iOS/Modules/Dex/DexSort/Presenter/DexSortPresenterProtocol.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexSort/Presenter/DexSortPresenterProtocol.swift rename to WavesWallet-iOS/Modules/Dex/DexSort/Presenter/DexSortPresenterProtocol.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexSort/Views/DexSortCell.swift b/WavesWallet-iOS/Modules/Dex/DexSort/Views/DexSortCell.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexSort/Views/DexSortCell.swift rename to WavesWallet-iOS/Modules/Dex/DexSort/Views/DexSortCell.swift index 295cd8ee..8d767c35 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexSort/Views/DexSortCell.swift +++ b/WavesWallet-iOS/Modules/Dex/DexSort/Views/DexSortCell.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions private enum Constants { static let movedRowAlpha: CGFloat = 0.9 diff --git a/WavesWallet-iOS/Modules/Dex/DexTraderContainer/DexTraderContainerTypes.swift b/WavesWallet-iOS/Modules/Dex/DexTraderContainer/DexTraderContainerTypes.swift new file mode 100644 index 00000000..7eadb760 --- /dev/null +++ b/WavesWallet-iOS/Modules/Dex/DexTraderContainer/DexTraderContainerTypes.swift @@ -0,0 +1,29 @@ +// +// DexTraderContainerTypes.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 8/15/18. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import DomainLayer + +public enum DexTraderContainer { + public enum DTO {} +} + +public extension DexTraderContainer.DTO { + + struct Pair { + public let amountAsset: DomainLayer.DTO.Dex.Asset + public let priceAsset: DomainLayer.DTO.Dex.Asset + public let isGeneral: Bool + + public init(amountAsset: DomainLayer.DTO.Dex.Asset, priceAsset: DomainLayer.DTO.Dex.Asset, isGeneral: Bool) { + self.amountAsset = amountAsset + self.priceAsset = priceAsset + self.isGeneral = isGeneral + } + } +} diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexTraderContainer/DexTraderContainerViewController.swift b/WavesWallet-iOS/Modules/Dex/DexTraderContainer/DexTraderContainerViewController.swift similarity index 94% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexTraderContainer/DexTraderContainerViewController.swift rename to WavesWallet-iOS/Modules/Dex/DexTraderContainer/DexTraderContainerViewController.swift index f449d870..d94b4e3c 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexTraderContainer/DexTraderContainerViewController.swift +++ b/WavesWallet-iOS/Modules/Dex/DexTraderContainer/DexTraderContainerViewController.swift @@ -7,6 +7,8 @@ // import UIKit +import DomainLayer +import Extensions protocol DexTraderContainerProcotol { func controllerWillAppear() @@ -24,6 +26,8 @@ final class DexTraderContainerViewController: UIViewController { private var viewControllers: [UIViewController] = [] private var scrolledPages: [Int] = [] + var backAction:(() -> Void)? + override func viewDidLoad() { super.viewDidLoad() @@ -36,6 +40,14 @@ final class DexTraderContainerViewController: UIViewController { updateControllersActiveState(page: scrollView.currentPage) } + override func backTapped() { + if let action = backAction { + action() + } + else { + navigationController?.popViewController(animated: true) + } + } override var preferredStatusBarStyle: UIStatusBarStyle { return .lightContent } @@ -43,7 +55,7 @@ final class DexTraderContainerViewController: UIViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) setupSmallNavigationBar() - hideTopBarLine() + removeTopBarLine() navigationItem.backgroundImage = UIImage() navigationItem.titleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.white] } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexTraderContainer/Modules/DexTraderContainerInputProtocol.swift b/WavesWallet-iOS/Modules/Dex/DexTraderContainer/Modules/DexTraderContainerInputProtocol.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexTraderContainer/Modules/DexTraderContainerInputProtocol.swift rename to WavesWallet-iOS/Modules/Dex/DexTraderContainer/Modules/DexTraderContainerInputProtocol.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexTraderContainer/Modules/DexTraderContainerModuleBuilder.swift b/WavesWallet-iOS/Modules/Dex/DexTraderContainer/Modules/DexTraderContainerModuleBuilder.swift similarity index 92% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexTraderContainer/Modules/DexTraderContainerModuleBuilder.swift rename to WavesWallet-iOS/Modules/Dex/DexTraderContainer/Modules/DexTraderContainerModuleBuilder.swift index 973de035..80f62426 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexTraderContainer/Modules/DexTraderContainerModuleBuilder.swift +++ b/WavesWallet-iOS/Modules/Dex/DexTraderContainer/Modules/DexTraderContainerModuleBuilder.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions struct DexTraderContainerModuleBuilder: ModuleBuilderOutput { @@ -15,10 +16,13 @@ struct DexTraderContainerModuleBuilder: ModuleBuilderOutput { weak var lastTradesOutput: DexLastTradesModuleOutput? weak var myOrdersOutpout: DexMyOrdersModuleOutput? + var backAction:(() -> Void)? + func build(input: DexTraderContainer.DTO.Pair) -> UIViewController { let vc = StoryboardScene.Dex.dexTraderContainerViewController.instantiate() vc.pair = input vc.moduleOutput = output + vc.backAction = backAction vc.addViewController(DexOrderBookModuleBuilder(output: orderBookOutput).build(input: input), isScrollEnabled: true) vc.addViewController(DexChartModuleBuilder().build(input: input), isScrollEnabled: false) diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexTraderContainer/Modules/DexTraderContainerModuleOutput.swift b/WavesWallet-iOS/Modules/Dex/DexTraderContainer/Modules/DexTraderContainerModuleOutput.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexTraderContainer/Modules/DexTraderContainerModuleOutput.swift rename to WavesWallet-iOS/Modules/Dex/DexTraderContainer/Modules/DexTraderContainerModuleOutput.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexTraderContainer/Views/DexTraderContainerBaseHeaderView.swift b/WavesWallet-iOS/Modules/Dex/DexTraderContainer/Views/DexTraderContainerBaseHeaderView.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexTraderContainer/Views/DexTraderContainerBaseHeaderView.swift rename to WavesWallet-iOS/Modules/Dex/DexTraderContainer/Views/DexTraderContainerBaseHeaderView.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexTraderContainer/Views/DexTraderContainerButton.swift b/WavesWallet-iOS/Modules/Dex/DexTraderContainer/Views/DexTraderContainerButton.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexTraderContainer/Views/DexTraderContainerButton.swift rename to WavesWallet-iOS/Modules/Dex/DexTraderContainer/Views/DexTraderContainerButton.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexTraderContainer/Views/DexTraderContainerSegmentedControl.swift b/WavesWallet-iOS/Modules/Dex/DexTraderContainer/Views/DexTraderContainerSegmentedControl.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexTraderContainer/Views/DexTraderContainerSegmentedControl.swift rename to WavesWallet-iOS/Modules/Dex/DexTraderContainer/Views/DexTraderContainerSegmentedControl.swift index eff428be..a545fa5d 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexTraderContainer/Views/DexTraderContainerSegmentedControl.swift +++ b/WavesWallet-iOS/Modules/Dex/DexTraderContainer/Views/DexTraderContainerSegmentedControl.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions private enum Constants { static let countButtons = 4 diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Dex/DexTraderContainer/Views/DexTraderContainerSegmentedControl.xib b/WavesWallet-iOS/Modules/Dex/DexTraderContainer/Views/DexTraderContainerSegmentedControl.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Dex/DexTraderContainer/Views/DexTraderContainerSegmentedControl.xib rename to WavesWallet-iOS/Modules/Dex/DexTraderContainer/Views/DexTraderContainerSegmentedControl.xib diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Enter/Edit/EditAccountName.storyboard b/WavesWallet-iOS/Modules/Enter/Edit/EditAccountName.storyboard similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Enter/Edit/EditAccountName.storyboard rename to WavesWallet-iOS/Modules/Enter/Edit/EditAccountName.storyboard diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Enter/Edit/EditAccountNameModuleBuilder.swift b/WavesWallet-iOS/Modules/Enter/Edit/EditAccountNameModuleBuilder.swift similarity index 94% rename from WavesWallet-iOS/PresentationLayer/Modules/Enter/Edit/EditAccountNameModuleBuilder.swift rename to WavesWallet-iOS/Modules/Enter/Edit/EditAccountNameModuleBuilder.swift index c6532854..1f161164 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Enter/Edit/EditAccountNameModuleBuilder.swift +++ b/WavesWallet-iOS/Modules/Enter/Edit/EditAccountNameModuleBuilder.swift @@ -7,6 +7,8 @@ // import UIKit +import DomainLayer +import Extensions struct EditAccountNameModuleBuilder: ModuleBuilderOutput { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Enter/Edit/EditAccountNameViewController.swift b/WavesWallet-iOS/Modules/Enter/Edit/EditAccountNameViewController.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/Enter/Edit/EditAccountNameViewController.swift rename to WavesWallet-iOS/Modules/Enter/Edit/EditAccountNameViewController.swift index 95202d84..71fea73c 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Enter/Edit/EditAccountNameViewController.swift +++ b/WavesWallet-iOS/Modules/Enter/Edit/EditAccountNameViewController.swift @@ -9,6 +9,8 @@ import UIKit import RxSwift import IdentityImg +import DomainLayer +import Extensions final class EditAccountNameViewController: UIViewController { @@ -25,7 +27,7 @@ final class EditAccountNameViewController: UIViewController { @IBOutlet private weak var saveButtonBottomConstraint: NSLayoutConstraint! - private let authorization: AuthorizationInteractorProtocol = FactoryInteractors.instance.authorization + private let authorization: AuthorizationUseCaseProtocol = UseCasesFactory.instance.authorization private let disposeBag: DisposeBag = DisposeBag() var wallet: DomainLayer.DTO.Wallet! @@ -65,7 +67,7 @@ final class EditAccountNameViewController: UIViewController { navigationItem.title = Localizable.Waves.Editaccountname.Navigation.title setupBigNavigationBar() createBackButton() - hideTopBarLine() + hideTopBarLineForIOS12() } private func setupSaveButton() { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Enter/Enter.storyboard b/WavesWallet-iOS/Modules/Enter/Enter.storyboard similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Enter/Enter.storyboard rename to WavesWallet-iOS/Modules/Enter/Enter.storyboard diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Enter/Start/EnterStartTypes.swift b/WavesWallet-iOS/Modules/Enter/Start/EnterStartTypes.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Enter/Start/EnterStartTypes.swift rename to WavesWallet-iOS/Modules/Enter/Start/EnterStartTypes.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Enter/Start/EnterStartViewController.swift b/WavesWallet-iOS/Modules/Enter/Start/EnterStartViewController.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Enter/Start/EnterStartViewController.swift rename to WavesWallet-iOS/Modules/Enter/Start/EnterStartViewController.swift index 6731625d..1cae5673 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Enter/Start/EnterStartViewController.swift +++ b/WavesWallet-iOS/Modules/Enter/Start/EnterStartViewController.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions private enum Constants { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Enter/Start/Views/EnterStartBlockCell.swift b/WavesWallet-iOS/Modules/Enter/Start/Views/EnterStartBlockCell.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Enter/Start/Views/EnterStartBlockCell.swift rename to WavesWallet-iOS/Modules/Enter/Start/Views/EnterStartBlockCell.swift index 114afff2..8ee9b73f 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Enter/Start/Views/EnterStartBlockCell.swift +++ b/WavesWallet-iOS/Modules/Enter/Start/Views/EnterStartBlockCell.swift @@ -7,7 +7,7 @@ // import UIKit - +import Extensions private enum Constants { static let imageSize = CGSize(width: 120, height: 100) diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Enter/Start/Views/EnterStartBlockCell.xib b/WavesWallet-iOS/Modules/Enter/Start/Views/EnterStartBlockCell.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Enter/Start/Views/EnterStartBlockCell.xib rename to WavesWallet-iOS/Modules/Enter/Start/Views/EnterStartBlockCell.xib diff --git a/WavesWallet-iOS/Modules/ForceUpdateApp/ForceUpdateApp.storyboard b/WavesWallet-iOS/Modules/ForceUpdateApp/ForceUpdateApp.storyboard new file mode 100644 index 00000000..dbc9a257 --- /dev/null +++ b/WavesWallet-iOS/Modules/ForceUpdateApp/ForceUpdateApp.storyboard @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/WavesWallet-iOS/Modules/ForceUpdateApp/ForceUpdateAppViewController.swift b/WavesWallet-iOS/Modules/ForceUpdateApp/ForceUpdateAppViewController.swift new file mode 100644 index 00000000..6af5b794 --- /dev/null +++ b/WavesWallet-iOS/Modules/ForceUpdateApp/ForceUpdateAppViewController.swift @@ -0,0 +1,38 @@ +// +// ForceUpdateAppViewController.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 01.11.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import UIKit +import WavesSDK +import DomainLayer + +final class ForceUpdateAppViewController: UIViewController { + + @IBOutlet private weak var labelTitle: UILabel! + @IBOutlet private weak var labelSubtitle: UILabel! + @IBOutlet private weak var buttonUpdate: HighlightedButton! + + var data: DomainLayer.DTO.VersionUpdateData? + + override func viewDidLoad() { + super.viewDidLoad() + + setupLocalization() + } + + + @IBAction private func updateTapped(_ sender: Any) { + UIApplication.shared.openURLAsync(WavesSDKConstants.appstoreURL) + } + + private func setupLocalization() { + + labelTitle.text = Localizable.Waves.Forceupdate.Label.title + labelSubtitle.text = Localizable.Waves.Forceupdate.Label.subtitle(self.data?.forceUpdateVersion ?? "") + buttonUpdate.setTitle(Localizable.Waves.Forceupdate.Button.update, for: .normal) + } +} diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Hello/Hello.storyboard b/WavesWallet-iOS/Modules/Hello/Hello.storyboard similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Hello/Hello.storyboard rename to WavesWallet-iOS/Modules/Hello/Hello.storyboard diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Hello/InfoPages/InfoPagesViewController.swift b/WavesWallet-iOS/Modules/Hello/InfoPages/InfoPagesViewController.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/Hello/InfoPages/InfoPagesViewController.swift rename to WavesWallet-iOS/Modules/Hello/InfoPages/InfoPagesViewController.swift index 7fa492e9..c27fffdd 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Hello/InfoPages/InfoPagesViewController.swift +++ b/WavesWallet-iOS/Modules/Hello/InfoPages/InfoPagesViewController.swift @@ -7,6 +7,8 @@ import UIKit import Koloda +import Extensions +import DomainLayer protocol InfoPagesViewModuleOutput: AnyObject { func userFinishedReadPages() @@ -98,8 +100,6 @@ final class InfoPagesViewController: UIViewController { view.backgroundColor = .basic50 -// self.nextControl.accessibilityIdentifier = AccessibilityIdentifiers.Viewcontroller.Infopagesviewcontroller.Button.next - navigationItem.isNavigationBarHidden = true setupCollectionView() @@ -188,7 +188,7 @@ final class InfoPagesViewController: UIViewController { } else { guard isActiveConfirm else { return } output?.userFinishedReadPages() - AnalyticManager.trackEvent(.newUser(.confirm)) + UseCasesFactory.instance.analyticManager.trackEvent(.createANewAccount(.newUserConfirm)) } } @@ -320,7 +320,8 @@ extension InfoPagesViewController: InfoPageConfirmViewDelegate { func infoPageContirmViewDidTapURL(_ url: URL) { let vc = BrowserViewController(url: url) - let nav = CustomNavigationController(rootViewController: vc) + let nav = UINavigationController(rootViewController: vc) + nav.modalPresentationStyle = .fullScreen present(nav, animated: true, completion: nil) } } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Hello/InfoPages/View/InfoPageConfirmView.swift b/WavesWallet-iOS/Modules/Hello/InfoPages/View/InfoPageConfirmView.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Hello/InfoPages/View/InfoPageConfirmView.swift rename to WavesWallet-iOS/Modules/Hello/InfoPages/View/InfoPageConfirmView.swift index facc22bd..7cf6bf68 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Hello/InfoPages/View/InfoPageConfirmView.swift +++ b/WavesWallet-iOS/Modules/Hello/InfoPages/View/InfoPageConfirmView.swift @@ -15,7 +15,7 @@ protocol InfoPageConfirmViewDelegate: AnyObject { //TODO: MOVE URL TO GLOBAL CONSTANTS private enum Constants { - static let termsOfUse = "https://wavesplatform.com/files/docs/Privacy%20Policy_SW.pdf" + static let termsOfUse = "https://wavesplatform.com/files/docs/Waves_privacy_policy.pdf" static let termsOfConditions = "https://wavesplatform.com/files/docs/Waves_terms_and_conditions.pdf" static let buttonDeltaWidth: CGFloat = 24 diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Hello/InfoPages/View/InfoPageConfirmView.xib b/WavesWallet-iOS/Modules/Hello/InfoPages/View/InfoPageConfirmView.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Hello/InfoPages/View/InfoPageConfirmView.xib rename to WavesWallet-iOS/Modules/Hello/InfoPages/View/InfoPageConfirmView.xib diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Hello/InfoPages/View/InfoPagesCell.swift b/WavesWallet-iOS/Modules/Hello/InfoPages/View/InfoPagesCell.swift similarity index 89% rename from WavesWallet-iOS/PresentationLayer/Modules/Hello/InfoPages/View/InfoPagesCell.swift rename to WavesWallet-iOS/Modules/Hello/InfoPages/View/InfoPagesCell.swift index ade51a6b..7fedbe3b 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Hello/InfoPages/View/InfoPagesCell.swift +++ b/WavesWallet-iOS/Modules/Hello/InfoPages/View/InfoPagesCell.swift @@ -7,8 +7,9 @@ // import UIKit +import Extensions -class InfoPagesCell: UICollectionViewCell, Reusable { +final class InfoPagesCell: UICollectionViewCell, Reusable { fileprivate var infoView: UIView? diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Hello/InfoPages/View/LongInfoPageView.swift b/WavesWallet-iOS/Modules/Hello/InfoPages/View/LongInfoPageView.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Hello/InfoPages/View/LongInfoPageView.swift rename to WavesWallet-iOS/Modules/Hello/InfoPages/View/LongInfoPageView.swift index 7cfbb5b8..0d593415 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Hello/InfoPages/View/LongInfoPageView.swift +++ b/WavesWallet-iOS/Modules/Hello/InfoPages/View/LongInfoPageView.swift @@ -6,11 +6,11 @@ // import UIKit +import Extensions protocol LongInfoPageViewDelegate: class { - func longInfoPageViewDidScrollToBottom(view: LongInfoPageView) - + func longInfoPageViewDidScrollToBottom(view: LongInfoPageView) } final class LongInfoPageView: UIView { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Hello/InfoPages/View/LongInfoPageView.xib b/WavesWallet-iOS/Modules/Hello/InfoPages/View/LongInfoPageView.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Hello/InfoPages/View/LongInfoPageView.xib rename to WavesWallet-iOS/Modules/Hello/InfoPages/View/LongInfoPageView.xib diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Hello/InfoPages/View/ShortInfoPageView.swift b/WavesWallet-iOS/Modules/Hello/InfoPages/View/ShortInfoPageView.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Hello/InfoPages/View/ShortInfoPageView.swift rename to WavesWallet-iOS/Modules/Hello/InfoPages/View/ShortInfoPageView.swift index d9fa6509..db863232 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Hello/InfoPages/View/ShortInfoPageView.swift +++ b/WavesWallet-iOS/Modules/Hello/InfoPages/View/ShortInfoPageView.swift @@ -6,6 +6,7 @@ // import UIKit +import Extensions protocol ShortInfoPageViewDelegate: class { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Hello/InfoPages/View/ShortInfoPageView.xib b/WavesWallet-iOS/Modules/Hello/InfoPages/View/ShortInfoPageView.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Hello/InfoPages/View/ShortInfoPageView.xib rename to WavesWallet-iOS/Modules/Hello/InfoPages/View/ShortInfoPageView.xib diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Hello/Languages/HelloLanguagesViewController.swift b/WavesWallet-iOS/Modules/Hello/Languages/HelloLanguagesViewController.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Hello/Languages/HelloLanguagesViewController.swift rename to WavesWallet-iOS/Modules/Hello/Languages/HelloLanguagesViewController.swift index d2400914..b09bac55 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Hello/Languages/HelloLanguagesViewController.swift +++ b/WavesWallet-iOS/Modules/Hello/Languages/HelloLanguagesViewController.swift @@ -6,6 +6,7 @@ // import UIKit +import Extensions private enum Constants { static let logoTop: CGFloat = 44 diff --git a/WavesWallet-iOS/PresentationLayer/Modules/History/History.storyboard b/WavesWallet-iOS/Modules/History/History.storyboard similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/History/History.storyboard rename to WavesWallet-iOS/Modules/History/History.storyboard diff --git a/WavesWallet-iOS/PresentationLayer/Modules/History/History/HistoryModuleBuilder.swift b/WavesWallet-iOS/Modules/History/History/HistoryModuleBuilder.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/History/History/HistoryModuleBuilder.swift rename to WavesWallet-iOS/Modules/History/History/HistoryModuleBuilder.swift index 2639b030..ae418c1e 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/History/History/HistoryModuleBuilder.swift +++ b/WavesWallet-iOS/Modules/History/History/HistoryModuleBuilder.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions struct HistoryModuleBuilder: ModuleBuilderOutput { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/History/History/HistoryTypes+State.swift b/WavesWallet-iOS/Modules/History/History/HistoryTypes+State.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/History/History/HistoryTypes+State.swift rename to WavesWallet-iOS/Modules/History/History/HistoryTypes+State.swift index f4c73a2c..46699a0b 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/History/History/HistoryTypes+State.swift +++ b/WavesWallet-iOS/Modules/History/History/HistoryTypes+State.swift @@ -7,7 +7,7 @@ // import Foundation - +import DomainLayer // MARK: Set Methods extension HistoryTypes.State { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/History/History/HistoryTypes+ViewModels.swift b/WavesWallet-iOS/Modules/History/History/HistoryTypes+ViewModels.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/History/History/HistoryTypes+ViewModels.swift rename to WavesWallet-iOS/Modules/History/History/HistoryTypes+ViewModels.swift index cd0363c9..fa355c04 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/History/History/HistoryTypes+ViewModels.swift +++ b/WavesWallet-iOS/Modules/History/History/HistoryTypes+ViewModels.swift @@ -7,6 +7,7 @@ // import Foundation +import DomainLayer extension HistoryTypes.ViewModel { struct Section { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/History/History/HistoryTypes.swift b/WavesWallet-iOS/Modules/History/History/HistoryTypes.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/History/History/HistoryTypes.swift rename to WavesWallet-iOS/Modules/History/History/HistoryTypes.swift index ea45cb3f..0ca910a1 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/History/History/HistoryTypes.swift +++ b/WavesWallet-iOS/Modules/History/History/HistoryTypes.swift @@ -7,7 +7,9 @@ // import UIKit -import WavesSDKCrypto +import WavesSDK +import Extensions +import DomainLayer enum HistoryTypes { enum DTO {} @@ -193,7 +195,7 @@ extension HistoryType { return [.all, .sent, .received, .exchanged, .leased, .issued] case .asset(let assetId): - if assetId == WavesSDKCryptoConstants.wavesAssetId { + if assetId == WavesSDKConstants.wavesAssetId { return [.all, .sent, .received, .exchanged, .leased] } return [.all, .sent, .received, .exchanged, .issued] diff --git a/WavesWallet-iOS/PresentationLayer/Modules/History/History/HistoryViewController.swift b/WavesWallet-iOS/Modules/History/History/HistoryViewController.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/History/History/HistoryViewController.swift rename to WavesWallet-iOS/Modules/History/History/HistoryViewController.swift index e43e2e21..7cbe33bf 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/History/History/HistoryViewController.swift +++ b/WavesWallet-iOS/Modules/History/History/HistoryViewController.swift @@ -11,6 +11,8 @@ import RxCocoa import RxFeedback import RxSwift import SwiftDate +import DomainLayer +import Extensions fileprivate enum Constants { static let historyDateFormatterKey: String = "historyDateFormatterKey" @@ -325,7 +327,7 @@ extension HistoryViewController { } func changeFilter(_ filter: HistoryTypes.Filter) { - segmentedControl.segmentedControl.selectedIndex = filters.index(of: filter) ?? 0 + segmentedControl.segmentedControl.selectedIndex = filters.firstIndex(of: filter) ?? 0 } func setupRefreshControl() { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/History/History/Interactor/HistoryInteractor.swift b/WavesWallet-iOS/Modules/History/History/Interactor/HistoryInteractor.swift similarity index 86% rename from WavesWallet-iOS/PresentationLayer/Modules/History/History/Interactor/HistoryInteractor.swift rename to WavesWallet-iOS/Modules/History/History/Interactor/HistoryInteractor.swift index c05f0142..142e2e8d 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/History/History/Interactor/HistoryInteractor.swift +++ b/WavesWallet-iOS/Modules/History/History/Interactor/HistoryInteractor.swift @@ -8,6 +8,9 @@ import Foundation import RxSwift +import Extensions +import DomainLayer +import WavesSDK fileprivate enum Constants { static let limitTransactions = 10000 @@ -19,8 +22,8 @@ protocol HistoryInteractorProtocol { final class HistoryInteractor: HistoryInteractorProtocol { - private let transactionsInteractor: TransactionsInteractorProtocol = FactoryInteractors.instance.transactions - private let authorizationInteractor: AuthorizationInteractorProtocol = FactoryInteractors.instance.authorization + private let transactionsInteractor: TransactionsUseCaseProtocol = UseCasesFactory.instance.transactions + private let authorizationInteractor: AuthorizationUseCaseProtocol = UseCasesFactory.instance.authorization func transactions(input: HistoryModuleInput) -> Observable> { @@ -41,7 +44,7 @@ final class HistoryInteractor: HistoryInteractorProtocol { specifications = TransactionsSpecifications.init(page: .init(offset: 0, limit: Constants.limitTransactions), assets: [], senders: [], - types: [.lease, .leaseCancel]) + types: [.createLease, .cancelLease]) } return loadingTransactions(specifications: specifications) diff --git a/WavesWallet-iOS/PresentationLayer/Modules/History/History/Presenter/HistoryModuleInput.swift b/WavesWallet-iOS/Modules/History/History/Presenter/HistoryModuleInput.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/History/History/Presenter/HistoryModuleInput.swift rename to WavesWallet-iOS/Modules/History/History/Presenter/HistoryModuleInput.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/History/History/Presenter/HistoryModuleOutput.swift b/WavesWallet-iOS/Modules/History/History/Presenter/HistoryModuleOutput.swift similarity index 93% rename from WavesWallet-iOS/PresentationLayer/Modules/History/History/Presenter/HistoryModuleOutput.swift rename to WavesWallet-iOS/Modules/History/History/Presenter/HistoryModuleOutput.swift index d574999c..95a3accc 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/History/History/Presenter/HistoryModuleOutput.swift +++ b/WavesWallet-iOS/Modules/History/History/Presenter/HistoryModuleOutput.swift @@ -7,6 +7,7 @@ // import Foundation +import DomainLayer protocol HistoryModuleOutput: class { func showTransaction(transactions: [DomainLayer.DTO.SmartTransaction], index: Int) diff --git a/WavesWallet-iOS/PresentationLayer/Modules/History/History/Presenter/HistoryPresenter.swift b/WavesWallet-iOS/Modules/History/History/Presenter/HistoryPresenter.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/History/History/Presenter/HistoryPresenter.swift rename to WavesWallet-iOS/Modules/History/History/Presenter/HistoryPresenter.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/History/History/Views/HeaderSkeletonView.swift b/WavesWallet-iOS/Modules/History/History/Views/HeaderSkeletonView.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/History/History/Views/HeaderSkeletonView.swift rename to WavesWallet-iOS/Modules/History/History/Views/HeaderSkeletonView.swift index 8987a87f..c3de7c40 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/History/History/Views/HeaderSkeletonView.swift +++ b/WavesWallet-iOS/Modules/History/History/Views/HeaderSkeletonView.swift @@ -8,6 +8,7 @@ import UIKit import Skeleton +import Extensions final class HeaderSkeletonView: UITableViewHeaderFooterView, SkeletonAnimatable, NibReusable { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/History/History/Views/HeaderSkeletonView.xib b/WavesWallet-iOS/Modules/History/History/Views/HeaderSkeletonView.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/History/History/Views/HeaderSkeletonView.xib rename to WavesWallet-iOS/Modules/History/History/Views/HeaderSkeletonView.xib diff --git a/WavesWallet-iOS/PresentationLayer/Modules/History/History/Views/HistoryHeaderView.swift b/WavesWallet-iOS/Modules/History/History/Views/HistoryHeaderView.swift similarity index 96% rename from WavesWallet-iOS/PresentationLayer/Modules/History/History/Views/HistoryHeaderView.swift rename to WavesWallet-iOS/Modules/History/History/Views/HistoryHeaderView.swift index 8377d87e..12637ec9 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/History/History/Views/HistoryHeaderView.swift +++ b/WavesWallet-iOS/Modules/History/History/Views/HistoryHeaderView.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions final class HistoryHeaderView: UITableViewHeaderFooterView, NibReusable { @IBOutlet private var labelTitle: UILabel! diff --git a/WavesWallet-iOS/PresentationLayer/Modules/History/History/Views/HistoryHeaderView.xib b/WavesWallet-iOS/Modules/History/History/Views/HistoryHeaderView.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/History/History/Views/HistoryHeaderView.xib rename to WavesWallet-iOS/Modules/History/History/Views/HistoryHeaderView.xib diff --git a/WavesWallet-iOS/PresentationLayer/Modules/History/History/Views/HistoryTransactionCell.swift b/WavesWallet-iOS/Modules/History/History/Views/HistoryTransactionCell.swift similarity index 95% rename from WavesWallet-iOS/PresentationLayer/Modules/History/History/Views/HistoryTransactionCell.swift rename to WavesWallet-iOS/Modules/History/History/Views/HistoryTransactionCell.swift index 32fdff4d..7fe6cba8 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/History/History/Views/HistoryTransactionCell.swift +++ b/WavesWallet-iOS/Modules/History/History/Views/HistoryTransactionCell.swift @@ -7,6 +7,8 @@ // import UIKit +import DomainLayer +import Extensions private enum Constansts { static let height: CGFloat = 76 diff --git a/WavesWallet-iOS/PresentationLayer/Modules/History/History/Views/HistoryTransactionSkeletonCell.swift b/WavesWallet-iOS/Modules/History/History/Views/HistoryTransactionSkeletonCell.swift similarity index 96% rename from WavesWallet-iOS/PresentationLayer/Modules/History/History/Views/HistoryTransactionSkeletonCell.swift rename to WavesWallet-iOS/Modules/History/History/Views/HistoryTransactionSkeletonCell.swift index 56bfc83c..a45dc41d 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/History/History/Views/HistoryTransactionSkeletonCell.swift +++ b/WavesWallet-iOS/Modules/History/History/Views/HistoryTransactionSkeletonCell.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions final class HistoryTransactionSkeletonCell: SkeletonTableCell, Reusable { @IBOutlet var viewContent: UIView! diff --git a/WavesWallet-iOS/PresentationLayer/Modules/History/History/Views/HistoryTransactionView.swift b/WavesWallet-iOS/Modules/History/History/Views/HistoryTransactionView.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/History/History/Views/HistoryTransactionView.swift rename to WavesWallet-iOS/Modules/History/History/Views/HistoryTransactionView.swift index c0ca250c..aebf432d 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/History/History/Views/HistoryTransactionView.swift +++ b/WavesWallet-iOS/Modules/History/History/Views/HistoryTransactionView.swift @@ -7,6 +7,8 @@ // import UIKit +import Extensions +import DomainLayer final class HistoryTransactionView: UIView, NibOwnerLoadable { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/History/History/Views/HistoryTransactionView.xib b/WavesWallet-iOS/Modules/History/History/Views/HistoryTransactionView.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/History/History/Views/HistoryTransactionView.xib rename to WavesWallet-iOS/Modules/History/History/Views/HistoryTransactionView.xib diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Import/CameraAccess.swift b/WavesWallet-iOS/Modules/Import/CameraAccess.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Import/CameraAccess.swift rename to WavesWallet-iOS/Modules/Import/CameraAccess.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Import/Import.storyboard b/WavesWallet-iOS/Modules/Import/Import.storyboard similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Import/Import.storyboard rename to WavesWallet-iOS/Modules/Import/Import.storyboard diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Import/ImportAccountManuallyViewController.swift b/WavesWallet-iOS/Modules/Import/ImportAccountManuallyViewController.swift similarity index 96% rename from WavesWallet-iOS/PresentationLayer/Modules/Import/ImportAccountManuallyViewController.swift rename to WavesWallet-iOS/Modules/Import/ImportAccountManuallyViewController.swift index 2adf556e..aeff3329 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Import/ImportAccountManuallyViewController.swift +++ b/WavesWallet-iOS/Modules/Import/ImportAccountManuallyViewController.swift @@ -10,8 +10,9 @@ import UIKit import IdentityImg import IQKeyboardManagerSwift import RxSwift -import WavesSDKExtension -import WavesSDKCrypto +import WavesSDKExtensions +import Extensions +import DomainLayer protocol ImportWelcomeBackViewControllerDelegate: AnyObject { func userCompletedInputSeed(_ keyAccount: PrivateKeyAccount) @@ -49,7 +50,7 @@ final class ImportAccountManuallyViewController: UIViewController, UIScrollViewD private let disposeBag: DisposeBag = DisposeBag() - private let auth: AuthorizationInteractorProtocol = FactoryInteractors.instance.authorization + private let auth: AuthorizationUseCaseProtocol = UseCasesFactory.instance.authorization private let identity: Identity = Identity(options: Identity.defaultOptions) @@ -93,7 +94,7 @@ final class ImportAccountManuallyViewController: UIViewController, UIScrollViewD private func setupTextField() { textField.delegate = self textField.textView.returnKeyType = .done - + textField.update(with: MultilineTextField.Model(title: Localizable.Waves.Import.Manually.Label.Address.title, placeholder: Localizable.Waves.Import.Manually.Label.Address.placeholder)) @@ -120,6 +121,11 @@ final class ImportAccountManuallyViewController: UIViewController, UIScrollViewD // MARK: - Actions @IBAction func continueTapped(_ sender: Any) { + + UseCasesFactory + .instance + .analyticManager + .trackEvent(.importAccount(.startImportManually)) completedInput() } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Import/ImportAccountPasswordViewController.swift b/WavesWallet-iOS/Modules/Import/ImportAccountPasswordViewController.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Import/ImportAccountPasswordViewController.swift rename to WavesWallet-iOS/Modules/Import/ImportAccountPasswordViewController.swift index 7c16251f..e9778a72 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Import/ImportAccountPasswordViewController.swift +++ b/WavesWallet-iOS/Modules/Import/ImportAccountPasswordViewController.swift @@ -9,7 +9,7 @@ import UIKit import IQKeyboardManagerSwift import IdentityImg -import WavesSDKExtension +import WavesSDKExtensions protocol ImportAccountPasswordViewControllerDelegate: AnyObject { func userCompletedInputAccountData(password: String, name: String) @@ -39,7 +39,7 @@ final class ImportAccountPasswordViewController: UIViewController { createBackButton() setupBigNavigationBar() - hideTopBarLine() + hideTopBarLineForIOS12() setupTextField() setupButtonContinue() diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Import/ImportAccountScanViewController.swift b/WavesWallet-iOS/Modules/Import/ImportAccountScanViewController.swift similarity index 93% rename from WavesWallet-iOS/PresentationLayer/Modules/Import/ImportAccountScanViewController.swift rename to WavesWallet-iOS/Modules/Import/ImportAccountScanViewController.swift index 13efc367..18720af9 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Import/ImportAccountScanViewController.swift +++ b/WavesWallet-iOS/Modules/Import/ImportAccountScanViewController.swift @@ -9,6 +9,8 @@ import UIKit import TTTAttributedLabel import AVFoundation +import Extensions +import DomainLayer protocol ImportAccountViewControllerDelegate: AnyObject { func scanTapped() @@ -59,6 +61,11 @@ final class ImportAccountScanViewController: UIViewController { @IBAction func scanTapped(_ sender: Any) { + UseCasesFactory + .instance + .analyticManager + .trackEvent(.importAccount(.startImportScan)) + CameraAccess.requestAccess(success: { [weak self] in guard let self = self else { return } self.delegate?.scanTapped() diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Import/ImportAccountViewController.swift b/WavesWallet-iOS/Modules/Import/ImportAccountViewController.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Import/ImportAccountViewController.swift rename to WavesWallet-iOS/Modules/Import/ImportAccountViewController.swift index 4b85313e..64ffbf37 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Import/ImportAccountViewController.swift +++ b/WavesWallet-iOS/Modules/Import/ImportAccountViewController.swift @@ -41,7 +41,7 @@ class ImportAccountViewController: UIViewController { setupBigNavigationBar() createBackButton() - hideTopBarLine() + hideTopBarLineForIOS12() setupViewControllers() setupSegmentedControl() diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Import/ImportTypes.swift b/WavesWallet-iOS/Modules/Import/ImportTypes.swift similarity index 94% rename from WavesWallet-iOS/PresentationLayer/Modules/Import/ImportTypes.swift rename to WavesWallet-iOS/Modules/Import/ImportTypes.swift index 3de62c68..9dfb877f 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Import/ImportTypes.swift +++ b/WavesWallet-iOS/Modules/Import/ImportTypes.swift @@ -7,7 +7,7 @@ // import Foundation -import WavesSDKCrypto +import DomainLayer enum ImportTypes { enum DTO { } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Import/ImportWelcomeBackViewController.swift b/WavesWallet-iOS/Modules/Import/ImportWelcomeBackViewController.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Import/ImportWelcomeBackViewController.swift rename to WavesWallet-iOS/Modules/Import/ImportWelcomeBackViewController.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Language/Language.storyboard b/WavesWallet-iOS/Modules/Language/Language.storyboard similarity index 93% rename from WavesWallet-iOS/PresentationLayer/Modules/Language/Language.storyboard rename to WavesWallet-iOS/Modules/Language/Language.storyboard index fde8d42a..f8d695e1 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Language/Language.storyboard +++ b/WavesWallet-iOS/Modules/Language/Language.storyboard @@ -1,11 +1,9 @@ - - - - + + - + @@ -19,7 +17,7 @@ - + @@ -50,7 +48,7 @@ - + @@ -63,7 +61,7 @@ - + diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Language/LanguageViewController.swift b/WavesWallet-iOS/Modules/Language/LanguageViewController.swift similarity index 91% rename from WavesWallet-iOS/PresentationLayer/Modules/Language/LanguageViewController.swift rename to WavesWallet-iOS/Modules/Language/LanguageViewController.swift index 3af4e911..b5e0fdfa 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Language/LanguageViewController.swift +++ b/WavesWallet-iOS/Modules/Language/LanguageViewController.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions protocol LanguageViewControllerDelegate: AnyObject { func languageViewChangedLanguage() @@ -14,10 +15,9 @@ protocol LanguageViewControllerDelegate: AnyObject { final class LanguageViewController: UIViewController { - @IBOutlet private weak var gradientView: CustomGradientView! + @IBOutlet private weak var gradientView: GradientView! @IBOutlet private weak var tableView: UITableView! @IBOutlet private weak var buttonConfirm: UIButton! - private var gradientLayer: CAGradientLayer! @IBOutlet weak var buttonConfirmLeadingConstraint: NSLayoutConstraint! @IBOutlet weak var buttonConfirmTrailingConstraint: NSLayoutConstraint! @@ -27,7 +27,7 @@ final class LanguageViewController: UIViewController { private lazy var selectedIndex: Int = { let current = Language.currentLanguage - return self.languages.index(where: { $0.code == current.code }) ?? 0 + return self.languages.firstIndex(where: { $0.code == current.code }) ?? 0 }() weak var delegate: LanguageViewControllerDelegate? @@ -44,6 +44,10 @@ final class LanguageViewController: UIViewController { setupBigNavigationBar() setupLanguage() setupConstraints() + + gradientView.startColor = UIColor.white.withAlphaComponent(0.0) + gradientView.endColor = UIColor.white + gradientView.direction = .vertical } // MARK: - Setups diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Language/Views/LanguageTableCell.swift b/WavesWallet-iOS/Modules/Language/Views/LanguageTableCell.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Language/Views/LanguageTableCell.swift rename to WavesWallet-iOS/Modules/Language/Views/LanguageTableCell.swift index 599804c7..681edb11 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Language/Views/LanguageTableCell.swift +++ b/WavesWallet-iOS/Modules/Language/Views/LanguageTableCell.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions private enum Constants { static let smallPading: CGFloat = 16 diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Language/Views/LanguageTableCell.xib b/WavesWallet-iOS/Modules/Language/Views/LanguageTableCell.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Language/Views/LanguageTableCell.xib rename to WavesWallet-iOS/Modules/Language/Views/LanguageTableCell.xib diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Legal/Views/CheckboxControl.swift b/WavesWallet-iOS/Modules/Legal/Views/CheckboxControl.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Legal/Views/CheckboxControl.swift rename to WavesWallet-iOS/Modules/Legal/Views/CheckboxControl.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/MainTabBar/MainTabBarController.swift b/WavesWallet-iOS/Modules/MainTabBar/MainTabBarController.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/MainTabBar/MainTabBarController.swift rename to WavesWallet-iOS/Modules/MainTabBar/MainTabBarController.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Menu/Main.storyboard b/WavesWallet-iOS/Modules/Menu/Main.storyboard similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/Menu/Main.storyboard rename to WavesWallet-iOS/Modules/Menu/Main.storyboard index 837e30ec..a476c781 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Menu/Main.storyboard +++ b/WavesWallet-iOS/Modules/Menu/Main.storyboard @@ -1,11 +1,11 @@ - + - + @@ -21,7 +21,7 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/WavesWallet-iOS/PresentationLayer/Modules/MyAddress/MyAddress.storyboard b/WavesWallet-iOS/Modules/MyAddress/MyAddress.storyboard similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/MyAddress/MyAddress.storyboard rename to WavesWallet-iOS/Modules/MyAddress/MyAddress.storyboard diff --git a/WavesWallet-iOS/PresentationLayer/Modules/MyAddress/MyAddressModuleBuilder.swift b/WavesWallet-iOS/Modules/MyAddress/MyAddressModuleBuilder.swift similarity index 96% rename from WavesWallet-iOS/PresentationLayer/Modules/MyAddress/MyAddressModuleBuilder.swift rename to WavesWallet-iOS/Modules/MyAddress/MyAddressModuleBuilder.swift index 758cf32f..65b01aa0 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/MyAddress/MyAddressModuleBuilder.swift +++ b/WavesWallet-iOS/Modules/MyAddress/MyAddressModuleBuilder.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions struct MyAddressModuleBuilder: ModuleBuilderOutput { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/MyAddress/MyAddressPresenter.swift b/WavesWallet-iOS/Modules/MyAddress/MyAddressPresenter.swift similarity index 95% rename from WavesWallet-iOS/PresentationLayer/Modules/MyAddress/MyAddressPresenter.swift rename to WavesWallet-iOS/Modules/MyAddress/MyAddressPresenter.swift index 424e75ef..8c176ff1 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/MyAddress/MyAddressPresenter.swift +++ b/WavesWallet-iOS/Modules/MyAddress/MyAddressPresenter.swift @@ -10,6 +10,7 @@ import Foundation import RxFeedback import RxSwift import RxCocoa +import DomainLayer protocol MyAddressModuleOutput: AnyObject { func myAddressShowAliases(_ aliases: [DomainLayer.DTO.Alias]) @@ -28,8 +29,8 @@ final class MyAddressPresenter: MyAddressPresenterProtocol { fileprivate typealias Types = MyAddressTypes private let disposeBag: DisposeBag = DisposeBag() - private let authorizationInteractor: AuthorizationInteractorProtocol = FactoryInteractors.instance.authorization - private let aliasesRepository: AliasesRepositoryProtocol = FactoryRepositories.instance.aliasesRepositoryRemote + private let authorizationInteractor: AuthorizationUseCaseProtocol = UseCasesFactory.instance.authorization + private let aliasesRepository: AliasesRepositoryProtocol = UseCasesFactory.instance.repositories.aliasesRepositoryRemote weak var moduleOutput: MyAddressModuleOutput? diff --git a/WavesWallet-iOS/PresentationLayer/Modules/MyAddress/MyAddressTypes.swift b/WavesWallet-iOS/Modules/MyAddress/MyAddressTypes.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/MyAddress/MyAddressTypes.swift rename to WavesWallet-iOS/Modules/MyAddress/MyAddressTypes.swift index 60ae08a2..61c63c91 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/MyAddress/MyAddressTypes.swift +++ b/WavesWallet-iOS/Modules/MyAddress/MyAddressTypes.swift @@ -7,6 +7,8 @@ // import Foundation +import DomainLayer +import Extensions enum MyAddressTypes { enum ViewModel { } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/MyAddress/MyAddressViewController.swift b/WavesWallet-iOS/Modules/MyAddress/MyAddressViewController.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/MyAddress/MyAddressViewController.swift rename to WavesWallet-iOS/Modules/MyAddress/MyAddressViewController.swift index 8a8d4b6a..b1da2687 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/MyAddress/MyAddressViewController.swift +++ b/WavesWallet-iOS/Modules/MyAddress/MyAddressViewController.swift @@ -10,6 +10,7 @@ import UIKit import RxFeedback import RxSwift import RxCocoa +import Extensions final class MyAddressViewController: UIViewController { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/MyAddress/Views/MyAddressAliacesCell.swift b/WavesWallet-iOS/Modules/MyAddress/Views/MyAddressAliacesCell.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/MyAddress/Views/MyAddressAliacesCell.swift rename to WavesWallet-iOS/Modules/MyAddress/Views/MyAddressAliacesCell.swift index 3864c792..e052c210 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/MyAddress/Views/MyAddressAliacesCell.swift +++ b/WavesWallet-iOS/Modules/MyAddress/Views/MyAddressAliacesCell.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions private enum Constants { static let height: CGFloat = 108 diff --git a/WavesWallet-iOS/PresentationLayer/Modules/MyAddress/Views/MyAddressAliacesSkeletonCell.swift b/WavesWallet-iOS/Modules/MyAddress/Views/MyAddressAliacesSkeletonCell.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/MyAddress/Views/MyAddressAliacesSkeletonCell.swift rename to WavesWallet-iOS/Modules/MyAddress/Views/MyAddressAliacesSkeletonCell.swift index 667e3cec..1e7d5ebe 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/MyAddress/Views/MyAddressAliacesSkeletonCell.swift +++ b/WavesWallet-iOS/Modules/MyAddress/Views/MyAddressAliacesSkeletonCell.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions private enum Constants { static let height: CGFloat = 108 diff --git a/WavesWallet-iOS/PresentationLayer/Modules/MyAddress/Views/MyAddressInfoAddressCell.swift b/WavesWallet-iOS/Modules/MyAddress/Views/MyAddressInfoAddressCell.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/MyAddress/Views/MyAddressInfoAddressCell.swift rename to WavesWallet-iOS/Modules/MyAddress/Views/MyAddressInfoAddressCell.swift index d423e568..3b1666aa 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/MyAddress/Views/MyAddressInfoAddressCell.swift +++ b/WavesWallet-iOS/Modules/MyAddress/Views/MyAddressInfoAddressCell.swift @@ -8,6 +8,7 @@ import UIKit import IdentityImg +import Extensions private enum Constants { static let height: CGFloat = 179 diff --git a/WavesWallet-iOS/PresentationLayer/Modules/MyAddress/Views/MyAddressQRCodeCell.swift b/WavesWallet-iOS/Modules/MyAddress/Views/MyAddressQRCodeCell.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/MyAddress/Views/MyAddressQRCodeCell.swift rename to WavesWallet-iOS/Modules/MyAddress/Views/MyAddressQRCodeCell.swift index 8ae029c0..3a972660 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/MyAddress/Views/MyAddressQRCodeCell.swift +++ b/WavesWallet-iOS/Modules/MyAddress/Views/MyAddressQRCodeCell.swift @@ -8,6 +8,7 @@ import UIKit import QRCode import CoreImage +import Extensions private enum Constants { static let height: CGFloat = 228 diff --git a/WavesWallet-iOS/PresentationLayer/Modules/NewAccount/NewAccount.storyboard b/WavesWallet-iOS/Modules/NewAccount/NewAccount.storyboard similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/NewAccount/NewAccount.storyboard rename to WavesWallet-iOS/Modules/NewAccount/NewAccount.storyboard diff --git a/WavesWallet-iOS/PresentationLayer/Modules/NewAccount/NewAccountTypes.swift b/WavesWallet-iOS/Modules/NewAccount/NewAccountTypes.swift similarity index 94% rename from WavesWallet-iOS/PresentationLayer/Modules/NewAccount/NewAccountTypes.swift rename to WavesWallet-iOS/Modules/NewAccount/NewAccountTypes.swift index cfd5c87f..a7a74201 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/NewAccount/NewAccountTypes.swift +++ b/WavesWallet-iOS/Modules/NewAccount/NewAccountTypes.swift @@ -7,7 +7,7 @@ // import Foundation -import WavesSDKCrypto +import DomainLayer enum NewAccountTypes { enum DTO { } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/NewAccount/NewAccountViewController.swift b/WavesWallet-iOS/Modules/NewAccount/NewAccountViewController.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/NewAccount/NewAccountViewController.swift rename to WavesWallet-iOS/Modules/NewAccount/NewAccountViewController.swift index 815c1f64..86207cce 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/NewAccount/NewAccountViewController.swift +++ b/WavesWallet-iOS/Modules/NewAccount/NewAccountViewController.swift @@ -9,8 +9,8 @@ import UIKit import IdentityImg import IQKeyboardManagerSwift -import WavesSDKExtension -import WavesSDKCrypto +import WavesSDKExtensions +import DomainLayer private struct Avatar { let address: String diff --git a/WavesWallet-iOS/PresentationLayer/Modules/NewAccount/Views/NewAccountAvatarView.swift b/WavesWallet-iOS/Modules/NewAccount/Views/NewAccountAvatarView.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/NewAccount/Views/NewAccountAvatarView.swift rename to WavesWallet-iOS/Modules/NewAccount/Views/NewAccountAvatarView.swift index 7155f622..6af1a083 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/NewAccount/Views/NewAccountAvatarView.swift +++ b/WavesWallet-iOS/Modules/NewAccount/Views/NewAccountAvatarView.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions private enum Constants { static let lineWidth: CGFloat = 0.75 diff --git a/WavesWallet-iOS/PresentationLayer/Modules/NewAccount/Views/NewAccountAvatarView.xib b/WavesWallet-iOS/Modules/NewAccount/Views/NewAccountAvatarView.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/NewAccount/Views/NewAccountAvatarView.xib rename to WavesWallet-iOS/Modules/NewAccount/Views/NewAccountAvatarView.xib diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Passcode/Passcode.storyboard b/WavesWallet-iOS/Modules/Passcode/Passcode.storyboard similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Passcode/Passcode.storyboard rename to WavesWallet-iOS/Modules/Passcode/Passcode.storyboard diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Passcode/PasscodeBuilder.swift b/WavesWallet-iOS/Modules/Passcode/PasscodeBuilder.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/Passcode/PasscodeBuilder.swift rename to WavesWallet-iOS/Modules/Passcode/PasscodeBuilder.swift index 9ba86f1e..e70cf2da 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Passcode/PasscodeBuilder.swift +++ b/WavesWallet-iOS/Modules/Passcode/PasscodeBuilder.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions struct PasscodeModuleBuilder: ModuleBuilderOutput { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Passcode/PasscodeInteractor.swift b/WavesWallet-iOS/Modules/Passcode/PasscodeInteractor.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/Passcode/PasscodeInteractor.swift rename to WavesWallet-iOS/Modules/Passcode/PasscodeInteractor.swift index 63517f5f..c3b6a8da 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Passcode/PasscodeInteractor.swift +++ b/WavesWallet-iOS/Modules/Passcode/PasscodeInteractor.swift @@ -8,6 +8,7 @@ import Foundation import RxSwift +import DomainLayer protocol PasscodeInteractorProtocol { @@ -31,7 +32,7 @@ protocol PasscodeInteractorProtocol { final class PasscodeInteractor: PasscodeInteractorProtocol { - private let authorizationInteractor: AuthorizationInteractorProtocol = FactoryInteractors.instance.authorization + private let authorizationInteractor: AuthorizationUseCaseProtocol = UseCasesFactory.instance.authorization func changePassword(wallet: DomainLayer.DTO.Wallet, passcode: String, oldPassword: String, newPassword: String) -> Observable { return authorizationInteractor diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Passcode/PasscodeTypes.swift b/WavesWallet-iOS/Modules/Passcode/PasscodeTypes.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/Passcode/PasscodeTypes.swift rename to WavesWallet-iOS/Modules/Passcode/PasscodeTypes.swift index f24c8d36..ac345838 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Passcode/PasscodeTypes.swift +++ b/WavesWallet-iOS/Modules/Passcode/PasscodeTypes.swift @@ -7,7 +7,9 @@ // import Foundation -import WavesSDKCrypto +import WavesSDK +import DomainLayer +import Extensions enum PasscodeTypes { enum DTO { } @@ -43,7 +45,7 @@ extension PasscodeTypes { case .internetNotWorking: return .internetNotWorking - case .notFound: + case .notFound, .none: return .notFound case .serverError: @@ -57,7 +59,7 @@ extension PasscodeTypes { } - case let authError as AuthorizationInteractorError: + case let authError as AuthorizationUseCaseError: switch authError { case .attemptsEnded: if case .logIn = kind { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Passcode/PasscodeViewController.swift b/WavesWallet-iOS/Modules/Passcode/PasscodeViewController.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/Passcode/PasscodeViewController.swift rename to WavesWallet-iOS/Modules/Passcode/PasscodeViewController.swift index 6b8234a3..3c265e2c 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Passcode/PasscodeViewController.swift +++ b/WavesWallet-iOS/Modules/Passcode/PasscodeViewController.swift @@ -92,8 +92,7 @@ private extension PasscodeViewController { let isAppeared = (try? self.isAppeared.value()) ?? false return Observable.just(isAppeared) }) - .ignoreWhen({ $0 == false }) - .sweetDebug("UIApplicationWillEnterForeground") + .ignoreWhen({ $0 == false }) return Observable.merge([self.rx.viewDidAppear.asObservable(), applicationWillEnterForeground]) diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Passcode/Presenter/PasscodeChangePasscodeByPasswordPresenter.swift b/WavesWallet-iOS/Modules/Passcode/Presenter/PasscodeChangePasscodeByPasswordPresenter.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Passcode/Presenter/PasscodeChangePasscodeByPasswordPresenter.swift rename to WavesWallet-iOS/Modules/Passcode/Presenter/PasscodeChangePasscodeByPasswordPresenter.swift index 98078a84..74c1ef7d 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Passcode/Presenter/PasscodeChangePasscodeByPasswordPresenter.swift +++ b/WavesWallet-iOS/Modules/Passcode/Presenter/PasscodeChangePasscodeByPasswordPresenter.swift @@ -10,6 +10,7 @@ import Foundation import RxCocoa import RxFeedback import RxSwift +import DomainLayer private struct ChangePasscodeByPasswordQuery: Hashable { let wallet: DomainLayer.DTO.Wallet @@ -212,6 +213,10 @@ private extension PasscodeChangePasscodeByPasswordPresenter { private func handlerInputNumbersForChangePasscodeByPassword(_ numbers: [Int], state: inout Types.State) { + defer { + state.displayState.titleLabel = state.displayState.kind.title() + } + let kind = state.displayState.kind state.numbers[kind] = numbers @@ -245,10 +250,6 @@ private extension PasscodeChangePasscodeByPasswordPresenter { default: break } - - defer { - state.displayState.titleLabel = state.displayState.kind.title() - } } } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Passcode/Presenter/PasscodeChangePasswordPresenter.swift b/WavesWallet-iOS/Modules/Passcode/Presenter/PasscodeChangePasswordPresenter.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Passcode/Presenter/PasscodeChangePasswordPresenter.swift rename to WavesWallet-iOS/Modules/Passcode/Presenter/PasscodeChangePasswordPresenter.swift index f665384f..57469afe 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Passcode/Presenter/PasscodeChangePasswordPresenter.swift +++ b/WavesWallet-iOS/Modules/Passcode/Presenter/PasscodeChangePasswordPresenter.swift @@ -9,6 +9,7 @@ import Foundation import RxCocoa import RxFeedback import RxSwift +import DomainLayer private struct ChangePasswordQuery: Hashable { let wallet: DomainLayer.DTO.Wallet diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Passcode/Presenter/PasscodeEnableBiometricPresenter.swift b/WavesWallet-iOS/Modules/Passcode/Presenter/PasscodeEnableBiometricPresenter.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Passcode/Presenter/PasscodeEnableBiometricPresenter.swift rename to WavesWallet-iOS/Modules/Passcode/Presenter/PasscodeEnableBiometricPresenter.swift index 11e47067..b5cef6eb 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Passcode/Presenter/PasscodeEnableBiometricPresenter.swift +++ b/WavesWallet-iOS/Modules/Passcode/Presenter/PasscodeEnableBiometricPresenter.swift @@ -10,6 +10,7 @@ import Foundation import RxCocoa import RxFeedback import RxSwift +import DomainLayer private struct SetEnableBiometricQuery: Hashable { let wallet: DomainLayer.DTO.Wallet diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Passcode/Presenter/PasscodeLogInPresenter.swift b/WavesWallet-iOS/Modules/Passcode/Presenter/PasscodeLogInPresenter.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Passcode/Presenter/PasscodeLogInPresenter.swift rename to WavesWallet-iOS/Modules/Passcode/Presenter/PasscodeLogInPresenter.swift index 40d3cd43..77a97dc2 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Passcode/Presenter/PasscodeLogInPresenter.swift +++ b/WavesWallet-iOS/Modules/Passcode/Presenter/PasscodeLogInPresenter.swift @@ -10,6 +10,7 @@ import Foundation import RxCocoa import RxFeedback import RxSwift +import DomainLayer private struct LogInByBiometricQuery: Hashable { let wallet: DomainLayer.DTO.Wallet diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Passcode/Presenter/PasscodePresenter.swift b/WavesWallet-iOS/Modules/Passcode/Presenter/PasscodePresenter.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Passcode/Presenter/PasscodePresenter.swift rename to WavesWallet-iOS/Modules/Passcode/Presenter/PasscodePresenter.swift index abb236f2..267bcf83 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Passcode/Presenter/PasscodePresenter.swift +++ b/WavesWallet-iOS/Modules/Passcode/Presenter/PasscodePresenter.swift @@ -10,6 +10,7 @@ import Foundation import RxCocoa import RxFeedback import RxSwift +import DomainLayer private struct LogInByBiometricQuery: Hashable { let wallet: DomainLayer.DTO.Wallet @@ -655,6 +656,10 @@ private extension PasscodePresenter { private func handlerInputNumbersForChangePasscodeByPassword(_ numbers: [Int], state: inout Types.State) { + defer { + state.displayState.titleLabel = state.kind.title(kind: state.displayState.kind) + } + let kind = state.displayState.kind state.numbers[kind] = numbers @@ -688,16 +693,16 @@ private extension PasscodePresenter { default: break } - - defer { - state.displayState.titleLabel = state.kind.title(kind: state.displayState.kind) - } } // MARK: - Input Numbers For Chanage Passcode private func handlerInputNumbersForChangePasscode(_ numbers: [Int], state: inout Types.State) { + defer { + state.displayState.titleLabel = state.kind.title(kind: state.displayState.kind) + } + let kind = state.displayState.kind state.numbers[kind] = numbers @@ -740,16 +745,16 @@ private extension PasscodePresenter { default: break } - - defer { - state.displayState.titleLabel = state.kind.title(kind: state.displayState.kind) - } } // MARK: - Input Numbers For Registration private func handlerInputNumbersForRegistration(_ numbers: [Int], state: inout Types.State) { + defer { + state.displayState.titleLabel = state.kind.title(kind: state.displayState.kind) + } + let kind = state.displayState.kind state.numbers[kind] = numbers @@ -778,10 +783,6 @@ private extension PasscodePresenter { default: break } - - defer { - state.displayState.titleLabel = state.kind.title(kind: state.displayState.kind) - } } // MARK: - Input Numbers For Verify Access diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Passcode/Presenter/PasscodePresenterProtocol.swift b/WavesWallet-iOS/Modules/Passcode/Presenter/PasscodePresenterProtocol.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/Passcode/Presenter/PasscodePresenterProtocol.swift rename to WavesWallet-iOS/Modules/Passcode/Presenter/PasscodePresenterProtocol.swift index 4596e954..45ac02f0 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Passcode/Presenter/PasscodePresenterProtocol.swift +++ b/WavesWallet-iOS/Modules/Passcode/Presenter/PasscodePresenterProtocol.swift @@ -12,7 +12,7 @@ import Foundation import RxCocoa import RxFeedback import RxSwift - +import DomainLayer protocol PasscodeModuleOutput: AnyObject { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Passcode/Presenter/PasscodeRegistationPresenter.swift b/WavesWallet-iOS/Modules/Passcode/Presenter/PasscodeRegistationPresenter.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Passcode/Presenter/PasscodeRegistationPresenter.swift rename to WavesWallet-iOS/Modules/Passcode/Presenter/PasscodeRegistationPresenter.swift index d7a5f915..2d0f841d 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Passcode/Presenter/PasscodeRegistationPresenter.swift +++ b/WavesWallet-iOS/Modules/Passcode/Presenter/PasscodeRegistationPresenter.swift @@ -10,6 +10,7 @@ import Foundation import RxCocoa import RxFeedback import RxSwift +import DomainLayer private struct RegistationQuery: Hashable { let account: PasscodeTypes.DTO.Account @@ -185,6 +186,10 @@ private extension PasscodeRegistationPresenter { private func handlerInputNumbersForRegistration(_ numbers: [Int], state: inout Types.State) { + defer { + state.displayState.titleLabel = state.displayState.kind.title() + } + let kind = state.displayState.kind state.numbers[kind] = numbers @@ -213,10 +218,6 @@ private extension PasscodeRegistationPresenter { default: break } - - defer { - state.displayState.titleLabel = state.displayState.kind.title() - } } } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Passcode/Presenter/PasscodeVerifyAccessPresenter.swift b/WavesWallet-iOS/Modules/Passcode/Presenter/PasscodeVerifyAccessPresenter.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Passcode/Presenter/PasscodeVerifyAccessPresenter.swift rename to WavesWallet-iOS/Modules/Passcode/Presenter/PasscodeVerifyAccessPresenter.swift index 0eba1311..c5e4ee3f 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Passcode/Presenter/PasscodeVerifyAccessPresenter.swift +++ b/WavesWallet-iOS/Modules/Passcode/Presenter/PasscodeVerifyAccessPresenter.swift @@ -10,6 +10,7 @@ import Foundation import RxCocoa import RxFeedback import RxSwift +import DomainLayer private struct LogInByBiometricQuery: Hashable { let wallet: DomainLayer.DTO.Wallet diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/AddressesKeys/AddressesKeysModuleBuilder.swift b/WavesWallet-iOS/Modules/Profile/AddressesKeys/AddressesKeysModuleBuilder.swift similarity index 95% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/AddressesKeys/AddressesKeysModuleBuilder.swift rename to WavesWallet-iOS/Modules/Profile/AddressesKeys/AddressesKeysModuleBuilder.swift index 4989a36d..77fb13c3 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/AddressesKeys/AddressesKeysModuleBuilder.swift +++ b/WavesWallet-iOS/Modules/Profile/AddressesKeys/AddressesKeysModuleBuilder.swift @@ -7,6 +7,8 @@ // import UIKit +import DomainLayer +import Extensions struct AddressesKeysModuleBuilder: ModuleBuilderOutput { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/AddressesKeys/AddressesKeysPresenter.swift b/WavesWallet-iOS/Modules/Profile/AddressesKeys/AddressesKeysPresenter.swift similarity index 96% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/AddressesKeys/AddressesKeysPresenter.swift rename to WavesWallet-iOS/Modules/Profile/AddressesKeys/AddressesKeysPresenter.swift index 0cf3bd76..227e26ba 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/AddressesKeys/AddressesKeysPresenter.swift +++ b/WavesWallet-iOS/Modules/Profile/AddressesKeys/AddressesKeysPresenter.swift @@ -10,6 +10,7 @@ import Foundation import RxFeedback import RxSwift import RxCocoa +import DomainLayer protocol AddressesKeysModuleOutput: AnyObject { func addressesKeysNeedPrivateKey(wallet: DomainLayer.DTO.Wallet, callback: @escaping ((DomainLayer.DTO.SignedWallet?) -> Void)) @@ -34,8 +35,8 @@ final class AddressesKeysPresenter: AddressesKeysPresenterProtocol { fileprivate typealias Types = AddressesKeysTypes private let disposeBag: DisposeBag = DisposeBag() - private let authorizationInteractor: AuthorizationInteractorProtocol = FactoryInteractors.instance.authorization - private let aliasesRepository: AliasesRepositoryProtocol = FactoryRepositories.instance.aliasesRepositoryRemote + private let authorizationInteractor: AuthorizationUseCaseProtocol = UseCasesFactory.instance.authorization + private let aliasesRepository: AliasesRepositoryProtocol = UseCasesFactory.instance.repositories.aliasesRepositoryRemote var moduleInput: AddressesKeysModuleInput! weak var moduleOutput: AddressesKeysModuleOutput? diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/AddressesKeys/AddressesKeysTypes.swift b/WavesWallet-iOS/Modules/Profile/AddressesKeys/AddressesKeysTypes.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/AddressesKeys/AddressesKeysTypes.swift rename to WavesWallet-iOS/Modules/Profile/AddressesKeys/AddressesKeysTypes.swift index 35f26531..9f5e6d37 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/AddressesKeys/AddressesKeysTypes.swift +++ b/WavesWallet-iOS/Modules/Profile/AddressesKeys/AddressesKeysTypes.swift @@ -7,6 +7,8 @@ // import Foundation +import DomainLayer +import Extensions enum AddressesKeysTypes { enum ViewModel { } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/AddressesKeys/AddressesKeysViewController.swift b/WavesWallet-iOS/Modules/Profile/AddressesKeys/AddressesKeysViewController.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/AddressesKeys/AddressesKeysViewController.swift rename to WavesWallet-iOS/Modules/Profile/AddressesKeys/AddressesKeysViewController.swift index c1d153d2..56d235c3 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/AddressesKeys/AddressesKeysViewController.swift +++ b/WavesWallet-iOS/Modules/Profile/AddressesKeys/AddressesKeysViewController.swift @@ -10,6 +10,7 @@ import UIKit import RxFeedback import RxSwift import RxCocoa +import Extensions final class AddressesKeysViewController: UIViewController { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/AddressesKeys/Views/AddressesKeysAliacesCell.swift b/WavesWallet-iOS/Modules/Profile/AddressesKeys/Views/AddressesKeysAliacesCell.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/AddressesKeys/Views/AddressesKeysAliacesCell.swift rename to WavesWallet-iOS/Modules/Profile/AddressesKeys/Views/AddressesKeysAliacesCell.swift index 5b403787..5fb0f2af 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/AddressesKeys/Views/AddressesKeysAliacesCell.swift +++ b/WavesWallet-iOS/Modules/Profile/AddressesKeys/Views/AddressesKeysAliacesCell.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions private enum Constants { static let height: CGFloat = 60 diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/AddressesKeys/Views/AddressesKeysHiddenPrivateKeyCell.swift b/WavesWallet-iOS/Modules/Profile/AddressesKeys/Views/AddressesKeysHiddenPrivateKeyCell.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/AddressesKeys/Views/AddressesKeysHiddenPrivateKeyCell.swift rename to WavesWallet-iOS/Modules/Profile/AddressesKeys/Views/AddressesKeysHiddenPrivateKeyCell.swift index 08d25c53..8f35e8b7 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/AddressesKeys/Views/AddressesKeysHiddenPrivateKeyCell.swift +++ b/WavesWallet-iOS/Modules/Profile/AddressesKeys/Views/AddressesKeysHiddenPrivateKeyCell.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions private enum Constants { static let height: CGFloat = 94 diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/AddressesKeys/Views/AddressesKeysSkeletonCell.swift b/WavesWallet-iOS/Modules/Profile/AddressesKeys/Views/AddressesKeysSkeletonCell.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/AddressesKeys/Views/AddressesKeysSkeletonCell.swift rename to WavesWallet-iOS/Modules/Profile/AddressesKeys/Views/AddressesKeysSkeletonCell.swift index d50ef1a9..227a9318 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/AddressesKeys/Views/AddressesKeysSkeletonCell.swift +++ b/WavesWallet-iOS/Modules/Profile/AddressesKeys/Views/AddressesKeysSkeletonCell.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions private enum Constants { static let height: CGFloat = 60 diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/AddressesKeys/Views/AddressesKeysValueCell.swift b/WavesWallet-iOS/Modules/Profile/AddressesKeys/Views/AddressesKeysValueCell.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/AddressesKeys/Views/AddressesKeysValueCell.swift rename to WavesWallet-iOS/Modules/Profile/AddressesKeys/Views/AddressesKeysValueCell.swift index b99ba1e5..c485a9fb 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/AddressesKeys/Views/AddressesKeysValueCell.swift +++ b/WavesWallet-iOS/Modules/Profile/AddressesKeys/Views/AddressesKeysValueCell.swift @@ -6,6 +6,7 @@ // import UIKit +import Extensions private enum Constants { static let topPadding: CGFloat = 24 diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/AlertDeleteAccount/AlertDeleteAccountViewController.swift b/WavesWallet-iOS/Modules/Profile/AlertDeleteAccount/AlertDeleteAccountViewController.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/AlertDeleteAccount/AlertDeleteAccountViewController.swift rename to WavesWallet-iOS/Modules/Profile/AlertDeleteAccount/AlertDeleteAccountViewController.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/AliasWithout/AliasWithoutViewController.swift b/WavesWallet-iOS/Modules/Profile/AliasWithout/AliasWithoutViewController.swift similarity index 91% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/AliasWithout/AliasWithoutViewController.swift rename to WavesWallet-iOS/Modules/Profile/AliasWithout/AliasWithoutViewController.swift index a9fb90ee..459b0bbc 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/AliasWithout/AliasWithoutViewController.swift +++ b/WavesWallet-iOS/Modules/Profile/AliasWithout/AliasWithoutViewController.swift @@ -8,7 +8,8 @@ import UIKit import RxSwift - +import Extensions +import DomainLayer protocol AliasWithoutViewControllerDelegate: AnyObject { func aliasWithoutUserTapCreateNewAlias() @@ -24,8 +25,8 @@ final class AliasWithoutViewController: UIViewController, Localization { @IBOutlet private var transactionFeeView: TransactionFeeView! private let disposeBag: DisposeBag = DisposeBag() - private let transactionsInteractor = FactoryInteractors.instance.transactions - private let authorizationInteractor = FactoryInteractors.instance.authorization + private let transactionsInteractor = UseCasesFactory.instance.transactions + private let authorizationInteractor = UseCasesFactory.instance.authorization private var errorSnackKey: String? override func viewDidLoad() { @@ -72,9 +73,9 @@ final class AliasWithoutViewController: UIViewController, Localization { private func handlerError(_ error: Error) { - var displayError: DisplayError = .notFound + var displayError: DisplayError = .none - if let error = error as? TransactionsInteractorError, error == .commissionReceiving { + if let error = error as? TransactionsUseCaseError, error == .commissionReceiving { displayError = DisplayError.message(Localizable.Waves.Transaction.Error.Commission.receiving) } else { displayError = DisplayError(error: error) @@ -102,7 +103,7 @@ final class AliasWithoutViewController: UIViewController, Localization { self?.loadingFee() }) - case .notFound, .scriptError: + case .none, .scriptError: errorSnackKey = showErrorNotFoundSnack(didTap: { [weak self] in self?.loadingFee() }) diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Aliases/AliasesPresenterProtocol.swift b/WavesWallet-iOS/Modules/Profile/Aliases/AliasesPresenterProtocol.swift similarity index 94% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/Aliases/AliasesPresenterProtocol.swift rename to WavesWallet-iOS/Modules/Profile/Aliases/AliasesPresenterProtocol.swift index b9bf65eb..2d4154d0 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Aliases/AliasesPresenterProtocol.swift +++ b/WavesWallet-iOS/Modules/Profile/Aliases/AliasesPresenterProtocol.swift @@ -10,6 +10,8 @@ import Foundation import RxFeedback import RxSwift import RxCocoa +import DomainLayer +import Extensions protocol AliasesModuleOutput: AnyObject { func aliasesCreateAlias() @@ -33,8 +35,8 @@ final class AliasesPresenter: AliasesPresenterProtocol { private let disposeBag: DisposeBag = DisposeBag() - private let transactionsInteractor = FactoryInteractors.instance.transactions - private let authorizationInteractor = FactoryInteractors.instance.authorization + private let transactionsInteractor = UseCasesFactory.instance.transactions + private let authorizationInteractor = UseCasesFactory.instance.authorization var moduleInput: AliasesModuleInput! weak var moduleOutput: AliasesModuleOutput? @@ -125,7 +127,7 @@ private extension AliasesPresenter { case .handlerFeeError(let error): state.query = nil - if let error = error as? TransactionsInteractorError, error == .commissionReceiving { + if let error = error as? TransactionsUseCaseError, error == .commissionReceiving { state.displayState.error = .error(DisplayError.message(Localizable.Waves.Transaction.Error.Commission.receiving)) } else { state.displayState.error = .error(DisplayError(error: error)) diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Aliases/AliasesTypes.swift b/WavesWallet-iOS/Modules/Profile/Aliases/AliasesTypes.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/Aliases/AliasesTypes.swift rename to WavesWallet-iOS/Modules/Profile/Aliases/AliasesTypes.swift index 34476391..59ab7018 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Aliases/AliasesTypes.swift +++ b/WavesWallet-iOS/Modules/Profile/Aliases/AliasesTypes.swift @@ -7,6 +7,8 @@ // import Foundation +import Extensions +import DomainLayer enum AliasesTypes { enum ViewModel { } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Aliases/AliasesViewController.swift b/WavesWallet-iOS/Modules/Profile/Aliases/AliasesViewController.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/Aliases/AliasesViewController.swift rename to WavesWallet-iOS/Modules/Profile/Aliases/AliasesViewController.swift index 5eccfee3..2746fff0 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Aliases/AliasesViewController.swift +++ b/WavesWallet-iOS/Modules/Profile/Aliases/AliasesViewController.swift @@ -179,7 +179,7 @@ private extension AliasesViewController { self?.eventInput.onNext(.refresh) }) - case .notFound, .scriptError: + case .none, .scriptError: errorSnackKey = showErrorNotFoundSnack(didTap: { [weak self] in self?.eventInput.onNext(.refresh) }) diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Aliases/AliasesViewModuleBuilder.swift b/WavesWallet-iOS/Modules/Profile/Aliases/AliasesViewModuleBuilder.swift similarity index 94% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/Aliases/AliasesViewModuleBuilder.swift rename to WavesWallet-iOS/Modules/Profile/Aliases/AliasesViewModuleBuilder.swift index 73e2721e..be21b845 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Aliases/AliasesViewModuleBuilder.swift +++ b/WavesWallet-iOS/Modules/Profile/Aliases/AliasesViewModuleBuilder.swift @@ -7,6 +7,8 @@ // import UIKit +import DomainLayer +import Extensions struct AliasesModuleBuilder: ModuleBuilderOutput { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Aliases/Views/AliasesAliasCell.swift b/WavesWallet-iOS/Modules/Profile/Aliases/Views/AliasesAliasCell.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/Aliases/Views/AliasesAliasCell.swift rename to WavesWallet-iOS/Modules/Profile/Aliases/Views/AliasesAliasCell.swift index 01102dc1..13657449 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Aliases/Views/AliasesAliasCell.swift +++ b/WavesWallet-iOS/Modules/Profile/Aliases/Views/AliasesAliasCell.swift @@ -8,6 +8,7 @@ import Foundation import UIKit +import Extensions private enum Constants { static let height: CGFloat = 46 diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Aliases/Views/AliasesHeadCell.swift b/WavesWallet-iOS/Modules/Profile/Aliases/Views/AliasesHeadCell.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/Aliases/Views/AliasesHeadCell.swift rename to WavesWallet-iOS/Modules/Profile/Aliases/Views/AliasesHeadCell.swift index 934bcdb6..0d66cdbc 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Aliases/Views/AliasesHeadCell.swift +++ b/WavesWallet-iOS/Modules/Profile/Aliases/Views/AliasesHeadCell.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions private enum Constants { static let height: CGFloat = 156 diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Aliases/Views/AliasesInfoView.swift b/WavesWallet-iOS/Modules/Profile/Aliases/Views/AliasesInfoView.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/Aliases/Views/AliasesInfoView.swift rename to WavesWallet-iOS/Modules/Profile/Aliases/Views/AliasesInfoView.swift index 4b7c7679..df5f134d 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Aliases/Views/AliasesInfoView.swift +++ b/WavesWallet-iOS/Modules/Profile/Aliases/Views/AliasesInfoView.swift @@ -8,7 +8,8 @@ import Foundation import UIKit -import WavesSDKExtension +import WavesSDKExtensions +import Extensions private enum Constants { static let height: CGFloat = 258 diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/CreateAlias/CreateAliasInputCell.swift b/WavesWallet-iOS/Modules/Profile/CreateAlias/CreateAliasInputCell.swift similarity index 87% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/CreateAlias/CreateAliasInputCell.swift rename to WavesWallet-iOS/Modules/Profile/CreateAlias/CreateAliasInputCell.swift index 1c7ffbd1..fbff1e6f 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/CreateAlias/CreateAliasInputCell.swift +++ b/WavesWallet-iOS/Modules/Profile/CreateAlias/CreateAliasInputCell.swift @@ -8,16 +8,19 @@ import UIKit import RxSwift +import Extensions private enum Constants { static let height: CGFloat = 62 + static let errorFeeHeight: CGFloat = 50 } final class CreateAliasInputCell: UITableViewCell, Reusable { - @IBOutlet private var viewContainer: UIView! @IBOutlet private var inputTextField: InputTextField! - + @IBOutlet private weak var viewFeeError: UIView! + @IBOutlet private weak var labelFeeError: UILabel! + var disposeBag: DisposeBag = DisposeBag() override func prepareForReuse() { @@ -90,11 +93,13 @@ extension CreateAliasInputCell: ViewConfiguration { struct Model { let text: String? let error: String? + let isValidFee: Bool } func update(with model: CreateAliasInputCell.Model) { inputTextField.value = model.text inputTextField.error = model.error + viewFeeError.isHidden = model.isValidFee } } @@ -103,7 +108,8 @@ extension CreateAliasInputCell: ViewConfiguration { extension CreateAliasInputCell: ViewCalculateHeight { static func viewHeight(model: Model, width: CGFloat) -> CGFloat { - return Constants.height + + return Constants.height + (model.isValidFee ? 0 : Constants.errorFeeHeight) } } @@ -113,6 +119,6 @@ extension CreateAliasInputCell: ViewCalculateHeight { extension CreateAliasInputCell: Localization { func setupLocalization() { -// self.titleLabel.text = Localizable.Waves.Createalias.Cell.Input.Label.title + labelFeeError.text = Localizable.Waves.Send.Label.Error.notFundsFee } } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/CreateAlias/CreateAliasModuleBuilder.swift b/WavesWallet-iOS/Modules/Profile/CreateAlias/CreateAliasModuleBuilder.swift similarity index 96% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/CreateAlias/CreateAliasModuleBuilder.swift rename to WavesWallet-iOS/Modules/Profile/CreateAlias/CreateAliasModuleBuilder.swift index 06ddbadc..905a6759 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/CreateAlias/CreateAliasModuleBuilder.swift +++ b/WavesWallet-iOS/Modules/Profile/CreateAlias/CreateAliasModuleBuilder.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions struct CreateAliasModuleBuilder: ModuleBuilderOutput { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/CreateAlias/CreateAliasPresenter.swift b/WavesWallet-iOS/Modules/Profile/CreateAlias/CreateAliasPresenter.swift similarity index 74% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/CreateAlias/CreateAliasPresenter.swift rename to WavesWallet-iOS/Modules/Profile/CreateAlias/CreateAliasPresenter.swift index 5dcafce5..b68fd14c 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/CreateAlias/CreateAliasPresenter.swift +++ b/WavesWallet-iOS/Modules/Profile/CreateAlias/CreateAliasPresenter.swift @@ -10,8 +10,10 @@ import Foundation import RxFeedback import RxSwift import RxCocoa -import WavesSDKExtension -import WavesSDKCrypto +import WavesSDKExtensions +import WavesSDK +import Extensions +import DomainLayer protocol CreateAliasModuleOutput: AnyObject { func createAliasCompletedCreateAlias(_ alias: String) @@ -32,9 +34,10 @@ final class CreateAliasPresenter: CreateAliasPresenterProtocol { fileprivate typealias Types = CreateAliasTypes private let disposeBag: DisposeBag = DisposeBag() - private let aliasesRepository: AliasesRepositoryProtocol = FactoryRepositories.instance.aliasesRepositoryRemote - private let authorizationInteractor: AuthorizationInteractorProtocol = FactoryInteractors.instance.authorization - private let transactionsInteractor: TransactionsInteractorProtocol = FactoryInteractors.instance.transactions + private let aliasesRepository: AliasesRepositoryProtocol = UseCasesFactory.instance.repositories.aliasesRepositoryRemote + private let authorizationInteractor: AuthorizationUseCaseProtocol = UseCasesFactory.instance.authorization + private let transactionsInteractor: TransactionsUseCaseProtocol = UseCasesFactory.instance.transactions + private let accountBalanceInteractor: AccountBalanceUseCaseProtocol = UseCasesFactory.instance.accountBalance weak var moduleOutput: CreateAliasModuleOutput? @@ -44,7 +47,8 @@ final class CreateAliasPresenter: CreateAliasPresenterProtocol { newFeedbacks.append(checkExistAliasQuery()) newFeedbacks.append(getAliasesQuery()) newFeedbacks.append(externalQueries()) - + newFeedbacks.append(enoughtWavesFeeBalanceQuery()) + let initialState = self.initialState() let system = Driver.system(initialState: initialState, @@ -60,6 +64,41 @@ final class CreateAliasPresenter: CreateAliasPresenterProtocol { fileprivate extension CreateAliasPresenter { + func enoughtWavesFeeBalanceQuery() -> Feedback { + return react(request: { state -> Bool? in + + return state.displayState.isAppeared ? true : nil + + }, effects: { [weak self] _ -> Signal in + + guard let self = self else { return Signal.empty() } + return self + .authorizationInteractor.authorizedWallet() + .flatMap{ [weak self] wallet -> Observable in + guard let self = self else { return Observable.empty() } + + return self.transactionsInteractor.calculateFee(by: .createAlias, accountAddress: wallet.address) + .flatMap { [weak self] fee -> Observable in + guard let self = self else { return Observable.empty() } + + return self.accountBalanceInteractor + .balances() + .flatMap { (balances) -> Observable in + if let assetBalance = balances.first(where: {$0.assetId == WavesSDKConstants.wavesAssetId}) { + return Observable.just(assetBalance.availableBalance >= fee.amount) + } + return Observable.just(false) + } + } + } + .map {.didFinishValidateFeeBalance($0)} + .asSignal(onErrorRecover: { e in + SweetLogger.error(e) + return Signal.just(Types.Event.didFinishValidateFeeBalance(false)) + }) + }) + } + func externalQueries() -> Feedback { return react(request: { state -> Types.Query? in @@ -187,10 +226,10 @@ private extension CreateAliasPresenter { var inputError: String? = nil if let text = text { if RegEx.alias(text) { - if text.count < WavesSDKCryptoConstants.aliasNameMinLimitSymbols { + if text.count < WavesSDKConstants.aliasNameMinLimitSymbols { state.displayState.isEnabledSaveButton = false inputError = Localizable.Waves.Createalias.Error.minimumcharacters - } else if text.count > WavesSDKCryptoConstants.aliasNameMaxLimitSymbols { + } else if text.count > WavesSDKConstants.aliasNameMaxLimitSymbols { state.displayState.isEnabledSaveButton = false inputError = Localizable.Waves.Createalias.Error.charactersmaximum } else { @@ -216,7 +255,7 @@ private extension CreateAliasPresenter { state.query = nil state.displayState.action = .update state.displayState.isLoading = false - state.displayState.isEnabledSaveButton = true + state.displayState.isEnabledSaveButton = state.displayState.isValidEnoughtFee let section = Types.ViewModel.Section(rows: [.input(state.displayState.input, error: nil)]) state.displayState.sections = [section] @@ -231,7 +270,7 @@ private extension CreateAliasPresenter { case .handlerError(let error): state.query = nil state.displayState.isLoading = false - state.displayState.isEnabledSaveButton = true + state.displayState.isEnabledSaveButton = state.displayState.isValidEnoughtFee state.displayState.errorState = DisplayErrorState.error(DisplayError(error: error)) case .aliasCreated: @@ -250,6 +289,11 @@ private extension CreateAliasPresenter { case .completedQuery: state.query = nil + + case .didFinishValidateFeeBalance(let isValidEnoughtFee): + state.displayState.isEnabledSaveButton = isValidEnoughtFee + state.displayState.isValidEnoughtFee = isValidEnoughtFee + state.displayState.action = .updateValidationFeeBalance(isValidEnoughtFee) } } } @@ -271,7 +315,8 @@ private extension CreateAliasPresenter { isEnabledSaveButton: false, isLoading: false, isAppeared: false, - action: .none) + action: .none, + isValidEnoughtFee: true) } } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/CreateAlias/CreateAliasTypes.swift b/WavesWallet-iOS/Modules/Profile/CreateAlias/CreateAliasTypes.swift similarity index 88% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/CreateAlias/CreateAliasTypes.swift rename to WavesWallet-iOS/Modules/Profile/CreateAlias/CreateAliasTypes.swift index 1ec18240..57c3dbe9 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/CreateAlias/CreateAliasTypes.swift +++ b/WavesWallet-iOS/Modules/Profile/CreateAlias/CreateAliasTypes.swift @@ -7,6 +7,8 @@ // import Foundation +import Extensions +import DomainLayer enum CreateAliasTypes { enum ViewModel { } @@ -35,6 +37,7 @@ extension CreateAliasTypes { case aliasCreated case handlerError(Error) case completedQuery + case didFinishValidateFeeBalance(Bool) } struct DisplayState: Mutating, DataSourceProtocol { @@ -43,6 +46,7 @@ extension CreateAliasTypes { case none case reload case update + case updateValidationFeeBalance(Bool) } var sections: [ViewModel.Section] @@ -52,6 +56,7 @@ extension CreateAliasTypes { var isLoading: Bool var isAppeared: Bool var action: Action? + var isValidEnoughtFee: Bool } } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/CreateAlias/CreateAliasViewController.swift b/WavesWallet-iOS/Modules/Profile/CreateAlias/CreateAliasViewController.swift similarity index 92% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/CreateAlias/CreateAliasViewController.swift rename to WavesWallet-iOS/Modules/Profile/CreateAlias/CreateAliasViewController.swift index 0279fa62..6a03c13a 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/CreateAlias/CreateAliasViewController.swift +++ b/WavesWallet-iOS/Modules/Profile/CreateAlias/CreateAliasViewController.swift @@ -23,7 +23,8 @@ final class CreateAliasViewController: UIViewController { private var sections: [Types.ViewModel.Section] = [] private var eventInput: PublishSubject = PublishSubject() private var errorSnackKey: String? - + private var isValidFee: Bool = true + var presenter: CreateAliasPresenterProtocol! override func viewDidLoad() { @@ -163,11 +164,11 @@ private extension CreateAliasViewController { case .message(let text): errorSnackKey = showMessageSnack(title: text) - case .notFound: + case .none: errorSnackKey = showErrorNotFoundSnackWithoutAction() case .scriptError: - TransactionScriptErrorView.show() + _ = TransactionScriptErrorView.show() } case .none: @@ -190,11 +191,18 @@ private extension CreateAliasViewController { guard let indexPath = tableView.indexPath(for: inputCell) else { return } if case .input(let text, let error) = sections[indexPath] { - inputCell.update(with: .init(text: text, error: error)) + inputCell.update(with: .init(text: text, error: error, isValidFee: isValidFee)) + if self.isValidFee != isValidFee { + tableView.reloadData() + } } case .none: break + + case .updateValidationFeeBalance(let isValidFee): + self.isValidFee = isValidFee + tableView.reloadData() } } } @@ -219,7 +227,7 @@ extension CreateAliasViewController: UITableViewDataSource { switch row { case .input(let text, let error): let cell: CreateAliasInputCell = tableView.dequeueCell() - cell.update(with: .init(text: text, error: error)) + cell.update(with: .init(text: text, error: error, isValidFee: isValidFee)) cell .textFieldChangedValue @@ -247,7 +255,7 @@ extension CreateAliasViewController: UITableViewDelegate { let row = sections[indexPath] switch row { case .input(let text, let error): - return CreateAliasInputCell.viewHeight(model: .init(text: text, error: error), width: tableView.frame.width) + return CreateAliasInputCell.viewHeight(model: .init(text: text, error: error, isValidFee: isValidFee), width: tableView.frame.width) } } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Network/NetworkSettingsModuleBuilder.swift b/WavesWallet-iOS/Modules/Profile/Network/NetworkSettingsModuleBuilder.swift similarity index 94% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/Network/NetworkSettingsModuleBuilder.swift rename to WavesWallet-iOS/Modules/Profile/Network/NetworkSettingsModuleBuilder.swift index 15848d9c..9b3c7e74 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Network/NetworkSettingsModuleBuilder.swift +++ b/WavesWallet-iOS/Modules/Profile/Network/NetworkSettingsModuleBuilder.swift @@ -7,6 +7,8 @@ // import UIKit +import DomainLayer +import Extensions struct NetworkSettingsModuleBuilder: ModuleBuilderOutput { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Network/NetworkSettingsPresenter.swift b/WavesWallet-iOS/Modules/Profile/Network/NetworkSettingsPresenter.swift similarity index 92% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/Network/NetworkSettingsPresenter.swift rename to WavesWallet-iOS/Modules/Profile/Network/NetworkSettingsPresenter.swift index b12dbe73..afc527ac 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Network/NetworkSettingsPresenter.swift +++ b/WavesWallet-iOS/Modules/Profile/Network/NetworkSettingsPresenter.swift @@ -10,7 +10,7 @@ import Foundation import RxCocoa import RxFeedback import RxSwift -import WavesSDKCrypto +import DomainLayer protocol NetworkSettingsModuleOutput: AnyObject { func networkSettingSavedSetting() @@ -34,8 +34,9 @@ final class NetworkSettingsPresenter: NetworkSettingsPresenterProtocol { weak var moduleOutput: NetworkSettingsModuleOutput? var input: NetworkSettingsModuleInput! - private var accountSettingsRepository: AccountSettingsRepositoryProtocol = FactoryRepositories.instance.accountSettingsRepository - private var environmentRepository: EnvironmentRepositoryProtocol = FactoryRepositories.instance.environmentRepository + private var accountSettingsRepository: AccountSettingsRepositoryProtocol = UseCasesFactory.instance.repositories.accountSettingsRepository + + private var environmentRepository: EnvironmentRepositoryProtocol = UseCasesFactory.instance.repositories.environmentRepository private let disposeBag: DisposeBag = DisposeBag() @@ -101,14 +102,15 @@ final class NetworkSettingsPresenter: NetworkSettingsPresenterProtocol { let environment = self .environmentRepository - .accountEnvironment(accountAddress: address) + .walletEnvironment() let accountSettings = self.accountSettingsRepository .accountSettings(accountAddress: address) - .sweetDebug("accountSettings") + + let accountEnvironment = self.accountSettingsRepository.accountEnvironment(accountAddress: address) - return Observable.zip(environment, accountSettings) - .map { Types.Event.setEnvironmets($0.0, $0.1) } + return Observable.zip(environment, accountSettings, accountEnvironment) + .map { Types.Event.setEnvironmets($0.0, $0.1, $0.2) } .asSignal(onErrorRecover: { error in return Signal.just(Types.Event.handlerError(error)) }) @@ -131,7 +133,7 @@ final class NetworkSettingsPresenter: NetworkSettingsPresenterProtocol { let environment = self .environmentRepository - .deffaultEnvironment(accountAddress: address) + .deffaultEnvironment() return environment .map { Types.Event.setDeffaultEnvironmet($0) } @@ -169,9 +171,9 @@ final class NetworkSettingsPresenter: NetworkSettingsPresenterProtocol { }, effects: { [weak self] query -> Signal in guard let self = self else { return Signal.empty() } - + let environment = self - .environmentRepository + .accountSettingsRepository .setSpamURL(query.url, by: query.accountAddress) let accountSettings = query.accountSettings @@ -180,7 +182,8 @@ final class NetworkSettingsPresenter: NetworkSettingsPresenterProtocol { .accountSettingsRepository .saveAccountSettings(accountAddress: query.accountAddress, settings: accountSettings) - + + return Observable.zip(environment, saveAccountSettings) .map { _ in Types.Event.successSave } .asSignal(onErrorRecover: { error in @@ -206,10 +209,10 @@ private extension NetworkSettingsPresenter { case .readyView: state.displayState.isAppeared = true - case .setEnvironmets(let environment, let accountSettings): + case .setEnvironmets(let environment, let accountSettings, let accountEnvironment): state.environment = environment state.accountSettings = accountSettings - state.displayState.spamUrl = environment.servers.spamUrl.absoluteString + state.displayState.spamUrl = accountEnvironment?.spamUrl ?? environment.servers.spamUrl.absoluteString state.displayState.isSpam = accountSettings?.isEnabledSpam ?? false state.displayState.isEnabledSaveButton = true state.displayState.isEnabledSetDeffaultButton = true diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Network/NetworkSettingsTypes.swift b/WavesWallet-iOS/Modules/Profile/Network/NetworkSettingsTypes.swift similarity index 81% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/Network/NetworkSettingsTypes.swift rename to WavesWallet-iOS/Modules/Profile/Network/NetworkSettingsTypes.swift index cc800608..72332b5a 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Network/NetworkSettingsTypes.swift +++ b/WavesWallet-iOS/Modules/Profile/Network/NetworkSettingsTypes.swift @@ -7,8 +7,9 @@ // import Foundation -import WavesSDKExtension -import WavesSDKCrypto +import WavesSDKExtensions +import DomainLayer +import Extensions enum NetworkSettingsTypes { enum DTO { } @@ -25,7 +26,7 @@ extension NetworkSettingsTypes { struct State: Mutating { var wallet: DomainLayer.DTO.Wallet var accountSettings: DomainLayer.DTO.AccountSettings? - var environment: Environment? + var environment: WalletEnvironment? var displayState: DisplayState var query: Query? var isValidSpam: Bool @@ -33,8 +34,8 @@ extension NetworkSettingsTypes { enum Event { case readyView - case setEnvironmets(Environment, DomainLayer.DTO.AccountSettings?) - case setDeffaultEnvironmet(Environment) + case setEnvironmets(WalletEnvironment, DomainLayer.DTO.AccountSettings?, DomainLayer.DTO.AccountEnvironment?) + case setDeffaultEnvironmet(WalletEnvironment) case handlerError(Error) case inputSpam(String?) case switchSpam(Bool) diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Network/NetworkSettingsViewController.swift b/WavesWallet-iOS/Modules/Profile/Network/NetworkSettingsViewController.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/Network/NetworkSettingsViewController.swift rename to WavesWallet-iOS/Modules/Profile/Network/NetworkSettingsViewController.swift index a1565d59..7a1f81a8 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Network/NetworkSettingsViewController.swift +++ b/WavesWallet-iOS/Modules/Profile/Network/NetworkSettingsViewController.swift @@ -10,6 +10,7 @@ import UIKit import RxFeedback import RxCocoa import RxSwift +import Extensions final class NetworkSettingsViewController: UIViewController { @@ -38,7 +39,7 @@ final class NetworkSettingsViewController: UIViewController { saveButton.setBackgroundImage(UIColor.submit200.image, for: .disabled) saveButton.setBackgroundImage(UIColor.submit400.image, for: .normal) - hideTopBarLine() + hideTopBarLineForIOS12() setupBigNavigationBar() createBackButton() setupTextField() diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile.storyboard b/WavesWallet-iOS/Modules/Profile/Profile.storyboard similarity index 96% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile.storyboard rename to WavesWallet-iOS/Modules/Profile/Profile.storyboard index 4434ba83..3459afea 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile.storyboard +++ b/WavesWallet-iOS/Modules/Profile/Profile.storyboard @@ -1,11 +1,9 @@ - - - - + + - + @@ -728,7 +726,7 @@ - + @@ -1064,7 +1062,7 @@ - + @@ -1082,7 +1080,7 @@ - + - + @@ -1178,7 +1176,7 @@ - + @@ -1189,7 +1187,7 @@ - + @@ -1200,7 +1198,7 @@ diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/ProfileModuleBuilder.swift b/WavesWallet-iOS/Modules/Profile/Profile/ProfileModuleBuilder.swift similarity index 96% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/ProfileModuleBuilder.swift rename to WavesWallet-iOS/Modules/Profile/Profile/ProfileModuleBuilder.swift index fa0890ea..204b577a 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/ProfileModuleBuilder.swift +++ b/WavesWallet-iOS/Modules/Profile/Profile/ProfileModuleBuilder.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions struct ProfileModuleBuilder: ModuleBuilderOutput { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/ProfilePresenter.swift b/WavesWallet-iOS/Modules/Profile/Profile/ProfilePresenter.swift similarity index 80% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/ProfilePresenter.swift rename to WavesWallet-iOS/Modules/Profile/Profile/ProfilePresenter.swift index c3738a31..25af6315 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/ProfilePresenter.swift +++ b/WavesWallet-iOS/Modules/Profile/Profile/ProfilePresenter.swift @@ -10,6 +10,8 @@ import Foundation import RxFeedback import RxSwift import RxCocoa +import DomainLayer +import Extensions protocol ProfileModuleOutput: AnyObject { @@ -37,26 +39,15 @@ protocol ProfilePresenterProtocol { func system(feedbacks: [Feedback]) } -//public func reactQuery(owner: Owner, -// query: @escaping (State) -> Query?, -// effects: @escaping (Owner, Query) -> Void) -> (Driver) -> Signal { -// -// return react(request: query, effects: { [weak owner] query -> Signal in -// guard let self = owner else { return Signal.never() } -// effects(ownerStrong, query) -// return Signal.empty() -// }) -//} - final class ProfilePresenter: ProfilePresenterProtocol { fileprivate typealias Types = ProfileTypes private let disposeBag: DisposeBag = DisposeBag() - private let blockRepository: BlockRepositoryProtocol = FactoryRepositories.instance.blockRemote - private let authorizationInteractor: AuthorizationInteractorProtocol = FactoryInteractors.instance.authorization - private let walletsRepository: WalletsRepositoryProtocol = FactoryRepositories.instance.walletsRepositoryLocal + private let blockRepository: BlockRepositoryProtocol = UseCasesFactory.instance.repositories.blockRemote + private let authorizationInteractor: AuthorizationUseCaseProtocol = UseCasesFactory.instance.authorization + private let walletsRepository: WalletsRepositoryProtocol = UseCasesFactory.instance.repositories.walletsRepositoryLocal private var eventInput: PublishSubject = PublishSubject() weak var moduleOutput: ProfileModuleOutput? @@ -71,6 +62,8 @@ final class ProfilePresenter: ProfilePresenterProtocol { newFeedbacks.append(logoutAccountQuery()) newFeedbacks.append(handlerEvent()) newFeedbacks.append(setBackupQuery()) + newFeedbacks.append(setPushNotificationsQeury()) + newFeedbacks.append(registerPushNotificationsQeury()) let initialState = self.initialState() @@ -86,7 +79,7 @@ final class ProfilePresenter: ProfilePresenterProtocol { // MARK: - Feedbacks fileprivate extension ProfilePresenter { - fileprivate static func needQuery(_ state: Types.State) -> Types.Query? { + static func needQuery(_ state: Types.State) -> Types.Query? { guard let query = state.query else { return nil } @@ -103,7 +96,7 @@ fileprivate extension ProfilePresenter { .showSupport, .setEnabledBiometric, .showAlertForEnabledBiometric: - + return query default: break @@ -112,7 +105,7 @@ fileprivate extension ProfilePresenter { return nil } - fileprivate static func handlerQuery(owner: ProfilePresenter, query: Types.Query) { + static func handlerQuery(owner: ProfilePresenter, query: Types.Query) { switch query { case .showAddressesKeys(let wallet): @@ -158,6 +151,49 @@ fileprivate extension ProfilePresenter { } } + func registerPushNotificationsQeury() -> Feedback { + return react(request: { state -> Bool? in + guard let query = state.query else { return nil } + if case .registerPushNotifications = query { + return true + } else { + return nil + } + + }, effects: { _ -> Signal in + return PushNotificationsManager.rx.getNotificationsStatus() + .flatMap { (status) -> Observable in + if status == .notDetermined { + return PushNotificationsManager.rx.registerRemoteNotifications() + } + else { + return PushNotificationsManager.rx.openSettings().map { _ in false } + } + } + .map { Types.Event.setPushNotificationsSettings($0)} + .asSignal(onErrorRecover: { _ in + return Signal.empty() + }) + }) + } + + func setPushNotificationsQeury() -> Feedback { + return react(request: { state -> Bool? in + guard let query = state.query else { return nil } + if case .updatePushNotificationsSettings = query { + return true + } else { + return nil + } + + }, effects: { _ -> Signal in + return PushNotificationsManager.rx.getNotificationsStatus().map { Types.Event.setPushNotificationsSettings($0 == .authorized)} + .asSignal(onErrorRecover: { _ in + return Signal.empty() + }) + }) + } + func reactQuries() -> Feedback { return react(request: { state -> Types.Query? in @@ -252,7 +288,7 @@ fileprivate extension ProfilePresenter { return self .blockRepository - .height(accountAddress: address) + .height(accountAddress: address) .map { Types.Event.setBlock($0) } .asSignal(onErrorRecover: { _ in return Signal.empty() @@ -347,12 +383,13 @@ private extension ProfilePresenter { case .viewDidAppear: state.displayState.isAppeared = true - + state.query = .updatePushNotificationsSettings + case .setWallet(let wallet): let generalSettings = Types.ViewModel.Section(rows: [.addressesKeys, .addressbook, - .pushNotifications, + .pushNotifications(isActive: state.isActivePushNotifications), .language(Language.currentLanguage)], kind: .general) @@ -419,6 +456,10 @@ private extension ProfilePresenter { case .biometricDisabled: state.query = .showAlertForEnabledBiometric + case .pushNotifications(let isActive): + guard isActive == false else { return } + state.query = .registerPushNotifications + default: break } @@ -496,11 +537,47 @@ private extension ProfilePresenter { case .completedQuery: state.query = nil + case .setPushNotificationsSettings(let isActive): + state.isActivePushNotifications = isActive + updateInfo(state: &state, isActivePushNotifications: isActive) + state.displayState.action = .update + state.query = nil + + case .updatePushNotificationsSettings: + state.query = .updatePushNotificationsSettings + default: break } } + static func updateInfo(state: inout Types.State, isActivePushNotifications: Bool) { + + guard let section = state + .displayState + .sections + .enumerated() + .first(where: { $0.element.kind == .general }) else { return } + + guard let index = section + .element + .rows + .enumerated() + .first(where: { element in + if case .pushNotifications = element.element { + return true + } + return false + }) else { + return + } + + state + .displayState + .sections[section.offset] + .rows[index.offset] = .pushNotifications(isActive: isActivePushNotifications) + } + static func updateInfo(state: inout Types.State, block: Int64, isBackedUp: Bool) { guard let section = state @@ -537,7 +614,7 @@ private extension ProfilePresenter { private extension ProfilePresenter { func initialState() -> Types.State { - return Types.State(query: nil, wallet: nil, block: nil, displayState: initialDisplayState()) + return Types.State(query: nil, wallet: nil, block: nil, displayState: initialDisplayState(), isActivePushNotifications: false) } func initialDisplayState() -> Types.DisplayState { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/ProfileTypes.swift b/WavesWallet-iOS/Modules/Profile/Profile/ProfileTypes.swift similarity index 87% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/ProfileTypes.swift rename to WavesWallet-iOS/Modules/Profile/Profile/ProfileTypes.swift index 9e5875ba..a6d7faca 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/ProfileTypes.swift +++ b/WavesWallet-iOS/Modules/Profile/Profile/ProfileTypes.swift @@ -7,6 +7,8 @@ // import Foundation +import DomainLayer +import Extensions enum ProfileTypes { enum ViewModel { } @@ -30,6 +32,8 @@ extension ProfileTypes { case setBackedUp(Bool) case logoutAccount case deleteAccount + case updatePushNotificationsSettings + case registerPushNotifications } struct State: Mutating { @@ -37,6 +41,7 @@ extension ProfileTypes { var wallet: DomainLayer.DTO.Wallet? var block: Int64? var displayState: DisplayState + var isActivePushNotifications: Bool } enum Event { @@ -50,6 +55,8 @@ extension ProfileTypes { case tapLogout case tapDelete case completedQuery + case setPushNotificationsSettings(Bool) + case updatePushNotificationsSettings case none } @@ -62,7 +69,7 @@ extension ProfileTypes { var sections: [ViewModel.Section] var isAppeared: Bool - var action: Action? + var action: Action? } } @@ -71,7 +78,7 @@ extension ProfileTypes.ViewModel { enum Row { case addressesKeys case addressbook - case pushNotifications + case pushNotifications(isActive: Bool) case language(Language) case backupPhrase(isBackedUp: Bool) case changePassword diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/ProfileViewController.swift b/WavesWallet-iOS/Modules/Profile/Profile/ProfileViewController.swift similarity index 90% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/ProfileViewController.swift rename to WavesWallet-iOS/Modules/Profile/Profile/ProfileViewController.swift index 319d2eca..606c7a52 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/ProfileViewController.swift +++ b/WavesWallet-iOS/Modules/Profile/Profile/ProfileViewController.swift @@ -10,6 +10,8 @@ import UIKit import RxFeedback import RxSwift import RxCocoa +import Extensions +import DomainLayer private enum Constants { static let contentInset = UIEdgeInsets.init(top: 0, left: 0, bottom: 24, right: 0) @@ -35,16 +37,27 @@ final class ProfileViewController: UIViewController { setupLanguages() setupTableview() NotificationCenter.default.addObserver(self, selector: #selector(changedLanguage), name: .changedLanguage, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(appDidBecomeActive), name: UIApplication.didBecomeActiveNotification, object: nil) } - @objc func logoutTapped() { + @objc private func logoutTapped() { + + UseCasesFactory + .instance + .analyticManager + .trackEvent(.profile(.profileLogoutUp)) + eventInput.onNext(.tapLogout) } - @objc func changedLanguage() { + @objc private func changedLanguage() { setupLanguages() tableView.reloadData() } + + @objc private func appDidBecomeActive() { + eventInput.onNext(.updatePushNotificationsSettings) + } } //MARK: - MainTabBarControllerProtocol @@ -150,9 +163,9 @@ extension ProfileViewController: UITableViewDataSource { cell.update(with: .init(title: Localizable.Waves.Profile.Cell.Addressbook.title)) return cell - case .pushNotifications: - let cell: ProfileDisabledButtomTableCell = tableView.dequeueCell() - cell.update(with: Localizable.Waves.Profile.Cell.Pushnotifications.title) + case .pushNotifications(let isActive): + let cell: ProfileBackupPhraseCell = tableView.dequeueCell() + cell.update(with: .init(isBackedUp: isActive, title: Localizable.Waves.Profile.Cell.Pushnotifications.title)) return cell case .language(let language): @@ -162,7 +175,7 @@ extension ProfileViewController: UITableViewDataSource { case .backupPhrase(let isBackedUp): let cell: ProfileBackupPhraseCell = tableView.dequeueCell() - cell.update(with: .init(isBackedUp: isBackedUp)) + cell.update(with: .init(isBackedUp: isBackedUp, title: Localizable.Waves.Profile.Cell.Backupphrase.title)) return cell case .changePassword: @@ -222,6 +235,13 @@ extension ProfileViewController: UITableViewDataSource { } } cell.logoutButtonDidTap = { [weak self] in + + UseCasesFactory + .instance + .analyticManager + .trackEvent(.profile(.profileLogoutDown)) + + self?.eventInput.onNext(.tapLogout) } return cell @@ -290,11 +310,10 @@ extension ProfileViewController: UITableViewDelegate { .supportWavesplatform: return ProfileValueCell.cellHeight() - case .backupPhrase: + case .backupPhrase, .pushNotifications: return ProfileBackupPhraseCell.cellHeight() - case .pushNotifications, - .biometricDisabled: + case .biometricDisabled: return ProfileDisabledButtomTableCell.cellHeight() case .language: diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/Views/ProfileBackupPhraseCell.swift b/WavesWallet-iOS/Modules/Profile/Profile/Views/ProfileBackupPhraseCell.swift similarity index 95% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/Views/ProfileBackupPhraseCell.swift rename to WavesWallet-iOS/Modules/Profile/Profile/Views/ProfileBackupPhraseCell.swift index 0017b98a..aa4beaae 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/Views/ProfileBackupPhraseCell.swift +++ b/WavesWallet-iOS/Modules/Profile/Profile/Views/ProfileBackupPhraseCell.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions private enum Constants { static let cornerRadii = CGSize(width: 2, height: 2) @@ -17,6 +18,7 @@ final class ProfileBackupPhraseCell: UITableViewCell, Reusable { struct Model { let isBackedUp: Bool + let title: String } @IBOutlet private weak var labelTitle: UILabel! @@ -49,7 +51,7 @@ final class ProfileBackupPhraseCell: UITableViewCell, Reusable { extension ProfileBackupPhraseCell: ViewConfiguration { func update(with model: ProfileBackupPhraseCell.Model) { - labelTitle.text = Localizable.Waves.Profile.Cell.Backupphrase.title + labelTitle.text = model.title if model.isBackedUp { viewColorState.backgroundColor = .success400 iconState.image = Images.check18Success400.image diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/Views/ProfileBiometricCell.swift b/WavesWallet-iOS/Modules/Profile/Profile/Views/ProfileBiometricCell.swift similarity index 96% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/Views/ProfileBiometricCell.swift rename to WavesWallet-iOS/Modules/Profile/Profile/Views/ProfileBiometricCell.swift index 57d60e27..d32b71f9 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/Views/ProfileBiometricCell.swift +++ b/WavesWallet-iOS/Modules/Profile/Profile/Views/ProfileBiometricCell.swift @@ -7,6 +7,8 @@ // import UIKit +import DomainLayer +import Extensions private enum Constants { static let height: CGFloat = 56 diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/Views/ProfileDisabledButtomTableCell.swift b/WavesWallet-iOS/Modules/Profile/Profile/Views/ProfileDisabledButtomTableCell.swift similarity index 96% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/Views/ProfileDisabledButtomTableCell.swift rename to WavesWallet-iOS/Modules/Profile/Profile/Views/ProfileDisabledButtomTableCell.swift index acc54a6b..9e7c8c62 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/Views/ProfileDisabledButtomTableCell.swift +++ b/WavesWallet-iOS/Modules/Profile/Profile/Views/ProfileDisabledButtomTableCell.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions private enum Constants { static let height: CGFloat = 56 diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/Views/ProfileHeaderView.swift b/WavesWallet-iOS/Modules/Profile/Profile/Views/ProfileHeaderView.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/Views/ProfileHeaderView.swift rename to WavesWallet-iOS/Modules/Profile/Profile/Views/ProfileHeaderView.swift index 96b7e6b3..65a6f2a4 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/Views/ProfileHeaderView.swift +++ b/WavesWallet-iOS/Modules/Profile/Profile/Views/ProfileHeaderView.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions private enum Constants { static let height: CGFloat = 44 diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/Views/ProfileHeaderView.xib b/WavesWallet-iOS/Modules/Profile/Profile/Views/ProfileHeaderView.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/Views/ProfileHeaderView.xib rename to WavesWallet-iOS/Modules/Profile/Profile/Views/ProfileHeaderView.xib diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/Views/ProfileInfoCell.swift b/WavesWallet-iOS/Modules/Profile/Profile/Views/ProfileInfoCell.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/Views/ProfileInfoCell.swift rename to WavesWallet-iOS/Modules/Profile/Profile/Views/ProfileInfoCell.swift index 5e56e79e..06d51aed 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/Views/ProfileInfoCell.swift +++ b/WavesWallet-iOS/Modules/Profile/Profile/Views/ProfileInfoCell.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions private enum Constants { static let height: CGFloat = 258 diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/Views/ProfileLanguageCell.swift b/WavesWallet-iOS/Modules/Profile/Profile/Views/ProfileLanguageCell.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/Views/ProfileLanguageCell.swift rename to WavesWallet-iOS/Modules/Profile/Profile/Views/ProfileLanguageCell.swift index bef4c2e5..a14bce9d 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/Views/ProfileLanguageCell.swift +++ b/WavesWallet-iOS/Modules/Profile/Profile/Views/ProfileLanguageCell.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions private enum Constants { static let height: CGFloat = 56 diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/Views/ProfilePushTableCell.swift b/WavesWallet-iOS/Modules/Profile/Profile/Views/ProfilePushTableCell.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/Views/ProfilePushTableCell.swift rename to WavesWallet-iOS/Modules/Profile/Profile/Views/ProfilePushTableCell.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/Views/ProfileValueCell.swift b/WavesWallet-iOS/Modules/Profile/Profile/Views/ProfileValueCell.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/Views/ProfileValueCell.swift rename to WavesWallet-iOS/Modules/Profile/Profile/Views/ProfileValueCell.swift index a23e6d5f..2da1c1c8 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Profile/Profile/Views/ProfileValueCell.swift +++ b/WavesWallet-iOS/Modules/Profile/Profile/Views/ProfileValueCell.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions private enum Constants { static let height: CGFloat = 56 diff --git a/WavesWallet-iOS/Modules/PushNotifictions/PushNotificationsAlertView.swift b/WavesWallet-iOS/Modules/PushNotifictions/PushNotificationsAlertView.swift new file mode 100644 index 00000000..879c0273 --- /dev/null +++ b/WavesWallet-iOS/Modules/PushNotifictions/PushNotificationsAlertView.swift @@ -0,0 +1,44 @@ +// +// PushNotificationsAlertView.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 07.11.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import UIKit + +class PushNotificationsAlertView: PopupActionView { + + @IBOutlet private weak var labelTitle: UILabel! + @IBOutlet private weak var labelSubtitle: UILabel! + @IBOutlet private weak var buttonActivate: HighlightedButton! + @IBOutlet private weak var buttonLater: HighlightedButton! + + var activateAction:(() -> Void)? + var laterAction:(() -> Void)? + + override func awakeFromNib() { + super.awakeFromNib() + + setupLocalization() + } + + + private func setupLocalization() { + labelTitle.text = Localizable.Waves.Pushnotificationsalert.Label.title + labelSubtitle.text = Localizable.Waves.Pushnotificationsalert.Label.subtitle + buttonActivate.setTitle(Localizable.Waves.Pushnotificationsalert.Button.activatePush, for: .normal) + buttonLater.setTitle(Localizable.Waves.Pushnotificationsalert.Button.later, for: .normal) + } + + @IBAction private func laterTapped(_ sender: Any) { + dismiss() + laterAction?() + } + + @IBAction private func activateTapped(_ sender: Any) { + dismiss() + activateAction?() + } +} diff --git a/WavesWallet-iOS/Modules/PushNotifictions/PushNotificationsAlertView.xib b/WavesWallet-iOS/Modules/PushNotifictions/PushNotificationsAlertView.xib new file mode 100644 index 00000000..d8415a6b --- /dev/null +++ b/WavesWallet-iOS/Modules/PushNotifictions/PushNotificationsAlertView.xib @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/WavesWallet-iOS/Modules/PushNotifictions/PushNotificationsManager.swift b/WavesWallet-iOS/Modules/PushNotifictions/PushNotificationsManager.swift new file mode 100644 index 00000000..61329aec --- /dev/null +++ b/WavesWallet-iOS/Modules/PushNotifictions/PushNotificationsManager.swift @@ -0,0 +1,88 @@ +// +// PushNotificationsManager.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 08.11.2019. +// Copyright © 2019 Waves Platform. All rights reserved. +// + +import UIKit +import UserNotifications +import RxSwift + +extension PushNotificationsManager: ReactiveCompatible {} + +final class PushNotificationsManager { + + static func registerRemoteNotifications() { + + UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { + (granted, error) in + + guard granted else { return } + + DispatchQueue.main.async { + UIApplication.shared.registerForRemoteNotifications() + } + } + } +} + +extension Reactive where Base == PushNotificationsManager { + + static func openSettings() -> Observable { + return Observable.create { (subscribe) -> Disposable in + + guard let url = URL(string: UIApplication.openSettingsURLString) else { + subscribe.onNext(false) + subscribe.onCompleted() + return Disposables.create() + } + if UIApplication.shared.canOpenURL(url) { + UIApplication.shared.open(url, options: [:], completionHandler: nil) + subscribe.onNext(true) + subscribe.onCompleted() + } + else { + subscribe.onNext(false) + subscribe.onCompleted() + } + return Disposables.create() + } + } + static func getNotificationsStatus() -> Observable { + + return Observable.create { (subscribe) -> Disposable in + let current = UNUserNotificationCenter.current() + current.getNotificationSettings(completionHandler: { (settings) in + + subscribe.onNext(settings.authorizationStatus) + subscribe.onCompleted() + }) + return Disposables.create() + } + } + + static func registerRemoteNotifications() -> Observable { + + return Observable.create { (subscribe) -> Disposable in + + UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { + (granted, error) in + + guard granted else { + subscribe.onNext(false) + subscribe.onCompleted() + return + } + + DispatchQueue.main.async { + UIApplication.shared.registerForRemoteNotifications() + subscribe.onNext(true) + subscribe.onCompleted() + } + } + return Disposables.create() + } + } +} diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Address/ReceiveAddressModuleBuilder.swift b/WavesWallet-iOS/Modules/Receive/Address/ReceiveAddressModuleBuilder.swift similarity index 96% rename from WavesWallet-iOS/PresentationLayer/Modules/Receive/Address/ReceiveAddressModuleBuilder.swift rename to WavesWallet-iOS/Modules/Receive/Address/ReceiveAddressModuleBuilder.swift index 4cf9cff1..5fbdc482 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Address/ReceiveAddressModuleBuilder.swift +++ b/WavesWallet-iOS/Modules/Receive/Address/ReceiveAddressModuleBuilder.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions struct ReceiveAddressModuleBuilder: ModuleBuilder { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Address/ReceiveAddressTypes.swift b/WavesWallet-iOS/Modules/Receive/Address/ReceiveAddressTypes.swift similarity index 86% rename from WavesWallet-iOS/PresentationLayer/Modules/Receive/Address/ReceiveAddressTypes.swift rename to WavesWallet-iOS/Modules/Receive/Address/ReceiveAddressTypes.swift index 23b24eb9..f72f474a 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Address/ReceiveAddressTypes.swift +++ b/WavesWallet-iOS/Modules/Receive/Address/ReceiveAddressTypes.swift @@ -7,13 +7,15 @@ // import Foundation +import DomainLayer +import Extensions enum ReceiveAddress { enum DTO { struct Info { let assetName: String let address: String - let icon: DomainLayer.DTO.Asset.Icon + let icon: AssetLogo.Icon let qrCode: String let invoiceLink: String? let isSponsored: Bool diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Address/ReceiveAddressViewController.swift b/WavesWallet-iOS/Modules/Receive/Address/ReceiveAddressViewController.swift similarity index 90% rename from WavesWallet-iOS/PresentationLayer/Modules/Receive/Address/ReceiveAddressViewController.swift rename to WavesWallet-iOS/Modules/Receive/Address/ReceiveAddressViewController.swift index b103beb8..1db79bfc 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Address/ReceiveAddressViewController.swift +++ b/WavesWallet-iOS/Modules/Receive/Address/ReceiveAddressViewController.swift @@ -9,10 +9,10 @@ import UIKit import QRCode import RxSwift +import DataLayer +import Extensions private enum Constants { - static let icon = CGSize(width: 48, height: 48) - static let sponsoredIcon = CGSize(width: 18, height: 18) static let copyDuration: TimeInterval = 2 } @@ -46,8 +46,9 @@ final class ReceiveAddressViewController: UIViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) navigationItem.backgroundImage = UIImage() - hideTopBarLine() + removeTopBarLine() navigationItem.titleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.white] + navigationItem.largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.white] } private func createCancelButton() { @@ -72,18 +73,17 @@ final class ReceiveAddressViewController: UIViewController { labelQRCode.text = Localizable.Waves.Receiveaddress.Label.yourQRCode buttonClose.setTitle(Localizable.Waves.Receiveaddress.Button.close, for: .normal) labelInvoiceLinkLocalized.text = Localizable.Waves.Receiveaddress.Label.linkToInvoice + buttonCopy.setTitle(Localizable.Waves.Receiveaddress.Button.copy, for: .normal) + buttonShare.setTitle(Localizable.Waves.Receiveaddress.Button.share, for: .normal) } private func setupInfo() { + title = Localizable.Waves.Receiveaddress.Label.yourAddress(input.assetName) labelAddress.text = input.address - + AssetLogo.logo(icon: input.icon, - style: AssetLogo.Style(size: Constants.icon, - font: UIFont.systemFont(ofSize: 22), - specs: .init(isSponsored: input.isSponsored, - hasScript: input.hasScript, - size: Constants.sponsoredIcon))) + style: .large) .observeOn(MainScheduler.instance) .bind(to: iconAsset.rx.image) .disposed(by: disposeBag) diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Card/Interactor/ReceiveCardInteractor.swift b/WavesWallet-iOS/Modules/Receive/Card/Interactor/ReceiveCardInteractor.swift similarity index 89% rename from WavesWallet-iOS/PresentationLayer/Modules/Receive/Card/Interactor/ReceiveCardInteractor.swift rename to WavesWallet-iOS/Modules/Receive/Card/Interactor/ReceiveCardInteractor.swift index e53d5019..c672695a 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Card/Interactor/ReceiveCardInteractor.swift +++ b/WavesWallet-iOS/Modules/Receive/Card/Interactor/ReceiveCardInteractor.swift @@ -8,13 +8,16 @@ import Foundation import RxSwift -import WavesSDKCrypto +import WavesSDKExtensions +import WavesSDK +import DomainLayer +import Extensions final class ReceiveCardInteractor: ReceiveCardInteractorProtocol { - private let auth = FactoryInteractors.instance.authorization - private let coinomatRepository = FactoryRepositories.instance.coinomatRepository - private let accountBalance = FactoryInteractors.instance.accountBalance + private let auth = UseCasesFactory.instance.authorization + private let coinomatRepository = UseCasesFactory.instance.repositories.coinomatRepository + private let accountBalance = UseCasesFactory.instance.accountBalance func getInfo(fiatType: ReceiveCard.DTO.FiatType) -> Observable> { @@ -38,7 +41,7 @@ final class ReceiveCardInteractor: ReceiveCardInteractorProtocol { func getWavesAmount(fiatAmount: Money, fiatType: ReceiveCard.DTO.FiatType) -> Observable> { - let authAccount = FactoryInteractors.instance.authorization + let authAccount = UseCasesFactory.instance.authorization return authAccount .authorizedWallet() .flatMap({ [weak self] (wallet) -> Observable> in @@ -63,7 +66,7 @@ private extension ReceiveCardInteractor { //TODO: need optimize return accountBalance.balances().flatMap({ balances -> Observable in - guard let wavesAsset = balances.first(where: {$0.asset.wavesId == WavesSDKCryptoConstants.wavesAssetId}) else { + guard let wavesAsset = balances.first(where: {$0.asset.wavesId == WavesSDKConstants.wavesAssetId}) else { return Observable.empty() } return Observable.just(wavesAsset) diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Card/Interactor/ReceiveCardInteractorProtocol.swift b/WavesWallet-iOS/Modules/Receive/Card/Interactor/ReceiveCardInteractorProtocol.swift similarity index 92% rename from WavesWallet-iOS/PresentationLayer/Modules/Receive/Card/Interactor/ReceiveCardInteractorProtocol.swift rename to WavesWallet-iOS/Modules/Receive/Card/Interactor/ReceiveCardInteractorProtocol.swift index ebdbcab5..b36fb2c9 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Card/Interactor/ReceiveCardInteractorProtocol.swift +++ b/WavesWallet-iOS/Modules/Receive/Card/Interactor/ReceiveCardInteractorProtocol.swift @@ -8,6 +8,8 @@ import Foundation import RxSwift +import DomainLayer +import Extensions protocol ReceiveCardInteractorProtocol { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Card/Presenter/ReceiveCardPresenter.swift b/WavesWallet-iOS/Modules/Receive/Card/Presenter/ReceiveCardPresenter.swift similarity index 96% rename from WavesWallet-iOS/PresentationLayer/Modules/Receive/Card/Presenter/ReceiveCardPresenter.swift rename to WavesWallet-iOS/Modules/Receive/Card/Presenter/ReceiveCardPresenter.swift index dfa2ffd4..6c8a2d4f 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Card/Presenter/ReceiveCardPresenter.swift +++ b/WavesWallet-iOS/Modules/Receive/Card/Presenter/ReceiveCardPresenter.swift @@ -10,15 +10,16 @@ import Foundation import RxSwift import RxFeedback import RxCocoa -import WavesSDKExtension -import WavesSDKCrypto +import WavesSDK +import Extensions +import DomainLayer final class ReceiveCardPresenter: ReceiveCardPresenterProtocol { var interactor: ReceiveCardInteractorProtocol! private let disposeBag = DisposeBag() - private let coinomateRepository = FactoryRepositories.instance.coinomatRepository + private let coinomateRepository = UseCasesFactory.instance.repositories.coinomatRepository func system(feedbacks: [ReceiveCardPresenter.Feedback]) { var newFeedbacks = feedbacks @@ -43,7 +44,7 @@ final class ReceiveCardPresenter: ReceiveCardPresenterProtocol { guard let self = self else { return Signal.empty() } let emptyAmount: Signal = Signal.just(.didGetPriceInfo( - ResponseType(output: Money(0, WavesSDKCryptoConstants.WavesDecimals), error: nil))) + ResponseType(output: Money(0, WavesSDKConstants.WavesDecimals), error: nil))) .asSignal(onErrorSignalWith: Signal.empty()) guard let amount = state.amount else { return emptyAmount } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Card/Presenter/ReceiveCardPresenterProtocol.swift b/WavesWallet-iOS/Modules/Receive/Card/Presenter/ReceiveCardPresenterProtocol.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Receive/Card/Presenter/ReceiveCardPresenterProtocol.swift rename to WavesWallet-iOS/Modules/Receive/Card/Presenter/ReceiveCardPresenterProtocol.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Card/ReceiveCardModuleBuilder.swift b/WavesWallet-iOS/Modules/Receive/Card/ReceiveCardModuleBuilder.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/Receive/Card/ReceiveCardModuleBuilder.swift rename to WavesWallet-iOS/Modules/Receive/Card/ReceiveCardModuleBuilder.swift index 08f13216..9eda6ff8 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Card/ReceiveCardModuleBuilder.swift +++ b/WavesWallet-iOS/Modules/Receive/Card/ReceiveCardModuleBuilder.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions struct ReceiveCardModuleBuilder: ModuleBuilder { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Card/ReceiveCardTypes.swift b/WavesWallet-iOS/Modules/Receive/Card/ReceiveCardTypes.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/Receive/Card/ReceiveCardTypes.swift rename to WavesWallet-iOS/Modules/Receive/Card/ReceiveCardTypes.swift index 7efcf5ab..6dfd20fa 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Card/ReceiveCardTypes.swift +++ b/WavesWallet-iOS/Modules/Receive/Card/ReceiveCardTypes.swift @@ -7,6 +7,9 @@ // import Foundation +import WavesSDK +import Extensions +import DomainLayer enum ReceiveCard { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Card/ReceiveCardViewController.swift b/WavesWallet-iOS/Modules/Receive/Card/ReceiveCardViewController.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/Receive/Card/ReceiveCardViewController.swift rename to WavesWallet-iOS/Modules/Receive/Card/ReceiveCardViewController.swift index 94c16c41..85ae2068 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Card/ReceiveCardViewController.swift +++ b/WavesWallet-iOS/Modules/Receive/Card/ReceiveCardViewController.swift @@ -10,8 +10,10 @@ import UIKit import RxSwift import RxCocoa import RxFeedback -import WavesSDKExtension -import WavesSDKCrypto +import WavesSDKExtensions +import WavesSDK +import DomainLayer +import Extensions final class ReceiveCardViewController: UIViewController { @@ -36,7 +38,7 @@ final class ReceiveCardViewController: UIViewController { private var amountUSDInfo: ReceiveCard.DTO.AmountInfo? private var amountEURInfo: ReceiveCard.DTO.AmountInfo? private var asset: DomainLayer.DTO.SmartAssetBalance? - private var amount: Money = Money(0, WavesSDKCryptoConstants.FiatDecimals) + private var amount: Money = Money(0, WavesSDKConstants.FiatDecimals) private var urlLink = "" override func viewDidLoad() { @@ -62,7 +64,7 @@ final class ReceiveCardViewController: UIViewController { let vc = StoryboardScene.Receive.receiveCardCompleteViewController.instantiate() navigationController?.pushViewController(vc, animated: false) - AnalyticManager.trackEvent(.walletAsset(.cardReceiveTap)) + UseCasesFactory.instance.analyticManager.trackEvent(.receive(.cardReceiveTap)) } @IBAction private func changeCurrency(_ sender: Any) { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Receive/CardComplete/ReceiveCardCompleteViewController.swift b/WavesWallet-iOS/Modules/Receive/CardComplete/ReceiveCardCompleteViewController.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/Receive/CardComplete/ReceiveCardCompleteViewController.swift rename to WavesWallet-iOS/Modules/Receive/CardComplete/ReceiveCardCompleteViewController.swift index 2735d943..660b6689 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Receive/CardComplete/ReceiveCardCompleteViewController.swift +++ b/WavesWallet-iOS/Modules/Receive/CardComplete/ReceiveCardCompleteViewController.swift @@ -23,7 +23,7 @@ final class ReceiveCardCompleteViewController: UIViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) setupSmallNavigationBar() - hideTopBarLine() + removeTopBarLine() navigationItem.backgroundImage = UIImage() navigationItem.hidesBackButton = true } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Generate/ReceiveGenerateAddressModuleBuilder.swift b/WavesWallet-iOS/Modules/Receive/Generate/ReceiveGenerateAddressModuleBuilder.swift similarity index 96% rename from WavesWallet-iOS/PresentationLayer/Modules/Receive/Generate/ReceiveGenerateAddressModuleBuilder.swift rename to WavesWallet-iOS/Modules/Receive/Generate/ReceiveGenerateAddressModuleBuilder.swift index d9e67765..b0bc570f 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Generate/ReceiveGenerateAddressModuleBuilder.swift +++ b/WavesWallet-iOS/Modules/Receive/Generate/ReceiveGenerateAddressModuleBuilder.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions struct ReceiveGenerateAddressModuleBuilder: ModuleBuilder { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Generate/ReceiveGenerateAddressViewController.swift b/WavesWallet-iOS/Modules/Receive/Generate/ReceiveGenerateAddressViewController.swift similarity index 95% rename from WavesWallet-iOS/PresentationLayer/Modules/Receive/Generate/ReceiveGenerateAddressViewController.swift rename to WavesWallet-iOS/Modules/Receive/Generate/ReceiveGenerateAddressViewController.swift index 84d31e9b..f83ca21f 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Generate/ReceiveGenerateAddressViewController.swift +++ b/WavesWallet-iOS/Modules/Receive/Generate/ReceiveGenerateAddressViewController.swift @@ -39,8 +39,9 @@ final class ReceiveGenerateAddressViewController: UIViewController { super.viewWillAppear(animated) navigationItem.backgroundImage = UIImage() - hideTopBarLine() + removeTopBarLine() navigationItem.titleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.white] + navigationItem.largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.white] } override func viewWillDisappear(_ animated: Bool) { @@ -49,6 +50,7 @@ final class ReceiveGenerateAddressViewController: UIViewController { navigationItem.backgroundImage = nil showTopBarLine() navigationItem.titleTextAttributes = nil + navigationItem.largeTitleTextAttributes = nil } private func acceptGeneratingAddress() { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Generate/ReceiveGenerateTypes.swift b/WavesWallet-iOS/Modules/Receive/Generate/ReceiveGenerateTypes.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Receive/Generate/ReceiveGenerateTypes.swift rename to WavesWallet-iOS/Modules/Receive/Generate/ReceiveGenerateTypes.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Invoice/Interactor/ReceiveInvoiceInteractor.swift b/WavesWallet-iOS/Modules/Receive/Invoice/Interactor/ReceiveInvoiceInteractor.swift similarity index 92% rename from WavesWallet-iOS/PresentationLayer/Modules/Receive/Invoice/Interactor/ReceiveInvoiceInteractor.swift rename to WavesWallet-iOS/Modules/Receive/Invoice/Interactor/ReceiveInvoiceInteractor.swift index c4dc0a72..5f0a29e8 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Invoice/Interactor/ReceiveInvoiceInteractor.swift +++ b/WavesWallet-iOS/Modules/Receive/Invoice/Interactor/ReceiveInvoiceInteractor.swift @@ -8,7 +8,9 @@ import Foundation import RxSwift -import WavesSDKExtension +import WavesSDKExtensions +import DomainLayer +import Extensions private enum Constancts { static let baseUrl = "https://client.wavesplatform.com/" @@ -19,7 +21,7 @@ final class ReceiveInvoiceInteractor: ReceiveInvoiceInteractorProtocol { func displayInfo(asset: DomainLayer.DTO.Asset, amount: Money) -> Observable { - let authAccount = FactoryInteractors.instance.authorization + let authAccount = UseCasesFactory.instance.authorization return authAccount.authorizedWallet() .flatMap({ signedWallet -> Observable in diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Invoice/Interactor/ReceiveInvoiceInteractorProtocol.swift b/WavesWallet-iOS/Modules/Receive/Invoice/Interactor/ReceiveInvoiceInteractorProtocol.swift similarity index 85% rename from WavesWallet-iOS/PresentationLayer/Modules/Receive/Invoice/Interactor/ReceiveInvoiceInteractorProtocol.swift rename to WavesWallet-iOS/Modules/Receive/Invoice/Interactor/ReceiveInvoiceInteractorProtocol.swift index d7a88af2..f814ca7e 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Invoice/Interactor/ReceiveInvoiceInteractorProtocol.swift +++ b/WavesWallet-iOS/Modules/Receive/Invoice/Interactor/ReceiveInvoiceInteractorProtocol.swift @@ -8,7 +8,9 @@ import Foundation import RxSwift -import WavesSDKExtension +import WavesSDKExtensions +import DomainLayer +import Extensions protocol ReceiveInvoiceInteractorProtocol { func displayInfo(asset: DomainLayer.DTO.Asset, amount: Money) -> Observable diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Invoice/ReceiveInvoiceModuleBuilder.swift b/WavesWallet-iOS/Modules/Receive/Invoice/ReceiveInvoiceModuleBuilder.swift similarity index 96% rename from WavesWallet-iOS/PresentationLayer/Modules/Receive/Invoice/ReceiveInvoiceModuleBuilder.swift rename to WavesWallet-iOS/Modules/Receive/Invoice/ReceiveInvoiceModuleBuilder.swift index 5a1e3cd7..2d862e85 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Invoice/ReceiveInvoiceModuleBuilder.swift +++ b/WavesWallet-iOS/Modules/Receive/Invoice/ReceiveInvoiceModuleBuilder.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions struct ReceiveInvoiceModuleBuilder: ModuleBuilder { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Invoice/ReceiveInvoiceViewController.swift b/WavesWallet-iOS/Modules/Receive/Invoice/ReceiveInvoiceViewController.swift similarity index 96% rename from WavesWallet-iOS/PresentationLayer/Modules/Receive/Invoice/ReceiveInvoiceViewController.swift rename to WavesWallet-iOS/Modules/Receive/Invoice/ReceiveInvoiceViewController.swift index 42a99ac1..718a6de4 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Invoice/ReceiveInvoiceViewController.swift +++ b/WavesWallet-iOS/Modules/Receive/Invoice/ReceiveInvoiceViewController.swift @@ -7,6 +7,8 @@ // import UIKit +import Extensions +import DomainLayer final class ReceiveInvoiceViewController: UIViewController { @@ -45,7 +47,7 @@ final class ReceiveInvoiceViewController: UIViewController { let vc = ReceiveGenerateAddressModuleBuilder().build(input: .invoice(info)) navigationController?.pushViewController(vc, animated: true) - AnalyticManager.trackEvent(.walletAsset(.receiveTap(assetName: info.assetName))) + UseCasesFactory.instance.analyticManager.trackEvent(.receive(.receiveTap(assetName: info.assetName))) } private func setupInfo(asset: DomainLayer.DTO.SmartAssetBalance) { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Invoice/ReceiveInvoiveTypes.swift b/WavesWallet-iOS/Modules/Receive/Invoice/ReceiveInvoiveTypes.swift similarity index 85% rename from WavesWallet-iOS/PresentationLayer/Modules/Receive/Invoice/ReceiveInvoiveTypes.swift rename to WavesWallet-iOS/Modules/Receive/Invoice/ReceiveInvoiveTypes.swift index 430bb1a8..ed346a80 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Invoice/ReceiveInvoiveTypes.swift +++ b/WavesWallet-iOS/Modules/Receive/Invoice/ReceiveInvoiveTypes.swift @@ -7,6 +7,8 @@ // import Foundation +import DomainLayer +import Extensions enum ReceiveInvoice { enum DTO {} @@ -18,7 +20,7 @@ extension ReceiveInvoice.DTO { let address: String let invoiceLink: String let assetName: String - let icon: DomainLayer.DTO.Asset.Icon + let icon: AssetLogo.Icon let isSponsored: Bool let hasScript: Bool } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Receive.storyboard b/WavesWallet-iOS/Modules/Receive/Receive.storyboard similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Receive/Receive.storyboard rename to WavesWallet-iOS/Modules/Receive/Receive.storyboard diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Receive/ReceiveContainerModuleBuilder.swift b/WavesWallet-iOS/Modules/Receive/ReceiveContainerModuleBuilder.swift similarity index 98% rename from WavesWallet-iOS/PresentationLayer/Modules/Receive/ReceiveContainerModuleBuilder.swift rename to WavesWallet-iOS/Modules/Receive/ReceiveContainerModuleBuilder.swift index 78559cf6..4c196a84 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Receive/ReceiveContainerModuleBuilder.swift +++ b/WavesWallet-iOS/Modules/Receive/ReceiveContainerModuleBuilder.swift @@ -7,6 +7,8 @@ // import UIKit +import DomainLayer +import Extensions struct ReceiveContainerModuleBuilder: ModuleBuilder { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Receive/ReceiveContainerViewController.swift b/WavesWallet-iOS/Modules/Receive/ReceiveContainerViewController.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Receive/ReceiveContainerViewController.swift rename to WavesWallet-iOS/Modules/Receive/ReceiveContainerViewController.swift index 7bd9dda6..2f55792f 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Receive/ReceiveContainerViewController.swift +++ b/WavesWallet-iOS/Modules/Receive/ReceiveContainerViewController.swift @@ -7,7 +7,7 @@ // import UIKit - +import DomainLayer private enum Constants { static let minScrollOffsetOnKeyboardDismiss: CGFloat = -0.3 diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Receive/ReceiveTypes.swift b/WavesWallet-iOS/Modules/Receive/ReceiveTypes.swift similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Receive/ReceiveTypes.swift rename to WavesWallet-iOS/Modules/Receive/ReceiveTypes.swift diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Views/AssetSelectSkeletonView.swift b/WavesWallet-iOS/Modules/Receive/Views/AssetSelectSkeletonView.swift similarity index 97% rename from WavesWallet-iOS/PresentationLayer/Modules/Receive/Views/AssetSelectSkeletonView.swift rename to WavesWallet-iOS/Modules/Receive/Views/AssetSelectSkeletonView.swift index f00b579a..909c5888 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Views/AssetSelectSkeletonView.swift +++ b/WavesWallet-iOS/Modules/Receive/Views/AssetSelectSkeletonView.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions final class AssetSelectSkeletonView: SkeletonView, NibOwnerLoadable { diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Views/AssetSelectSkeletonView.xib b/WavesWallet-iOS/Modules/Receive/Views/AssetSelectSkeletonView.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Receive/Views/AssetSelectSkeletonView.xib rename to WavesWallet-iOS/Modules/Receive/Views/AssetSelectSkeletonView.xib diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Views/AssetSelectView.swift b/WavesWallet-iOS/Modules/Receive/Views/AssetSelectView.swift similarity index 85% rename from WavesWallet-iOS/PresentationLayer/Modules/Receive/Views/AssetSelectView.swift rename to WavesWallet-iOS/Modules/Receive/Views/AssetSelectView.swift index bebe513e..728df77a 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Views/AssetSelectView.swift +++ b/WavesWallet-iOS/Modules/Receive/Views/AssetSelectView.swift @@ -8,16 +8,16 @@ import UIKit import RxSwift -import WavesSDKExtension -import WavesSDKCrypto +import WavesSDK +import Extensions +import DomainLayer +import DataLayer private enum Constants { static let borderRadius: CGFloat = 2 static let borderWidth: CGFloat = 0.5 static let assetRightOffsetSelectedMode: CGFloat = 36 static let assetRightOffsetNotSelectedMode: CGFloat = 14 - static let icon = CGSize(width: 24, height: 24) - static let sponsoredIcon = CGSize(width: 10, height: 10) } protocol AssetSelectViewDelegate: AnyObject { @@ -77,9 +77,11 @@ final class AssetSelectView: UIView, NibOwnerLoadable { labelAmount.isHidden = true //TODO: mb get url from enviromnets - loadIcon(icon: .init(assetId: WavesSDKCryptoConstants.wavesAssetId, - name: WavesSDKCryptoConstants.wavesAssetId, - url: nil), isSponsored: false, hasScript: false) + loadIcon(icon: .init(assetId: WavesSDKConstants.wavesAssetId, + name: WavesSDKConstants.wavesAssetId, + url: nil, + isSponsored: false, + hasScript: false), isSponsored: false, hasScript: false) } func showLoadingState() { @@ -135,16 +137,12 @@ extension AssetSelectView: ViewConfiguration { labelAmount.text = money.displayText } - private func loadIcon(icon: DomainLayer.DTO.Asset.Icon, isSponsored: Bool, hasScript: Bool) { + private func loadIcon(icon: AssetLogo.Icon, isSponsored: Bool, hasScript: Bool) { disposeBag = DisposeBag() AssetLogo.logo(icon: icon, - style: AssetLogo.Style(size: Constants.icon, - font: UIFont.systemFont(ofSize: 15), - specs: .init(isSponsored: isSponsored, - hasScript: hasScript, - size: Constants.sponsoredIcon))) + style: AssetLogo.Style.litle) .observeOn(MainScheduler.instance) .bind(to: iconAssetLogo.rx.image) .disposed(by: disposeBag) diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Receive/Views/AssetSelectView.xib b/WavesWallet-iOS/Modules/Receive/Views/AssetSelectView.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Receive/Views/AssetSelectView.xib rename to WavesWallet-iOS/Modules/Receive/Views/AssetSelectView.xib diff --git "a/WavesWallet-iOS/Modules/Receive/\320\241ryptocurrency/Interactor/ReceiveCryptocurrencyInteractor.swift" "b/WavesWallet-iOS/Modules/Receive/\320\241ryptocurrency/Interactor/ReceiveCryptocurrencyInteractor.swift" new file mode 100644 index 00000000..1689c582 --- /dev/null +++ "b/WavesWallet-iOS/Modules/Receive/\320\241ryptocurrency/Interactor/ReceiveCryptocurrencyInteractor.swift" @@ -0,0 +1,71 @@ +// +// ReceiveCryptocurrencyInteractor.swift +// WavesWallet-iOS +// +// Created by Pavel Gubin on 10/5/18. +// Copyright © 2018 Waves Platform. All rights reserved. +// + +import Foundation +import RxSwift +import WavesSDK +import DomainLayer +import Extensions + +final class ReceiveCryptocurrencyInteractor: ReceiveCryptocurrencyInteractorProtocol { + + private let auth: AuthorizationUseCaseProtocol = UseCasesFactory.instance.authorization + private let coinomatRepository = UseCasesFactory.instance.repositories.coinomatRepository + private let gatewayRepository = UseCasesFactory.instance.repositories.gatewayRepository + + func generateAddress(asset: DomainLayer.DTO.Asset) -> Observable> { + + return auth.authorizedWallet().flatMap({ [weak self] (wallet) -> Observable> in + + guard let self = self, let gatewayType = asset.gatewayType else { return Observable.empty() } + + switch gatewayType { + case .gateway: + return self.gatewayRepository.startDepositProcess(address: wallet.address, asset: asset) + .map({ (startDeposit) -> ResponseType in + + let displayInfo = ReceiveCryptocurrency.DTO.DisplayInfo(address: startDeposit.address, + assetName: asset.displayName, + assetShort: asset.ticker ?? "", + minAmount: startDeposit.minAmount, + icon: asset.iconLogo) + + return ResponseType(output: displayInfo, error: nil) + }) + + case .coinomat: + guard let currencyFrom = asset.gatewayId, + let currencyTo = asset.wavesId else { return Observable.empty() } + + let tunnel = self.coinomatRepository.tunnelInfo(asset: asset, + currencyFrom: currencyFrom, + currencyTo: currencyTo, + walletTo: wallet.address, + moneroPaymentID: nil) + let rate = self.coinomatRepository.getRate(asset: asset) + return Observable.zip(tunnel, rate) + .flatMap({ (tunnel, rate) -> Observable> in + + let displayInfo = ReceiveCryptocurrency.DTO.DisplayInfo(address: tunnel.address, + assetName: asset.displayName, + assetShort: currencyFrom, + minAmount: tunnel.min, + icon: asset.iconLogo) + return Observable.just(ResponseType(output: displayInfo, error: nil)) + }) + } + }) + .catchError({ (error) -> Observable> in + if let networkError = error as? NetworkError { + return Observable.just(ResponseType(output: nil, error: networkError)) + } + + return Observable.just(ResponseType(output: nil, error: NetworkError.error(by: error))) + }) + } +} diff --git "a/WavesWallet-iOS/PresentationLayer/Modules/Receive/\320\241ryptocurrency/Interactor/ReceiveCryptocurrencyInteractorProtocol.swift" "b/WavesWallet-iOS/Modules/Receive/\320\241ryptocurrency/Interactor/ReceiveCryptocurrencyInteractorProtocol.swift" similarity index 95% rename from "WavesWallet-iOS/PresentationLayer/Modules/Receive/\320\241ryptocurrency/Interactor/ReceiveCryptocurrencyInteractorProtocol.swift" rename to "WavesWallet-iOS/Modules/Receive/\320\241ryptocurrency/Interactor/ReceiveCryptocurrencyInteractorProtocol.swift" index fe5bd04e..64a52dc6 100644 --- "a/WavesWallet-iOS/PresentationLayer/Modules/Receive/\320\241ryptocurrency/Interactor/ReceiveCryptocurrencyInteractorProtocol.swift" +++ "b/WavesWallet-iOS/Modules/Receive/\320\241ryptocurrency/Interactor/ReceiveCryptocurrencyInteractorProtocol.swift" @@ -8,6 +8,7 @@ import Foundation import RxSwift +import DomainLayer protocol ReceiveCryptocurrencyInteractorProtocol { diff --git "a/WavesWallet-iOS/PresentationLayer/Modules/Receive/\320\241ryptocurrency/Presenter/ReceiveCryptocurrencyPresenter.swift" "b/WavesWallet-iOS/Modules/Receive/\320\241ryptocurrency/Presenter/ReceiveCryptocurrencyPresenter.swift" similarity index 100% rename from "WavesWallet-iOS/PresentationLayer/Modules/Receive/\320\241ryptocurrency/Presenter/ReceiveCryptocurrencyPresenter.swift" rename to "WavesWallet-iOS/Modules/Receive/\320\241ryptocurrency/Presenter/ReceiveCryptocurrencyPresenter.swift" diff --git "a/WavesWallet-iOS/PresentationLayer/Modules/Receive/\320\241ryptocurrency/Presenter/ReceiveCryptocurrencyPresenterProtocol.swift" "b/WavesWallet-iOS/Modules/Receive/\320\241ryptocurrency/Presenter/ReceiveCryptocurrencyPresenterProtocol.swift" similarity index 100% rename from "WavesWallet-iOS/PresentationLayer/Modules/Receive/\320\241ryptocurrency/Presenter/ReceiveCryptocurrencyPresenterProtocol.swift" rename to "WavesWallet-iOS/Modules/Receive/\320\241ryptocurrency/Presenter/ReceiveCryptocurrencyPresenterProtocol.swift" diff --git "a/WavesWallet-iOS/PresentationLayer/Modules/Receive/\320\241ryptocurrency/ReceiveCryptocurrencyModuleBuilder.swift" "b/WavesWallet-iOS/Modules/Receive/\320\241ryptocurrency/ReceiveCryptocurrencyModuleBuilder.swift" similarity index 97% rename from "WavesWallet-iOS/PresentationLayer/Modules/Receive/\320\241ryptocurrency/ReceiveCryptocurrencyModuleBuilder.swift" rename to "WavesWallet-iOS/Modules/Receive/\320\241ryptocurrency/ReceiveCryptocurrencyModuleBuilder.swift" index 877174c3..52c44f3c 100644 --- "a/WavesWallet-iOS/PresentationLayer/Modules/Receive/\320\241ryptocurrency/ReceiveCryptocurrencyModuleBuilder.swift" +++ "b/WavesWallet-iOS/Modules/Receive/\320\241ryptocurrency/ReceiveCryptocurrencyModuleBuilder.swift" @@ -7,6 +7,7 @@ // import UIKit +import Extensions struct ReceiveCryptocurrencyModuleBuilder: ModuleBuilder { diff --git "a/WavesWallet-iOS/PresentationLayer/Modules/Receive/\320\241ryptocurrency/ReceiveCryptocurrencyTypes.swift" "b/WavesWallet-iOS/Modules/Receive/\320\241ryptocurrency/ReceiveCryptocurrencyTypes.swift" similarity index 91% rename from "WavesWallet-iOS/PresentationLayer/Modules/Receive/\320\241ryptocurrency/ReceiveCryptocurrencyTypes.swift" rename to "WavesWallet-iOS/Modules/Receive/\320\241ryptocurrency/ReceiveCryptocurrencyTypes.swift" index d894b998..bfd88f69 100644 --- "a/WavesWallet-iOS/PresentationLayer/Modules/Receive/\320\241ryptocurrency/ReceiveCryptocurrencyTypes.swift" +++ "b/WavesWallet-iOS/Modules/Receive/\320\241ryptocurrency/ReceiveCryptocurrencyTypes.swift" @@ -7,6 +7,9 @@ // import Foundation +import WavesSDK +import DomainLayer +import Extensions enum ReceiveCryptocurrency { enum DTO {} @@ -37,6 +40,6 @@ extension ReceiveCryptocurrency.DTO { let assetName: String let assetShort: String let minAmount: Money - let icon: DomainLayer.DTO.Asset.Icon + let icon: AssetLogo.Icon } } diff --git "a/WavesWallet-iOS/PresentationLayer/Modules/Receive/\320\241ryptocurrency/ReceiveCryptocurrencyViewController.swift" "b/WavesWallet-iOS/Modules/Receive/\320\241ryptocurrency/ReceiveCryptocurrencyViewController.swift" similarity index 98% rename from "WavesWallet-iOS/PresentationLayer/Modules/Receive/\320\241ryptocurrency/ReceiveCryptocurrencyViewController.swift" rename to "WavesWallet-iOS/Modules/Receive/\320\241ryptocurrency/ReceiveCryptocurrencyViewController.swift" index b31a15f1..6851c545 100644 --- "a/WavesWallet-iOS/PresentationLayer/Modules/Receive/\320\241ryptocurrency/ReceiveCryptocurrencyViewController.swift" +++ "b/WavesWallet-iOS/Modules/Receive/\320\241ryptocurrency/ReceiveCryptocurrencyViewController.swift" @@ -10,7 +10,7 @@ import UIKit import RxCocoa import RxFeedback import RxSwift - +import DomainLayer final class ReceiveCryptocurrencyViewController: UIViewController { @@ -55,7 +55,7 @@ final class ReceiveCryptocurrencyViewController: UIViewController { let vc = ReceiveGenerateAddressModuleBuilder().build(input: .cryptoCurrency(info)) navigationController?.pushViewController(vc, animated: true) - AnalyticManager.trackEvent(.walletAsset(.receiveTap(assetName: info.assetName))) + UseCasesFactory.instance.analyticManager.trackEvent(.receive(.receiveTap(assetName: info.assetName))) } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Send/Complete/SendCompleteViewController.swift b/WavesWallet-iOS/Modules/Send/Complete/SendCompleteViewController.swift similarity index 95% rename from WavesWallet-iOS/PresentationLayer/Modules/Send/Complete/SendCompleteViewController.swift rename to WavesWallet-iOS/Modules/Send/Complete/SendCompleteViewController.swift index 8103e59e..08e6a7d6 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Send/Complete/SendCompleteViewController.swift +++ b/WavesWallet-iOS/Modules/Send/Complete/SendCompleteViewController.swift @@ -8,6 +8,8 @@ import UIKit import RxSwift +import DomainLayer +import Extensions final class SendCompleteViewController: UIViewController { @@ -27,12 +29,14 @@ final class SendCompleteViewController: UIViewController { var input: Input! + weak var delegate: SendResultDelegate? + private let disposeBag = DisposeBag() override func viewDidLoad() { super.viewDidLoad() - hideTopBarLine() + removeTopBarLine() navigationItem.backgroundImage = UIImage() navigationItem.hidesBackButton = true @@ -47,6 +51,8 @@ final class SendCompleteViewController: UIViewController { @IBAction private func okeyTapped(_ sender: Any) { + delegate?.sendResultDidTapFinish() + if let assetVc = navigationController?.viewControllers.first(where: {$0.classForCoder == AssetDetailViewController.classForCoder()}) { navigationController?.popToViewController(assetVc, animated: true) } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Send/Confirmaion/SendConfirmationViewController.swift b/WavesWallet-iOS/Modules/Send/Confirmaion/SendConfirmationViewController.swift similarity index 90% rename from WavesWallet-iOS/PresentationLayer/Modules/Send/Confirmaion/SendConfirmationViewController.swift rename to WavesWallet-iOS/Modules/Send/Confirmaion/SendConfirmationViewController.swift index 72bb72c2..a3cc4ad0 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Send/Confirmaion/SendConfirmationViewController.swift +++ b/WavesWallet-iOS/Modules/Send/Confirmaion/SendConfirmationViewController.swift @@ -8,6 +8,8 @@ import UIKit import RxSwift +import DomainLayer +import Extensions private enum Constants { static let cornerRadius: CGFloat = 2 @@ -27,6 +29,8 @@ final class SendConfirmationViewController: UIViewController { let amountWithoutFee: Money var attachment: String let isGateway: Bool + let gateWayFeeAmount: Money? + let gateWayFeeName: String? } @IBOutlet private weak var viewContainer: UIView! @@ -41,6 +45,9 @@ final class SendConfirmationViewController: UIViewController { @IBOutlet private weak var tickerView: TickerView! @IBOutlet private weak var labelAssetName: UILabel! @IBOutlet private weak var viewDescription: UIView! + @IBOutlet private weak var labelGatewayFee: UILabel! + @IBOutlet private weak var labelGatewayFeeAmount: UILabel! + @IBOutlet private weak var viewGatewayFee: UIView! private var isShowError = false @@ -57,6 +64,7 @@ final class SendConfirmationViewController: UIViewController { setupData() labelDescriptionError.alpha = 0 viewDescription.isHidden = input.isGateway + viewGatewayFee.isHidden = !input.isGateway setupButtonState() } @@ -67,7 +75,7 @@ final class SendConfirmationViewController: UIViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - hideTopBarLine() + removeTopBarLine() setupBigNavigationBar() navigationItem.backgroundImage = UIImage() navigationItem.titleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.white] @@ -85,7 +93,7 @@ final class SendConfirmationViewController: UIViewController { vc.input = input navigationController?.pushViewController(vc, animated: true) - AnalyticManager.trackEvent(.walletAsset(.sendConfirm(assetName: input.asset.displayName))) + UseCasesFactory.instance.analyticManager.trackEvent(.send(.sendConfirm(assetName: input.asset.displayName))) } @@ -150,6 +158,7 @@ private extension SendConfirmationViewController { labelDescriptionError.text = Localizable.Waves.Sendconfirmation.Label.descriptionIsTooLong textField.placeholder = Localizable.Waves.Sendconfirmation.Label.optionalMessage buttonConfirm.setTitle(Localizable.Waves.Sendconfirmation.Button.confim, for: .normal) + labelGatewayFee.text = Localizable.Waves.Sendconfirmation.Label.gatewayFee } func setupData() { @@ -182,5 +191,6 @@ private extension SendConfirmationViewController { } labelFeeAmount.text = input.fee.displayText + " " + input.feeName labelBalance.attributedText = NSAttributedString.styleForBalance(text: input.amountWithoutFee.displayText, font: labelBalance.font) + labelGatewayFeeAmount.text = (input.gateWayFeeAmount?.displayText ?? "") + " " + (input.gateWayFeeName ?? "") } } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Send/Confirmaion/Views/SendConfirmationRecipientView.swift b/WavesWallet-iOS/Modules/Send/Confirmaion/Views/SendConfirmationRecipientView.swift similarity index 99% rename from WavesWallet-iOS/PresentationLayer/Modules/Send/Confirmaion/Views/SendConfirmationRecipientView.swift rename to WavesWallet-iOS/Modules/Send/Confirmaion/Views/SendConfirmationRecipientView.swift index 51dac0fd..c31e4f2e 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Send/Confirmaion/Views/SendConfirmationRecipientView.swift +++ b/WavesWallet-iOS/Modules/Send/Confirmaion/Views/SendConfirmationRecipientView.swift @@ -7,6 +7,7 @@ // import UIKit +import Extensions private enum Constants { static let fullHeight: CGFloat = 76 diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Send/Confirmaion/Views/SendConfirmationRecipientView.xib b/WavesWallet-iOS/Modules/Send/Confirmaion/Views/SendConfirmationRecipientView.xib similarity index 100% rename from WavesWallet-iOS/PresentationLayer/Modules/Send/Confirmaion/Views/SendConfirmationRecipientView.xib rename to WavesWallet-iOS/Modules/Send/Confirmaion/Views/SendConfirmationRecipientView.xib diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Send/Loading/SendLoadingViewController.swift b/WavesWallet-iOS/Modules/Send/Loading/SendLoadingViewController.swift similarity index 90% rename from WavesWallet-iOS/PresentationLayer/Modules/Send/Loading/SendLoadingViewController.swift rename to WavesWallet-iOS/Modules/Send/Loading/SendLoadingViewController.swift index 855c8e73..854dd06e 100644 --- a/WavesWallet-iOS/PresentationLayer/Modules/Send/Loading/SendLoadingViewController.swift +++ b/WavesWallet-iOS/Modules/Send/Loading/SendLoadingViewController.swift @@ -8,6 +8,7 @@ import UIKit import RxSwift +import DomainLayer final class SendLoadingViewController: UIViewController { @@ -29,7 +30,7 @@ final class SendLoadingViewController: UIViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - hideTopBarLine() + removeTopBarLine() navigationItem.backgroundImage = UIImage() } @@ -39,6 +40,7 @@ final class SendLoadingViewController: UIViewController { private func showComplete() { let vc = StoryboardScene.Send.sendCompleteViewController.instantiate() + vc.delegate = delegate vc.input = .init(assetName: input.asset.displayName, amount: input.amount, address: input.displayAddress, @@ -49,9 +51,8 @@ final class SendLoadingViewController: UIViewController { private func send() { - let assetId = input.asset.isWaves ? "" : input.asset.id interactor - .send(fee: input.fee, recipient: input.address, assetId: assetId, amount: input.amount, attachment: input.attachment, feeAssetID: input.feeAssetID) + .send(fee: input.fee, recipient: input.address, asset: input.asset, amount: input.amount, attachment: input.attachment, feeAssetID: input.feeAssetID, isGatewayTransaction: input.isGateway) .observeOn(MainScheduler.asyncInstance) .subscribe(onNext: { [weak self] status in guard let self = self else { return } diff --git a/WavesWallet-iOS/PresentationLayer/Modules/Send/Send.storyboard b/WavesWallet-iOS/Modules/Send/Send.storyboard similarity index 93% rename from WavesWallet-iOS/PresentationLayer/Modules/Send/Send.storyboard rename to WavesWallet-iOS/Modules/Send/Send.storyboard index dee85592..39762779 100755 --- a/WavesWallet-iOS/PresentationLayer/Modules/Send/Send.storyboard +++ b/WavesWallet-iOS/Modules/Send/Send.storyboard @@ -1,11 +1,9 @@ - - - - + + - + @@ -19,7 +17,7 @@ - + @@ -497,7 +495,7 @@ - + @@ -549,7 +547,7 @@ - + @@ -606,7 +604,7 @@ - +