react-native-candle 0.1.42 → 0.1.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. package/ReactNativeCandle.podspec +1 -1
  2. package/ios/Sources/CandleActionViewModel.swift +4 -7
  3. package/ios/Sources/CandleLinkSheetWrapperView.swift +40 -59
  4. package/ios/Sources/CandleLinkViewModel.swift +21 -31
  5. package/ios/Sources/CandleTradeExecutionSheetWrapper.swift +14 -23
  6. package/ios/Sources/HostingViewController.swift +26 -26
  7. package/ios/Sources/RNCandle.swift +159 -1307
  8. package/ios/Sources/Types.swift +847 -0
  9. package/ios/Sources/UIApplication++.swift +5 -9
  10. package/lib/commonjs/context.js +17 -0
  11. package/lib/commonjs/context.js.map +1 -0
  12. package/lib/commonjs/index.js +17 -407
  13. package/lib/commonjs/index.js.map +1 -1
  14. package/lib/commonjs/package.json +1 -0
  15. package/lib/commonjs/provider.js +117 -0
  16. package/lib/commonjs/provider.js.map +1 -0
  17. package/lib/commonjs/types.js +271 -0
  18. package/lib/commonjs/types.js.map +1 -0
  19. package/lib/module/context.js +12 -0
  20. package/lib/module/context.js.map +1 -0
  21. package/lib/module/index.js +2 -408
  22. package/lib/module/index.js.map +1 -1
  23. package/lib/module/package.json +1 -0
  24. package/lib/module/provider.js +111 -0
  25. package/lib/module/provider.js.map +1 -0
  26. package/lib/module/types.js +256 -0
  27. package/lib/module/types.js.map +1 -0
  28. package/lib/typescript/commonjs/src/context.d.ts +47 -0
  29. package/lib/typescript/commonjs/src/context.d.ts.map +1 -0
  30. package/lib/typescript/commonjs/src/index.d.ts +4 -166
  31. package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
  32. package/lib/typescript/commonjs/src/provider.d.ts +8 -0
  33. package/lib/typescript/commonjs/src/provider.d.ts.map +1 -0
  34. package/lib/typescript/commonjs/src/specs/RNCandle.nitro.d.ts +22 -24
  35. package/lib/typescript/commonjs/src/specs/RNCandle.nitro.d.ts.map +1 -1
  36. package/lib/typescript/commonjs/src/types.d.ts +125 -0
  37. package/lib/typescript/commonjs/src/types.d.ts.map +1 -0
  38. package/lib/typescript/module/src/context.d.ts +47 -0
  39. package/lib/typescript/module/src/context.d.ts.map +1 -0
  40. package/lib/typescript/module/src/index.d.ts +4 -166
  41. package/lib/typescript/module/src/index.d.ts.map +1 -1
  42. package/lib/typescript/module/src/provider.d.ts +8 -0
  43. package/lib/typescript/module/src/provider.d.ts.map +1 -0
  44. package/lib/typescript/module/src/specs/RNCandle.nitro.d.ts +22 -24
  45. package/lib/typescript/module/src/specs/RNCandle.nitro.d.ts.map +1 -1
  46. package/lib/typescript/module/src/types.d.ts +125 -0
  47. package/lib/typescript/module/src/types.d.ts.map +1 -0
  48. package/nitrogen/generated/.gitattributes +1 -1
  49. package/nitrogen/generated/ios/ReactNativeCandle-Swift-Cxx-Bridge.cpp +15 -31
  50. package/nitrogen/generated/ios/ReactNativeCandle-Swift-Cxx-Bridge.hpp +379 -242
  51. package/nitrogen/generated/ios/ReactNativeCandle-Swift-Cxx-Umbrella.hpp +23 -22
  52. package/nitrogen/generated/ios/ReactNativeCandleAutolinking.mm +1 -1
  53. package/nitrogen/generated/ios/ReactNativeCandleAutolinking.swift +2 -4
  54. package/nitrogen/generated/ios/c++/HybridRNCandleSpecSwift.hpp +36 -42
  55. package/nitrogen/generated/ios/swift/ActiveLinkedAccountDetails.swift +6 -3
  56. package/nitrogen/generated/ios/swift/AssetAccount.swift +6 -3
  57. package/nitrogen/generated/ios/swift/AssetAccountKind.swift +4 -4
  58. package/nitrogen/generated/ios/swift/AssetAccountRef.swift +5 -5
  59. package/nitrogen/generated/ios/swift/{AssetAccountQuery.swift → AssetAccountsQuery.swift} +7 -6
  60. package/nitrogen/generated/ios/swift/Counterparty.swift +8 -3
  61. package/nitrogen/generated/ios/swift/CounterpartyKind.swift +42 -0
  62. package/nitrogen/generated/ios/swift/FiatAccount.swift +4 -2
  63. package/nitrogen/generated/ios/swift/FiatAsset.swift +2 -1
  64. package/nitrogen/generated/ios/swift/FiatAssetQuoteRequest.swift +4 -2
  65. package/nitrogen/generated/ios/swift/FiatAssetRef.swift +2 -1
  66. package/nitrogen/generated/ios/swift/Func_void_LinkedAccount.swift +5 -5
  67. package/nitrogen/generated/ios/swift/HybridRNCandleSpec.swift +7 -7
  68. package/nitrogen/generated/ios/swift/HybridRNCandleSpec_cxx.swift +40 -65
  69. package/nitrogen/generated/ios/swift/LinkedAccountDetails.swift +15 -3
  70. package/nitrogen/generated/ios/swift/{StatePayload.swift → LinkedAccountState.swift} +6 -6
  71. package/nitrogen/generated/ios/swift/LinkedAccountStatusRef.swift +4 -3
  72. package/nitrogen/generated/ios/swift/MarketAccount.swift +5 -5
  73. package/nitrogen/generated/ios/swift/MarketAssetKind.swift +38 -0
  74. package/nitrogen/generated/ios/swift/MarketAssetQuoteRequest.swift +11 -8
  75. package/nitrogen/generated/ios/swift/MarketTradeAsset.swift +7 -7
  76. package/nitrogen/generated/ios/swift/MarketTradeAssetRef.swift +5 -5
  77. package/nitrogen/generated/ios/swift/MerchantCounterparty.swift +2 -1
  78. package/nitrogen/generated/ios/swift/TradeAsset.swift +10 -5
  79. package/nitrogen/generated/ios/swift/TradeAssetKind.swift +54 -0
  80. package/nitrogen/generated/ios/swift/TradeAssetQuoteRequest.swift +15 -4
  81. package/nitrogen/generated/ios/swift/TradeAssetRef.swift +11 -5
  82. package/nitrogen/generated/ios/swift/TradeExecutionResult.swift +4 -2
  83. package/nitrogen/generated/ios/swift/{TradeQuoteRequest.swift → TradeQuotesRequest.swift} +7 -6
  84. package/nitrogen/generated/ios/swift/{TradeQuery.swift → TradesQuery.swift} +29 -45
  85. package/nitrogen/generated/ios/swift/TransportAssetQuoteRequest.swift +12 -6
  86. package/nitrogen/generated/shared/c++/ACHAccountKind.hpp +7 -9
  87. package/nitrogen/generated/shared/c++/ACHDetails.hpp +7 -9
  88. package/nitrogen/generated/shared/c++/ActiveLinkedAccountDetails.hpp +4 -6
  89. package/nitrogen/generated/shared/c++/Address.hpp +4 -6
  90. package/nitrogen/generated/shared/c++/AssetAccount.hpp +14 -16
  91. package/nitrogen/generated/shared/c++/AssetAccountKind.hpp +15 -17
  92. package/nitrogen/generated/shared/c++/AssetAccountRef.hpp +12 -12
  93. package/nitrogen/generated/shared/c++/{AssetAccountQuery.hpp → AssetAccountsQuery.hpp} +14 -16
  94. package/nitrogen/generated/shared/c++/AssetAccountsResponse.hpp +11 -13
  95. package/nitrogen/generated/shared/c++/Coordinates.hpp +4 -6
  96. package/nitrogen/generated/shared/c++/Counterparty.hpp +14 -16
  97. package/nitrogen/generated/shared/c++/CounterpartyKind.hpp +80 -0
  98. package/nitrogen/generated/shared/c++/FiatAccount.hpp +16 -18
  99. package/nitrogen/generated/shared/c++/FiatAsset.hpp +7 -9
  100. package/nitrogen/generated/shared/c++/FiatAssetQuoteRequest.hpp +4 -6
  101. package/nitrogen/generated/shared/c++/FiatAssetRef.hpp +4 -6
  102. package/nitrogen/generated/shared/c++/FiatMarketAccountKind.hpp +13 -15
  103. package/nitrogen/generated/shared/c++/HybridRNCandleSpec.cpp +1 -2
  104. package/nitrogen/generated/shared/c++/HybridRNCandleSpec.hpp +17 -27
  105. package/nitrogen/generated/shared/c++/InactiveLinkedAccountDetails.hpp +4 -6
  106. package/nitrogen/generated/shared/c++/LinkedAccount.hpp +10 -12
  107. package/nitrogen/generated/shared/c++/LinkedAccountDetails.hpp +14 -16
  108. package/nitrogen/generated/shared/c++/LinkedAccountRef.hpp +4 -6
  109. package/nitrogen/generated/shared/c++/{StatePayload.hpp → LinkedAccountState.hpp} +15 -17
  110. package/nitrogen/generated/shared/c++/LinkedAccountStatusRef.hpp +15 -17
  111. package/nitrogen/generated/shared/c++/MarketAccount.hpp +18 -17
  112. package/nitrogen/generated/shared/c++/MarketAssetKind.hpp +76 -0
  113. package/nitrogen/generated/shared/c++/MarketAssetQuoteRequest.hpp +12 -12
  114. package/nitrogen/generated/shared/c++/MarketTradeAsset.hpp +15 -14
  115. package/nitrogen/generated/shared/c++/MarketTradeAssetRef.hpp +12 -12
  116. package/nitrogen/generated/shared/c++/MerchantCounterparty.hpp +8 -10
  117. package/nitrogen/generated/shared/c++/MerchantLocation.hpp +4 -6
  118. package/nitrogen/generated/shared/c++/NothingAsset.hpp +4 -6
  119. package/nitrogen/generated/shared/c++/NothingAssetQuoteRequest.hpp +4 -6
  120. package/nitrogen/generated/shared/c++/NothingAssetRef.hpp +4 -6
  121. package/nitrogen/generated/shared/c++/OtherAsset.hpp +4 -6
  122. package/nitrogen/generated/shared/c++/OtherAssetRef.hpp +4 -6
  123. package/nitrogen/generated/shared/c++/PresentationBackground.hpp +7 -9
  124. package/nitrogen/generated/shared/c++/PresentationStyle.hpp +7 -9
  125. package/nitrogen/generated/shared/c++/Service.hpp +163 -165
  126. package/nitrogen/generated/shared/c++/ServiceCounterparty.hpp +7 -9
  127. package/nitrogen/generated/shared/c++/Trade.hpp +16 -18
  128. package/nitrogen/generated/shared/c++/TradeAsset.hpp +20 -22
  129. package/nitrogen/generated/shared/c++/TradeAssetKind.hpp +92 -0
  130. package/nitrogen/generated/shared/c++/TradeAssetQuoteRequest.hpp +17 -19
  131. package/nitrogen/generated/shared/c++/TradeAssetRef.hpp +20 -22
  132. package/nitrogen/generated/shared/c++/TradeExecutionResult.hpp +8 -10
  133. package/nitrogen/generated/shared/c++/TradeQuote.hpp +10 -12
  134. package/nitrogen/generated/shared/c++/{TradeQuoteRequest.hpp → TradeQuotesRequest.hpp} +17 -19
  135. package/nitrogen/generated/shared/c++/TradeQuotesResponse.hpp +11 -13
  136. package/nitrogen/generated/shared/c++/TradeRef.hpp +10 -12
  137. package/nitrogen/generated/shared/c++/TradeState.hpp +9 -11
  138. package/nitrogen/generated/shared/c++/TradesQuery.hpp +89 -0
  139. package/nitrogen/generated/shared/c++/TradesResponse.hpp +11 -13
  140. package/nitrogen/generated/shared/c++/TransportAccount.hpp +10 -12
  141. package/nitrogen/generated/shared/c++/TransportAccountKind.hpp +9 -11
  142. package/nitrogen/generated/shared/c++/TransportAsset.hpp +19 -21
  143. package/nitrogen/generated/shared/c++/TransportAssetQuoteRequest.hpp +16 -18
  144. package/nitrogen/generated/shared/c++/TransportAssetRef.hpp +4 -6
  145. package/nitrogen/generated/shared/c++/UnavailableLinkedAccountDetails.hpp +4 -6
  146. package/nitrogen/generated/shared/c++/UserCounterparty.hpp +4 -6
  147. package/nitrogen/generated/shared/c++/WireDetails.hpp +4 -6
  148. package/package.json +9 -11
  149. package/src/context.ts +86 -0
  150. package/src/index.ts +4 -634
  151. package/src/provider.tsx +152 -0
  152. package/src/specs/RNCandle.nitro.ts +38 -29
  153. package/src/types.ts +462 -0
  154. package/nitrogen/generated/ios/swift/AppUser.swift +0 -75
  155. package/nitrogen/generated/ios/swift/Func_void_std__string.swift +0 -44
  156. package/nitrogen/generated/ios/swift/Func_void_std__vector_std__shared_ptr_AnyMap__.swift +0 -47
  157. package/nitrogen/generated/ios/swift/ToolCall.swift +0 -44
  158. package/nitrogen/generated/shared/c++/AppUser.hpp +0 -78
  159. package/nitrogen/generated/shared/c++/ToolCall.hpp +0 -73
  160. package/nitrogen/generated/shared/c++/TradeQuery.hpp +0 -86
@@ -5,1355 +5,207 @@ import NitroModules
5
5
  import SwiftUI
6
6
  import UIKit
7
7
 
8
- public enum RNClientError: Error {
9
- case badEncoding
10
- case badInitialization(message: String)
11
- }
12
-
13
- @available(iOS 17.0, *)
14
- final class HybridRNCandle: HybridRNCandleSpec {
8
+ @available(iOS 17.0, *) final class HybridRNCandle: HybridRNCandleSpec {
9
+ private var rootVC: UIHostingController<CandleLinkSheetWrapper>?
15
10
 
16
- private var rootVC: UIHostingController<CandleLinkSheetWrapper>?
11
+ private var cancellables = Set<AnyCancellable>()
17
12
 
18
- private var cancellables = Set<AnyCancellable>()
19
-
20
- var viewModel: CandleLinkViewModel {
21
- get throws {
22
- if let viewModel = rootVC?.rootView.viewModel {
23
- return viewModel
24
- }
25
- throw RNClientError.badInitialization(
26
- message: "Failed to properly initialize the client."
27
- )
28
- }
29
- }
30
-
31
- // MARK: - UI
32
-
33
- public func initialize(appUser: AppUser, accessGroup: String?) throws {
34
- Task { @MainActor in
35
- let wrapperView = CandleLinkSheetWrapper(
36
- appUser: .init(
37
- appKey: appUser.appKey,
38
- appSecret: appUser.appSecret,
39
- appUserID: appUser.appUserID
40
- ),
41
- accessGroup: accessGroup
42
- )
43
- let hostingVC = UIHostingController(rootView: wrapperView)
44
- self.rootVC = hostingVC
13
+ var viewModel: CandleLinkViewModel {
14
+ get throws {
15
+ if let viewModel = rootVC?.rootView.viewModel { return viewModel }
16
+ throw CandleError.unexpected(message: "Failed to properly initialize the client.")
17
+ }
45
18
  }
46
- }
47
19
 
48
- public func candleLinkSheet(
49
- isPresented: Bool,
50
- services: [Service]?,
51
- cornerRadius: Double,
52
- customerName: String?,
53
- showDynamicLoading: Bool,
54
- presentationBackground: PresentationBackground,
55
- presentationStyle: PresentationStyle,
56
- onSuccess: @escaping (LinkedAccount) -> Void
57
- ) throws {
58
- Task { @MainActor in
59
- try viewModel.isPresented = isPresented
60
- try viewModel.services = services
61
- try viewModel.cornerRadius = cornerRadius
62
- try viewModel.customerName = customerName
63
- try viewModel.showDynamicLoading = showDynamicLoading
64
- try viewModel.presentationBackground = presentationBackground
65
- try viewModel.presentationStyle = presentationStyle
66
- guard
67
- let rootViewController = UIApplication.keyWindow?
68
- .rootViewController
69
- else {
70
- throw RNClientError.badInitialization(
71
- message: "Application root view was not initialized."
72
- )
73
- }
20
+ // MARK: - UI
74
21
 
75
- let parentVC = rootViewController.candleTopMost
76
- DispatchQueue.main.async { [weak self] in
77
- guard let self else {
78
- #if DEBUG
79
- print("Self was deinitialized \(#function).")
80
- #endif
81
- return
22
+ public func initialize(appKey: String, appSecret: String, accessGroup: String?) throws {
23
+ try Client.initialize(appKey: appKey, appSecret: appSecret, accessGroup: accessGroup)
24
+ Task { @MainActor in
25
+ let wrapperView = CandleLinkSheetWrapper()
26
+ let hostingVC = UIHostingController(rootView: wrapperView)
27
+ self.rootVC = hostingVC
82
28
  }
83
-
84
- do {
85
- if let rootVC = self.rootVC {
86
- parentVC.embed(rootVC)
87
- }
88
- try self.viewModel.showSheet = isPresented
89
- } catch {
90
- #if DEBUG
91
- print("Failed to present sheet \(#function).")
92
- #endif
93
- }
94
- }
95
- try viewModel.$isPresented
96
- .removeDuplicates()
97
- .receive(on: RunLoop.main)
98
- .sink(receiveValue: { [weak self] isPresented in
99
- if let rootVC = self?.rootVC, !isPresented {
100
- parentVC.removeEmbedded(rootVC)
101
- }
102
- })
103
- .store(in: &cancellables)
104
- try viewModel.$linkedAccount
105
- .removeDuplicates()
106
- .compactMap(\.?.toLinkedAccount)
107
- .receive(on: RunLoop.main)
108
- .sink(receiveValue: onSuccess)
109
- .store(in: &cancellables)
110
29
  }
111
- }
112
-
113
- public func candleTradeExecutionSheet(
114
- tradeQuote: TradeQuote,
115
- presentationBackground: PresentationBackground,
116
- completion: @escaping (TradeExecutionResult) -> Void
117
- ) throws {
118
- Task { @MainActor in
119
- let wrapperView = CandleTradeExecutionSheetWrapper(
120
- candleClient: try viewModel.candleClient,
121
- viewModel: .init(tradeQuote: nil),
122
- presentationBackground: presentationBackground
123
- )
124
30
 
125
- let hostingVC = UIHostingController(rootView: wrapperView)
126
- hostingVC.view.backgroundColor = .clear
127
- guard
128
- let rootHostingVC = UIApplication.keyWindow?
129
- .rootViewController
130
- else {
131
- throw RNClientError.badInitialization(
132
- message:
133
- "\(#function) \(#line): Candle client was not initialized."
134
- )
135
- }
136
- let parentVC = rootHostingVC.candleTopMost
137
- parentVC.embedOnTop(hostingVC)
138
- let tradeQuote = try tradeQuote.toCandleModel
139
- DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
140
- wrapperView.viewModel.tradeQuote = tradeQuote
141
- }
142
- wrapperView.viewModel.$tradeQuote
143
- .dropFirst()
144
- .receive(on: RunLoop.main)
145
- .sink { [weak hostingVC] trade in
146
- if trade == nil {
147
- DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
148
- hostingVC?.willMove(toParent: nil)
149
- hostingVC?.view.removeFromSuperview()
150
- hostingVC?.removeFromParent()
31
+ public func candleLinkSheet(
32
+ isPresented: Bool,
33
+ services: [Service]?,
34
+ cornerRadius: Double,
35
+ customerName: String?,
36
+ showDynamicLoading: Bool,
37
+ presentationBackground: PresentationBackground,
38
+ presentationStyle: PresentationStyle,
39
+ onSuccess: @escaping (LinkedAccount) -> Void
40
+ ) throws {
41
+ Task { @MainActor in
42
+ try viewModel.isPresented = isPresented
43
+ try viewModel.services = services
44
+ try viewModel.cornerRadius = cornerRadius
45
+ try viewModel.customerName = customerName
46
+ try viewModel.showDynamicLoading = showDynamicLoading
47
+ try viewModel.presentationBackground = presentationBackground
48
+ try viewModel.presentationStyle = presentationStyle
49
+ guard let rootViewController = UIApplication.keyWindow?.rootViewController else {
50
+ throw CandleError.unexpected(message: "Application root view was not initialized.")
151
51
  }
152
- }
153
- }
154
- .store(in: &cancellables)
155
52
 
156
- wrapperView.viewModel.$tradeResult
157
- .receive(on: RunLoop.main)
158
- .sink { result in
159
- switch result {
160
- case .success(let trade):
161
- completion(
162
- .init(
163
- trade: trade.toRNModel,
164
- error: nil
165
- )
166
- )
167
- case .failure(let error):
168
- completion(
169
- .init(
170
- trade: nil,
171
- error: "We encountered an error: \(error)"
172
- )
173
- )
174
- case .none:
175
- break
176
- }
53
+ let parentVC = rootViewController.candleTopMost
54
+ DispatchQueue.main.async { [weak self] in
55
+ guard let self else {
56
+ #if DEBUG
57
+ print("Self was deinitialized \(#function).")
58
+ #endif
59
+ return
60
+ }
61
+
62
+ do {
63
+ if let rootVC = self.rootVC { parentVC.embed(rootVC) }
64
+ try self.viewModel.showSheet = isPresented
65
+ } catch {
66
+ #if DEBUG
67
+ print("Failed to present sheet \(#function).")
68
+ #endif
69
+ }
70
+ }
71
+ try viewModel.$isPresented.removeDuplicates().receive(on: RunLoop.main)
72
+ .sink(receiveValue: { [weak self] isPresented in
73
+ if let rootVC = self?.rootVC, !isPresented { parentVC.removeEmbedded(rootVC) }
74
+ })
75
+ .store(in: &cancellables)
76
+ try viewModel.$linkedAccount.removeDuplicates().compactMap(\.?.reactModel)
77
+ .receive(on: RunLoop.main).sink(receiveValue: onSuccess).store(in: &cancellables)
177
78
  }
178
- .store(in: &cancellables)
179
- }
180
- }
181
-
182
- // MARK: - Public
183
-
184
- public func unlinkAccount(ref: LinkedAccountRef) throws -> Promise<Void> {
185
- .async {
186
- try await self.viewModel.candleClient.unlinkAccount(
187
- path: .init(linkedAccountID: ref.linkedAccountID)
188
- )
189
- }
190
- }
191
-
192
- public func getLinkedAccounts() throws -> Promise<[LinkedAccount]> {
193
- .async {
194
- let accounts = try await self.viewModel.candleClient
195
- .getLinkedAccounts()
196
- return accounts.map(\.toLinkedAccount)
197
- }
198
- }
199
-
200
- public func getLinkedAccount(ref: LinkedAccountRef) throws -> Promise<
201
- LinkedAccount
202
- > {
203
- .async {
204
- let account = try await self.viewModel.candleClient
205
- .getLinkedAccount(
206
- ref: .init(linkedAccountID: ref.linkedAccountID)
207
- )
208
- return account.toLinkedAccount
209
- }
210
- }
211
-
212
- public func getAssetAccounts(query: AssetAccountQuery) throws -> Promise<
213
- AssetAccountsResponse
214
- > {
215
- .async {
216
- let accounts = try await self.viewModel.candleClient
217
- .getAssetAccounts(
218
- query: .init(
219
- linkedAccountIDs: query.linkedAccountIDs,
220
- assetKind: query.assetKind?.asCandleModel
221
- )
222
- )
223
- return AssetAccountsResponse(
224
- linkedAccounts: accounts.linkedAccounts.map(\.toRNModel),
225
- assetAccounts: accounts.assetAccounts.map(\.toRNModel)
226
- )
227
- }
228
- }
229
-
230
- public func getAssetAccount(ref: AssetAccountRef) throws -> Promise<
231
- AssetAccount
232
- > {
233
- .async {
234
- let account = try await self.viewModel.candleClient.getAssetAccount(
235
- ref: .init(
236
- linkedAccountID: ref.linkedAccountID,
237
- assetKind: .init(rawValue: ref.assetKind)!,
238
- serviceAccountID: ref.serviceAccountID
239
- )
240
- )
241
- return account.toRNModel
242
- }
243
- }
244
-
245
- public func getTrade(ref: TradeRef) throws -> Promise<Trade> {
246
- .async {
247
- let trade = try await self.viewModel.candleClient.getTrade(
248
- ref: .init(
249
- lost: try ref.lost.toRNModelAssetRef,
250
- gained: try ref.gained.toRNModelAssetRef
251
- )
252
- )
253
- return trade.toRNModel
254
- }
255
- }
256
-
257
- public func getTrades(query: TradeQuery) throws -> Promise<TradesResponse> {
258
- .async {
259
- let trades = try await self.viewModel.candleClient.getTrades(
260
- query: .init(
261
- linkedAccountIDs: query.linkedAccountIDs,
262
- dateTimeSpan: query.dateTimeSpan,
263
- gainedAssetKind: query.toGainedAssetKind,
264
- lostAssetKind: query.toLostAssetKind,
265
- counterpartyKind: query.toCounterpartyKindPayload
266
- )
267
- )
268
- return TradesResponse(
269
- linkedAccounts:
270
- trades.linkedAccounts.map(\.toRNModel),
271
- trades: trades.trades.map(\.toRNModel)
272
- )
273
79
  }
274
- }
275
80
 
276
- public func getTradeQuotes(request: TradeQuoteRequest) throws -> Promise<
277
- TradeQuotesResponse
278
- > {
279
- .async {
280
- let accounts = try await self.viewModel.candleClient.getTradeQuotes(
281
- request:
282
- .init(
283
- linkedAccountIDs: request.linkedAccountIDs,
284
- gained: try request.gained.toRNModel,
285
- lost: try request.lost.toRNModel
286
- )
287
- )
288
- return TradeQuotesResponse.init(
289
- linkedAccounts: accounts.linkedAccounts.map(\.toRNModel),
290
- tradeQuotes:
291
- accounts.tradeQuotes.map { account in
292
- TradeQuote(
293
- lost: account.lost.toRNModel,
294
- gained: account.gained.toRNModel,
295
- context: account.context,
296
- expirationDateTime: account.expirationDateTime
81
+ public func candleTradeExecutionSheet(
82
+ tradeQuote: TradeQuote,
83
+ presentationBackground: PresentationBackground,
84
+ completion: @escaping (TradeExecutionResult) -> Void
85
+ ) throws {
86
+ Task { @MainActor in
87
+ let wrapperView = CandleTradeExecutionSheetWrapper(
88
+ viewModel: .init(tradeQuote: nil),
89
+ presentationBackground: presentationBackground
297
90
  )
298
- }
299
- )
300
- }
301
- }
302
-
303
- public func deleteUser() throws -> Promise<Void> {
304
- .async {
305
- try await self.viewModel.candleClient.deleteUser()
306
- }
307
- }
308
-
309
- public func getAvailableTools() throws -> Promise<[AnyMapHolder]> {
310
- .async { [weak self] in
311
- guard let self else {
312
- throw RNClientError.badInitialization(
313
- message: "Self was deinitialized \(#function)."
314
- )
315
- }
316
- let result = try await self.viewModel.candleClient
317
- .getAvailableTools()
318
- return result.map(self.toHolder)
319
- }
320
- }
321
-
322
- public func executeTool(tool: ToolCall) throws -> Promise<String> {
323
- .async {
324
- let result = try await self.viewModel.candleClient.executeTool(
325
- tool: RNToolCall(name: tool.name, arguments: tool.arguments)
326
- )
327
- return try result.encodedToJSONString
328
- }
329
- }
330
-
331
- // MARK: - Private
332
-
333
- private func toHolder(_ dict: [String: Any]) -> AnyMapHolder {
334
- let holder = AnyMapHolder()
335
- for (key, rawValue) in dict {
336
- let anyValue = self.toValue(rawValue)
337
- switch anyValue {
338
- case .string(let s):
339
- holder.setString(key: key, value: s)
340
- case .number(let d):
341
- holder.setDouble(key: key, value: d)
342
- case .bigint(let i):
343
- holder.setBigInt(key: key, value: i)
344
- case .bool(let b):
345
- holder.setBoolean(key: key, value: b)
346
- case .array(let arr):
347
- holder.setArray(key: key, value: arr)
348
- case .object(let obj):
349
- holder.setObject(key: key, value: obj)
350
- case .null:
351
- holder.setNull(key: key)
352
- }
353
- }
354
- return holder
355
- }
356
91
 
357
- private func toValue(_ value: Any) -> AnyValue {
358
- switch value {
359
- case let int as Int:
360
- return .bigint(Int64(int))
361
- case let int as Int64:
362
- return .bigint(int)
363
- case let double as Double:
364
- return .number(double)
365
- case let bool as Bool:
366
- return .bool(bool)
367
- case let str as String:
368
- return .string(str)
369
- case let array as [Any]:
370
- return .array(array.map(toValue(_:)))
371
- case let object as [String: Any]:
372
- let mapped = object.mapValues { toValue($0) }
373
- return .object(mapped)
374
- default:
375
- return .null
376
- }
377
- }
378
-
379
- struct RNToolCall: ToolCallRequest, Codable {
380
- let name: String
381
- let arguments: String
382
- }
383
-
384
- }
385
-
386
- extension Encodable {
387
- var encodedToJSONString: String {
388
- get throws {
389
- let data = try JSONEncoder().encode(self)
390
- if let string = String(data: data, encoding: .utf8) {
391
- return string
392
- }
393
- throw RNClientError.badEncoding
92
+ let hostingVC = UIHostingController(rootView: wrapperView)
93
+ hostingVC.view.backgroundColor = .clear
94
+ guard let rootHostingVC = UIApplication.keyWindow?.rootViewController else {
95
+ throw CandleError.unexpected(
96
+ message: "\(#function) \(#line): Candle client was not initialized."
97
+ )
98
+ }
99
+ let parentVC = rootHostingVC.candleTopMost
100
+ parentVC.embedOnTop(hostingVC)
101
+ let tradeQuote = try Models.TradeQuote(reactModel: tradeQuote)
102
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
103
+ wrapperView.viewModel.tradeQuote = tradeQuote
104
+ }
105
+ wrapperView.viewModel.$tradeQuote.dropFirst().receive(on: RunLoop.main)
106
+ .sink { [weak hostingVC] trade in
107
+ if trade == nil {
108
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
109
+ hostingVC?.willMove(toParent: nil)
110
+ hostingVC?.view.removeFromSuperview()
111
+ hostingVC?.removeFromParent()
112
+ }
113
+ }
114
+ }
115
+ .store(in: &cancellables)
116
+
117
+ wrapperView.viewModel.$tradeResult.receive(on: RunLoop.main)
118
+ .sink { result in
119
+ switch result {
120
+ case .success(let trade): completion(.init(trade: trade.reactModel, error: nil))
121
+ case .failure(let error):
122
+ completion(.init(trade: nil, error: "We encountered an error: \(error)"))
123
+ case .none: break
124
+ }
125
+ }
126
+ .store(in: &cancellables)
127
+ }
394
128
  }
395
- }
396
- }
397
129
 
398
- extension Candle.Models.LinkedAccount {
399
- var toLinkedAccount: LinkedAccount {
400
- let service: Service = self.service.toRNModel
401
- switch details {
402
- case .ActiveLinkedAccountDetails(let details):
403
- return LinkedAccount(
404
- linkedAccountID: linkedAccountID,
405
- service: service,
406
- serviceUserID: serviceUserID,
407
- details: .init(
408
- activeLinkedAccountDetails: .init(
409
- state: details.state.rawValue,
410
- accountOpened: details.accountOpened,
411
- username: details.username,
412
- emailAddress: details.emailAddress,
413
- legalName: details.legalName
414
- ),
415
- inactiveLinkedAccountDetails: nil,
416
- unavailableLinkedAccountDetails: nil
417
- )
418
- )
419
- case .InactiveLinkedAccountDetails(let details):
420
- switch details.state {
421
- case .inactive:
422
- return LinkedAccount(
423
- linkedAccountID: linkedAccountID,
424
- service: service,
425
- serviceUserID: serviceUserID,
426
- details: .init(
427
- activeLinkedAccountDetails: nil,
428
- inactiveLinkedAccountDetails: .init(
429
- state: details.state.rawValue
430
- ),
431
- unavailableLinkedAccountDetails: nil
432
- )
433
- )
434
- case .unavailable:
435
- return LinkedAccount(
436
- linkedAccountID: linkedAccountID,
437
- service: service,
438
- serviceUserID: serviceUserID,
439
- details: .init(
440
- activeLinkedAccountDetails: nil,
441
- inactiveLinkedAccountDetails: nil,
442
- unavailableLinkedAccountDetails: .init(
443
- state: details.state.rawValue
444
- )
445
- )
446
- )
447
- }
448
- }
449
- }
450
- }
130
+ // MARK: - Public
451
131
 
452
- extension Models.MerchantCounterparty {
453
- var toLocation: MerchantLocation? {
454
- if let location {
455
- return .init(
456
- countryCode: location.countryCode,
457
- countrySubdivisionCode: location.countrySubdivisionCode,
458
- localityName: location.localityName
459
- )
132
+ public func unlinkAccount(ref: LinkedAccountRef) throws -> Promise<Void> {
133
+ .async { try await Client.shared.unlinkAccount(ref: .init(reactModel: ref)) }
460
134
  }
461
- return nil
462
- }
463
- }
464
135
 
465
- extension Models.Trade {
466
- var toCounterparty: Counterparty {
467
- switch counterparty {
468
- case .MerchantCounterparty(let merchant):
469
- return .init(
470
- merchantCounterparty: .init(
471
- kind: merchant.kind.rawValue,
472
- name: merchant.name,
473
- logoURL: merchant.logoURL,
474
- location: merchant.toLocation
475
- ),
476
- userCounterparty: nil,
477
- serviceCounterparty: nil
478
- )
479
- case .ServiceCounterparty(let service):
480
- return .init(
481
- merchantCounterparty: nil,
482
- userCounterparty: nil,
483
- serviceCounterparty: .init(
484
- kind: service.kind.rawValue,
485
- service: service.service.toRNModel
486
- )
487
- )
488
- case .UserCounterparty(let user):
489
- return .init(
490
- merchantCounterparty: nil,
491
- userCounterparty: .init(
492
- kind: user.kind.rawValue,
493
- legalName: user.legalName,
494
- avatarURL: user.avatarURL,
495
- username: user.username
496
- ),
497
- serviceCounterparty: nil
498
- )
136
+ public func getLinkedAccounts() throws -> Promise<[LinkedAccount]> {
137
+ .async {
138
+ let accounts = try await Client.shared.getLinkedAccounts()
139
+ return accounts.map(\.reactModel)
140
+ }
499
141
  }
500
- }
501
- }
502
142
 
503
- extension Models.TradeAsset {
504
- var toRNModel: TradeAsset {
505
- switch self {
506
- case .FiatAsset(let fiatAsset):
507
- return .init(
508
- fiatAsset: .init(
509
- assetKind: fiatAsset.assetKind.rawValue,
510
- serviceTradeID: fiatAsset.serviceTradeID,
511
- serviceAccountID: fiatAsset.serviceAccountID,
512
- currencyCode: fiatAsset.currencyCode,
513
- amount: fiatAsset.amount,
514
- linkedAccountID: fiatAsset.linkedAccountID,
515
- service: fiatAsset.service.toRNModel
516
- ),
517
- marketTradeAsset: nil,
518
- transportAsset: nil,
519
- otherAsset: nil,
520
- nothingAsset: nil
521
- )
522
- case .MarketTradeAsset(let marketAsset):
523
- return .init(
524
- fiatAsset: nil,
525
- marketTradeAsset: .init(
526
- assetKind: marketAsset.assetKind.rawValue,
527
- serviceAccountID: marketAsset.serviceAccountID,
528
- serviceAssetID: marketAsset.serviceAssetID,
529
- symbol: marketAsset.symbol,
530
- amount: marketAsset.amount,
531
- serviceTradeID: marketAsset.serviceTradeID,
532
- linkedAccountID: marketAsset.linkedAccountID,
533
- name: marketAsset.name,
534
- color: marketAsset.color,
535
- logoURL: marketAsset.logoURL,
536
- service: marketAsset.service.toRNModel
537
- ),
538
- transportAsset: nil,
539
- otherAsset: nil,
540
- nothingAsset: nil
541
- )
542
- case .TransportAsset(let transportAsset):
543
- return .init(
544
- fiatAsset: nil,
545
- marketTradeAsset: nil,
546
- transportAsset: .init(
547
- assetKind: transportAsset.assetKind.rawValue,
548
- serviceTradeID: transportAsset.serviceTradeID,
549
- serviceAssetID: transportAsset.serviceAssetID,
550
- serviceAccountID: transportAsset.serviceAccountID,
551
- name: transportAsset.name,
552
- description: transportAsset.description,
553
- imageURL: transportAsset.imageURL,
554
- originCoordinates: .init(
555
- latitude: transportAsset.originCoordinates.latitude,
556
- longitude: transportAsset.originCoordinates.longitude
557
- ),
558
- originAddress: .init(
559
- value: transportAsset.originAddress.value
560
- ),
561
- destinationCoordinates: .init(
562
- latitude: transportAsset.destinationCoordinates
563
- .latitude,
564
- longitude: transportAsset.destinationCoordinates
565
- .longitude
566
- ),
567
- destinationAddress: .init(
568
- value: transportAsset.destinationAddress.value
569
- ),
570
- seats: transportAsset.seats,
571
- departureDateTime: transportAsset.departureDateTime,
572
- arrivalDateTime: transportAsset.arrivalDateTime,
573
- linkedAccountID: transportAsset.linkedAccountID,
574
- service: transportAsset.service.toRNModel
575
- ),
576
- otherAsset: nil,
577
- nothingAsset: nil
578
- )
579
- case .OtherAsset(let otherAsset):
580
- return .init(
581
- fiatAsset: nil,
582
- marketTradeAsset: nil,
583
- transportAsset: nil,
584
- otherAsset: .init(assetKind: otherAsset.assetKind.rawValue),
585
- nothingAsset: nil
586
- )
587
- case .NothingAsset(let nothingAsset):
588
- return .init(
589
- fiatAsset: nil,
590
- marketTradeAsset: nil,
591
- transportAsset: nil,
592
- otherAsset: nil,
593
- nothingAsset: .init(assetKind: nothingAsset.assetKind.rawValue)
594
- )
143
+ public func getLinkedAccount(ref: LinkedAccountRef) throws -> Promise<LinkedAccount> {
144
+ .async {
145
+ let account = try await Client.shared.getLinkedAccount(ref: .init(reactModel: ref))
146
+ return account.reactModel
147
+ }
595
148
  }
596
- }
597
- }
598
149
 
599
- extension Models.Trade {
600
- var toRNModel: Trade {
601
- .init(
602
- dateTime: dateTime,
603
- state: state.toRNModel,
604
- counterparty: toCounterparty,
605
- lost: lost.toRNModel,
606
- gained: gained.toRNModel
607
- )
608
- }
609
- }
610
-
611
- extension TradeAssetQuoteRequest {
612
- var toRNModel: Models.TradeAssetQuoteRequest {
613
- get throws {
614
- if let fiatAssetQuoteRequest {
615
- return Models.TradeAssetQuoteRequest.FiatAssetQuoteRequest(
616
- .init(
617
- assetKind: .fiat,
618
- serviceAccountID: fiatAssetQuoteRequest
619
- .serviceAccountID,
620
- currencyCode: fiatAssetQuoteRequest.currencyCode,
621
- amount: fiatAssetQuoteRequest.amount
622
- )
623
- )
624
- } else if let marketAssetQuoteRequest {
625
- guard
626
- let assetKind = Models.MarketAssetQuoteRequest
627
- .AssetKindPayload(
628
- rawValue: marketAssetQuoteRequest.assetKind
150
+ public func getAssetAccounts(query: AssetAccountsQuery) throws -> Promise<AssetAccountsResponse>
151
+ {
152
+ .async {
153
+ let accounts = try await Client.shared.getAssetAccounts(query: .init(reactModel: query))
154
+ return AssetAccountsResponse(
155
+ linkedAccounts: accounts.linkedAccounts.map(\.reactModel),
156
+ assetAccounts: accounts.assetAccounts.map(\.reactModel)
629
157
  )
630
- else {
631
- throw RNClientError.badEncoding
632
158
  }
633
- return Models.TradeAssetQuoteRequest.MarketAssetQuoteRequest(
634
- .init(
635
- assetKind: assetKind,
636
- serviceAccountID: marketAssetQuoteRequest
637
- .serviceAccountID,
638
- serviceAssetID: marketAssetQuoteRequest.serviceAssetID,
639
- symbol: marketAssetQuoteRequest.symbol,
640
- amount: marketAssetQuoteRequest.amount
641
- )
642
- )
643
- } else if nothingAssetQuoteRequest != nil {
644
- return Models.TradeAssetQuoteRequest.NothingAssetQuoteRequest(
645
- .init(assetKind: .nothing)
646
- )
647
- } else if let transportAssetQuoteRequest {
648
- return Models.TradeAssetQuoteRequest.TransportAssetQuoteRequest(
649
- .init(
650
- assetKind: .transport,
651
- serviceAssetID: transportAssetQuoteRequest
652
- .serviceAssetID,
653
- originCoordinates: transportAssetQuoteRequest
654
- .originCoordinates?.toCoordinates,
655
- originAddress: transportAssetQuoteRequest.originAddress?
656
- .toAddress,
657
- destinationCoordinates: transportAssetQuoteRequest
658
- .destinationCoordinates?
659
- .toCoordinates,
660
- destinationAddress: transportAssetQuoteRequest
661
- .destinationAddress?.toAddress,
662
- seats: transportAssetQuoteRequest.seats,
663
- serviceAccountID: transportAssetQuoteRequest.serviceAccountID
664
- )
665
- )
666
- } else {
667
- throw RNClientError.badInitialization(
668
- message:
669
- "Internal Candle Error: corrupted trade quote request."
670
- )
671
- }
672
- }
673
- }
674
- }
675
-
676
- extension Address {
677
- var toAddress: Models.Address {
678
- return .init(value: value)
679
- }
680
- }
681
-
682
- extension Coordinates {
683
- var toCoordinates: Models.Coordinates {
684
- return .init(
685
- latitude: latitude,
686
- longitude: longitude
687
- )
688
- }
689
- }
690
-
691
- extension Service {
692
- var toRNModel: Models.Service {
693
- switch self {
694
- case .apple:
695
- return .apple
696
- case .cashApp:
697
- return .cashApp
698
- case .sandbox:
699
- return .sandbox
700
- case .robinhood:
701
- return .robinhood
702
- case .uber:
703
- return .uber
704
- case .lyft:
705
- return .lyft
706
- case .venmo:
707
- return .venmo
708
- case .chime:
709
- return .chime
710
- case .paypal:
711
- return .paypal
712
- case .coinbase:
713
- return .coinbase
714
- case .discover:
715
- return .discover
716
- case .americanExpress:
717
- return .americanExpress
718
- case .jpmorganChase:
719
- return .jpmorganChase
720
- case .bankOfAmerica:
721
- return .bankOfAmerica
722
- case .capitalOne:
723
- return .capitalOne
724
- case .citibank:
725
- return .citibank
726
- case .vanguard:
727
- return .vanguard
728
- case .wellsFargo:
729
- return .wellsFargo
730
- case .charlesSchwab:
731
- return .charlesSchwab
732
- case .kalshi:
733
- return .kalshi
734
- case .experian:
735
- return .experian
736
- case .waymo:
737
- return .waymo
738
- case .revel:
739
- return .revel
740
- case .turo:
741
- return .turo
742
- case .getaround:
743
- return .getaround
744
- case .zipcar:
745
- return .zipcar
746
- case .airbnb:
747
- return .airbnb
748
- case .americanAirlines:
749
- return .americanAirlines
750
- case .delta:
751
- return .delta
752
- case .united:
753
- return .united
754
- case .jetblue:
755
- return .jetblue
756
- case .southwest:
757
- return .southwest
758
- case .hawaiian:
759
- return .hawaiian
760
- case .hotels:
761
- return .hotels
762
- case .geico:
763
- return .geico
764
- case .progressive:
765
- return .progressive
766
- case .aaa:
767
- return .aaa
768
- case .stateFarm:
769
- return .stateFarm
770
- case .hertz:
771
- return .hertz
772
- case .avis:
773
- return .avis
774
- case .tesla:
775
- return .tesla
776
- case .doordash:
777
- return .doordash
778
- case .uberEats:
779
- return .uberEats
780
- case .grubhub:
781
- return .grubhub
782
- case .resy:
783
- return .resy
784
- case .opentable:
785
- return .opentable
786
- case .starbucks:
787
- return .starbucks
788
- case .blueBottle:
789
- return .blueBottle
790
- case .costco:
791
- return .costco
792
- case .amazon:
793
- return .amazon
794
- case .walmart:
795
- return .walmart
796
- case .wholeFoods:
797
- return .wholeFoods
798
- case .mcdonalds:
799
- return .mcdonalds
800
- case .chipotle:
801
- return .chipotle
802
- case .sweetgreen:
803
- return .sweetgreen
804
- case .snapchat:
805
- return .snapchat
806
- case .x:
807
- return .x
808
- case .facebook:
809
- return .facebook
810
- case .instagram:
811
- return .instagram
812
- case .signal:
813
- return .signal
814
- case .whatsapp:
815
- return .whatsapp
816
- case .messenger:
817
- return .messenger
818
- case .linkedin:
819
- return .linkedin
820
- case .discord:
821
- return .discord
822
- case .messages:
823
- return .messages
824
- case .telegram:
825
- return .telegram
826
- case .reddit:
827
- return .reddit
828
- case .pinterest:
829
- return .pinterest
830
- case .newYorkTimes:
831
- return .newYorkTimes
832
- case .washingtonPost:
833
- return .washingtonPost
834
- case .wallStreetJournal:
835
- return .wallStreetJournal
836
- case .cnn:
837
- return .cnn
838
- case .yahoo:
839
- return .yahoo
840
- case .fox:
841
- return .fox
842
- case .perplexity:
843
- return .perplexity
844
- case .openai:
845
- return .openai
846
- case .polymarket:
847
- return .polymarket
848
- case .espn:
849
- return .espn
850
- case .youtube:
851
- return .youtube
852
- case .netflix:
853
- return .netflix
854
159
  }
855
- }
856
- }
857
-
858
- extension Models.Service {
859
- var toRNModel: Service {
860
- switch self {
861
- case .apple:
862
- return .apple
863
- case .cashApp:
864
- return .cashApp
865
- case .sandbox:
866
- return .sandbox
867
- case .robinhood:
868
- return .robinhood
869
- case .uber:
870
- return .uber
871
- case .lyft:
872
- return .lyft
873
- case .venmo:
874
- return .venmo
875
- case .chime:
876
- return .chime
877
- case .paypal:
878
- return .paypal
879
- case .coinbase:
880
- return .coinbase
881
- case .discover:
882
- return .discover
883
- case .americanExpress:
884
- return .americanExpress
885
- case .jpmorganChase:
886
- return .jpmorganChase
887
- case .bankOfAmerica:
888
- return .bankOfAmerica
889
- case .capitalOne:
890
- return .capitalOne
891
- case .citibank:
892
- return .citibank
893
- case .vanguard:
894
- return .vanguard
895
- case .wellsFargo:
896
- return .wellsFargo
897
- case .charlesSchwab:
898
- return .charlesSchwab
899
- case .kalshi:
900
- return .kalshi
901
- case .experian:
902
- return .experian
903
- case .waymo:
904
- return .waymo
905
- case .revel:
906
- return .revel
907
- case .turo:
908
- return .turo
909
- case .getaround:
910
- return .getaround
911
- case .zipcar:
912
- return .zipcar
913
- case .airbnb:
914
- return .airbnb
915
- case .americanAirlines:
916
- return .americanAirlines
917
- case .delta:
918
- return .delta
919
- case .united:
920
- return .united
921
- case .jetblue:
922
- return .jetblue
923
- case .southwest:
924
- return .southwest
925
- case .hawaiian:
926
- return .hawaiian
927
- case .hotels:
928
- return .hotels
929
- case .geico:
930
- return .geico
931
- case .progressive:
932
- return .progressive
933
- case .aaa:
934
- return .aaa
935
- case .stateFarm:
936
- return .stateFarm
937
- case .hertz:
938
- return .hertz
939
- case .avis:
940
- return .avis
941
- case .tesla:
942
- return .tesla
943
- case .doordash:
944
- return .doordash
945
- case .uberEats:
946
- return .uberEats
947
- case .grubhub:
948
- return .grubhub
949
- case .resy:
950
- return .resy
951
- case .opentable:
952
- return .opentable
953
- case .starbucks:
954
- return .starbucks
955
- case .blueBottle:
956
- return .blueBottle
957
- case .costco:
958
- return .costco
959
- case .amazon:
960
- return .amazon
961
- case .walmart:
962
- return .walmart
963
- case .wholeFoods:
964
- return .wholeFoods
965
- case .mcdonalds:
966
- return .mcdonalds
967
- case .chipotle:
968
- return .chipotle
969
- case .sweetgreen:
970
- return .sweetgreen
971
- case .snapchat:
972
- return .snapchat
973
- case .x:
974
- return .x
975
- case .facebook:
976
- return .facebook
977
- case .instagram:
978
- return .instagram
979
- case .signal:
980
- return .signal
981
- case .whatsapp:
982
- return .whatsapp
983
- case .messenger:
984
- return .messenger
985
- case .linkedin:
986
- return .linkedin
987
- case .discord:
988
- return .discord
989
- case .messages:
990
- return .messages
991
- case .telegram:
992
- return .telegram
993
- case .reddit:
994
- return .reddit
995
- case .pinterest:
996
- return .pinterest
997
- case .newYorkTimes:
998
- return .newYorkTimes
999
- case .washingtonPost:
1000
- return .washingtonPost
1001
- case .wallStreetJournal:
1002
- return .wallStreetJournal
1003
- case .cnn:
1004
- return .cnn
1005
- case .yahoo:
1006
- return .yahoo
1007
- case .fox:
1008
- return .fox
1009
- case .perplexity:
1010
- return .perplexity
1011
- case .openai:
1012
- return .openai
1013
- case .polymarket:
1014
- return .polymarket
1015
- case .espn:
1016
- return .espn
1017
- case .youtube:
1018
- return .youtube
1019
- case .netflix:
1020
- return .netflix
1021
- }
1022
- }
1023
- }
1024
-
1025
- extension AssetAccountKind {
1026
- var asCandleModel: Models.GetAssetAccounts.Input.Query.AssetKindPayload {
1027
- switch self {
1028
- case .fiat:
1029
- return .fiat
1030
- case .stock:
1031
- return .stock
1032
- case .crypto:
1033
- return .crypto
1034
- case .transport:
1035
- return .transport
1036
- }
1037
- }
1038
- }
1039
-
1040
- extension Candle.Components.Schemas.FiatMarketAccountKind {
1041
- var toRNModel: FiatMarketAccountKind {
1042
- switch self {
1043
- case .individual:
1044
- return .individual
1045
- case .joint:
1046
- return .joint
1047
- case .rothIra:
1048
- return .rothira
1049
- case .traditionalIra:
1050
- return .traditionalira
1051
- case .business:
1052
- return .business
1053
- }
1054
- }
1055
- }
1056
-
1057
- extension Candle.Components.Schemas.TransportAccountKind {
1058
- var toRNModel: TransportAccountKind {
1059
- switch self {
1060
- case .individual:
1061
- return .individual
1062
- case .joint:
1063
- return .joint
1064
- case .business:
1065
- return .business
1066
- }
1067
- }
1068
- }
1069
160
 
1070
- extension Candle.Components.Schemas.ACHAccountKind {
1071
- var toRNModel: ACHAccountKind {
1072
- switch self {
1073
- case .checking:
1074
- return .checking
1075
- case .savings:
1076
- return .savings
1077
- }
1078
- }
1079
- }
1080
-
1081
- extension Models.Trade.StatePayload {
1082
- var toRNModel: TradeState {
1083
- switch self {
1084
- case .success:
1085
- return .success
1086
- case .failure:
1087
- return .failure
1088
- case .inProgress:
1089
- return .inprogress
1090
- }
1091
- }
1092
- }
1093
-
1094
- extension TradeQuery {
1095
-
1096
- var toGainedAssetKind:
1097
- Candle.Operations.GetLinkedAccountsTrades.Input.Query
1098
- .GainedAssetKindPayload?
1099
- {
1100
- if let gainedAssetKind {
1101
- return .init(rawValue: gainedAssetKind)
1102
- }
1103
- return nil
1104
- }
1105
-
1106
- var toLostAssetKind:
1107
- Candle.Operations.GetLinkedAccountsTrades.Input.Query
1108
- .LostAssetKindPayload?
1109
- {
1110
- if let lostAssetKind {
1111
- return .init(rawValue: lostAssetKind)
1112
- }
1113
- return nil
1114
- }
1115
-
1116
- var toCounterpartyKindPayload:
1117
- Candle.Operations.GetLinkedAccountsTrades.Input.Query
1118
- .CounterpartyKindPayload?
1119
- {
1120
- if let counterpartyKind {
1121
- return .init(rawValue: counterpartyKind)
161
+ public func getAssetAccount(ref: AssetAccountRef) throws -> Promise<AssetAccount> {
162
+ .async {
163
+ let account = try await Client.shared.getAssetAccount(ref: .init(reactModel: ref))
164
+ return account.reactModel
165
+ }
1122
166
  }
1123
- return nil
1124
- }
1125
- }
1126
167
 
1127
- extension Models.AssetAccount {
1128
- var toRNModel: AssetAccount {
1129
- switch self {
1130
- case .FiatAccount(let fiatDetails):
1131
- let ach = fiatDetails.ach.map { details in
1132
- ACHDetails(
1133
- accountNumber: details.accountNumber,
1134
- routingNumber: details.routingNumber,
1135
- accountKind: details.accountKind.toRNModel
1136
- )
1137
- }
1138
-
1139
- let wire = fiatDetails.wire.map { details in
1140
- WireDetails(
1141
- accountNumber: details.accountNumber,
1142
- routingNumber: details.routingNumber
1143
- )
1144
- }
1145
- return AssetAccount(
1146
- fiatAccount: .init(
1147
- assetKind: fiatDetails.assetKind.rawValue,
1148
- serviceAccountID: fiatDetails.serviceAccountID,
1149
- accountKind: fiatDetails.accountKind.toRNModel,
1150
- nickname: nickname,
1151
- currencyCode: fiatDetails.currencyCode,
1152
- balance: fiatDetails.balance,
1153
- ach: ach,
1154
- wire: wire,
1155
- linkedAccountID: fiatDetails.linkedAccountID,
1156
- service: fiatDetails.service.toRNModel
1157
- ),
1158
- marketAccount: nil,
1159
- transportAccount: nil
1160
- )
1161
- case .MarketAccount(let marketDetails):
1162
- return AssetAccount(
1163
- fiatAccount: nil,
1164
- marketAccount: .init(
1165
- assetKind: marketDetails.assetKind.rawValue,
1166
- serviceAccountID: marketDetails.serviceAccountID,
1167
- accountKind: marketDetails.accountKind.toRNModel,
1168
- nickname: nickname,
1169
- linkedAccountID: marketDetails.linkedAccountID,
1170
- service: marketDetails.service.toRNModel
1171
- ),
1172
- transportAccount: nil
1173
- )
1174
- case .TransportAccount(let transportDetails):
1175
- return AssetAccount(
1176
- fiatAccount: nil,
1177
- marketAccount: nil,
1178
- transportAccount: .init(
1179
- assetKind: transportDetails.assetKind.rawValue,
1180
- serviceAccountID: transportDetails.serviceAccountID,
1181
- accountKind: transportDetails.accountKind.toRNModel,
1182
- nickname: nickname,
1183
- linkedAccountID: transportDetails.linkedAccountID,
1184
- service: transportDetails.service.toRNModel
1185
- )
1186
- )
168
+ public func getTrade(ref: TradeRef) throws -> Promise<Trade> {
169
+ .async {
170
+ let trade = try await Client.shared.getTrade(ref: .init(reactModel: ref))
171
+ return trade.reactModel
172
+ }
1187
173
  }
1188
- }
1189
- }
1190
174
 
1191
- extension TradeAssetRef {
1192
- var toRNModelAssetRef: Models.TradeAssetRef {
1193
- get throws {
1194
- if let fiatAssetRef {
1195
- return .FiatAssetRef(
1196
- .init(
1197
- assetKind: .fiat,
1198
- serviceTradeID: fiatAssetRef.serviceTradeID,
1199
- linkedAccountID: fiatAssetRef.linkedAccountID
1200
- )
1201
- )
1202
- } else if let nothingAssetRef {
1203
- return .NothingAsset(.init(assetKind: .nothing))
1204
- } else if let marketTradeAssetRef {
1205
- guard
1206
- let assetKind = Models.MarketAssetRef.AssetKindPayload.init(
1207
- rawValue: marketTradeAssetRef.assetKind
1208
- )
1209
- else {
1210
- throw RNClientError.badEncoding
175
+ public func getTrades(query: TradesQuery) throws -> Promise<TradesResponse> {
176
+ .async {
177
+ let trades = try await Client.shared.getTrades(query: .init(reactModel: query))
178
+ return TradesResponse(
179
+ linkedAccounts: trades.linkedAccounts.map(\.reactModel),
180
+ trades: trades.trades.map(\.reactModel)
181
+ )
1211
182
  }
1212
- return .MarketAssetRef(
1213
- .init(
1214
- assetKind: assetKind,
1215
- serviceTradeID: marketTradeAssetRef.serviceTradeID,
1216
- linkedAccountID: marketTradeAssetRef.linkedAccountID
1217
- )
1218
- )
1219
- } else if let otherAssetRef {
1220
- return .OtherAsset(
1221
- .init(assetKind: .other)
1222
- )
1223
- } else if let transportAssetRef {
1224
- return .TransportAssetRef(
1225
- .init(
1226
- assetKind: .transport,
1227
- serviceTradeID: transportAssetRef.serviceTradeID,
1228
- linkedAccountID: transportAssetRef.linkedAccountID
1229
- )
1230
- )
1231
- } else {
1232
- throw RNClientError.badEncoding
1233
- }
1234
183
  }
1235
- }
1236
- }
1237
184
 
1238
- extension TradeAsset {
1239
- var toCandleModel: Models.TradeAsset {
1240
- get throws {
1241
- if let fiat = fiatAsset {
1242
- return .FiatAsset(
1243
- .init(
1244
- assetKind: .fiat,
1245
- serviceTradeID: fiat.serviceTradeID,
1246
- serviceAccountID: fiat.serviceAccountID,
1247
- currencyCode: fiat.currencyCode,
1248
- amount: fiat.amount,
1249
- linkedAccountID: fiat.linkedAccountID,
1250
- service: fiat.service.toRNModel
1251
- )
1252
- )
1253
- } else if let market = marketTradeAsset {
1254
- guard
1255
- let assetKind = Models.MarketTradeAsset.AssetKindPayload(
1256
- rawValue: market.assetKind
1257
- )
1258
- else {
1259
- throw RNClientError.badEncoding
185
+ public func getTradeQuotes(request: TradeQuotesRequest) throws -> Promise<TradeQuotesResponse> {
186
+ .async {
187
+ let accounts = try await Client.shared.getTradeQuotes(
188
+ request: .init(reactModel: request)
189
+ )
190
+ return TradeQuotesResponse.init(
191
+ linkedAccounts: accounts.linkedAccounts.map(\.reactModel),
192
+ tradeQuotes: accounts.tradeQuotes.map(\.reactModel)
193
+ )
1260
194
  }
1261
- return .MarketTradeAsset(
1262
- .init(
1263
- assetKind: assetKind,
1264
- serviceAccountID: market.serviceAccountID,
1265
- serviceAssetID: market.serviceAssetID,
1266
- symbol: market.symbol,
1267
- amount: market.amount,
1268
- serviceTradeID: market.serviceTradeID,
1269
- linkedAccountID: market.linkedAccountID,
1270
- service: market.service.toRNModel,
1271
- name: market.name,
1272
- color: market.color,
1273
- logoURL: market.logoURL
1274
- )
1275
- )
1276
- } else if let transport = transportAsset {
1277
- return .TransportAsset(
1278
- .init(
1279
- assetKind: .transport,
1280
- serviceTradeID: transport.serviceTradeID,
1281
- serviceAssetID: transport.serviceAssetID,
1282
- serviceAccountID: transport.serviceAccountID,
1283
- name: transport.name,
1284
- description: transport.description,
1285
- imageURL: transport.imageURL,
1286
- originCoordinates: .init(
1287
- latitude: transport.originCoordinates.latitude,
1288
- longitude: transport.originCoordinates.longitude
1289
- ),
1290
- originAddress: .init(
1291
- value: transport.originAddress.value
1292
- ),
1293
- destinationCoordinates: .init(
1294
- latitude: transport.destinationCoordinates.latitude,
1295
- longitude: transport.destinationCoordinates
1296
- .longitude
1297
- ),
1298
- destinationAddress: .init(
1299
- value: transport.destinationAddress.value
1300
- ),
1301
- seats: transport.seats,
1302
- departureDateTime: transport.departureDateTime,
1303
- arrivalDateTime: transport.arrivalDateTime,
1304
- linkedAccountID: transport.linkedAccountID,
1305
- service: transport.service.toRNModel
1306
- )
1307
- )
1308
- } else if otherAsset != nil {
1309
- return .OtherAsset(.init(assetKind: .other))
1310
- } else {
1311
- return .NothingAsset(.init(assetKind: .nothing))
1312
- }
1313
195
  }
1314
- }
1315
- }
1316
-
1317
- extension TradeQuote {
1318
- var toCandleModel: Models.TradeQuote {
1319
- get throws {
1320
- .init(
1321
- lost: try lost.toCandleModel,
1322
- gained: try gained.toCandleModel,
1323
- context: context,
1324
- expirationDateTime: expirationDateTime
1325
- )
196
+ public func createUser(appUserID: String) throws -> Promise<Void> {
197
+ .async { try await Client.shared.createUser(appUserID: appUserID) }
1326
198
  }
1327
- }
1328
- }
1329
199
 
1330
- extension Components.Schemas.LinkedAccountStatusRef.StatePayload {
1331
- var toRNModel: StatePayload {
1332
- switch self {
1333
- case .active: return .active
1334
- case .inactive: return .inactive
1335
- case .unavailable: return .unavailable
200
+ public func deleteUser() throws -> Promise<Void> {
201
+ .async { try await Client.shared.deleteUser() }
1336
202
  }
1337
- }
1338
- }
1339
-
1340
- extension Models.LinkedAccountStatusRef {
1341
- var toRNModel: LinkedAccountStatusRef {
1342
- .init(
1343
- linkedAccountID: linkedAccountID,
1344
- service: service.toRNModel,
1345
- serviceUserID: serviceUserID,
1346
- state: state.toRNModel
1347
- )
1348
- }
1349
203
  }
1350
204
 
1351
205
  extension UIViewController {
1352
- fileprivate var candleTopMost: UIViewController {
1353
- var top = self
1354
- while let presented = top.presentedViewController {
1355
- top = presented
206
+ fileprivate var candleTopMost: UIViewController {
207
+ var top = self
208
+ while let presented = top.presentedViewController { top = presented }
209
+ return top
1356
210
  }
1357
- return top
1358
- }
1359
211
  }