react-native-zcash 0.6.13 → 0.7.0

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 (162) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/android/build.gradle +4 -4
  3. package/android/src/main/assets/co.electriccoin.zcash/checkpoint/mainnet/2470000.json +8 -0
  4. package/android/src/main/assets/co.electriccoin.zcash/checkpoint/mainnet/2480000.json +8 -0
  5. package/android/src/main/java/app/edge/rnzcash/RNZcashModule.kt +51 -9
  6. package/ios/RNZcash.m +8 -0
  7. package/ios/RNZcash.swift +66 -16
  8. package/ios/ZCashLightClientKit/Block/Actions/DownloadAction.swift +1 -1
  9. package/ios/ZCashLightClientKit/Block/Actions/EnhanceAction.swift +3 -1
  10. package/ios/ZCashLightClientKit/Block/Actions/FetchUTXOsAction.swift +1 -1
  11. package/ios/ZCashLightClientKit/Block/Actions/ProcessSuggestedScanRangesAction.swift +11 -2
  12. package/ios/ZCashLightClientKit/Block/Actions/RewindAction.swift +2 -2
  13. package/ios/ZCashLightClientKit/Block/Actions/ScanAction.swift +28 -11
  14. package/ios/ZCashLightClientKit/Block/Actions/UpdateChainTipAction.swift +4 -4
  15. package/ios/ZCashLightClientKit/Block/Actions/UpdateSubtreeRootsAction.swift +36 -7
  16. package/ios/ZCashLightClientKit/Block/Actions/ValidateServerAction.swift +1 -1
  17. package/ios/ZCashLightClientKit/Block/CompactBlockProcessor.swift +93 -51
  18. package/ios/ZCashLightClientKit/Block/Download/BlockDownloader.swift +0 -26
  19. package/ios/ZCashLightClientKit/Block/Enhance/BlockEnhancer.swift +5 -6
  20. package/ios/ZCashLightClientKit/Block/FetchUnspentTxOutputs/UTXOFetcher.swift +1 -11
  21. package/ios/ZCashLightClientKit/Block/SaplingParameters/SaplingParametersHandler.swift +6 -4
  22. package/ios/ZCashLightClientKit/Block/Scan/BlockScanner.swift +10 -12
  23. package/ios/ZCashLightClientKit/Checkpoint/BundleCheckpointSource.swift +38 -0
  24. package/ios/ZCashLightClientKit/Checkpoint/BundleCheckpointURLProvider.swift +40 -0
  25. package/ios/ZCashLightClientKit/{Constants/Checkpoint+Constants.swift → Checkpoint/Checkpoint+helpers.swift} +1 -33
  26. package/ios/ZCashLightClientKit/Checkpoint/CheckpointSource.swift +34 -0
  27. package/ios/ZCashLightClientKit/Checkpoint/CheckpointSourceFactory.swift +14 -0
  28. package/ios/ZCashLightClientKit/ClosureSynchronizer.swift +61 -6
  29. package/ios/ZCashLightClientKit/CombineSynchronizer.swift +63 -4
  30. package/ios/ZCashLightClientKit/Constants/ZcashSDK.swift +4 -0
  31. package/ios/ZCashLightClientKit/DAO/TransactionDao.swift +21 -33
  32. package/ios/ZCashLightClientKit/DAO/UnspentTransactionOutputDao.swift +0 -182
  33. package/ios/ZCashLightClientKit/Entity/AccountEntity.swift +0 -173
  34. package/ios/ZCashLightClientKit/Entity/TransactionEntity.swift +5 -2
  35. package/ios/ZCashLightClientKit/Error/Sourcery/generateErrorCode.sh +1 -1
  36. package/ios/ZCashLightClientKit/Error/ZcashError.swift +53 -1
  37. package/ios/ZCashLightClientKit/Error/ZcashErrorCode.swift +19 -1
  38. package/ios/ZCashLightClientKit/Error/ZcashErrorCodeDefinition.swift +32 -0
  39. package/ios/ZCashLightClientKit/Initializer.swift +8 -17
  40. package/ios/ZCashLightClientKit/Metrics/SDKMetrics.swift +103 -217
  41. package/ios/ZCashLightClientKit/Model/Proposal.swift +45 -0
  42. package/ios/ZCashLightClientKit/Model/ScanSummary.swift +14 -0
  43. package/ios/ZCashLightClientKit/Model/WalletSummary.swift +58 -0
  44. package/ios/ZCashLightClientKit/Model/WalletTypes.swift +0 -16
  45. package/ios/ZCashLightClientKit/Modules/Service/GRPC/LightWalletGRPCService.swift +5 -3
  46. package/ios/ZCashLightClientKit/Modules/Service/GRPC/ProtoBuf/proposal.pb.swift +934 -0
  47. package/ios/ZCashLightClientKit/Modules/Service/GRPC/ProtoBuf/proto/proposal.proto +138 -0
  48. package/ios/ZCashLightClientKit/Modules/Service/LightWalletService.swift +2 -4
  49. package/ios/ZCashLightClientKit/Providers/LatestBlocksDataProvider.swift +9 -1
  50. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2272500.json +8 -0
  51. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2275000.json +8 -0
  52. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2277500.json +8 -0
  53. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2282500.json +8 -0
  54. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2285000.json +8 -0
  55. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2287500.json +8 -0
  56. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2292500.json +8 -0
  57. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2295000.json +8 -0
  58. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2297500.json +8 -0
  59. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2302500.json +8 -0
  60. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2305000.json +8 -0
  61. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2307500.json +8 -0
  62. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2312500.json +8 -0
  63. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2315000.json +8 -0
  64. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2317500.json +8 -0
  65. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2322500.json +8 -0
  66. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2325000.json +8 -0
  67. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2327500.json +8 -0
  68. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2332500.json +8 -0
  69. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2335000.json +8 -0
  70. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2337500.json +8 -0
  71. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2342500.json +8 -0
  72. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2345000.json +8 -0
  73. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2347500.json +8 -0
  74. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2352500.json +8 -0
  75. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2355000.json +8 -0
  76. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2357500.json +8 -0
  77. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2362500.json +8 -0
  78. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2365000.json +8 -0
  79. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2367500.json +8 -0
  80. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2372500.json +8 -0
  81. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2375000.json +8 -0
  82. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2377500.json +8 -0
  83. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2382500.json +8 -0
  84. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2385000.json +8 -0
  85. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2387500.json +8 -0
  86. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2392500.json +8 -0
  87. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2395000.json +8 -0
  88. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2397500.json +8 -0
  89. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2402500.json +8 -0
  90. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2405000.json +8 -0
  91. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2407500.json +8 -0
  92. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2412500.json +8 -0
  93. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2415000.json +8 -0
  94. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2417500.json +8 -0
  95. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2422500.json +8 -0
  96. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2425000.json +8 -0
  97. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2427500.json +8 -0
  98. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2432500.json +8 -0
  99. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2435000.json +8 -0
  100. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2437500.json +8 -0
  101. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2442500.json +8 -0
  102. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2445000.json +8 -0
  103. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2447500.json +8 -0
  104. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2452500.json +8 -0
  105. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2455000.json +8 -0
  106. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2457500.json +8 -0
  107. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2462500.json +8 -0
  108. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2465000.json +8 -0
  109. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2467500.json +8 -0
  110. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2470000.json +8 -0
  111. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2472500.json +8 -0
  112. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2480000.json +8 -0
  113. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2560000.json +8 -0
  114. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2570000.json +8 -0
  115. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2580000.json +8 -0
  116. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2590000.json +8 -0
  117. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2600000.json +8 -0
  118. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2610000.json +8 -0
  119. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2620000.json +8 -0
  120. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2630000.json +8 -0
  121. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2640000.json +8 -0
  122. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2650000.json +8 -0
  123. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2660000.json +8 -0
  124. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2670000.json +8 -0
  125. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2680000.json +8 -0
  126. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2690000.json +8 -0
  127. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2700000.json +8 -0
  128. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2710000.json +8 -0
  129. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2720000.json +8 -0
  130. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2730000.json +8 -0
  131. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2740000.json +8 -0
  132. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2750000.json +8 -0
  133. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2760000.json +8 -0
  134. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2770000.json +8 -0
  135. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2780000.json +8 -0
  136. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2790000.json +8 -0
  137. package/ios/ZCashLightClientKit/Rust/ZcashKeyDerivationBackend.swift +1 -5
  138. package/ios/ZCashLightClientKit/Rust/ZcashRustBackend.swift +327 -153
  139. package/ios/ZCashLightClientKit/Rust/ZcashRustBackendWelding.swift +78 -36
  140. package/ios/ZCashLightClientKit/Rust/zcashlc.h +1441 -0
  141. package/ios/ZCashLightClientKit/Synchronizer/ClosureSDKSynchronizer.swift +43 -14
  142. package/ios/ZCashLightClientKit/Synchronizer/CombineSDKSynchronizer.swift +52 -14
  143. package/ios/ZCashLightClientKit/Synchronizer/Dependencies.swift +10 -6
  144. package/ios/ZCashLightClientKit/Synchronizer/SDKSynchronizer.swift +220 -70
  145. package/ios/ZCashLightClientKit/Synchronizer.swift +105 -29
  146. package/ios/ZCashLightClientKit/Transaction/TransactionEncoder.swift +61 -32
  147. package/ios/ZCashLightClientKit/Transaction/WalletTransactionEncoder.swift +52 -61
  148. package/ios/ZCashLightClientKit/Utils/DBActor.swift +21 -0
  149. package/ios/ZCashLightClientKit/Utils/LoggingProxy.swift +5 -0
  150. package/ios/ZCashLightClientKit/Utils/OSLogger.swift +71 -14
  151. package/ios/libzcashlc.xcframework/ios-arm64/libzcashlc.a +0 -0
  152. package/ios/libzcashlc.xcframework/ios-arm64_x86_64-simulator/libzcashlc.a +0 -0
  153. package/lib/rnzcash.rn.js +21 -6
  154. package/lib/rnzcash.rn.js.map +1 -1
  155. package/lib/src/react-native.d.ts +2 -1
  156. package/lib/src/types.d.ts +9 -1
  157. package/package.json +1 -1
  158. package/src/react-native.ts +23 -4
  159. package/src/types.ts +10 -1
  160. package/ios/ZCashLightClientKit/Model/ScanProgress.swift +0 -29
  161. package/ios/ZCashLightClientKit/Repository/UnspentTransactionOutputRepository.swift +0 -16
  162. /package/ios/ZCashLightClientKit/{Model → Checkpoint}/Checkpoint.swift +0 -0
@@ -35,10 +35,8 @@ public struct SynchronizerState: Equatable {
35
35
  /// given how application lifecycle varies between OS Versions, platforms, etc.
36
36
  /// SyncSessionIDs are provided to users
37
37
  public var syncSessionID: UUID
38
- /// shielded balance known to this synchronizer given the data that has processed locally
39
- public var shieldedBalance: WalletBalance
40
- /// transparent balance known to this synchronizer given the data that has processed locally
41
- public var transparentBalance: WalletBalance
38
+ /// account balance known to this synchronizer given the data that has processed locally
39
+ public var accountBalance: AccountBalance?
42
40
  /// status of the whole sync process
43
41
  var internalSyncStatus: InternalSyncStatus
44
42
  public var syncStatus: SyncStatus
@@ -49,8 +47,7 @@ public struct SynchronizerState: Equatable {
49
47
  public static var zero: SynchronizerState {
50
48
  SynchronizerState(
51
49
  syncSessionID: .nullID,
52
- shieldedBalance: .zero,
53
- transparentBalance: .zero,
50
+ accountBalance: .zero,
54
51
  internalSyncStatus: .unprepared,
55
52
  latestBlockHeight: .zero
56
53
  )
@@ -58,14 +55,12 @@ public struct SynchronizerState: Equatable {
58
55
 
59
56
  init(
60
57
  syncSessionID: UUID,
61
- shieldedBalance: WalletBalance,
62
- transparentBalance: WalletBalance,
58
+ accountBalance: AccountBalance?,
63
59
  internalSyncStatus: InternalSyncStatus,
64
60
  latestBlockHeight: BlockHeight
65
61
  ) {
66
62
  self.syncSessionID = syncSessionID
67
- self.shieldedBalance = shieldedBalance
68
- self.transparentBalance = transparentBalance
63
+ self.accountBalance = accountBalance
69
64
  self.internalSyncStatus = internalSyncStatus
70
65
  self.latestBlockHeight = latestBlockHeight
71
66
  self.syncStatus = internalSyncStatus.mapToSyncStatus()
@@ -106,9 +101,6 @@ public protocol Synchronizer: AnyObject {
106
101
  /// This stream is backed by `PassthroughSubject`. Check `SynchronizerEvent` to see which events may be emitted.
107
102
  var eventStream: AnyPublisher<SynchronizerEvent, Never> { get }
108
103
 
109
- /// An object that when enabled collects mertrics from the synchronizer
110
- var metrics: SDKMetrics { get }
111
-
112
104
  /// Initialize the wallet. The ZIP-32 seed bytes can optionally be passed to perform
113
105
  /// database migrations. most of the times the seed won't be needed. If they do and are
114
106
  /// not provided this will fail with `InitializationResult.seedRequired`. It could
@@ -162,15 +154,70 @@ public protocol Synchronizer: AnyObject {
162
154
  /// - Parameter accountIndex: the optional accountId whose address is of interest. By default, the first account is used.
163
155
  /// - Returns the address or nil if account index is incorrect
164
156
  func getTransparentAddress(accountIndex: Int) async throws -> TransparentAddress
165
-
157
+
158
+ /// Creates a proposal for transferring funds to the given recipient.
159
+ ///
160
+ /// - Parameter accountIndex: the account from which to transfer funds.
161
+ /// - Parameter recipient: the recipient's address.
162
+ /// - Parameter amount: the amount to send in Zatoshi.
163
+ /// - Parameter memo: an optional memo to include as part of the proposal's transactions. Use `nil` when sending to transparent receivers otherwise the function will throw an error.
164
+ ///
165
+ /// If `prepare()` hasn't already been called since creation of the synchronizer instance or since the last wipe then this method throws
166
+ /// `SynchronizerErrors.notPrepared`.
167
+ func proposeTransfer(
168
+ accountIndex: Int,
169
+ recipient: Recipient,
170
+ amount: Zatoshi,
171
+ memo: Memo?
172
+ ) async throws -> Proposal
173
+
174
+ /// Creates a proposal for shielding any transparent funds received by the given account.
175
+ ///
176
+ /// - Parameter accountIndex: the account for which to shield funds.
177
+ /// - Parameter shieldingThreshold: the minimum transparent balance required before a proposal will be created.
178
+ /// - Parameter memo: an optional memo to include as part of the proposal's transactions.
179
+ /// - Parameter transparentReceiver: a specific transparent receiver within the account
180
+ /// that should be the source of transparent funds. Default is `nil` which
181
+ /// will select whichever of the account's transparent receivers has funds
182
+ /// to shield.
183
+ ///
184
+ /// Returns the proposal, or `nil` if the transparent balance that would be shielded
185
+ /// is zero or below `shieldingThreshold`.
186
+ ///
187
+ /// If `prepare()` hasn't already been called since creation of the synchronizer instance or since the last wipe then this method throws
188
+ /// `SynchronizerErrors.notPrepared`.
189
+ func proposeShielding(
190
+ accountIndex: Int,
191
+ shieldingThreshold: Zatoshi,
192
+ memo: Memo,
193
+ transparentReceiver: TransparentAddress?
194
+ ) async throws -> Proposal?
195
+
196
+ /// Creates the transactions in the given proposal.
197
+ ///
198
+ /// - Parameter proposal: the proposal for which to create transactions.
199
+ /// - Parameter spendingKey: the `UnifiedSpendingKey` associated with the account for which the proposal was created.
200
+ ///
201
+ /// Returns a stream of objects for the transactions that were created as part of the
202
+ /// proposal, indicating whether they were submitted to the network or if an error
203
+ /// occurred.
204
+ ///
205
+ /// If `prepare()` hasn't already been called since creation of the synchronizer instance
206
+ /// or since the last wipe then this method throws `SynchronizerErrors.notPrepared`.
207
+ func createProposedTransactions(
208
+ proposal: Proposal,
209
+ spendingKey: UnifiedSpendingKey
210
+ ) async throws -> AsyncThrowingStream<TransactionSubmitResult, Error>
211
+
166
212
  /// Sends zatoshi.
167
213
  /// - Parameter spendingKey: the `UnifiedSpendingKey` that allows spends to occur.
168
214
  /// - Parameter zatoshi: the amount to send in Zatoshi.
169
215
  /// - Parameter toAddress: the recipient's address.
170
216
  /// - Parameter memo: an `Optional<Memo>`with the memo to include as part of the transaction. send `nil` when sending to transparent receivers otherwise the function will throw an error
171
217
  ///
172
- /// If `prepare()` hasn't already been called since creating of synchronizer instance or since the last wipe then this method throws
218
+ /// - NOTE: If `prepare()` hasn't already been called since creating of synchronizer instance or since the last wipe then this method throws
173
219
  /// `SynchronizerErrors.notPrepared`.
220
+ @available(*, deprecated, message: "Upcoming SDK 2.1 will create multiple transactions at once for some recipients.")
174
221
  func sendToAddress(
175
222
  spendingKey: UnifiedSpendingKey,
176
223
  zatoshi: Zatoshi,
@@ -178,12 +225,25 @@ public protocol Synchronizer: AnyObject {
178
225
  memo: Memo?
179
226
  ) async throws -> ZcashTransaction.Overview
180
227
 
228
+ /// Attempts to propose fulfilling a [ZIP-321](https://zips.z.cash/zip-0321) payment URI using the given `accountIndex`
229
+ /// - Parameter uri: a valid ZIP-321 payment URI
230
+ /// - Parameter accountIndex: the account index that allows spends to occur.
231
+ ///
232
+ /// - NOTE: If `prepare()` hasn't already been called since creating of synchronizer instance or since the last wipe then this method throws
233
+ /// `SynchronizerErrors.notPrepared`.
234
+ func proposefulfillingPaymentURI(
235
+ _ uri: String,
236
+ accountIndex: Int
237
+ ) async throws -> Proposal
238
+
181
239
  /// Shields transparent funds from the given private key into the best shielded pool of the account associated to the given `UnifiedSpendingKey`.
182
240
  /// - Parameter spendingKey: the `UnifiedSpendingKey` that allows to spend transparent funds
183
241
  /// - Parameter memo: the optional memo to include as part of the transaction.
242
+ /// - Parameter shieldingThreshold: the minimum transparent balance required before a transaction will be created.
184
243
  ///
185
- /// If `prepare()` hasn't already been called since creating of synchronizer instance or since the last wipe then this method throws
244
+ /// - Note: If `prepare()` hasn't already been called since creating of synchronizer instance or since the last wipe then this method throws
186
245
  /// `SynchronizerErrors.notPrepared`.
246
+ @available(*, deprecated, message: "Upcoming SDK 2.1 will create multiple transactions at once for some recipients.")
187
247
  func shieldFunds(
188
248
  spendingKey: UnifiedSpendingKey,
189
249
  memo: Memo,
@@ -235,22 +295,14 @@ public protocol Synchronizer: AnyObject {
235
295
 
236
296
  /// Returns the latests UTXOs for the given address from the specified height on
237
297
  ///
238
- /// If `prepare()` hasn't already been called since creating of synchronizer instance or since the last wipe then this method throws
298
+ /// If `prepare()` hasn't already been called since creation of the synchronizer instance or since the last wipe then this method throws
239
299
  /// `SynchronizerErrors.notPrepared`.
240
300
  func refreshUTXOs(address: TransparentAddress, from height: BlockHeight) async throws -> RefreshedUTXOs
241
301
 
242
- /// Returns the last stored transparent balance
243
- func getTransparentBalance(accountIndex: Int) async throws -> WalletBalance
244
-
245
- /// get (unverified) balance from the given account index
302
+ /// Account balances from the given account index
246
303
  /// - Parameter accountIndex: the index of the account
247
- /// - Returns: balance in `Zatoshi`
248
- func getShieldedBalance(accountIndex: Int) async throws -> Zatoshi
249
-
250
- /// get verified balance from the given account index
251
- /// - Parameter accountIndex: the index of the account
252
- /// - Returns: balance in `Zatoshi`
253
- func getShieldedVerifiedBalance(accountIndex: Int) async throws -> Zatoshi
304
+ /// - Returns: `AccountBalance`, struct that holds sapling and unshielded balances or `nil` when no account is associated with `accountIndex`
305
+ func getAccountBalance(accountIndex: Int) async throws -> AccountBalance?
254
306
 
255
307
  /// Rescans the known blocks with the current keys.
256
308
  ///
@@ -267,7 +319,7 @@ public protocol Synchronizer: AnyObject {
267
319
  /// `rewind(policy:)` itself doesn't start the sync process when it's done and it doesn't trigger notifications as regorg would. After it is done
268
320
  /// you have start the sync process by calling `start()`
269
321
  ///
270
- /// If `prepare()` hasn't already been called since creating of synchronizer instance or since the last wipe then returned publisher emits
322
+ /// If `prepare()` hasn't already been called since creation of the synchronizer instance or since the last wipe then returned publisher emits
271
323
  /// `SynchronizerErrors.notPrepared` error.
272
324
  ///
273
325
  /// - Parameter policy: the rewind policy
@@ -293,6 +345,17 @@ public protocol Synchronizer: AnyObject {
293
345
  /// this happens it means that some path passed to `Initializer` is invalid. The SDK can't recover from this and this instance won't do anything.
294
346
  ///
295
347
  func wipe() -> AnyPublisher<Void, Error>
348
+
349
+ /// This API stops the synchronization and re-initalizes everything according to the new endpoint provided.
350
+ /// It can be called anytime.
351
+ /// - Throws: ZcashError when failures occur and related to `synchronizer.start(retry: Bool)`, it's the only throwing operation
352
+ /// during the whole endpoint change.
353
+ func switchTo(endpoint: LightWalletEndpoint) async throws
354
+
355
+ /// Checks whether the given seed is relevant to any of the derived accounts in the wallet.
356
+ ///
357
+ /// - parameter seed: byte array of the seed
358
+ func isSeedRelevantToAnyDerivedAccount(seed: [UInt8]) async throws -> Bool
296
359
  }
297
360
 
298
361
  public enum SyncStatus: Equatable {
@@ -443,6 +506,19 @@ public enum RewindPolicy {
443
506
  case quick
444
507
  }
445
508
 
509
+ /// The result of submitting a transaction to the network.
510
+ ///
511
+ /// - success: the transaction was successfully submitted to the mempool.
512
+ /// - grpcFailure: the transaction failed to reach the lightwalletd server.
513
+ /// - submitFailure: the transaction reached the lightwalletd server but failed to enter the mempool.
514
+ /// - notAttempted: the transaction was created and is in the local wallet, but was not submitted to the network.
515
+ public enum TransactionSubmitResult: Equatable {
516
+ case success(txId: Data)
517
+ case grpcFailure(txId: Data, error: LightWalletServiceError)
518
+ case submitFailure(txId: Data, code: Int, description: String)
519
+ case notAttempted(txId: Data)
520
+ }
521
+
446
522
  extension InternalSyncStatus {
447
523
  public static func == (lhs: InternalSyncStatus, rhs: InternalSyncStatus) -> Bool {
448
524
  switch (lhs, rhs) {
@@ -2,7 +2,7 @@
2
2
  // TransactionEncoder.swift
3
3
  // ZcashLightClientKit
4
4
  //
5
- // Created by Francisco Gindre on 11/20/19.
5
+ // Created by Francisco Gindre on 2019-11-20.
6
6
  //
7
7
 
8
8
  import Foundation
@@ -19,44 +19,73 @@ public enum TransactionEncoderError: Error {
19
19
  }
20
20
 
21
21
  protocol TransactionEncoder {
22
- /// Creates a transaction, throwing an exception whenever things are missing. When the provided wallet implementation
23
- /// doesn't throw an exception, we wrap the issue into a descriptive exception ourselves (rather than using
24
- /// double-bangs for things).
22
+ /// Creates a proposal for transferring funds to the given recipient.
25
23
  ///
26
- /// - Parameters:
27
- /// - Parameter spendingKey: a `UnifiedSpendingKey` containing the spending key
28
- /// - Parameter zatoshi: the amount to send in `Zatoshi`
29
- /// - Parameter to: string containing the recipient address
30
- /// - Parameter MemoBytes: string containing the memo (optional)
31
- /// - Parameter accountIndex: index of the account that will be used to send the funds
24
+ /// - Parameter accountIndex: the account from which to transfer funds.
25
+ /// - Parameter recipient: string containing the recipient's address.
26
+ /// - Parameter amount: the amount to send in Zatoshi.
27
+ /// - Parameter memoBytes: an optional memo to include as part of the proposal's transactions. Use `nil` when sending to transparent receivers otherwise the function will throw an error.
28
+ ///
29
+ /// If `prepare()` hasn't already been called since creation of the synchronizer instance or since the last wipe then this method throws
30
+ /// `SynchronizerErrors.notPrepared`.
31
+ func proposeTransfer(
32
+ accountIndex: Int,
33
+ recipient: String,
34
+ amount: Zatoshi,
35
+ memoBytes: MemoBytes?
36
+ ) async throws -> Proposal
37
+
38
+ /// Creates a proposal for shielding any transparent funds received by the given account.
39
+ ///
40
+ /// - Parameter accountIndex: the account for which to shield funds.
41
+ /// - Parameter shieldingThreshold: the minimum transparent balance required before a proposal will be created.
42
+ /// - Parameter memoBytes: an optional memo to include as part of the proposal's transactions.
43
+ /// - Parameter transparentReceiver: a specific transparent receiver within the account
44
+ /// that should be the source of transparent funds. Default is `nil` which
45
+ /// will select whichever of the account's transparent receivers has funds
46
+ /// to shield.
47
+ ///
48
+ /// Returns the proposal, or `nil` if the transparent balance that would be shielded
49
+ /// is zero or below `shieldingThreshold`.
50
+ ///
51
+ /// If `prepare()` hasn't already been called since creation of the synchronizer instance or since the last wipe then this method throws
52
+ /// `SynchronizerErrors.notPrepared`.
53
+ func proposeShielding(
54
+ accountIndex: Int,
55
+ shieldingThreshold: Zatoshi,
56
+ memoBytes: MemoBytes?,
57
+ transparentReceiver: String?
58
+ ) async throws -> Proposal?
59
+
60
+ /// Creates the transactions in the given proposal.
61
+ ///
62
+ /// - Parameter proposal: the proposal for which to create transactions.
63
+ /// - Parameter spendingKey: the `UnifiedSpendingKey` associated with the account for which the proposal was created.
32
64
  /// - Throws:
33
65
  /// - `walletTransEncoderCreateTransactionMissingSaplingParams` if the sapling parameters aren't downloaded.
34
- /// - Some `ZcashError.rust*` if the creation of transaction fails.
35
- func createTransaction(
36
- spendingKey: UnifiedSpendingKey,
37
- zatoshi: Zatoshi,
38
- to address: String,
39
- memoBytes: MemoBytes?,
40
- from accountIndex: Int
41
- ) async throws -> ZcashTransaction.Overview
42
-
43
- /// Creates a transaction that will attempt to shield transparent funds that are present on the blocks cache .throwing
44
- /// an exception whenever things are missing. When the provided wallet implementation doesn't throw an exception,
45
- /// we wrap the issue into a descriptive exception ourselves (rather than using double-bangs for things).
66
+ /// - Some `ZcashError.rust*` if the creation of transaction(s) fails.
67
+ ///
68
+ /// If `prepare()` hasn't already been called since creation of the synchronizer instance or since the last wipe then this method throws
69
+ /// `SynchronizerErrors.notPrepared`.
70
+ func createProposedTransactions(
71
+ proposal: Proposal,
72
+ spendingKey: UnifiedSpendingKey
73
+ ) async throws -> [ZcashTransaction.Overview]
74
+
75
+ /// Creates a transaction proposal to fulfill a [ZIP-321](https://zips.z.cash/zip-0321), throwing an exception whenever things are missing. When the provided wallet implementation
76
+ /// doesn't throw an exception, we wrap the issue into a descriptive exception ourselves (rather than using
77
+ /// double-bangs for things).
46
78
  ///
47
79
  /// - Parameters:
48
- /// - Parameter spendingKey: `UnifiedSpendingKey` to spend the UTXOs
49
- /// - Parameter memoBytes: containing the memo (optional)
50
- /// - Parameter accountIndex: index of the account that will be used to send the funds
80
+ /// - Parameter uri: a valid ZIP-321 payment URI.
81
+ /// - Parameter accountIndex: the index of the account the proposal should be made from.
51
82
  /// - Throws:
52
- /// - `walletTransEncoderShieldFundsMissingSaplingParams` if the sapling parameters aren't downloaded.
83
+ /// - `walletTransEncoderCreateTransactionMissingSaplingParams` if the sapling parameters aren't downloaded.
53
84
  /// - Some `ZcashError.rust*` if the creation of transaction fails.
54
- func createShieldingTransaction(
55
- spendingKey: UnifiedSpendingKey,
56
- shieldingThreshold: Zatoshi,
57
- memoBytes: MemoBytes?,
58
- from accountIndex: Int
59
- ) async throws -> ZcashTransaction.Overview
85
+ func proposeFulfillingPaymentFromURI(
86
+ _ uri: String,
87
+ accountIndex: Int
88
+ ) async throws -> Proposal
60
89
 
61
90
  /// submits a transaction to the Zcash peer-to-peer network.
62
91
  /// - Parameter transaction: a transaction overview
@@ -54,81 +54,72 @@ class WalletTransactionEncoder: TransactionEncoder {
54
54
  logger: initializer.logger
55
55
  )
56
56
  }
57
-
58
- func createTransaction(
59
- spendingKey: UnifiedSpendingKey,
60
- zatoshi: Zatoshi,
61
- to address: String,
62
- memoBytes: MemoBytes?,
63
- from accountIndex: Int
64
- ) async throws -> ZcashTransaction.Overview {
65
- let txId = try await createSpend(
66
- spendingKey: spendingKey,
67
- zatoshi: zatoshi,
68
- to: address,
69
- memoBytes: memoBytes,
70
- from: accountIndex
71
- )
72
57
 
73
- logger.debug("transaction id: \(txId)")
74
- return try await repository.find(rawID: txId)
75
- }
76
-
77
- func createSpend(
78
- spendingKey: UnifiedSpendingKey,
79
- zatoshi: Zatoshi,
80
- to address: String,
81
- memoBytes: MemoBytes?,
82
- from accountIndex: Int
83
- ) async throws -> Data {
84
- guard ensureParams(spend: self.spendParamsURL, output: self.outputParamsURL) else {
85
- throw ZcashError.walletTransEncoderCreateTransactionMissingSaplingParams
86
- }
87
-
88
- let txId = try await rustBackend.createToAddress(
89
- usk: spendingKey,
90
- to: address,
91
- value: zatoshi.amount,
58
+ func proposeTransfer(
59
+ accountIndex: Int,
60
+ recipient: String,
61
+ amount: Zatoshi,
62
+ memoBytes: MemoBytes?
63
+ ) async throws -> Proposal {
64
+ let proposal = try await rustBackend.proposeTransfer(
65
+ account: Int32(accountIndex),
66
+ to: recipient,
67
+ value: amount.amount,
92
68
  memo: memoBytes
93
69
  )
94
70
 
95
- return txId
71
+ return Proposal(inner: proposal)
96
72
  }
97
-
98
- func createShieldingTransaction(
99
- spendingKey: UnifiedSpendingKey,
73
+
74
+ func proposeShielding(
75
+ accountIndex: Int,
100
76
  shieldingThreshold: Zatoshi,
101
77
  memoBytes: MemoBytes?,
102
- from accountIndex: Int
103
- ) async throws -> ZcashTransaction.Overview {
104
- let txId = try await createShieldingSpend(
105
- spendingKey: spendingKey,
106
- shieldingThreshold: shieldingThreshold,
78
+ transparentReceiver: String? = nil
79
+ ) async throws -> Proposal? {
80
+ guard let proposal = try await rustBackend.proposeShielding(
81
+ account: Int32(accountIndex),
107
82
  memo: memoBytes,
108
- accountIndex: accountIndex
109
- )
110
-
111
- logger.debug("transaction id: \(txId)")
112
- return try await repository.find(rawID: txId)
83
+ shieldingThreshold: shieldingThreshold,
84
+ transparentReceiver: transparentReceiver
85
+ ) else { return nil }
86
+
87
+ return Proposal(inner: proposal)
113
88
  }
114
89
 
115
- func createShieldingSpend(
116
- spendingKey: UnifiedSpendingKey,
117
- shieldingThreshold: Zatoshi,
118
- memo: MemoBytes?,
90
+ func proposeFulfillingPaymentFromURI(
91
+ _ uri: String,
119
92
  accountIndex: Int
120
- ) async throws -> Data {
93
+ ) async throws -> Proposal {
94
+ let proposal = try await rustBackend.proposeTransferFromURI(
95
+ uri,
96
+ account: Int32(accountIndex)
97
+ )
98
+ return Proposal(inner: proposal)
99
+ }
100
+
101
+ func createProposedTransactions(
102
+ proposal: Proposal,
103
+ spendingKey: UnifiedSpendingKey
104
+ ) async throws -> [ZcashTransaction.Overview] {
121
105
  guard ensureParams(spend: self.spendParamsURL, output: self.outputParamsURL) else {
122
- throw ZcashError.walletTransEncoderShieldFundsMissingSaplingParams
106
+ throw ZcashError.walletTransEncoderCreateTransactionMissingSaplingParams
123
107
  }
124
-
125
- let txId = try await rustBackend.shieldFunds(
126
- usk: spendingKey,
127
- memo: memo,
128
- shieldingThreshold: shieldingThreshold
108
+
109
+ let txIds = try await rustBackend.createProposedTransactions(
110
+ proposal: proposal.inner,
111
+ usk: spendingKey
129
112
  )
130
-
131
- return txId
113
+
114
+ logger.debug("transaction ids: \(txIds)")
115
+
116
+ var txs: [ZcashTransaction.Overview] = []
117
+
118
+ for txId in txIds {
119
+ txs.append(try await repository.find(rawID: txId))
120
+ }
121
+
122
+ return txs
132
123
  }
133
124
 
134
125
  func submit(
@@ -0,0 +1,21 @@
1
+ //
2
+ // DBActor.swift
3
+ //
4
+ //
5
+ // Created by LukÃĄÅĄ Korba on 04-08-2024.
6
+ //
7
+
8
+ import Foundation
9
+
10
+ /// Global actor used to protect access to the Data DB.
11
+ @globalActor
12
+ enum DBActor {
13
+ typealias ActorType = Actor
14
+
15
+ actor Actor { }
16
+ static let shared = Actor()
17
+
18
+ static var sharedUnownedExecutor: UnownedSerialExecutor {
19
+ shared.unownedExecutor
20
+ }
21
+ }
@@ -16,6 +16,7 @@ public protocol Logger {
16
16
  func event(_ message: String, file: StaticString, function: StaticString, line: Int)
17
17
  func warn(_ message: String, file: StaticString, function: StaticString, line: Int)
18
18
  func error(_ message: String, file: StaticString, function: StaticString, line: Int)
19
+ func sync(_ message: String, file: StaticString, function: StaticString, line: Int)
19
20
  }
20
21
 
21
22
  extension Logger {
@@ -34,6 +35,9 @@ extension Logger {
34
35
  func error(_ message: String, file: StaticString = #file, function: StaticString = #function, line: Int = #line) {
35
36
  error(message, file: file, function: function, line: line)
36
37
  }
38
+ func sync(_ message: String, file: StaticString = #file, function: StaticString = #function, line: Int = #line) {
39
+ sync(message, file: file, function: function, line: line)
40
+ }
37
41
  }
38
42
 
39
43
  /**
@@ -45,4 +49,5 @@ struct NullLogger: Logger {
45
49
  func event(_ message: String, file: StaticString, function: StaticString, line: Int) {}
46
50
  func warn(_ message: String, file: StaticString, function: StaticString, line: Int) {}
47
51
  func error(_ message: String, file: StaticString, function: StaticString, line: Int) {}
52
+ func sync(_ message: String, file: StaticString, function: StaticString, line: Int) {}
48
53
  }
@@ -23,7 +23,11 @@ public class OSLogger: Logger {
23
23
 
24
24
  var level: LogLevel
25
25
 
26
- public init(logLevel: LogLevel, category: String = "logs", alias: ZcashSynchronizerAlias? = nil) {
26
+ public init(
27
+ logLevel: LogLevel,
28
+ category: String = "sdkLogs",
29
+ alias: ZcashSynchronizerAlias? = nil
30
+ ) {
27
31
  self.alias = alias
28
32
  self.level = logLevel
29
33
  if let bundleName = Bundle.main.bundleIdentifier {
@@ -42,19 +46,50 @@ public class OSLogger: Logger {
42
46
  line: Int = #line
43
47
  ) {
44
48
  guard level.rawValue == LogLevel.debug.rawValue else { return }
45
- log(level: "DEBUG 🐞", message: message, file: file, function: function, line: line)
49
+ log(
50
+ level: "DEBUG 🐞",
51
+ logType: .debug,
52
+ message: message,
53
+ file: file,
54
+ function: function,
55
+ line: line
56
+ )
46
57
  }
47
58
 
48
- public func error(
59
+ public func info(
49
60
  _ message: String,
50
61
  file: StaticString = #file,
51
62
  function: StaticString = #function,
52
63
  line: Int = #line
53
64
  ) {
54
- guard level.rawValue <= LogLevel.error.rawValue else { return }
55
- log(level: "ERROR đŸ’Ĩ", message: message, file: file, function: function, line: line)
65
+ guard level.rawValue <= LogLevel.info.rawValue else { return }
66
+ log(
67
+ level: "INFO â„šī¸",
68
+ logType: .info,
69
+ message: message,
70
+ file: file,
71
+ function: function,
72
+ line: line
73
+ )
56
74
  }
57
-
75
+
76
+ public func event(
77
+ _ message: String,
78
+ file: StaticString = #file,
79
+ function: StaticString = #function,
80
+ line: Int = #line
81
+ ) {
82
+ guard level.rawValue <= LogLevel.event.rawValue else { return }
83
+ log(
84
+ level: "EVENT ⏱",
85
+ logType: .default,
86
+ message: message,
87
+ file: file,
88
+ function: function,
89
+ line: line
90
+ )
91
+ }
92
+
58
93
  public func warn(
59
94
  _ message: String,
60
95
  file: StaticString = #file,
@@ -62,31 +97,52 @@ public class OSLogger: Logger {
62
97
  line: Int = #line
63
98
  ) {
64
99
  guard level.rawValue <= LogLevel.warning.rawValue else { return }
65
- log(level: "WARNING âš ī¸", message: message, file: file, function: function, line: line)
100
+ log(
101
+ level: "WARNING âš ī¸",
102
+ logType: .default,
103
+ message: message,
104
+ file: file,
105
+ function: function,
106
+ line: line
107
+ )
66
108
  }
67
109
 
68
- public func event(
110
+ public func error(
69
111
  _ message: String,
70
112
  file: StaticString = #file,
71
113
  function: StaticString = #function,
72
114
  line: Int = #line
73
115
  ) {
74
- guard level.rawValue <= LogLevel.event.rawValue else { return }
75
- log(level: "EVENT ⏱", message: message, file: file, function: function, line: line)
116
+ guard level.rawValue <= LogLevel.error.rawValue else { return }
117
+ log(
118
+ level: "ERROR đŸ’Ĩ",
119
+ logType: .error,
120
+ message: message,
121
+ file: file,
122
+ function: function,
123
+ line: line
124
+ )
76
125
  }
77
126
 
78
- public func info(
127
+ public func sync(
79
128
  _ message: String,
80
129
  file: StaticString = #file,
81
130
  function: StaticString = #function,
82
131
  line: Int = #line
83
132
  ) {
84
- guard level.rawValue <= LogLevel.info.rawValue else { return }
85
- log(level: "INFO â„šī¸", message: message, file: file, function: function, line: line)
133
+ log(
134
+ level: "SYNC_METRIC",
135
+ logType: .info,
136
+ message: message,
137
+ file: file,
138
+ function: function,
139
+ line: line
140
+ )
86
141
  }
87
-
142
+
88
143
  private func log(
89
144
  level: String,
145
+ logType: OSLogType,
90
146
  message: String,
91
147
  file: StaticString = #file,
92
148
  function: StaticString = #function,
@@ -99,6 +155,7 @@ public class OSLogger: Logger {
99
155
  os_log(
100
156
  "[%{public}@] %{public}@ - %{public}@ - Line: %{public}d -> %{public}@",
101
157
  log: oslog,
158
+ type: logType,
102
159
  level,
103
160
  fileName,
104
161
  String(describing: function),