mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-02-24 07:28:07 +01:00
Merge branch 'master' of github.com:BlueWallet/BlueWallet into refactor-app-storage
This commit is contained in:
commit
f65478da56
31 changed files with 762 additions and 468 deletions
|
@ -15,9 +15,8 @@
|
|||
6D2A6464258BA92D0092292B /* Stickers.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2A6463258BA92D0092292B /* Stickers.xcassets */; };
|
||||
6D2A6468258BA92D0092292B /* Stickers.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 6D2A6461258BA92C0092292B /* Stickers.appex */; platformFilter = ios; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
6D32C5C62596CE3A008C077C /* EventEmitter.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D32C5C52596CE3A008C077C /* EventEmitter.m */; };
|
||||
6D4AF15925D21172009DD853 /* WidgetAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D9A2E6A254BAB1B007B5B82 /* WidgetAPI.swift */; };
|
||||
6D4AF16325D21185009DD853 /* WidgetDataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D9A2E6B254BAB1B007B5B82 /* WidgetDataStore.swift */; };
|
||||
6D4AF16D25D21192009DD853 /* Models.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DEB4BFA254FBA0E00E9F9AA /* Models.swift */; };
|
||||
6D4AF15925D21172009DD853 /* MarketAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D9A2E6A254BAB1B007B5B82 /* MarketAPI.swift */; };
|
||||
6D4AF16D25D21192009DD853 /* Placeholders.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DEB4BFA254FBA0E00E9F9AA /* Placeholders.swift */; };
|
||||
6D4AF17825D211A3009DD853 /* FiatUnit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D2AA8072568B8F40090B089 /* FiatUnit.swift */; };
|
||||
6D4AF18425D215D1009DD853 /* UserDefaultsExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D4AF18325D215D1009DD853 /* UserDefaultsExtension.swift */; };
|
||||
6DD4109D266CADF10087DE03 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D333B3A252FE1A3004D72DF /* WidgetKit.framework */; };
|
||||
|
@ -25,14 +24,12 @@
|
|||
6DD410A1266CADF10087DE03 /* Widgets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DD410A0266CADF10087DE03 /* Widgets.swift */; };
|
||||
6DD410A7266CADF40087DE03 /* WidgetsExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 6DD4109C266CADF10087DE03 /* WidgetsExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
6DD410AC266CAE470087DE03 /* PriceWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D6CA4BC255872E3009312A5 /* PriceWidget.swift */; };
|
||||
6DD410AE266CAF1F0087DE03 /* fiatUnits.json in Resources */ = {isa = PBXBuildFile; fileRef = 6DD410AD266CAF1F0087DE03 /* fiatUnits.json */; };
|
||||
6DD410AF266CAF5C0087DE03 /* WalletInformationAndMarketWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D9A2E06254BA347007B5B82 /* WalletInformationAndMarketWidget.swift */; };
|
||||
6DD410B0266CAF5C0087DE03 /* WalletInformationWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DEB4AB1254FB59C00E9F9AA /* WalletInformationWidget.swift */; };
|
||||
6DD410B1266CAF5C0087DE03 /* WidgetAPI+Electrum.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D6CA5142558EBA3009312A5 /* WidgetAPI+Electrum.swift */; };
|
||||
6DD410B1266CAF5C0087DE03 /* MarketAPI+Electrum.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D6CA5142558EBA3009312A5 /* MarketAPI+Electrum.swift */; };
|
||||
6DD410B2266CAF5C0087DE03 /* WalletInformationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D641F2225525053003792DF /* WalletInformationView.swift */; };
|
||||
6DD410B3266CAF5C0087DE03 /* Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DEB4C3A254FBF4800E9F9AA /* Colors.swift */; };
|
||||
6DD410B4266CAF5C0087DE03 /* WidgetAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D9A2E6A254BAB1B007B5B82 /* WidgetAPI.swift */; };
|
||||
6DD410B5266CAF5C0087DE03 /* WidgetDataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D9A2E6B254BAB1B007B5B82 /* WidgetDataStore.swift */; };
|
||||
6DD410B4266CAF5C0087DE03 /* MarketAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D9A2E6A254BAB1B007B5B82 /* MarketAPI.swift */; };
|
||||
6DD410B6266CAF5C0087DE03 /* PriceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D6CA5272558EC52009312A5 /* PriceView.swift */; };
|
||||
6DD410B7266CAF5C0087DE03 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D9A2E08254BA348007B5B82 /* Assets.xcassets */; };
|
||||
6DD410B8266CAF5C0087DE03 /* UserDefaultsExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D4AF18325D215D1009DD853 /* UserDefaultsExtension.swift */; };
|
||||
|
@ -40,7 +37,7 @@
|
|||
6DD410BA266CAF5C0087DE03 /* FiatUnit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D2AA8072568B8F40090B089 /* FiatUnit.swift */; };
|
||||
6DD410BB266CAF5C0087DE03 /* MarketView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D641F17255226DA003792DF /* MarketView.swift */; };
|
||||
6DD410BE266CAF5C0087DE03 /* SendReceiveButtons.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D641F3425526311003792DF /* SendReceiveButtons.swift */; };
|
||||
6DD410BF266CB13D0087DE03 /* Models.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DEB4BFA254FBA0E00E9F9AA /* Models.swift */; };
|
||||
6DD410BF266CB13D0087DE03 /* Placeholders.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DEB4BFA254FBA0E00E9F9AA /* Placeholders.swift */; };
|
||||
6DD410C0266CB1460087DE03 /* MarketWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D9946622555A660000E52E8 /* MarketWidget.swift */; };
|
||||
6DF25A9F249DB97E001D06F5 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6DF25A9E249DB97E001D06F5 /* LaunchScreen.storyboard */; };
|
||||
6DFC807024EA0B6C007B8700 /* EFQRCode in Frameworks */ = {isa = PBXBuildFile; productRef = 6DFC806F24EA0B6C007B8700 /* EFQRCode */; };
|
||||
|
@ -75,6 +72,70 @@
|
|||
B43D037B225847C500FBAA95 /* TransactionTableRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = B43D0375225847C500FBAA95 /* TransactionTableRow.swift */; };
|
||||
B43D037C225847C500FBAA95 /* Wallet.swift in Sources */ = {isa = PBXBuildFile; fileRef = B43D0376225847C500FBAA95 /* Wallet.swift */; };
|
||||
B43D037D225847C500FBAA95 /* WalletInformation.swift in Sources */ = {isa = PBXBuildFile; fileRef = B43D0377225847C500FBAA95 /* WalletInformation.swift */; };
|
||||
B44033BF2BCC32F800162242 /* BitcoinUnit.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033BE2BCC32F800162242 /* BitcoinUnit.swift */; };
|
||||
B44033C02BCC32F800162242 /* BitcoinUnit.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033BE2BCC32F800162242 /* BitcoinUnit.swift */; };
|
||||
B44033C12BCC32F800162242 /* BitcoinUnit.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033BE2BCC32F800162242 /* BitcoinUnit.swift */; };
|
||||
B44033C22BCC32F800162242 /* BitcoinUnit.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033BE2BCC32F800162242 /* BitcoinUnit.swift */; };
|
||||
B44033C42BCC332400162242 /* Balance.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033C32BCC332400162242 /* Balance.swift */; };
|
||||
B44033C52BCC332400162242 /* Balance.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033C32BCC332400162242 /* Balance.swift */; };
|
||||
B44033C62BCC332400162242 /* Balance.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033C32BCC332400162242 /* Balance.swift */; };
|
||||
B44033C72BCC332400162242 /* Balance.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033C32BCC332400162242 /* Balance.swift */; };
|
||||
B44033CA2BCC350A00162242 /* Currency.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033C92BCC350A00162242 /* Currency.swift */; };
|
||||
B44033CB2BCC350A00162242 /* Currency.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033C92BCC350A00162242 /* Currency.swift */; };
|
||||
B44033CC2BCC350A00162242 /* Currency.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033C92BCC350A00162242 /* Currency.swift */; };
|
||||
B44033CD2BCC350A00162242 /* Currency.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033C92BCC350A00162242 /* Currency.swift */; };
|
||||
B44033CE2BCC352900162242 /* UserDefaultsGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DA7047D254E24D5005FE5E2 /* UserDefaultsGroup.swift */; };
|
||||
B44033CF2BCC352C00162242 /* UserDefaultsGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DA7047D254E24D5005FE5E2 /* UserDefaultsGroup.swift */; };
|
||||
B44033D02BCC352F00162242 /* UserDefaultsGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DA7047D254E24D5005FE5E2 /* UserDefaultsGroup.swift */; };
|
||||
B44033D32BCC368800162242 /* UserDefaultsGroupKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033D22BCC368800162242 /* UserDefaultsGroupKey.swift */; };
|
||||
B44033D42BCC368800162242 /* UserDefaultsGroupKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033D22BCC368800162242 /* UserDefaultsGroupKey.swift */; };
|
||||
B44033D52BCC368800162242 /* UserDefaultsGroupKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033D22BCC368800162242 /* UserDefaultsGroupKey.swift */; };
|
||||
B44033D62BCC368800162242 /* UserDefaultsGroupKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033D22BCC368800162242 /* UserDefaultsGroupKey.swift */; };
|
||||
B44033D72BCC369400162242 /* UserDefaultsExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D4AF18325D215D1009DD853 /* UserDefaultsExtension.swift */; };
|
||||
B44033D82BCC369500162242 /* UserDefaultsExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D4AF18325D215D1009DD853 /* UserDefaultsExtension.swift */; };
|
||||
B44033D92BCC369900162242 /* Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DEB4C3A254FBF4800E9F9AA /* Colors.swift */; };
|
||||
B44033DA2BCC369A00162242 /* Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DEB4C3A254FBF4800E9F9AA /* Colors.swift */; };
|
||||
B44033DB2BCC369B00162242 /* Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DEB4C3A254FBF4800E9F9AA /* Colors.swift */; };
|
||||
B44033DD2BCC36C300162242 /* LatestTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033DC2BCC36C300162242 /* LatestTransaction.swift */; };
|
||||
B44033DE2BCC36C300162242 /* LatestTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033DC2BCC36C300162242 /* LatestTransaction.swift */; };
|
||||
B44033DF2BCC36C300162242 /* LatestTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033DC2BCC36C300162242 /* LatestTransaction.swift */; };
|
||||
B44033E02BCC36C300162242 /* LatestTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033DC2BCC36C300162242 /* LatestTransaction.swift */; };
|
||||
B44033E12BCC36CA00162242 /* Placeholders.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DEB4BFA254FBA0E00E9F9AA /* Placeholders.swift */; };
|
||||
B44033E22BCC36CB00162242 /* Placeholders.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DEB4BFA254FBA0E00E9F9AA /* Placeholders.swift */; };
|
||||
B44033E42BCC36FF00162242 /* WalletData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033E32BCC36FF00162242 /* WalletData.swift */; };
|
||||
B44033E52BCC36FF00162242 /* WalletData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033E32BCC36FF00162242 /* WalletData.swift */; };
|
||||
B44033E62BCC36FF00162242 /* WalletData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033E32BCC36FF00162242 /* WalletData.swift */; };
|
||||
B44033E72BCC36FF00162242 /* WalletData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033E32BCC36FF00162242 /* WalletData.swift */; };
|
||||
B44033E92BCC371A00162242 /* MarketData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033E82BCC371A00162242 /* MarketData.swift */; };
|
||||
B44033EA2BCC371A00162242 /* MarketData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033E82BCC371A00162242 /* MarketData.swift */; };
|
||||
B44033EB2BCC371A00162242 /* MarketData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033E82BCC371A00162242 /* MarketData.swift */; };
|
||||
B44033EC2BCC371A00162242 /* MarketData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033E82BCC371A00162242 /* MarketData.swift */; };
|
||||
B44033EE2BCC374500162242 /* Numeric+abbreviated.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033ED2BCC374500162242 /* Numeric+abbreviated.swift */; };
|
||||
B44033EF2BCC374500162242 /* Numeric+abbreviated.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033ED2BCC374500162242 /* Numeric+abbreviated.swift */; };
|
||||
B44033F02BCC374500162242 /* Numeric+abbreviated.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033ED2BCC374500162242 /* Numeric+abbreviated.swift */; };
|
||||
B44033F12BCC374500162242 /* Numeric+abbreviated.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033ED2BCC374500162242 /* Numeric+abbreviated.swift */; };
|
||||
B44033F42BCC377F00162242 /* WidgetData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033F32BCC377F00162242 /* WidgetData.swift */; };
|
||||
B44033F52BCC377F00162242 /* WidgetData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033F32BCC377F00162242 /* WidgetData.swift */; };
|
||||
B44033F62BCC377F00162242 /* WidgetData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033F32BCC377F00162242 /* WidgetData.swift */; };
|
||||
B44033F72BCC377F00162242 /* WidgetData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033F32BCC377F00162242 /* WidgetData.swift */; };
|
||||
B44033F92BCC379200162242 /* WidgetDataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033F82BCC379200162242 /* WidgetDataStore.swift */; };
|
||||
B44033FA2BCC379200162242 /* WidgetDataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033F82BCC379200162242 /* WidgetDataStore.swift */; };
|
||||
B44033FB2BCC379200162242 /* WidgetDataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033F82BCC379200162242 /* WidgetDataStore.swift */; };
|
||||
B44033FC2BCC379200162242 /* WidgetDataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033F82BCC379200162242 /* WidgetDataStore.swift */; };
|
||||
B44033FD2BCC37D600162242 /* MarketAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D9A2E6A254BAB1B007B5B82 /* MarketAPI.swift */; };
|
||||
B44033FE2BCC37D700162242 /* MarketAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D9A2E6A254BAB1B007B5B82 /* MarketAPI.swift */; };
|
||||
B44034002BCC37F800162242 /* Bundle+decode.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033FF2BCC37F800162242 /* Bundle+decode.swift */; };
|
||||
B44034012BCC37F800162242 /* Bundle+decode.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033FF2BCC37F800162242 /* Bundle+decode.swift */; };
|
||||
B44034022BCC37F800162242 /* Bundle+decode.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033FF2BCC37F800162242 /* Bundle+decode.swift */; };
|
||||
B44034032BCC37F800162242 /* Bundle+decode.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033FF2BCC37F800162242 /* Bundle+decode.swift */; };
|
||||
B44034042BCC389100162242 /* XMLParserDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4AB225C2B02AD12001F4328 /* XMLParserDelegate.swift */; };
|
||||
B44034052BCC389200162242 /* XMLParserDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4AB225C2B02AD12001F4328 /* XMLParserDelegate.swift */; };
|
||||
B44034062BCC389F00162242 /* FiatUnit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D2AA8072568B8F40090B089 /* FiatUnit.swift */; };
|
||||
B44034072BCC38A000162242 /* FiatUnit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D2AA8072568B8F40090B089 /* FiatUnit.swift */; };
|
||||
B440340F2BCC40A400162242 /* fiatUnits.json in Resources */ = {isa = PBXBuildFile; fileRef = B440340E2BCC40A400162242 /* fiatUnits.json */; };
|
||||
B44034102BCC40A400162242 /* fiatUnits.json in Resources */ = {isa = PBXBuildFile; fileRef = B440340E2BCC40A400162242 /* fiatUnits.json */; };
|
||||
B44034112BCC40A400162242 /* fiatUnits.json in Resources */ = {isa = PBXBuildFile; fileRef = B440340E2BCC40A400162242 /* fiatUnits.json */; };
|
||||
B44034122BCC40A400162242 /* fiatUnits.json in Resources */ = {isa = PBXBuildFile; fileRef = B440340E2BCC40A400162242 /* fiatUnits.json */; };
|
||||
B4549F362B82B10D002E3153 /* ci_post_clone.sh in Resources */ = {isa = PBXBuildFile; fileRef = B4549F352B82B10D002E3153 /* ci_post_clone.sh */; };
|
||||
B461B852299599F800E431AA /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = B461B851299599F800E431AA /* AppDelegate.mm */; };
|
||||
B47B21EC2B2128B8001F6690 /* BlueWalletUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B47B21EB2B2128B8001F6690 /* BlueWalletUITests.swift */; };
|
||||
|
@ -96,9 +157,7 @@
|
|||
B4AB225E2B02AD12001F4328 /* XMLParserDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4AB225C2B02AD12001F4328 /* XMLParserDelegate.swift */; };
|
||||
B4EE583C226703320003363C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B40D4E35225841ED00428FCC /* Assets.xcassets */; };
|
||||
C59F90CE0D04D3E4BB39BC5D /* libPods-BlueWalletUITests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6F02C2F7CA3591E4E0B06EBA /* libPods-BlueWalletUITests.a */; };
|
||||
C978A716948AB7DEC5B6F677 /* BuildFile in Frameworks */ = {isa = PBXBuildFile; };
|
||||
E5D4794B26781FC0007838C1 /* fiatUnits.json in Resources */ = {isa = PBXBuildFile; fileRef = 6DD410AD266CAF1F0087DE03 /* fiatUnits.json */; };
|
||||
E5D4794C26781FC1007838C1 /* fiatUnits.json in Resources */ = {isa = PBXBuildFile; fileRef = 6DD410AD266CAF1F0087DE03 /* fiatUnits.json */; };
|
||||
C978A716948AB7DEC5B6F677 /* (null) in Frameworks */ = {isa = PBXBuildFile; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
|
@ -151,13 +210,6 @@
|
|||
remoteGlobalIDString = B4A29A212B55C990002A67DF;
|
||||
remoteInfo = "BlueWallet-NoLDK";
|
||||
};
|
||||
B4A29A232B55C990002A67DF /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = B40D4E2F225841EC00428FCC;
|
||||
remoteInfo = BlueWalletWatch;
|
||||
};
|
||||
B4A29A252B55C990002A67DF /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
|
||||
|
@ -310,21 +362,19 @@
|
|||
6D641F2225525053003792DF /* WalletInformationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletInformationView.swift; sourceTree = "<group>"; };
|
||||
6D641F3425526311003792DF /* SendReceiveButtons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendReceiveButtons.swift; sourceTree = "<group>"; };
|
||||
6D6CA4BC255872E3009312A5 /* PriceWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PriceWidget.swift; sourceTree = "<group>"; };
|
||||
6D6CA5142558EBA3009312A5 /* WidgetAPI+Electrum.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WidgetAPI+Electrum.swift"; sourceTree = "<group>"; };
|
||||
6D6CA5142558EBA3009312A5 /* MarketAPI+Electrum.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MarketAPI+Electrum.swift"; sourceTree = "<group>"; };
|
||||
6D6CA5272558EC52009312A5 /* PriceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PriceView.swift; sourceTree = "<group>"; };
|
||||
6D9946622555A660000E52E8 /* MarketWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarketWidget.swift; sourceTree = "<group>"; };
|
||||
6D9A2E06254BA347007B5B82 /* WalletInformationAndMarketWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletInformationAndMarketWidget.swift; sourceTree = "<group>"; };
|
||||
6D9A2E08254BA348007B5B82 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
6D9A2E6A254BAB1B007B5B82 /* WidgetAPI.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WidgetAPI.swift; sourceTree = "<group>"; };
|
||||
6D9A2E6B254BAB1B007B5B82 /* WidgetDataStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WidgetDataStore.swift; sourceTree = "<group>"; };
|
||||
6D9A2E6A254BAB1B007B5B82 /* MarketAPI.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MarketAPI.swift; sourceTree = "<group>"; };
|
||||
6DA7047D254E24D5005FE5E2 /* UserDefaultsGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsGroup.swift; sourceTree = "<group>"; };
|
||||
6DD4109C266CADF10087DE03 /* WidgetsExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = WidgetsExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
6DD410A0266CADF10087DE03 /* Widgets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Widgets.swift; sourceTree = "<group>"; };
|
||||
6DD410A4266CADF40087DE03 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
6DD410AD266CAF1F0087DE03 /* fiatUnits.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = fiatUnits.json; path = ../../../../models/fiatUnits.json; sourceTree = "<group>"; };
|
||||
6DD410C3266CCB780087DE03 /* WidgetsExtension.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = WidgetsExtension.entitlements; sourceTree = SOURCE_ROOT; };
|
||||
6DEB4AB1254FB59C00E9F9AA /* WalletInformationWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletInformationWidget.swift; sourceTree = "<group>"; };
|
||||
6DEB4BFA254FBA0E00E9F9AA /* Models.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Models.swift; sourceTree = "<group>"; };
|
||||
6DEB4BFA254FBA0E00E9F9AA /* Placeholders.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Placeholders.swift; sourceTree = "<group>"; };
|
||||
6DEB4C3A254FBF4800E9F9AA /* Colors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Colors.swift; sourceTree = "<group>"; };
|
||||
6DF25A9E249DB97E001D06F5 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
6DFC807124EA2FA9007B8700 /* ViewQRCodefaceController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewQRCodefaceController.swift; sourceTree = "<group>"; };
|
||||
|
@ -375,6 +425,18 @@
|
|||
B43D0376225847C500FBAA95 /* Wallet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Wallet.swift; sourceTree = "<group>"; };
|
||||
B43D0377225847C500FBAA95 /* WalletInformation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletInformation.swift; sourceTree = "<group>"; };
|
||||
B43D046E22584C1B00FBAA95 /* libRNWatch.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libRNWatch.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
B44033BE2BCC32F800162242 /* BitcoinUnit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BitcoinUnit.swift; sourceTree = "<group>"; };
|
||||
B44033C32BCC332400162242 /* Balance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Balance.swift; sourceTree = "<group>"; };
|
||||
B44033C92BCC350A00162242 /* Currency.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Currency.swift; sourceTree = "<group>"; };
|
||||
B44033D22BCC368800162242 /* UserDefaultsGroupKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsGroupKey.swift; sourceTree = "<group>"; };
|
||||
B44033DC2BCC36C300162242 /* LatestTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LatestTransaction.swift; sourceTree = "<group>"; };
|
||||
B44033E32BCC36FF00162242 /* WalletData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletData.swift; sourceTree = "<group>"; };
|
||||
B44033E82BCC371A00162242 /* MarketData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarketData.swift; sourceTree = "<group>"; };
|
||||
B44033ED2BCC374500162242 /* Numeric+abbreviated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Numeric+abbreviated.swift"; sourceTree = "<group>"; };
|
||||
B44033F32BCC377F00162242 /* WidgetData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetData.swift; sourceTree = "<group>"; };
|
||||
B44033F82BCC379200162242 /* WidgetDataStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetDataStore.swift; sourceTree = "<group>"; };
|
||||
B44033FF2BCC37F800162242 /* Bundle+decode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Bundle+decode.swift"; sourceTree = "<group>"; };
|
||||
B440340E2BCC40A400162242 /* fiatUnits.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = fiatUnits.json; path = ../../../models/fiatUnits.json; sourceTree = "<group>"; };
|
||||
B4549F352B82B10D002E3153 /* ci_post_clone.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = ci_post_clone.sh; sourceTree = "<group>"; };
|
||||
B461B850299599F800E431AA /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = BlueWallet/AppDelegate.h; sourceTree = "<group>"; };
|
||||
B461B851299599F800E431AA /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = BlueWallet/AppDelegate.mm; sourceTree = "<group>"; };
|
||||
|
@ -412,7 +474,7 @@
|
|||
files = (
|
||||
782F075B5DD048449E2DECE9 /* libz.tbd in Frameworks */,
|
||||
764B49B1420D4AEB8109BF62 /* libsqlite3.0.tbd in Frameworks */,
|
||||
C978A716948AB7DEC5B6F677 /* BuildFile in Frameworks */,
|
||||
C978A716948AB7DEC5B6F677 /* (null) in Frameworks */,
|
||||
773E382FE62E836172AAB98B /* libPods-BlueWallet.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -567,7 +629,8 @@
|
|||
6D2AA8062568B8E50090B089 /* Fiat */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6DD410AD266CAF1F0087DE03 /* fiatUnits.json */,
|
||||
B440340E2BCC40A400162242 /* fiatUnits.json */,
|
||||
B4AB225C2B02AD12001F4328 /* XMLParserDelegate.swift */,
|
||||
6D2AA8072568B8F40090B089 /* FiatUnit.swift */,
|
||||
);
|
||||
path = Fiat;
|
||||
|
@ -625,16 +688,7 @@
|
|||
6DEB4BC1254FB98300E9F9AA /* Shared */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B4AB225C2B02AD12001F4328 /* XMLParserDelegate.swift */,
|
||||
6D2AA8062568B8E50090B089 /* Fiat */,
|
||||
6DEB4DD82552260200E9F9AA /* Views */,
|
||||
6D9A2E6A254BAB1B007B5B82 /* WidgetAPI.swift */,
|
||||
6D6CA5142558EBA3009312A5 /* WidgetAPI+Electrum.swift */,
|
||||
6D9A2E6B254BAB1B007B5B82 /* WidgetDataStore.swift */,
|
||||
6DA7047D254E24D5005FE5E2 /* UserDefaultsGroup.swift */,
|
||||
6DEB4BFA254FBA0E00E9F9AA /* Models.swift */,
|
||||
6DEB4C3A254FBF4800E9F9AA /* Colors.swift */,
|
||||
6D4AF18325D215D1009DD853 /* UserDefaultsExtension.swift */,
|
||||
6D4AF18225D215D0009DD853 /* BlueWalletWatch-Bridging-Header.h */,
|
||||
B40FC3F829CCD1AC0007EBAC /* SwiftTCPClient.swift */,
|
||||
);
|
||||
|
@ -655,6 +709,7 @@
|
|||
83CBB9F61A601CBA00E9B192 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B44033C82BCC34AC00162242 /* Shared */,
|
||||
B41C2E552BB3DCB8000FE097 /* PrivacyInfo.xcprivacy */,
|
||||
B4549F2E2B80FEA1002E3153 /* ci_scripts */,
|
||||
13B07FAE1A68108700A75B9A /* BlueWallet */,
|
||||
|
@ -766,6 +821,31 @@
|
|||
path = Objects;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B44033C82BCC34AC00162242 /* Shared */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6D2AA8062568B8E50090B089 /* Fiat */,
|
||||
6D9A2E6A254BAB1B007B5B82 /* MarketAPI.swift */,
|
||||
6D6CA5142558EBA3009312A5 /* MarketAPI+Electrum.swift */,
|
||||
B44033C92BCC350A00162242 /* Currency.swift */,
|
||||
6DA7047D254E24D5005FE5E2 /* UserDefaultsGroup.swift */,
|
||||
6DEB4C3A254FBF4800E9F9AA /* Colors.swift */,
|
||||
6D4AF18325D215D1009DD853 /* UserDefaultsExtension.swift */,
|
||||
B44033D22BCC368800162242 /* UserDefaultsGroupKey.swift */,
|
||||
B44033DC2BCC36C300162242 /* LatestTransaction.swift */,
|
||||
B44033E32BCC36FF00162242 /* WalletData.swift */,
|
||||
B44033E82BCC371A00162242 /* MarketData.swift */,
|
||||
B44033ED2BCC374500162242 /* Numeric+abbreviated.swift */,
|
||||
B44033F32BCC377F00162242 /* WidgetData.swift */,
|
||||
B44033F82BCC379200162242 /* WidgetDataStore.swift */,
|
||||
B44033FF2BCC37F800162242 /* Bundle+decode.swift */,
|
||||
6DEB4BFA254FBA0E00E9F9AA /* Placeholders.swift */,
|
||||
B44033BE2BCC32F800162242 /* BitcoinUnit.swift */,
|
||||
B44033C32BCC332400162242 /* Balance.swift */,
|
||||
);
|
||||
path = Shared;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B4549F2E2B80FEA1002E3153 /* ci_scripts */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -951,7 +1031,6 @@
|
|||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
B4A29A222B55C990002A67DF /* PBXTargetDependency */,
|
||||
B4A29A242B55C990002A67DF /* PBXTargetDependency */,
|
||||
B4A29A262B55C990002A67DF /* PBXTargetDependency */,
|
||||
B4A29A282B55C990002A67DF /* PBXTargetDependency */,
|
||||
|
@ -1037,7 +1116,7 @@
|
|||
);
|
||||
mainGroup = 83CBB9F61A601CBA00E9B192;
|
||||
packageReferences = (
|
||||
6DFC806E24EA0B6C007B8700 /* XCRemoteSwiftPackageReference "EFQRCode.git" */,
|
||||
6DFC806E24EA0B6C007B8700 /* XCRemoteSwiftPackageReference "EFQRCode" */,
|
||||
B41B76832B66B2FF002C48D5 /* XCRemoteSwiftPackageReference "bugsnag-cocoa" */,
|
||||
);
|
||||
productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
|
||||
|
@ -1061,6 +1140,7 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
6DF25A9F249DB97E001D06F5 /* LaunchScreen.storyboard in Resources */,
|
||||
B440340F2BCC40A400162242 /* fiatUnits.json in Resources */,
|
||||
84E05A842721191B001A0D3A /* Settings.bundle in Resources */,
|
||||
B4549F362B82B10D002E3153 /* ci_post_clone.sh in Resources */,
|
||||
B41C2E562BB3DCB8000FE097 /* PrivacyInfo.xcprivacy in Resources */,
|
||||
|
@ -1081,8 +1161,8 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
B41C2E582BB3DCB8000FE097 /* PrivacyInfo.xcprivacy in Resources */,
|
||||
B44034112BCC40A400162242 /* fiatUnits.json in Resources */,
|
||||
6DD410B7266CAF5C0087DE03 /* Assets.xcassets in Resources */,
|
||||
6DD410AE266CAF1F0087DE03 /* fiatUnits.json in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -1091,7 +1171,6 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
B40D4E36225841ED00428FCC /* Assets.xcassets in Resources */,
|
||||
E5D4794C26781FC1007838C1 /* fiatUnits.json in Resources */,
|
||||
B40D4E34225841EC00428FCC /* Interface.storyboard in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -1101,8 +1180,8 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
B41C2E572BB3DCB8000FE097 /* PrivacyInfo.xcprivacy in Resources */,
|
||||
B44034102BCC40A400162242 /* fiatUnits.json in Resources */,
|
||||
B4EE583C226703320003363C /* Assets.xcassets in Resources */,
|
||||
E5D4794B26781FC0007838C1 /* fiatUnits.json in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -1118,6 +1197,7 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
B41C2E592BB3DCB8000FE097 /* PrivacyInfo.xcprivacy in Resources */,
|
||||
B44034122BCC40A400162242 /* fiatUnits.json in Resources */,
|
||||
B4A29A352B55C990002A67DF /* LaunchScreen.storyboard in Resources */,
|
||||
B4A29A372B55C990002A67DF /* Images.xcassets in Resources */,
|
||||
);
|
||||
|
@ -1420,12 +1500,30 @@
|
|||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
B44033E92BCC371A00162242 /* MarketData.swift in Sources */,
|
||||
B44033CA2BCC350A00162242 /* Currency.swift in Sources */,
|
||||
B4AB21092B61DC3F0080440C /* SplashScreen.m in Sources */,
|
||||
B44033EE2BCC374500162242 /* Numeric+abbreviated.swift in Sources */,
|
||||
B4AB21072B61D8CA0080440C /* SplashScreen.swift in Sources */,
|
||||
B44033DD2BCC36C300162242 /* LatestTransaction.swift in Sources */,
|
||||
6D32C5C62596CE3A008C077C /* EventEmitter.m in Sources */,
|
||||
B44033FE2BCC37D700162242 /* MarketAPI.swift in Sources */,
|
||||
B44033CE2BCC352900162242 /* UserDefaultsGroup.swift in Sources */,
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */,
|
||||
B461B852299599F800E431AA /* AppDelegate.mm in Sources */,
|
||||
B44033F42BCC377F00162242 /* WidgetData.swift in Sources */,
|
||||
B44033C42BCC332400162242 /* Balance.swift in Sources */,
|
||||
B44034072BCC38A000162242 /* FiatUnit.swift in Sources */,
|
||||
B44034002BCC37F800162242 /* Bundle+decode.swift in Sources */,
|
||||
B44033E22BCC36CB00162242 /* Placeholders.swift in Sources */,
|
||||
B44033DA2BCC369A00162242 /* Colors.swift in Sources */,
|
||||
B44033D32BCC368800162242 /* UserDefaultsGroupKey.swift in Sources */,
|
||||
32B5A32A2334450100F8D608 /* Bridge.swift in Sources */,
|
||||
B44033D82BCC369500162242 /* UserDefaultsExtension.swift in Sources */,
|
||||
B44033E42BCC36FF00162242 /* WalletData.swift in Sources */,
|
||||
B44033BF2BCC32F800162242 /* BitcoinUnit.swift in Sources */,
|
||||
B44034052BCC389200162242 /* XMLParserDelegate.swift in Sources */,
|
||||
B44033F92BCC379200162242 /* WidgetDataStore.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -1434,22 +1532,32 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
6DD410BE266CAF5C0087DE03 /* SendReceiveButtons.swift in Sources */,
|
||||
6DD410B4266CAF5C0087DE03 /* WidgetAPI.swift in Sources */,
|
||||
6DD410B4266CAF5C0087DE03 /* MarketAPI.swift in Sources */,
|
||||
B40FC3FA29CCD1D00007EBAC /* SwiftTCPClient.swift in Sources */,
|
||||
6DD410A1266CADF10087DE03 /* Widgets.swift in Sources */,
|
||||
6DD410AC266CAE470087DE03 /* PriceWidget.swift in Sources */,
|
||||
B44033D52BCC368800162242 /* UserDefaultsGroupKey.swift in Sources */,
|
||||
6DD410B2266CAF5C0087DE03 /* WalletInformationView.swift in Sources */,
|
||||
B44034022BCC37F800162242 /* Bundle+decode.swift in Sources */,
|
||||
B44033CC2BCC350A00162242 /* Currency.swift in Sources */,
|
||||
6DD410B6266CAF5C0087DE03 /* PriceView.swift in Sources */,
|
||||
6DD410B3266CAF5C0087DE03 /* Colors.swift in Sources */,
|
||||
B44033C12BCC32F800162242 /* BitcoinUnit.swift in Sources */,
|
||||
6DD410BB266CAF5C0087DE03 /* MarketView.swift in Sources */,
|
||||
6DD410B5266CAF5C0087DE03 /* WidgetDataStore.swift in Sources */,
|
||||
B44033F02BCC374500162242 /* Numeric+abbreviated.swift in Sources */,
|
||||
B44033DF2BCC36C300162242 /* LatestTransaction.swift in Sources */,
|
||||
6DD410C0266CB1460087DE03 /* MarketWidget.swift in Sources */,
|
||||
B4AB225E2B02AD12001F4328 /* XMLParserDelegate.swift in Sources */,
|
||||
B44033F62BCC377F00162242 /* WidgetData.swift in Sources */,
|
||||
6DD410BA266CAF5C0087DE03 /* FiatUnit.swift in Sources */,
|
||||
B44033FB2BCC379200162242 /* WidgetDataStore.swift in Sources */,
|
||||
B44033EB2BCC371A00162242 /* MarketData.swift in Sources */,
|
||||
6DD410AF266CAF5C0087DE03 /* WalletInformationAndMarketWidget.swift in Sources */,
|
||||
6DD410BF266CB13D0087DE03 /* Models.swift in Sources */,
|
||||
B44033C62BCC332400162242 /* Balance.swift in Sources */,
|
||||
B44033E62BCC36FF00162242 /* WalletData.swift in Sources */,
|
||||
6DD410BF266CB13D0087DE03 /* Placeholders.swift in Sources */,
|
||||
6DD410B0266CAF5C0087DE03 /* WalletInformationWidget.swift in Sources */,
|
||||
6DD410B1266CAF5C0087DE03 /* WidgetAPI+Electrum.swift in Sources */,
|
||||
6DD410B1266CAF5C0087DE03 /* MarketAPI+Electrum.swift in Sources */,
|
||||
6DD410B9266CAF5C0087DE03 /* UserDefaultsGroup.swift in Sources */,
|
||||
6DD410B8266CAF5C0087DE03 /* UserDefaultsExtension.swift in Sources */,
|
||||
);
|
||||
|
@ -1465,23 +1573,35 @@
|
|||
32F0A29A2311DBB20095C559 /* ComplicationController.swift in Sources */,
|
||||
B40D4E602258425500428FCC /* SpecifyInterfaceController.swift in Sources */,
|
||||
B43D0379225847C500FBAA95 /* WatchDataSource.swift in Sources */,
|
||||
B44033D42BCC368800162242 /* UserDefaultsGroupKey.swift in Sources */,
|
||||
B44034012BCC37F800162242 /* Bundle+decode.swift in Sources */,
|
||||
849047CA2702A32A008EE567 /* Handoff.swift in Sources */,
|
||||
6D4AF16325D21185009DD853 /* WidgetDataStore.swift in Sources */,
|
||||
B44033EA2BCC371A00162242 /* MarketData.swift in Sources */,
|
||||
B44033CB2BCC350A00162242 /* Currency.swift in Sources */,
|
||||
6DFC807224EA2FA9007B8700 /* ViewQRCodefaceController.swift in Sources */,
|
||||
B40D4E46225841ED00428FCC /* NotificationController.swift in Sources */,
|
||||
B40D4E5D2258425500428FCC /* InterfaceController.swift in Sources */,
|
||||
B44033FA2BCC379200162242 /* WidgetDataStore.swift in Sources */,
|
||||
B44033DE2BCC36C300162242 /* LatestTransaction.swift in Sources */,
|
||||
B43D037B225847C500FBAA95 /* TransactionTableRow.swift in Sources */,
|
||||
B43D037D225847C500FBAA95 /* WalletInformation.swift in Sources */,
|
||||
6D4AF15925D21172009DD853 /* WidgetAPI.swift in Sources */,
|
||||
6D4AF15925D21172009DD853 /* MarketAPI.swift in Sources */,
|
||||
B40D4E642258425500428FCC /* WalletDetailsInterfaceController.swift in Sources */,
|
||||
B40D4E44225841ED00428FCC /* ExtensionDelegate.swift in Sources */,
|
||||
B40D4E682258426B00428FCC /* KeychainSwiftDistrib.swift in Sources */,
|
||||
6D4AF16D25D21192009DD853 /* Models.swift in Sources */,
|
||||
6D4AF16D25D21192009DD853 /* Placeholders.swift in Sources */,
|
||||
B44033DB2BCC369B00162242 /* Colors.swift in Sources */,
|
||||
B40D4E632258425500428FCC /* ReceiveInterfaceController.swift in Sources */,
|
||||
B43D0378225847C500FBAA95 /* WalletGradient.swift in Sources */,
|
||||
B44033C02BCC32F800162242 /* BitcoinUnit.swift in Sources */,
|
||||
B44033E52BCC36FF00162242 /* WalletData.swift in Sources */,
|
||||
B44033EF2BCC374500162242 /* Numeric+abbreviated.swift in Sources */,
|
||||
B44033D02BCC352F00162242 /* UserDefaultsGroup.swift in Sources */,
|
||||
B44033C52BCC332400162242 /* Balance.swift in Sources */,
|
||||
6D4AF18425D215D1009DD853 /* UserDefaultsExtension.swift in Sources */,
|
||||
B4AB225D2B02AD12001F4328 /* XMLParserDelegate.swift in Sources */,
|
||||
B40D4E5E2258425500428FCC /* NumericKeypadInterfaceController.swift in Sources */,
|
||||
B44033F52BCC377F00162242 /* WidgetData.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -1498,10 +1618,28 @@
|
|||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
B44033D72BCC369400162242 /* UserDefaultsExtension.swift in Sources */,
|
||||
B44033F72BCC377F00162242 /* WidgetData.swift in Sources */,
|
||||
B44033E12BCC36CA00162242 /* Placeholders.swift in Sources */,
|
||||
B44033E72BCC36FF00162242 /* WalletData.swift in Sources */,
|
||||
B44033E02BCC36C300162242 /* LatestTransaction.swift in Sources */,
|
||||
B44033D92BCC369900162242 /* Colors.swift in Sources */,
|
||||
B4A29A2C2B55C990002A67DF /* EventEmitter.m in Sources */,
|
||||
B44033D62BCC368800162242 /* UserDefaultsGroupKey.swift in Sources */,
|
||||
B44033FD2BCC37D600162242 /* MarketAPI.swift in Sources */,
|
||||
B4A29A2D2B55C990002A67DF /* main.m in Sources */,
|
||||
B4A29A2E2B55C990002A67DF /* AppDelegate.mm in Sources */,
|
||||
B44033C72BCC332400162242 /* Balance.swift in Sources */,
|
||||
B44033FC2BCC379200162242 /* WidgetDataStore.swift in Sources */,
|
||||
B44033C22BCC32F800162242 /* BitcoinUnit.swift in Sources */,
|
||||
B44033F12BCC374500162242 /* Numeric+abbreviated.swift in Sources */,
|
||||
B44034032BCC37F800162242 /* Bundle+decode.swift in Sources */,
|
||||
B44033CD2BCC350A00162242 /* Currency.swift in Sources */,
|
||||
B44034062BCC389F00162242 /* FiatUnit.swift in Sources */,
|
||||
B44033CF2BCC352C00162242 /* UserDefaultsGroup.swift in Sources */,
|
||||
B4A29A2F2B55C990002A67DF /* Bridge.swift in Sources */,
|
||||
B44034042BCC389100162242 /* XMLParserDelegate.swift in Sources */,
|
||||
B44033EC2BCC371A00162242 /* MarketData.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -1544,12 +1682,6 @@
|
|||
target = B4A29A212B55C990002A67DF /* BlueWallet-NoLDK */;
|
||||
targetProxy = B49038D62B8FBA2500A8164A /* PBXContainerItemProxy */;
|
||||
};
|
||||
B4A29A222B55C990002A67DF /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
platformFilter = ios;
|
||||
target = B40D4E2F225841EC00428FCC /* BlueWalletWatch */;
|
||||
targetProxy = B4A29A232B55C990002A67DF /* PBXContainerItemProxy */;
|
||||
};
|
||||
B4A29A242B55C990002A67DF /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
targetProxy = B4A29A252B55C990002A67DF /* PBXContainerItemProxy */;
|
||||
|
@ -2074,7 +2206,7 @@
|
|||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = 4;
|
||||
WATCHOS_DEPLOYMENT_TARGET = 5.0;
|
||||
WATCHOS_DEPLOYMENT_TARGET = 6.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
|
@ -2123,7 +2255,7 @@
|
|||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = 4;
|
||||
WATCHOS_DEPLOYMENT_TARGET = 5.0;
|
||||
WATCHOS_DEPLOYMENT_TARGET = 6.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
|
@ -2170,7 +2302,7 @@
|
|||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 4.2;
|
||||
TARGETED_DEVICE_FAMILY = 4;
|
||||
WATCHOS_DEPLOYMENT_TARGET = 5.0;
|
||||
WATCHOS_DEPLOYMENT_TARGET = 6.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
|
@ -2217,7 +2349,7 @@
|
|||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||
SWIFT_VERSION = 4.2;
|
||||
TARGETED_DEVICE_FAMILY = 4;
|
||||
WATCHOS_DEPLOYMENT_TARGET = 5.0;
|
||||
WATCHOS_DEPLOYMENT_TARGET = 6.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
|
@ -2495,7 +2627,7 @@
|
|||
/* End XCConfigurationList section */
|
||||
|
||||
/* Begin XCRemoteSwiftPackageReference section */
|
||||
6DFC806E24EA0B6C007B8700 /* XCRemoteSwiftPackageReference "EFQRCode.git" */ = {
|
||||
6DFC806E24EA0B6C007B8700 /* XCRemoteSwiftPackageReference "EFQRCode" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/EFPrefix/EFQRCode.git";
|
||||
requirement = {
|
||||
|
@ -2516,7 +2648,7 @@
|
|||
/* Begin XCSwiftPackageProductDependency section */
|
||||
6DFC806F24EA0B6C007B8700 /* EFQRCode */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 6DFC806E24EA0B6C007B8700 /* XCRemoteSwiftPackageReference "EFQRCode.git" */;
|
||||
package = 6DFC806E24EA0B6C007B8700 /* XCRemoteSwiftPackageReference "EFQRCode" */;
|
||||
productName = EFQRCode;
|
||||
};
|
||||
B41B76842B66B2FF002C48D5 /* Bugsnag */ = {
|
||||
|
|
|
@ -102,7 +102,7 @@
|
|||
</EnvironmentVariable>
|
||||
<EnvironmentVariable
|
||||
key = "_XCWidgetFamily"
|
||||
value = "systemMedium"
|
||||
value = "systemSmall"
|
||||
isEnabled = "YES">
|
||||
</EnvironmentVariable>
|
||||
</EnvironmentVariables>
|
||||
|
|
|
@ -36,7 +36,7 @@ class ExtensionDelegate: NSObject, WKExtensionDelegate {
|
|||
}
|
||||
|
||||
private func updateMarketData(for fiatUnit: FiatUnit) {
|
||||
WidgetAPI.fetchPrice(currency: fiatUnit.endPointKey) { (data, error) in
|
||||
MarketAPI.fetchPrice(currency: fiatUnit.endPointKey) { (data, error) in
|
||||
guard let data = data, let encodedData = try? PropertyListEncoder().encode(data) else { return }
|
||||
let groupUserDefaults = UserDefaults(suiteName: UserDefaultsGroupKey.GroupName.rawValue)
|
||||
groupUserDefaults?.set(encodedData, forKey: MarketData.string)
|
||||
|
|
35
ios/Shared/Balance.swift
Normal file
35
ios/Shared/Balance.swift
Normal file
|
@ -0,0 +1,35 @@
|
|||
import Foundation
|
||||
|
||||
class Balance {
|
||||
static func formatBalance(_ balance: Decimal, toUnit: BitcoinUnit, withFormatting: Bool = false, completion: @escaping (String) -> Void) {
|
||||
switch toUnit {
|
||||
case .BTC:
|
||||
let value = balance / Decimal(100_000_000)
|
||||
completion("\(value) BTC") // Localize unit names as needed.
|
||||
case .SATS:
|
||||
if withFormatting {
|
||||
completion(NumberFormatter.localizedString(from: balance as NSNumber, number: .decimal) + " SATS")
|
||||
} else {
|
||||
completion("\(balance) SATS")
|
||||
}
|
||||
case .LOCAL_CURRENCY:
|
||||
fetchLocalCurrencyEquivalent(satoshi: balance, completion: completion)
|
||||
}
|
||||
}
|
||||
|
||||
private static func fetchLocalCurrencyEquivalent(satoshi: Decimal, completion: @escaping (String) -> Void) {
|
||||
|
||||
let currency = Currency.getUserPreferredCurrency() // Ensure this method retrieves the correct currency code.
|
||||
MarketAPI.fetchPrice(currency: currency) { dataStore, error in
|
||||
DispatchQueue.main.async {
|
||||
guard let dataStore = dataStore, error == nil else {
|
||||
completion("Error: \(error?.localizedDescription ?? "Unknown error")")
|
||||
return
|
||||
}
|
||||
let rate = Decimal(string: dataStore.rate) ?? Decimal(0)
|
||||
let convertedAmount = (satoshi / Decimal(100_000_000)) * rate
|
||||
completion("\(convertedAmount) \(currency)")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
15
ios/Shared/BitcoinUnit.swift
Normal file
15
ios/Shared/BitcoinUnit.swift
Normal file
|
@ -0,0 +1,15 @@
|
|||
//
|
||||
// BitcoinUnit.swift
|
||||
// BlueWallet
|
||||
//
|
||||
// Created by Marcos Rodriguez on 4/14/24.
|
||||
// Copyright © 2024 BlueWallet. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum BitcoinUnit: String {
|
||||
case BTC = "BTC"
|
||||
case SATS = "SATS"
|
||||
case LOCAL_CURRENCY = "LOCAL_CURRENCY"
|
||||
}
|
|
@ -1,24 +1,13 @@
|
|||
//
|
||||
// FiatUnit.swift
|
||||
// Bundle+decode.swift
|
||||
// BlueWallet
|
||||
//
|
||||
// Created by Marcos Rodriguez on 11/20/20.
|
||||
// Copyright © 2020 BlueWallet. All rights reserved.
|
||||
// Created by Marcos Rodriguez on 4/14/24.
|
||||
// Copyright © 2024 BlueWallet. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct FiatUnit: Codable {
|
||||
let endPointKey: String
|
||||
let symbol: String
|
||||
let locale: String
|
||||
let source: String
|
||||
|
||||
}
|
||||
|
||||
func fiatUnit(currency: String) -> FiatUnit? {
|
||||
return Bundle.main.decode([String: FiatUnit].self, from: "fiatUnits.json").first(where: {$1.endPointKey == currency})?.value
|
||||
}
|
||||
|
||||
extension Bundle {
|
||||
func decode<T: Decodable>(_ type: T.Type, from file: String, dateDecodingStrategy: JSONDecoder.DateDecodingStrategy = .deferredToDate, keyDecodingStrategy: JSONDecoder.KeyDecodingStrategy = .useDefaultKeys) -> T {
|
||||
guard let url = self.url(forResource: file, withExtension: nil) else {
|
57
ios/Shared/Currency.swift
Normal file
57
ios/Shared/Currency.swift
Normal file
|
@ -0,0 +1,57 @@
|
|||
//
|
||||
// Currency.swift
|
||||
// BlueWallet
|
||||
//
|
||||
// Created by Marcos Rodriguez on 4/14/24.
|
||||
// Copyright © 2024 BlueWallet. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct CurrencyError: LocalizedError {
|
||||
var errorDescription: String = "Failed to parse response"
|
||||
}
|
||||
|
||||
class Currency {
|
||||
|
||||
static func getUserPreferredCurrency() -> String {
|
||||
|
||||
guard let userDefaults = UserDefaults(suiteName: UserDefaultsGroupKey.GroupName.rawValue),
|
||||
let preferredCurrency = userDefaults.string(forKey: "preferredCurrency")
|
||||
else {
|
||||
return "USD"
|
||||
}
|
||||
|
||||
if preferredCurrency != Currency.getLastSelectedCurrency() {
|
||||
UserDefaults.standard.removeObject(forKey: WidgetData.WidgetCachedDataStoreKey)
|
||||
UserDefaults.standard.removeObject(forKey: WidgetData.WidgetDataStoreKey)
|
||||
UserDefaults.standard.synchronize()
|
||||
}
|
||||
|
||||
return preferredCurrency
|
||||
}
|
||||
|
||||
static func getUserPreferredCurrencyLocale() -> String {
|
||||
guard let userDefaults = UserDefaults(suiteName: UserDefaultsGroupKey.GroupName.rawValue),
|
||||
let preferredCurrency = userDefaults.string(forKey: "preferredCurrencyLocale")
|
||||
else {
|
||||
return "en_US"
|
||||
}
|
||||
return preferredCurrency
|
||||
}
|
||||
|
||||
static func getLastSelectedCurrency() -> String {
|
||||
guard let userDefaults = UserDefaults(suiteName: UserDefaultsGroupKey.GroupName.rawValue), let dataStore = userDefaults.string(forKey: "currency") else {
|
||||
return "USD"
|
||||
}
|
||||
|
||||
return dataStore
|
||||
}
|
||||
|
||||
static func saveNewSelectedCurrency() {
|
||||
UserDefaults.standard.setValue(Currency.getUserPreferredCurrency(), forKey: "currency")
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
20
ios/Shared/Fiat/FiatUnit.swift
Normal file
20
ios/Shared/Fiat/FiatUnit.swift
Normal file
|
@ -0,0 +1,20 @@
|
|||
//
|
||||
// FiatUnit.swift
|
||||
// BlueWallet
|
||||
//
|
||||
// Created by Marcos Rodriguez on 11/20/20.
|
||||
// Copyright © 2020 BlueWallet. All rights reserved.
|
||||
//
|
||||
import Foundation
|
||||
|
||||
struct FiatUnit: Codable {
|
||||
let endPointKey: String
|
||||
let symbol: String
|
||||
let locale: String
|
||||
let source: String
|
||||
|
||||
}
|
||||
|
||||
func fiatUnit(currency: String) -> FiatUnit? {
|
||||
return Bundle.main.decode([String: FiatUnit].self, from: "fiatUnits.json").first(where: {$1.endPointKey == currency})?.value
|
||||
}
|
14
ios/Shared/LatestTransaction.swift
Normal file
14
ios/Shared/LatestTransaction.swift
Normal file
|
@ -0,0 +1,14 @@
|
|||
//
|
||||
// LatestTransaction.swift
|
||||
// BlueWallet
|
||||
//
|
||||
// Created by Marcos Rodriguez on 4/14/24.
|
||||
// Copyright © 2024 BlueWallet. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct LatestTransaction {
|
||||
let isUnconfirmed: Bool?
|
||||
let epochValue: Int?
|
||||
}
|
|
@ -12,7 +12,7 @@ struct APIError: LocalizedError {
|
|||
var errorDescription: String = "Failed to fetch Electrum data..."
|
||||
}
|
||||
|
||||
extension WidgetAPI {
|
||||
extension MarketAPI {
|
||||
|
||||
static func fetchNextBlockFee(completion: @escaping ((MarketData?, Error?) -> Void), userElectrumSettings: UserDefaultsElectrumSettings = UserDefaultsGroup.getElectrumSettings()) {
|
||||
let settings = userElectrumSettings
|
||||
|
@ -73,12 +73,12 @@ extension WidgetAPI {
|
|||
|
||||
static func fetchMarketData(currency: String, completion: @escaping ((MarketData?, Error?) -> Void)) {
|
||||
var marketDataEntry = MarketData(nextBlock: "...", sats: "...", price: "...", rate: 0)
|
||||
WidgetAPI.fetchPrice(currency: currency, completion: { (result, error) in
|
||||
MarketAPI.fetchPrice(currency: currency, completion: { (result, error) in
|
||||
if let result = result {
|
||||
marketDataEntry.rate = result.rateDouble
|
||||
marketDataEntry.price = result.formattedRate ?? "!"
|
||||
}
|
||||
WidgetAPI.fetchNextBlockFee { (marketData, error) in
|
||||
MarketAPI.fetchNextBlockFee { (marketData, error) in
|
||||
if let nextBlock = marketData?.nextBlock {
|
||||
marketDataEntry.nextBlock = nextBlock
|
||||
} else {
|
199
ios/Shared/MarketAPI.swift
Normal file
199
ios/Shared/MarketAPI.swift
Normal file
|
@ -0,0 +1,199 @@
|
|||
//
|
||||
// WidgetAPI.swift
|
||||
// TodayExtension
|
||||
//
|
||||
// Created by Marcos Rodriguez on 11/2/19.
|
||||
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
var numberFormatter: NumberFormatter {
|
||||
let formatter = NumberFormatter()
|
||||
formatter.numberStyle = .decimal
|
||||
formatter.maximumFractionDigits = 0
|
||||
formatter.locale = Locale.current
|
||||
return formatter
|
||||
}
|
||||
|
||||
class MarketAPI {
|
||||
|
||||
private static func buildURLString(source: String, endPointKey: String) -> String {
|
||||
switch source {
|
||||
case "Yadio":
|
||||
return "https://api.yadio.io/json/\(endPointKey)"
|
||||
case "YadioConvert":
|
||||
return "https://api.yadio.io/convert/1/BTC/\(endPointKey)"
|
||||
case "Exir":
|
||||
return "https://api.exir.io/v1/ticker?symbol=btc-irt"
|
||||
case "wazirx":
|
||||
return "https://api.wazirx.com/api/v2/tickers/btcinr"
|
||||
case "Bitstamp":
|
||||
return "https://www.bitstamp.net/api/v2/ticker/btc\(endPointKey.lowercased())"
|
||||
case "Coinbase":
|
||||
return "https://api.coinbase.com/v2/prices/BTC-\(endPointKey.uppercased())/buy"
|
||||
case "CoinGecko":
|
||||
return "https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=\(endPointKey.lowercased())"
|
||||
case "BNR":
|
||||
return "https://www.bnr.ro/nbrfxrates.xml"
|
||||
default:
|
||||
return "https://api.coindesk.com/v1/bpi/currentprice/\(endPointKey).json"
|
||||
}
|
||||
}
|
||||
|
||||
private static func handleDefaultData(data: Data, source: String, endPointKey: String, completion: @escaping ((WidgetDataStore?, Error?) -> Void)) {
|
||||
guard let json = (try? JSONSerialization.jsonObject(with: data, options: [])) as? Dictionary<String, Any> else {
|
||||
completion(nil, CurrencyError(errorDescription: "JSON parsing error."))
|
||||
return
|
||||
}
|
||||
|
||||
// Parse the JSON based on the source and format the response
|
||||
parseJSONBasedOnSource(json: json, source: source, endPointKey: endPointKey, completion: completion)
|
||||
}
|
||||
|
||||
private static func parseJSONBasedOnSource(json: Dictionary<String, Any>, source: String, endPointKey: String, completion: @escaping ((WidgetDataStore?, Error?) -> Void)) {
|
||||
var latestRateDataStore: WidgetDataStore?
|
||||
|
||||
switch source {
|
||||
case "Yadio":
|
||||
if let rateDict = json[endPointKey] as? [String: Any],
|
||||
let rateDouble = rateDict["price"] as? Double,
|
||||
let lastUpdated = rateDict["timestamp"] as? Int {
|
||||
let unix = Double(lastUpdated / 1_000)
|
||||
let lastUpdatedString = ISO8601DateFormatter().string(from: Date(timeIntervalSince1970: unix))
|
||||
latestRateDataStore = WidgetDataStore(rate: String(rateDouble), lastUpdate: lastUpdatedString, rateDouble: rateDouble)
|
||||
completion(latestRateDataStore, nil)
|
||||
} else {
|
||||
completion(nil, CurrencyError(errorDescription: "Data formatting error for source: \(source)"))
|
||||
}
|
||||
case "YadioConvert":
|
||||
guard let rateDouble = json["rate"] as? Double,
|
||||
let lastUpdated = json["timestamp"] as? Int
|
||||
else { break }
|
||||
let unix = Double(lastUpdated / 1_000)
|
||||
let lastUpdatedString = ISO8601DateFormatter().string(from: Date(timeIntervalSince1970: unix))
|
||||
latestRateDataStore = WidgetDataStore(rate: String(rateDouble), lastUpdate: lastUpdatedString, rateDouble: rateDouble)
|
||||
completion(latestRateDataStore, nil)
|
||||
case "CoinGecko":
|
||||
if let bitcoinDict = json["bitcoin"] as? [String: Any],
|
||||
let rateDouble = bitcoinDict[endPointKey.lowercased()] as? Double {
|
||||
let lastUpdatedString = ISO8601DateFormatter().string(from: Date())
|
||||
latestRateDataStore = WidgetDataStore(rate: String(rateDouble), lastUpdate: lastUpdatedString, rateDouble: rateDouble)
|
||||
completion(latestRateDataStore, nil)
|
||||
} else {
|
||||
completion(nil, CurrencyError(errorDescription: "Data formatting error for source: \(source)"))
|
||||
}
|
||||
|
||||
case "Exir":
|
||||
if let rateDouble = json["last"] as? Double {
|
||||
let lastUpdatedString = ISO8601DateFormatter().string(from: Date())
|
||||
latestRateDataStore = WidgetDataStore(rate: String(rateDouble), lastUpdate: lastUpdatedString, rateDouble: rateDouble)
|
||||
completion(latestRateDataStore, nil)
|
||||
} else {
|
||||
completion(nil, CurrencyError(errorDescription: "Data formatting error for source: \(source)"))
|
||||
}
|
||||
|
||||
case "Bitstamp":
|
||||
if let rateString = json["last"] as? String, let rateDouble = Double(rateString) {
|
||||
let lastUpdatedString = ISO8601DateFormatter().string(from: Date())
|
||||
latestRateDataStore = WidgetDataStore(rate: rateString, lastUpdate: lastUpdatedString, rateDouble: rateDouble)
|
||||
completion(latestRateDataStore, nil)
|
||||
} else {
|
||||
completion(nil, CurrencyError(errorDescription: "Data formatting error for source: \(source)"))
|
||||
}
|
||||
|
||||
case "wazirx":
|
||||
if let tickerDict = json["ticker"] as? [String: Any],
|
||||
let rateString = tickerDict["buy"] as? String,
|
||||
let rateDouble = Double(rateString) {
|
||||
let lastUpdatedString = ISO8601DateFormatter().string(from: Date())
|
||||
latestRateDataStore = WidgetDataStore(rate: rateString, lastUpdate: lastUpdatedString, rateDouble: rateDouble)
|
||||
completion(latestRateDataStore, nil)
|
||||
} else {
|
||||
completion(nil, CurrencyError(errorDescription: "Data formatting error for source: \(source)"))
|
||||
}
|
||||
|
||||
case "Coinbase":
|
||||
if let data = json["data"] as? [String: Any],
|
||||
let rateString = data["amount"] as? String,
|
||||
let rateDouble = Double(rateString) {
|
||||
let lastUpdatedString = ISO8601DateFormatter().string(from: Date())
|
||||
latestRateDataStore = WidgetDataStore(rate: rateString, lastUpdate: lastUpdatedString, rateDouble: rateDouble)
|
||||
completion(latestRateDataStore, nil)
|
||||
} else {
|
||||
completion(nil, CurrencyError(errorDescription: "Data formatting error for source: \(source)"))
|
||||
}
|
||||
|
||||
case "BNR":
|
||||
// Handle BNR source differently if needed, perhaps requiring XML parsing
|
||||
// Placeholder for potential XML parsing logic or alternative JSON structure
|
||||
completion(nil, CurrencyError(errorDescription: "BNR data source is not yet implemented"))
|
||||
|
||||
default:
|
||||
completion(nil, CurrencyError(errorDescription: "Unsupported data source \(source)"))
|
||||
}
|
||||
}
|
||||
|
||||
// Handles XML data for BNR source
|
||||
private static func handleBNRData(data: Data, completion: @escaping ((WidgetDataStore?, Error?) -> Void)) {
|
||||
let parser = XMLParser(data: data)
|
||||
let delegate = BNRXMLParserDelegate()
|
||||
parser.delegate = delegate
|
||||
if parser.parse(), let usdToRonRate = delegate.usdRate {
|
||||
let coinGeckoUrl = URL(string: "https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd")!
|
||||
URLSession.shared.dataTask(with: coinGeckoUrl) { data, _, error in
|
||||
guard let data = data, error == nil else {
|
||||
completion(nil, error ?? CurrencyError())
|
||||
return
|
||||
}
|
||||
|
||||
do {
|
||||
if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
|
||||
let bitcoinDict = json["bitcoin"] as? [String: Double],
|
||||
let btcToUsdRate = bitcoinDict["usd"] {
|
||||
let btcToRonRate = btcToUsdRate * usdToRonRate
|
||||
let lastUpdatedString = ISO8601DateFormatter().string(from: Date())
|
||||
let latestRateDataStore = WidgetDataStore(rate: String(btcToRonRate), lastUpdate: lastUpdatedString, rateDouble: btcToRonRate)
|
||||
completion(latestRateDataStore, nil)
|
||||
} else {
|
||||
completion(nil, CurrencyError())
|
||||
}
|
||||
} catch {
|
||||
completion(nil, error)
|
||||
}
|
||||
}.resume()
|
||||
} else {
|
||||
completion(nil, CurrencyError(errorDescription: "XML parsing error."))
|
||||
}
|
||||
}
|
||||
|
||||
static func fetchPrice(currency: String, completion: @escaping ((WidgetDataStore?, Error?) -> Void)) {
|
||||
let currencyToFiatUnit = fiatUnit(currency: currency)
|
||||
guard let source = currencyToFiatUnit?.source, let endPointKey = currencyToFiatUnit?.endPointKey else {
|
||||
completion(nil, CurrencyError(errorDescription: "Invalid currency unit or endpoint."))
|
||||
return
|
||||
}
|
||||
|
||||
let urlString = buildURLString(source: source, endPointKey: endPointKey)
|
||||
guard let url = URL(string: urlString) else {
|
||||
completion(nil, CurrencyError(errorDescription: "Invalid URL."))
|
||||
return
|
||||
}
|
||||
|
||||
URLSession.shared.dataTask(with: url) { data, response, error in
|
||||
guard let data = data, error == nil else {
|
||||
completion(nil, error ?? CurrencyError(errorDescription: "Network error or data not found."))
|
||||
return
|
||||
}
|
||||
|
||||
if source == "BNR" {
|
||||
handleBNRData(data: data, completion: completion)
|
||||
} else {
|
||||
handleDefaultData(data: data, source: source, endPointKey: endPointKey, completion: completion)
|
||||
}
|
||||
}.resume()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
37
ios/Shared/MarketData.swift
Normal file
37
ios/Shared/MarketData.swift
Normal file
|
@ -0,0 +1,37 @@
|
|||
//
|
||||
// MarketData.swift
|
||||
// BlueWallet
|
||||
//
|
||||
// Created by Marcos Rodriguez on 4/14/24.
|
||||
// Copyright © 2024 BlueWallet. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct MarketData:Codable {
|
||||
var nextBlock: String
|
||||
var sats: String
|
||||
var price: String
|
||||
var rate: Double
|
||||
var formattedNextBlock: String {
|
||||
return nextBlock == "..." ? "..." : #"\#(nextBlock) sat/b"#
|
||||
}
|
||||
var dateString: String = ""
|
||||
var formattedDate: String? {
|
||||
let isoDateFormatter = ISO8601DateFormatter()
|
||||
let dateFormatter = DateFormatter()
|
||||
dateFormatter.locale = Locale.current
|
||||
dateFormatter.timeStyle = .short
|
||||
|
||||
if let date = isoDateFormatter.date(from: dateString) {
|
||||
return dateFormatter.string(from: date)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
static let string = "MarketData"
|
||||
}
|
||||
|
||||
enum MarketDataTimeline: String {
|
||||
case Previous = "previous"
|
||||
case Current = "current"
|
||||
}
|
27
ios/Shared/Numeric+abbreviated.swift
Normal file
27
ios/Shared/Numeric+abbreviated.swift
Normal file
|
@ -0,0 +1,27 @@
|
|||
//
|
||||
// Numeric+abbreviated.swift
|
||||
// BlueWallet
|
||||
//
|
||||
// Created by Marcos Rodriguez on 4/14/24.
|
||||
// Copyright © 2024 BlueWallet. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension Numeric {
|
||||
|
||||
var abbreviated: String {
|
||||
let bytecountFormatter = ByteCountFormatter()
|
||||
bytecountFormatter.zeroPadsFractionDigits = true
|
||||
bytecountFormatter.countStyle = .decimal
|
||||
bytecountFormatter.isAdaptive = false
|
||||
let bytesString = bytecountFormatter.string(fromByteCount: (self as! NSNumber).int64Value)
|
||||
|
||||
let numericString = bytesString
|
||||
.replacingOccurrences(of: "bytes", with: "")
|
||||
.replacingOccurrences(of: "B", with: "") // removes B (bytes) in 'KB'/'MB'/'GB'
|
||||
.replacingOccurrences(of: "G", with: "B") // replace G (Giga) to just B (billions)
|
||||
return numericString.replacingOccurrences(of: " ", with: "")
|
||||
}
|
||||
|
||||
}
|
16
ios/Shared/Placeholders.swift
Normal file
16
ios/Shared/Placeholders.swift
Normal file
|
@ -0,0 +1,16 @@
|
|||
//
|
||||
// Models.swift
|
||||
// BlueWallet
|
||||
//
|
||||
// Created by Marcos Rodriguez on 11/1/20.
|
||||
// Copyright © 2020 BlueWallet. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
|
||||
let emptyMarketData = MarketData(nextBlock: "...", sats: "...", price: "...", rate: 0)
|
||||
let emptyWalletData = WalletData(balance: 0, latestTransactionTime: LatestTransaction(isUnconfirmed: false, epochValue: Int(Date().timeIntervalSince1970)))
|
||||
|
||||
|
20
ios/Shared/UserDefaultsGroupKey.swift
Normal file
20
ios/Shared/UserDefaultsGroupKey.swift
Normal file
|
@ -0,0 +1,20 @@
|
|||
//
|
||||
// UserDefaultsGroupKeys.swift
|
||||
// BlueWallet
|
||||
//
|
||||
// Created by Marcos Rodriguez on 4/14/24.
|
||||
// Copyright © 2024 BlueWallet. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum UserDefaultsGroupKey: String {
|
||||
case GroupName = "group.io.bluewallet.bluewallet"
|
||||
case PreferredCurrency = "preferredCurrency"
|
||||
case ElectrumSettingsHost = "electrum_host"
|
||||
case ElectrumSettingsTCPPort = "electrum_tcp_port"
|
||||
case ElectrumSettingsSSLPort = "electrum_ssl_port"
|
||||
case AllWalletsBalance = "WidgetCommunicationAllWalletsSatoshiBalance"
|
||||
case AllWalletsLatestTransactionTime = "WidgetCommunicationAllWalletsLatestTransactionTime"
|
||||
case LatestTransactionIsUnconfirmed = "\"WidgetCommunicationLatestTransactionIsUnconfirmed\""
|
||||
}
|
27
ios/Shared/WalletData.swift
Normal file
27
ios/Shared/WalletData.swift
Normal file
|
@ -0,0 +1,27 @@
|
|||
//
|
||||
// WalletData.swift
|
||||
// BlueWallet
|
||||
//
|
||||
// Created by Marcos Rodriguez on 4/14/24.
|
||||
// Copyright © 2024 BlueWallet. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct WalletData {
|
||||
var balance: Double
|
||||
var latestTransactionTime: LatestTransaction = LatestTransaction(isUnconfirmed: false, epochValue: 0)
|
||||
var formattedBalanceBTC: String {
|
||||
let formatter = NumberFormatter()
|
||||
formatter.numberStyle = .none
|
||||
formatter.usesSignificantDigits = true
|
||||
formatter.maximumSignificantDigits = 9
|
||||
formatter.roundingMode = .up
|
||||
let value = NSNumber(value: balance / 100000000);
|
||||
if let valueString = formatter.string(from: value) {
|
||||
return "\(String(describing: valueString)) \(BitcoinUnit.BTC.rawValue)"
|
||||
} else {
|
||||
return "0 \(BitcoinUnit.BTC.rawValue)"
|
||||
}
|
||||
}
|
||||
}
|
22
ios/Shared/WidgetData.swift
Normal file
22
ios/Shared/WidgetData.swift
Normal file
|
@ -0,0 +1,22 @@
|
|||
//
|
||||
// WidgetData.swift
|
||||
// BlueWallet
|
||||
//
|
||||
// Created by Marcos Rodriguez on 4/14/24.
|
||||
// Copyright © 2024 BlueWallet. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class WidgetData {
|
||||
|
||||
static let WidgetDataStoreKey = "WidgetDataStoreKey"
|
||||
static let WidgetCachedDataStoreKey = "WidgetCachedDataStoreKey"
|
||||
|
||||
static func savePriceRateAndLastUpdate(rate: String, lastUpdate: String) {
|
||||
guard let userDefaults = UserDefaults(suiteName: UserDefaultsGroupKey.GroupName.rawValue) else { return }
|
||||
userDefaults.setValue(["rate": rate, "lastUpdate": lastUpdate], forKey: WidgetDataStoreKey)
|
||||
userDefaults.synchronize()
|
||||
}
|
||||
|
||||
}
|
62
ios/Shared/WidgetDataStore.swift
Normal file
62
ios/Shared/WidgetDataStore.swift
Normal file
|
@ -0,0 +1,62 @@
|
|||
//
|
||||
// WidgetDataStore.swift
|
||||
// BlueWallet
|
||||
//
|
||||
// Created by Marcos Rodriguez on 4/14/24.
|
||||
// Copyright © 2024 BlueWallet. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
struct WidgetDataStore: Codable {
|
||||
let rate: String
|
||||
let lastUpdate: String
|
||||
let rateDouble: Double
|
||||
var formattedRate: String? {
|
||||
let numberFormatter = NumberFormatter()
|
||||
numberFormatter.locale = Locale(identifier: Currency.getUserPreferredCurrencyLocale())
|
||||
numberFormatter.numberStyle = .currency
|
||||
numberFormatter.maximumFractionDigits = 0
|
||||
numberFormatter.minimumFractionDigits = 0
|
||||
if let rateString = numberFormatter.string(from: NSNumber(value: rateDouble)) {
|
||||
return rateString
|
||||
}
|
||||
return rate
|
||||
}
|
||||
var formattedRateForSmallComplication: String? {
|
||||
return rateDouble.abbreviated
|
||||
}
|
||||
|
||||
var formattedRateForComplication: String? {
|
||||
let numberFormatter = NumberFormatter()
|
||||
numberFormatter.locale = Locale(identifier: Currency.getUserPreferredCurrencyLocale())
|
||||
numberFormatter.numberStyle = .currency
|
||||
numberFormatter.currencySymbol = ""
|
||||
if let rateString = numberFormatter.string(from: NSNumber(value: rateDouble)) {
|
||||
return rateString
|
||||
}
|
||||
return rate
|
||||
}
|
||||
|
||||
var date: Date? {
|
||||
let isoDateFormatter = ISO8601DateFormatter()
|
||||
let dateFormatter = DateFormatter()
|
||||
dateFormatter.locale = Locale.current
|
||||
dateFormatter.timeStyle = .short
|
||||
|
||||
return isoDateFormatter.date(from: lastUpdate)
|
||||
}
|
||||
var formattedDate: String? {
|
||||
let isoDateFormatter = ISO8601DateFormatter()
|
||||
let dateFormatter = DateFormatter()
|
||||
dateFormatter.locale = Locale.current
|
||||
dateFormatter.timeStyle = .short
|
||||
|
||||
if let date = isoDateFormatter.date(from: lastUpdate) {
|
||||
return dateFormatter.string(from: date)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
@ -29,10 +29,10 @@ struct WalletInformationWidgetProvider: TimelineProvider {
|
|||
|
||||
func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
|
||||
var entries: [WalletInformationWidgetEntry] = []
|
||||
let userPreferredCurrency = WidgetAPI.getUserPreferredCurrency()
|
||||
let userPreferredCurrency = Currency.getUserPreferredCurrency()
|
||||
let allwalletsBalance = WalletData(balance: UserDefaultsGroup.getAllWalletsBalance(), latestTransactionTime: UserDefaultsGroup.getAllWalletsLatestTransactionTime())
|
||||
|
||||
WidgetAPI.fetchPrice(currency: userPreferredCurrency) { (result, error) in
|
||||
MarketAPI.fetchPrice(currency: userPreferredCurrency) { (result, error) in
|
||||
let entry: WalletInformationWidgetEntry
|
||||
|
||||
if let result = result {
|
||||
|
|
|
@ -34,8 +34,8 @@ struct MarketWidgetProvider: TimelineProvider {
|
|||
let timeline = Timeline(entries: entries, policy: .atEnd)
|
||||
completion(timeline)
|
||||
} else {
|
||||
let userPreferredCurrency = WidgetAPI.getUserPreferredCurrency()
|
||||
WidgetAPI.fetchMarketData(currency: userPreferredCurrency) { (result, error) in
|
||||
let userPreferredCurrency = Currency.getUserPreferredCurrency()
|
||||
MarketAPI.fetchMarketData(currency: userPreferredCurrency) { (result, error) in
|
||||
let entry: MarketWidgetEntry
|
||||
|
||||
if let result = result {
|
||||
|
|
|
@ -36,14 +36,14 @@ struct PriceWidgetProvider: TimelineProvider {
|
|||
let timeline = Timeline(entries: entries, policy: .atEnd)
|
||||
completion(timeline)
|
||||
} else {
|
||||
let userPreferredCurrency = WidgetAPI.getUserPreferredCurrency()
|
||||
if userPreferredCurrency != WidgetAPI.getLastSelectedCurrency() {
|
||||
let userPreferredCurrency = Currency.getUserPreferredCurrency()
|
||||
if userPreferredCurrency != Currency.getLastSelectedCurrency() {
|
||||
marketData[.Current] = nil
|
||||
marketData[.Previous] = nil
|
||||
WidgetAPI.saveNewSelectedCurrency()
|
||||
Currency.saveNewSelectedCurrency()
|
||||
}
|
||||
|
||||
WidgetAPI.fetchPrice(currency: userPreferredCurrency) { (data, error) in
|
||||
MarketAPI.fetchPrice(currency: userPreferredCurrency) { (data, error) in
|
||||
let entry: PriceWidgetEntry
|
||||
|
||||
if let data = data, let formattedRate = data.formattedRate {
|
||||
|
|
|
@ -1,74 +0,0 @@
|
|||
//
|
||||
// Models.swift
|
||||
// BlueWallet
|
||||
//
|
||||
// Created by Marcos Rodriguez on 11/1/20.
|
||||
// Copyright © 2020 BlueWallet. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct MarketData:Codable {
|
||||
var nextBlock: String
|
||||
var sats: String
|
||||
var price: String
|
||||
var rate: Double
|
||||
var formattedNextBlock: String {
|
||||
return nextBlock == "..." ? "..." : #"\#(nextBlock) sat/b"#
|
||||
}
|
||||
var dateString: String = ""
|
||||
var formattedDate: String? {
|
||||
let isoDateFormatter = ISO8601DateFormatter()
|
||||
let dateFormatter = DateFormatter()
|
||||
dateFormatter.locale = Locale.current
|
||||
dateFormatter.timeStyle = .short
|
||||
|
||||
if let date = isoDateFormatter.date(from: dateString) {
|
||||
return dateFormatter.string(from: date)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
static let string = "MarketData"
|
||||
}
|
||||
|
||||
struct WalletData {
|
||||
var balance: Double
|
||||
var latestTransactionTime: LatestTransaction = LatestTransaction(isUnconfirmed: false, epochValue: 0)
|
||||
var formattedBalanceBTC: String {
|
||||
let formatter = NumberFormatter()
|
||||
formatter.numberStyle = .none
|
||||
formatter.usesSignificantDigits = true
|
||||
formatter.maximumSignificantDigits = 9
|
||||
formatter.roundingMode = .up
|
||||
let value = NSNumber(value: balance / 100000000);
|
||||
if let valueString = formatter.string(from: value) {
|
||||
return "\(String(describing: valueString)) BTC"
|
||||
} else {
|
||||
return "0 BTC"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct LatestTransaction {
|
||||
let isUnconfirmed: Bool?
|
||||
let epochValue: Int?
|
||||
}
|
||||
let emptyMarketData = MarketData(nextBlock: "...", sats: "...", price: "...", rate: 0)
|
||||
let emptyWalletData = WalletData(balance: 0, latestTransactionTime: LatestTransaction(isUnconfirmed: false, epochValue: Int(Date().timeIntervalSince1970)))
|
||||
|
||||
enum MarketDataTimeline: String {
|
||||
case Previous = "previous"
|
||||
case Current = "current"
|
||||
}
|
||||
|
||||
enum UserDefaultsGroupKey: String {
|
||||
case GroupName = "group.io.bluewallet.bluewallet"
|
||||
case PreferredCurrency = "preferredCurrency"
|
||||
case ElectrumSettingsHost = "electrum_host"
|
||||
case ElectrumSettingsTCPPort = "electrum_tcp_port"
|
||||
case ElectrumSettingsSSLPort = "electrum_ssl_port"
|
||||
case AllWalletsBalance = "WidgetCommunicationAllWalletsSatoshiBalance"
|
||||
case AllWalletsLatestTransactionTime = "WidgetCommunicationAllWalletsLatestTransactionTime"
|
||||
case LatestTransactionIsUnconfirmed = "\"WidgetCommunicationLatestTransactionIsUnconfirmed\""
|
||||
}
|
|
@ -28,7 +28,7 @@ struct MarketView: View {
|
|||
|
||||
Spacer()
|
||||
HStack(alignment: .center, spacing: 0, content: {
|
||||
Text("Sats/\(WidgetAPI.getUserPreferredCurrency())").bold().lineLimit(1).font(Font.system(size:11, weight: .medium, design: .default)).foregroundColor(.textColor)
|
||||
Text("Sats/\(Currency.getUserPreferredCurrency())").bold().lineLimit(1).font(Font.system(size:11, weight: .medium, design: .default)).foregroundColor(.textColor)
|
||||
Spacer()
|
||||
Text(marketData.sats == "..." ? "..." : marketData.sats).padding(EdgeInsets(top: 2, leading: 4, bottom: 2, trailing: 4)).lineLimit(1).minimumScaleFactor(0.1).foregroundColor(.widgetBackground).font(Font.system(size:11, weight: .semibold, design: .default)).background(Color(red: 0.97, green: 0.21, blue: 0.38)).overlay(
|
||||
RoundedRectangle(cornerRadius: 4.0)
|
||||
|
|
|
@ -16,7 +16,7 @@ struct WalletInformationView: View {
|
|||
|
||||
var formattedBalance: String {
|
||||
let numberFormatter = NumberFormatter()
|
||||
numberFormatter.locale = Locale(identifier: WidgetAPI.getUserPreferredCurrencyLocale())
|
||||
numberFormatter.locale = Locale(identifier: Currency.getUserPreferredCurrencyLocale())
|
||||
numberFormatter.numberStyle = .currency
|
||||
let amount = numberFormatter.string(from: NSNumber(value: ((allWalletsBalance.balance / 100000000) * marketData.rate))) ?? ""
|
||||
return amount
|
||||
|
|
|
@ -1,218 +0,0 @@
|
|||
//
|
||||
// WidgetAPI.swift
|
||||
// TodayExtension
|
||||
//
|
||||
// Created by Marcos Rodriguez on 11/2/19.
|
||||
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct CurrencyError: LocalizedError {
|
||||
var errorDescription: String = "Failed to parse response"
|
||||
}
|
||||
|
||||
var numberFormatter: NumberFormatter {
|
||||
let formatter = NumberFormatter()
|
||||
formatter.numberStyle = .decimal
|
||||
formatter.maximumFractionDigits = 0
|
||||
formatter.locale = Locale.current
|
||||
return formatter
|
||||
}
|
||||
|
||||
class WidgetAPI {
|
||||
static func fetchPrice(currency: String, completion: @escaping ((WidgetDataStore?, Error?) -> Void)) {
|
||||
let currencyToFiatUnit = fiatUnit(currency: currency)
|
||||
guard let source = currencyToFiatUnit?.source, let endPointKey = currencyToFiatUnit?.endPointKey else { return }
|
||||
|
||||
var urlString: String
|
||||
switch source {
|
||||
case "Yadio":
|
||||
urlString = "https://api.yadio.io/json/\(endPointKey)"
|
||||
case "YadioConvert":
|
||||
urlString = "https://api.yadio.io/convert/1/BTC/\(endPointKey)"
|
||||
case "Exir":
|
||||
urlString = "https://api.exir.io/v1/ticker?symbol=btc-irt"
|
||||
case "wazirx":
|
||||
urlString = "https://api.wazirx.com/api/v2/tickers/btcinr"
|
||||
case "Bitstamp":
|
||||
urlString = "https://www.bitstamp.net/api/v2/ticker/btc\(endPointKey.lowercased())"
|
||||
case "Coinbase":
|
||||
urlString = "https://api.coinbase.com/v2/prices/BTC-\(endPointKey.uppercased())/buy"
|
||||
case "CoinGecko":
|
||||
urlString = "https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=\(endPointKey.lowercased())"
|
||||
case "BNR":
|
||||
urlString = "https://www.bnr.ro/nbrfxrates.xml"
|
||||
default:
|
||||
urlString = "https://api.coindesk.com/v1/bpi/currentprice/\(endPointKey).json"
|
||||
}
|
||||
|
||||
guard let url = URL(string:urlString) else { return }
|
||||
|
||||
if source == "BNR" {
|
||||
URLSession.shared.dataTask(with: url) { (data, response, error) in
|
||||
if let error = error {
|
||||
print("Error fetching data: \(error.localizedDescription)")
|
||||
completion(nil, error)
|
||||
return
|
||||
}
|
||||
|
||||
guard let data = data else {
|
||||
print("No data received")
|
||||
completion(nil, nil)
|
||||
return
|
||||
}
|
||||
|
||||
// Parse XML data for USD to RON rate
|
||||
let parser = XMLParser(data: data)
|
||||
let delegate = BNRXMLParserDelegate()
|
||||
parser.delegate = delegate
|
||||
if parser.parse(), let usdToRonRate = delegate.usdRate {
|
||||
// Fetch BTC to USD rate using CoinGecko
|
||||
let coinGeckoUrl = URL(string: "https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd")!
|
||||
URLSession.shared.dataTask(with: coinGeckoUrl) { (data, _, error) in
|
||||
guard let data = data, error == nil else {
|
||||
completion(nil, error ?? CurrencyError())
|
||||
return
|
||||
}
|
||||
|
||||
do {
|
||||
if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
|
||||
let bitcoinDict = json["bitcoin"] as? [String: Double],
|
||||
let btcToUsdRate = bitcoinDict["usd"] {
|
||||
let btcToRonRate = btcToUsdRate * usdToRonRate
|
||||
let lastUpdatedString = ISO8601DateFormatter().string(from: Date())
|
||||
let latestRateDataStore = WidgetDataStore(rate: String(btcToRonRate), lastUpdate: lastUpdatedString, rateDouble: btcToRonRate)
|
||||
completion(latestRateDataStore, nil)
|
||||
} else {
|
||||
completion(nil, CurrencyError())
|
||||
}
|
||||
} catch {
|
||||
completion(nil, error)
|
||||
}
|
||||
}.resume()
|
||||
} else {
|
||||
print("Error parsing XML")
|
||||
completion(nil, CurrencyError())
|
||||
}
|
||||
}.resume()
|
||||
} else {
|
||||
URLSession.shared.dataTask(with: url) { (data, response, error) in
|
||||
guard let dataResponse = data,
|
||||
let json = (try? JSONSerialization.jsonObject(with: dataResponse, options: .mutableContainers) as? Dictionary<String, Any>),
|
||||
error == nil
|
||||
else {
|
||||
print(error?.localizedDescription ?? "Response Error")
|
||||
completion(nil, error)
|
||||
return
|
||||
}
|
||||
|
||||
var latestRateDataStore: WidgetDataStore?
|
||||
switch source {
|
||||
case "Yadio":
|
||||
guard let rateDict = json[endPointKey] as? [String: Any],
|
||||
let rateDouble = rateDict["price"] as? Double,
|
||||
let lastUpdated = json["timestamp"] as? Int
|
||||
else { break }
|
||||
let unix = Double(lastUpdated / 1_000)
|
||||
let lastUpdatedString = ISO8601DateFormatter().string(from: Date(timeIntervalSince1970: unix))
|
||||
latestRateDataStore = WidgetDataStore(rate: String(rateDouble), lastUpdate: lastUpdatedString, rateDouble: rateDouble)
|
||||
case "CoinGecko":
|
||||
guard let rateDict = json["bitcoin"] as? [String: Any],
|
||||
let rateDouble = rateDict[endPointKey.lowercased()] as? Double
|
||||
else { break }
|
||||
let lastUpdatedString = ISO8601DateFormatter().string(from: Date())
|
||||
latestRateDataStore = WidgetDataStore(rate: String(rateDouble), lastUpdate: lastUpdatedString, rateDouble: rateDouble)
|
||||
case "YadioConvert":
|
||||
guard let rateDict = json as? [String: Any],
|
||||
let rateDouble = rateDict["rate"] as? Double,
|
||||
let lastUpdated = json["timestamp"] as? Int
|
||||
else { break }
|
||||
let unix = Double(lastUpdated / 1_000)
|
||||
let lastUpdatedString = ISO8601DateFormatter().string(from: Date(timeIntervalSince1970: unix))
|
||||
latestRateDataStore = WidgetDataStore(rate: String(rateDouble), lastUpdate: lastUpdatedString, rateDouble: rateDouble)
|
||||
case "Exir":
|
||||
guard let rateDouble = json["last"] as? Double else { break }
|
||||
let rateString = String(rateDouble)
|
||||
let lastUpdatedString = ISO8601DateFormatter().string(from: Date())
|
||||
latestRateDataStore = WidgetDataStore(rate: rateString, lastUpdate: lastUpdatedString, rateDouble: rateDouble)
|
||||
case "Bitstamp":
|
||||
guard let rateString = json["last"] as? String, let rateDouble = Double(rateString) else { break }
|
||||
let lastUpdatedString = ISO8601DateFormatter().string(from: Date())
|
||||
latestRateDataStore = WidgetDataStore(rate: rateString, lastUpdate: lastUpdatedString, rateDouble: rateDouble)
|
||||
case "wazirx":
|
||||
guard let tickerDict = json["ticker"] as? [String: Any],
|
||||
let rateString = tickerDict["buy"] as? String,
|
||||
let rateDouble = Double(rateString)
|
||||
else { break }
|
||||
let lastUpdatedString = ISO8601DateFormatter().string(from: Date())
|
||||
latestRateDataStore = WidgetDataStore(rate: rateString, lastUpdate: lastUpdatedString, rateDouble: rateDouble)
|
||||
case "Coinbase":
|
||||
guard let data = json["data"] as? Dictionary<String, Any>,
|
||||
let rateString = data["amount"] as? String,
|
||||
let rateDouble = Double(rateString)
|
||||
else { break }
|
||||
let lastUpdatedString = ISO8601DateFormatter().string(from: Date())
|
||||
latestRateDataStore = WidgetDataStore(rate: rateString, lastUpdate: lastUpdatedString, rateDouble: rateDouble)
|
||||
default:
|
||||
guard let bpi = json["bpi"] as? Dictionary<String, Any>,
|
||||
let preferredCurrency = bpi[endPointKey] as? Dictionary<String, Any>,
|
||||
let rateString = preferredCurrency["rate"] as? String,
|
||||
let rateDouble = preferredCurrency["rate_float"] as? Double,
|
||||
let time = json["time"] as? Dictionary<String, Any>,
|
||||
let lastUpdatedString = time["updatedISO"] as? String
|
||||
else { break }
|
||||
latestRateDataStore = WidgetDataStore(rate: rateString, lastUpdate: lastUpdatedString, rateDouble: rateDouble)
|
||||
}
|
||||
|
||||
if (latestRateDataStore == nil) {
|
||||
completion(nil, CurrencyError())
|
||||
return
|
||||
}
|
||||
|
||||
completion(latestRateDataStore, nil)
|
||||
}.resume()
|
||||
}
|
||||
}
|
||||
|
||||
static func getUserPreferredCurrency() -> String {
|
||||
|
||||
guard let userDefaults = UserDefaults(suiteName: UserDefaultsGroupKey.GroupName.rawValue),
|
||||
let preferredCurrency = userDefaults.string(forKey: "preferredCurrency")
|
||||
else {
|
||||
return "USD"
|
||||
}
|
||||
|
||||
if preferredCurrency != WidgetAPI.getLastSelectedCurrency() {
|
||||
UserDefaults.standard.removeObject(forKey: WidgetData.WidgetCachedDataStoreKey)
|
||||
UserDefaults.standard.removeObject(forKey: WidgetData.WidgetDataStoreKey)
|
||||
UserDefaults.standard.synchronize()
|
||||
}
|
||||
|
||||
return preferredCurrency
|
||||
}
|
||||
|
||||
static func getUserPreferredCurrencyLocale() -> String {
|
||||
guard let userDefaults = UserDefaults(suiteName: UserDefaultsGroupKey.GroupName.rawValue),
|
||||
let preferredCurrency = userDefaults.string(forKey: "preferredCurrencyLocale")
|
||||
else {
|
||||
return "en_US"
|
||||
}
|
||||
return preferredCurrency
|
||||
}
|
||||
|
||||
static func getLastSelectedCurrency() -> String {
|
||||
guard let userDefaults = UserDefaults(suiteName: UserDefaultsGroupKey.GroupName.rawValue), let dataStore = userDefaults.string(forKey: "currency") else {
|
||||
return "USD"
|
||||
}
|
||||
|
||||
return dataStore
|
||||
}
|
||||
|
||||
static func saveNewSelectedCurrency() {
|
||||
UserDefaults.standard.setValue(WidgetAPI.getUserPreferredCurrency(), forKey: "currency")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
//
|
||||
// Created by Marcos Rodriguez on 11/3/19.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension Numeric {
|
||||
|
||||
var abbreviated: String {
|
||||
let bytecountFormatter = ByteCountFormatter()
|
||||
bytecountFormatter.zeroPadsFractionDigits = true
|
||||
bytecountFormatter.countStyle = .decimal
|
||||
bytecountFormatter.isAdaptive = false
|
||||
let bytesString = bytecountFormatter.string(fromByteCount: (self as! NSNumber).int64Value)
|
||||
|
||||
let numericString = bytesString
|
||||
.replacingOccurrences(of: "bytes", with: "")
|
||||
.replacingOccurrences(of: "B", with: "") // removes B (bytes) in 'KB'/'MB'/'GB'
|
||||
.replacingOccurrences(of: "G", with: "B") // replace G (Giga) to just B (billions)
|
||||
return numericString.replacingOccurrences(of: " ", with: "")
|
||||
}
|
||||
}
|
||||
|
||||
struct WidgetDataStore: Codable {
|
||||
let rate: String
|
||||
let lastUpdate: String
|
||||
let rateDouble: Double
|
||||
var formattedRate: String? {
|
||||
let numberFormatter = NumberFormatter()
|
||||
numberFormatter.locale = Locale(identifier: WidgetAPI.getUserPreferredCurrencyLocale())
|
||||
numberFormatter.numberStyle = .currency
|
||||
numberFormatter.maximumFractionDigits = 0
|
||||
numberFormatter.minimumFractionDigits = 0
|
||||
if let rateString = numberFormatter.string(from: NSNumber(value: rateDouble)) {
|
||||
return rateString
|
||||
}
|
||||
return rate
|
||||
}
|
||||
var formattedRateForSmallComplication: String? {
|
||||
return rateDouble.abbreviated
|
||||
}
|
||||
|
||||
var formattedRateForComplication: String? {
|
||||
let numberFormatter = NumberFormatter()
|
||||
numberFormatter.locale = Locale(identifier: WidgetAPI.getUserPreferredCurrencyLocale())
|
||||
numberFormatter.numberStyle = .currency
|
||||
numberFormatter.currencySymbol = ""
|
||||
if let rateString = numberFormatter.string(from: NSNumber(value: rateDouble)) {
|
||||
return rateString
|
||||
}
|
||||
return rate
|
||||
}
|
||||
|
||||
var date: Date? {
|
||||
let isoDateFormatter = ISO8601DateFormatter()
|
||||
let dateFormatter = DateFormatter()
|
||||
dateFormatter.locale = Locale.current
|
||||
dateFormatter.timeStyle = .short
|
||||
|
||||
return isoDateFormatter.date(from: lastUpdate)
|
||||
}
|
||||
var formattedDate: String? {
|
||||
let isoDateFormatter = ISO8601DateFormatter()
|
||||
let dateFormatter = DateFormatter()
|
||||
dateFormatter.locale = Locale.current
|
||||
dateFormatter.timeStyle = .short
|
||||
|
||||
if let date = isoDateFormatter.date(from: lastUpdate) {
|
||||
return dateFormatter.string(from: date)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
class WidgetData {
|
||||
|
||||
static let WidgetDataStoreKey = "WidgetDataStoreKey"
|
||||
static let WidgetCachedDataStoreKey = "WidgetCachedDataStoreKey"
|
||||
|
||||
static func savePriceRateAndLastUpdate(rate: String, lastUpdate: String) {
|
||||
guard let userDefaults = UserDefaults(suiteName: UserDefaultsGroupKey.GroupName.rawValue) else { return }
|
||||
userDefaults.setValue(["rate": rate, "lastUpdate": lastUpdate], forKey: WidgetDataStoreKey)
|
||||
userDefaults.synchronize()
|
||||
}
|
||||
|
||||
}
|
|
@ -35,10 +35,10 @@ struct WalletInformationAndMarketWidgetProvider: TimelineProvider {
|
|||
let timeline = Timeline(entries: entries, policy: .atEnd)
|
||||
completion(timeline)
|
||||
} else {
|
||||
let userPreferredCurrency = WidgetAPI.getUserPreferredCurrency()
|
||||
let userPreferredCurrency = Currency.getUserPreferredCurrency()
|
||||
let allwalletsBalance = WalletData(balance: UserDefaultsGroup.getAllWalletsBalance(), latestTransactionTime: UserDefaultsGroup.getAllWalletsLatestTransactionTime())
|
||||
|
||||
WidgetAPI.fetchMarketData(currency: userPreferredCurrency) { (result, error) in
|
||||
MarketAPI.fetchMarketData(currency: userPreferredCurrency) { (result, error) in
|
||||
let entry: WalletInformationAndMarketWidgetEntry
|
||||
|
||||
if let result = result {
|
||||
|
|
Loading…
Add table
Reference in a new issue