react-native-zcash 0.6.14 → 0.7.1

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 (168) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +1 -0
  3. package/android/build.gradle +4 -4
  4. package/android/src/main/assets/co.electriccoin.zcash/checkpoint/mainnet/2470000.json +8 -0
  5. package/android/src/main/assets/co.electriccoin.zcash/checkpoint/mainnet/2480000.json +8 -0
  6. package/android/src/main/assets/co.electriccoin.zcash/checkpoint/mainnet/2490000.json +8 -0
  7. package/android/src/main/assets/co.electriccoin.zcash/checkpoint/mainnet/2500000.json +8 -0
  8. package/android/src/main/java/app/edge/rnzcash/RNZcashModule.kt +51 -9
  9. package/ios/RNZcash.m +8 -0
  10. package/ios/RNZcash.swift +66 -16
  11. package/ios/ZCashLightClientKit/Block/Actions/DownloadAction.swift +1 -1
  12. package/ios/ZCashLightClientKit/Block/Actions/EnhanceAction.swift +3 -1
  13. package/ios/ZCashLightClientKit/Block/Actions/FetchUTXOsAction.swift +1 -1
  14. package/ios/ZCashLightClientKit/Block/Actions/ProcessSuggestedScanRangesAction.swift +11 -2
  15. package/ios/ZCashLightClientKit/Block/Actions/RewindAction.swift +2 -2
  16. package/ios/ZCashLightClientKit/Block/Actions/ScanAction.swift +28 -11
  17. package/ios/ZCashLightClientKit/Block/Actions/UpdateChainTipAction.swift +4 -4
  18. package/ios/ZCashLightClientKit/Block/Actions/UpdateSubtreeRootsAction.swift +36 -7
  19. package/ios/ZCashLightClientKit/Block/Actions/ValidateServerAction.swift +1 -1
  20. package/ios/ZCashLightClientKit/Block/CompactBlockProcessor.swift +93 -51
  21. package/ios/ZCashLightClientKit/Block/Download/BlockDownloader.swift +0 -26
  22. package/ios/ZCashLightClientKit/Block/Enhance/BlockEnhancer.swift +5 -6
  23. package/ios/ZCashLightClientKit/Block/FetchUnspentTxOutputs/UTXOFetcher.swift +1 -11
  24. package/ios/ZCashLightClientKit/Block/SaplingParameters/SaplingParametersHandler.swift +6 -4
  25. package/ios/ZCashLightClientKit/Block/Scan/BlockScanner.swift +10 -12
  26. package/ios/ZCashLightClientKit/Checkpoint/BundleCheckpointSource.swift +38 -0
  27. package/ios/ZCashLightClientKit/Checkpoint/BundleCheckpointURLProvider.swift +40 -0
  28. package/ios/ZCashLightClientKit/{Constants/Checkpoint+Constants.swift → Checkpoint/Checkpoint+helpers.swift} +1 -33
  29. package/ios/ZCashLightClientKit/Checkpoint/CheckpointSource.swift +34 -0
  30. package/ios/ZCashLightClientKit/Checkpoint/CheckpointSourceFactory.swift +14 -0
  31. package/ios/ZCashLightClientKit/ClosureSynchronizer.swift +61 -6
  32. package/ios/ZCashLightClientKit/CombineSynchronizer.swift +63 -4
  33. package/ios/ZCashLightClientKit/Constants/ZcashSDK.swift +4 -0
  34. package/ios/ZCashLightClientKit/DAO/TransactionDao.swift +21 -33
  35. package/ios/ZCashLightClientKit/DAO/UnspentTransactionOutputDao.swift +0 -182
  36. package/ios/ZCashLightClientKit/Entity/AccountEntity.swift +0 -173
  37. package/ios/ZCashLightClientKit/Entity/TransactionEntity.swift +5 -2
  38. package/ios/ZCashLightClientKit/Error/Sourcery/generateErrorCode.sh +1 -1
  39. package/ios/ZCashLightClientKit/Error/ZcashError.swift +53 -1
  40. package/ios/ZCashLightClientKit/Error/ZcashErrorCode.swift +19 -1
  41. package/ios/ZCashLightClientKit/Error/ZcashErrorCodeDefinition.swift +32 -0
  42. package/ios/ZCashLightClientKit/Initializer.swift +8 -17
  43. package/ios/ZCashLightClientKit/Metrics/SDKMetrics.swift +103 -217
  44. package/ios/ZCashLightClientKit/Model/Proposal.swift +45 -0
  45. package/ios/ZCashLightClientKit/Model/ScanSummary.swift +14 -0
  46. package/ios/ZCashLightClientKit/Model/WalletSummary.swift +58 -0
  47. package/ios/ZCashLightClientKit/Model/WalletTypes.swift +0 -16
  48. package/ios/ZCashLightClientKit/Modules/Service/GRPC/LightWalletGRPCService.swift +5 -3
  49. package/ios/ZCashLightClientKit/Modules/Service/GRPC/ProtoBuf/proposal.pb.swift +934 -0
  50. package/ios/ZCashLightClientKit/Modules/Service/GRPC/ProtoBuf/proto/proposal.proto +138 -0
  51. package/ios/ZCashLightClientKit/Modules/Service/LightWalletService.swift +2 -4
  52. package/ios/ZCashLightClientKit/Providers/LatestBlocksDataProvider.swift +9 -1
  53. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2272500.json +8 -0
  54. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2275000.json +8 -0
  55. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2277500.json +8 -0
  56. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2282500.json +8 -0
  57. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2285000.json +8 -0
  58. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2287500.json +8 -0
  59. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2292500.json +8 -0
  60. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2295000.json +8 -0
  61. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2297500.json +8 -0
  62. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2302500.json +8 -0
  63. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2305000.json +8 -0
  64. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2307500.json +8 -0
  65. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2312500.json +8 -0
  66. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2315000.json +8 -0
  67. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2317500.json +8 -0
  68. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2322500.json +8 -0
  69. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2325000.json +8 -0
  70. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2327500.json +8 -0
  71. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2332500.json +8 -0
  72. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2335000.json +8 -0
  73. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2337500.json +8 -0
  74. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2342500.json +8 -0
  75. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2345000.json +8 -0
  76. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2347500.json +8 -0
  77. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2352500.json +8 -0
  78. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2355000.json +8 -0
  79. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2357500.json +8 -0
  80. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2362500.json +8 -0
  81. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2365000.json +8 -0
  82. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2367500.json +8 -0
  83. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2372500.json +8 -0
  84. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2375000.json +8 -0
  85. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2377500.json +8 -0
  86. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2382500.json +8 -0
  87. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2385000.json +8 -0
  88. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2387500.json +8 -0
  89. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2392500.json +8 -0
  90. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2395000.json +8 -0
  91. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2397500.json +8 -0
  92. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2402500.json +8 -0
  93. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2405000.json +8 -0
  94. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2407500.json +8 -0
  95. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2412500.json +8 -0
  96. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2415000.json +8 -0
  97. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2417500.json +8 -0
  98. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2422500.json +8 -0
  99. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2425000.json +8 -0
  100. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2427500.json +8 -0
  101. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2432500.json +8 -0
  102. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2435000.json +8 -0
  103. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2437500.json +8 -0
  104. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2442500.json +8 -0
  105. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2445000.json +8 -0
  106. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2447500.json +8 -0
  107. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2452500.json +8 -0
  108. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2455000.json +8 -0
  109. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2457500.json +8 -0
  110. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2462500.json +8 -0
  111. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2465000.json +8 -0
  112. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2467500.json +8 -0
  113. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2470000.json +8 -0
  114. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2472500.json +8 -0
  115. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2480000.json +8 -0
  116. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2490000.json +8 -0
  117. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2500000.json +8 -0
  118. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2560000.json +8 -0
  119. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2570000.json +8 -0
  120. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2580000.json +8 -0
  121. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2590000.json +8 -0
  122. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2600000.json +8 -0
  123. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2610000.json +8 -0
  124. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2620000.json +8 -0
  125. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2630000.json +8 -0
  126. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2640000.json +8 -0
  127. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2650000.json +8 -0
  128. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2660000.json +8 -0
  129. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2670000.json +8 -0
  130. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2680000.json +8 -0
  131. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2690000.json +8 -0
  132. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2700000.json +8 -0
  133. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2710000.json +8 -0
  134. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2720000.json +8 -0
  135. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2730000.json +8 -0
  136. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2740000.json +8 -0
  137. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2750000.json +8 -0
  138. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2760000.json +8 -0
  139. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2770000.json +8 -0
  140. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2780000.json +8 -0
  141. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2790000.json +8 -0
  142. package/ios/ZCashLightClientKit/Rust/ZcashKeyDerivationBackend.swift +1 -5
  143. package/ios/ZCashLightClientKit/Rust/ZcashRustBackend.swift +327 -153
  144. package/ios/ZCashLightClientKit/Rust/ZcashRustBackendWelding.swift +78 -36
  145. package/ios/ZCashLightClientKit/Rust/zcashlc.h +402 -118
  146. package/ios/ZCashLightClientKit/Synchronizer/ClosureSDKSynchronizer.swift +43 -14
  147. package/ios/ZCashLightClientKit/Synchronizer/CombineSDKSynchronizer.swift +52 -14
  148. package/ios/ZCashLightClientKit/Synchronizer/Dependencies.swift +10 -6
  149. package/ios/ZCashLightClientKit/Synchronizer/SDKSynchronizer.swift +220 -70
  150. package/ios/ZCashLightClientKit/Synchronizer.swift +105 -29
  151. package/ios/ZCashLightClientKit/Transaction/TransactionEncoder.swift +61 -32
  152. package/ios/ZCashLightClientKit/Transaction/WalletTransactionEncoder.swift +52 -61
  153. package/ios/ZCashLightClientKit/Utils/DBActor.swift +21 -0
  154. package/ios/ZCashLightClientKit/Utils/LoggingProxy.swift +5 -0
  155. package/ios/ZCashLightClientKit/Utils/OSLogger.swift +71 -14
  156. package/ios/libzcashlc.xcframework/ios-arm64/libzcashlc.a +0 -0
  157. package/ios/libzcashlc.xcframework/ios-arm64_x86_64-simulator/libzcashlc.a +0 -0
  158. package/lib/rnzcash.rn.js +21 -6
  159. package/lib/rnzcash.rn.js.map +1 -1
  160. package/lib/src/react-native.d.ts +2 -1
  161. package/lib/src/types.d.ts +9 -1
  162. package/package.json +1 -1
  163. package/react-native-zcash.podspec +1 -1
  164. package/src/react-native.ts +23 -4
  165. package/src/types.ts +10 -1
  166. package/ios/ZCashLightClientKit/Model/ScanProgress.swift +0 -29
  167. package/ios/ZCashLightClientKit/Repository/UnspentTransactionOutputRepository.swift +0 -16
  168. /package/ios/ZCashLightClientKit/{Model → Checkpoint}/Checkpoint.swift +0 -0
@@ -36,6 +36,64 @@ public protocol ClosureSynchronizer {
36
36
  func getUnifiedAddress(accountIndex: Int, completion: @escaping (Result<UnifiedAddress, Error>) -> Void)
37
37
  func getTransparentAddress(accountIndex: Int, completion: @escaping (Result<TransparentAddress, Error>) -> Void)
38
38
 
39
+ /// Creates a proposal for transferring funds to the given recipient.
40
+ ///
41
+ /// - Parameter accountIndex: the account from which to transfer funds.
42
+ /// - Parameter recipient: the recipient's address.
43
+ /// - Parameter amount: the amount to send in Zatoshi.
44
+ /// - 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.
45
+ ///
46
+ /// If `prepare()` hasn't already been called since creation of the synchronizer instance or since the last wipe then this method throws
47
+ /// `SynchronizerErrors.notPrepared`.
48
+ func proposeTransfer(
49
+ accountIndex: Int,
50
+ recipient: Recipient,
51
+ amount: Zatoshi,
52
+ memo: Memo?,
53
+ completion: @escaping (Result<Proposal, Error>) -> Void
54
+ )
55
+
56
+ /// Creates a proposal for shielding any transparent funds received by the given account.
57
+ ///
58
+ /// - Parameter accountIndex: the account for which to shield funds.
59
+ /// - Parameter shieldingThreshold: the minimum transparent balance required before a proposal will be created.
60
+ /// - Parameter memo: an optional memo to include as part of the proposal's transactions.
61
+ /// - Parameter transparentReceiver: a specific transparent receiver within the account
62
+ /// that should be the source of transparent funds. Default is `nil` which
63
+ /// will select whichever of the account's transparent receivers has funds
64
+ /// to shield.
65
+ ///
66
+ /// Returns the proposal, or `nil` if the transparent balance that would be shielded
67
+ /// is zero or below `shieldingThreshold`.
68
+ ///
69
+ /// If `prepare()` hasn't already been called since creation of the synchronizer instance or since the last wipe then this method throws
70
+ /// `SynchronizerErrors.notPrepared`.
71
+ func proposeShielding(
72
+ accountIndex: Int,
73
+ shieldingThreshold: Zatoshi,
74
+ memo: Memo,
75
+ transparentReceiver: TransparentAddress?,
76
+ completion: @escaping (Result<Proposal?, Error>) -> Void
77
+ )
78
+
79
+ /// Creates the transactions in the given proposal.
80
+ ///
81
+ /// - Parameter proposal: the proposal for which to create transactions.
82
+ /// - Parameter spendingKey: the `UnifiedSpendingKey` associated with the account for which the proposal was created.
83
+ ///
84
+ /// Returns a stream of objects for the transactions that were created as part of the
85
+ /// proposal, indicating whether they were submitted to the network or if an error
86
+ /// occurred.
87
+ ///
88
+ /// If `prepare()` hasn't already been called since creation of the synchronizer instance
89
+ /// or since the last wipe then this method throws `SynchronizerErrors.notPrepared`.
90
+ func createProposedTransactions(
91
+ proposal: Proposal,
92
+ spendingKey: UnifiedSpendingKey,
93
+ completion: @escaping (Result<AsyncThrowingStream<TransactionSubmitResult, Error>, Error>) -> Void
94
+ )
95
+
96
+ @available(*, deprecated, message: "Upcoming SDK 2.1 will create multiple transactions at once for some recipients.")
39
97
  func sendToAddress(
40
98
  spendingKey: UnifiedSpendingKey,
41
99
  zatoshi: Zatoshi,
@@ -44,6 +102,7 @@ public protocol ClosureSynchronizer {
44
102
  completion: @escaping (Result<ZcashTransaction.Overview, Error>) -> Void
45
103
  )
46
104
 
105
+ @available(*, deprecated, message: "Upcoming SDK 2.1 will create multiple transactions at once for some recipients.")
47
106
  func shieldFunds(
48
107
  spendingKey: UnifiedSpendingKey,
49
108
  memo: Memo,
@@ -68,12 +127,8 @@ public protocol ClosureSynchronizer {
68
127
 
69
128
  func refreshUTXOs(address: TransparentAddress, from height: BlockHeight, completion: @escaping (Result<RefreshedUTXOs, Error>) -> Void)
70
129
 
71
- func getTransparentBalance(accountIndex: Int, completion: @escaping (Result<WalletBalance, Error>) -> Void)
72
-
73
- func getShieldedBalance(accountIndex: Int, completion: @escaping (Result<Zatoshi, Error>) -> Void)
74
-
75
- func getShieldedVerifiedBalance(accountIndex: Int, completion: @escaping (Result<Zatoshi, Error>) -> Void)
76
-
130
+ func getAccountBalance(accountIndex: Int, completion: @escaping (Result<AccountBalance?, Error>) -> Void)
131
+
77
132
  /*
78
133
  It can be missleading that these two methods are returning Publisher even this protocol is closure based. Reason is that Synchronizer doesn't
79
134
  provide different implementations for these two methods. So Combine it is even here.
@@ -35,19 +35,80 @@ public protocol CombineSynchronizer {
35
35
  func getUnifiedAddress(accountIndex: Int) -> SinglePublisher<UnifiedAddress, Error>
36
36
  func getTransparentAddress(accountIndex: Int) -> SinglePublisher<TransparentAddress, Error>
37
37
 
38
+ /// Creates a proposal for transferring funds to the given recipient.
39
+ ///
40
+ /// - Parameter accountIndex: the account from which to transfer funds.
41
+ /// - Parameter recipient: the recipient's address.
42
+ /// - Parameter amount: the amount to send in Zatoshi.
43
+ /// - 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.
44
+ ///
45
+ /// If `prepare()` hasn't already been called since creation of the synchronizer instance or since the last wipe then this method throws
46
+ /// `SynchronizerErrors.notPrepared`.
47
+ func proposeTransfer(
48
+ accountIndex: Int,
49
+ recipient: Recipient,
50
+ amount: Zatoshi,
51
+ memo: Memo?
52
+ ) -> SinglePublisher<Proposal, Error>
53
+
54
+ /// Creates a proposal for shielding any transparent funds received by the given account.
55
+ ///
56
+ /// - Parameter accountIndex: the account for which to shield funds.
57
+ /// - Parameter shieldingThreshold: the minimum transparent balance required before a proposal will be created.
58
+ /// - Parameter memo: an optional memo to include as part of the proposal's transactions.
59
+ /// - Parameter transparentReceiver: a specific transparent receiver within the account
60
+ /// that should be the source of transparent funds. Default is `nil` which
61
+ /// will select whichever of the account's transparent receivers has funds
62
+ /// to shield.
63
+ ///
64
+ /// Returns the proposal, or `nil` if the transparent balance that would be shielded
65
+ /// is zero or below `shieldingThreshold`.
66
+ ///
67
+ /// If `prepare()` hasn't already been called since creation of the synchronizer instance or since the last wipe then this method throws
68
+ /// `SynchronizerErrors.notPrepared`.
69
+ func proposeShielding(
70
+ accountIndex: Int,
71
+ shieldingThreshold: Zatoshi,
72
+ memo: Memo,
73
+ transparentReceiver: TransparentAddress?
74
+ ) -> SinglePublisher<Proposal?, Error>
75
+
76
+ /// Creates the transactions in the given proposal.
77
+ ///
78
+ /// - Parameter proposal: the proposal for which to create transactions.
79
+ /// - Parameter spendingKey: the `UnifiedSpendingKey` associated with the account for which the proposal was created.
80
+ ///
81
+ /// Returns a stream of objects for the transactions that were created as part of the
82
+ /// proposal, indicating whether they were submitted to the network or if an error
83
+ /// occurred.
84
+ ///
85
+ /// If `prepare()` hasn't already been called since creation of the synchronizer instance
86
+ /// or since the last wipe then this method throws `SynchronizerErrors.notPrepared`.
87
+ func createProposedTransactions(
88
+ proposal: Proposal,
89
+ spendingKey: UnifiedSpendingKey
90
+ ) -> SinglePublisher<AsyncThrowingStream<TransactionSubmitResult, Error>, Error>
91
+
92
+ @available(*, deprecated, message: "Upcoming SDK 2.1 will create multiple transactions at once for some recipients.")
38
93
  func sendToAddress(
39
94
  spendingKey: UnifiedSpendingKey,
40
95
  zatoshi: Zatoshi,
41
96
  toAddress: Recipient,
42
97
  memo: Memo?
43
98
  ) -> SinglePublisher<ZcashTransaction.Overview, Error>
44
-
99
+
100
+ @available(*, deprecated, message: "Upcoming SDK 2.1 will create multiple transactions at once for some recipients. use `proposeShielding:` instead")
45
101
  func shieldFunds(
46
102
  spendingKey: UnifiedSpendingKey,
47
103
  memo: Memo,
48
104
  shieldingThreshold: Zatoshi
49
105
  ) -> SinglePublisher<ZcashTransaction.Overview, Error>
50
106
 
107
+ func proposefulfillingPaymentURI(
108
+ _ uri: String,
109
+ accountIndex: Int
110
+ ) -> SinglePublisher<Proposal, Error>
111
+
51
112
  var allTransactions: SinglePublisher<[ZcashTransaction.Overview], Never> { get }
52
113
  var sentTransactions: SinglePublisher<[ZcashTransaction.Overview], Never> { get }
53
114
  var receivedTransactions: SinglePublisher<[ZcashTransaction.Overview], Never> { get }
@@ -64,9 +125,7 @@ public protocol CombineSynchronizer {
64
125
 
65
126
  func refreshUTXOs(address: TransparentAddress, from height: BlockHeight) -> SinglePublisher<RefreshedUTXOs, Error>
66
127
 
67
- func getTransparentBalance(accountIndex: Int) -> SinglePublisher<WalletBalance, Error>
68
- func getShieldedBalance(accountIndex: Int) -> SinglePublisher<Zatoshi, Error>
69
- func getShieldedVerifiedBalance(accountIndex: Int) -> SinglePublisher<Zatoshi, Error>
128
+ func getAccountBalance(accountIndex: Int) -> SinglePublisher<AccountBalance?, Error>
70
129
 
71
130
  func rewind(_ policy: RewindPolicy) -> CompletablePublisher<Error>
72
131
  func wipe() -> CompletablePublisher<Error>
@@ -105,6 +105,10 @@ public enum ZcashSDK {
105
105
  // TODO: [#1304] smart retry logic, https://github.com/zcash/ZcashLightClientKit/issues/1304
106
106
  public static let defaultRetries = Int.max
107
107
 
108
+ /// The communication errors are usually false positive and another try will continue the work,
109
+ /// in case the service is trully down we cap the amount of retries by this value.
110
+ public static let serviceFailureRetries = 3
111
+
108
112
  /// The default maximum amount of time to wait during retry backoff intervals. Failed loops will never wait longer than
109
113
  /// this before retrying.
110
114
  public static let defaultMaxBackOffInterval: TimeInterval = 600
@@ -8,22 +8,6 @@
8
8
  import Foundation
9
9
  import SQLite
10
10
 
11
- extension Connection {
12
- public func scalarLocked<V: Value>(_ query: ScalarQuery<V?>) throws -> V.ValueType? {
13
- globalDBLock.lock()
14
- defer { globalDBLock.unlock() }
15
-
16
- return try scalar(query)
17
- }
18
-
19
- public func scalarLocked<V: Value>(_ query: ScalarQuery<V>) throws -> V {
20
- globalDBLock.lock()
21
- defer { globalDBLock.unlock() }
22
-
23
- return try scalar(query)
24
- }
25
- }
26
-
27
11
  class TransactionSQLDAO: TransactionRepository {
28
12
  enum NotesTableStructure {
29
13
  static let transactionID = Expression<Int>("tx")
@@ -55,17 +39,19 @@ class TransactionSQLDAO: TransactionRepository {
55
39
  true
56
40
  }
57
41
 
42
+ @DBActor
58
43
  func countAll() async throws -> Int {
59
44
  do {
60
- return try connection().scalarLocked(transactionsView.count)
45
+ return try connection().scalar(transactionsView.count)
61
46
  } catch {
62
47
  throw ZcashError.transactionRepositoryCountAll(error)
63
48
  }
64
49
  }
65
50
 
51
+ @DBActor
66
52
  func countUnmined() async throws -> Int {
67
53
  do {
68
- return try connection().scalarLocked(transactionsView.filter(ZcashTransaction.Overview.Column.minedHeight == nil).count)
54
+ return try connection().scalar(transactionsView.filter(ZcashTransaction.Overview.Column.minedHeight == nil).count)
69
55
  } catch {
70
56
  throw ZcashError.transactionRepositoryCountUnmined(error)
71
57
  }
@@ -76,7 +62,7 @@ class TransactionSQLDAO: TransactionRepository {
76
62
  .filter(ZcashTransaction.Overview.Column.rawID == Blob(bytes: rawID.bytes))
77
63
  .limit(1)
78
64
 
79
- return try execute(query) { try ZcashTransaction.Overview(row: $0) }
65
+ return try await execute(query) { try ZcashTransaction.Overview(row: $0) }
80
66
  }
81
67
 
82
68
  func find(offset: Int, limit: Int, kind: TransactionKind) async throws -> [ZcashTransaction.Overview] {
@@ -85,7 +71,7 @@ class TransactionSQLDAO: TransactionRepository {
85
71
  .filterQueryFor(kind: kind)
86
72
  .limit(limit, offset: offset)
87
73
 
88
- return try execute(query) { try ZcashTransaction.Overview(row: $0) }
74
+ return try await execute(query) { try ZcashTransaction.Overview(row: $0) }
89
75
  }
90
76
 
91
77
  func find(in range: CompactBlockRange, limit: Int, kind: TransactionKind) async throws -> [ZcashTransaction.Overview] {
@@ -98,7 +84,7 @@ class TransactionSQLDAO: TransactionRepository {
98
84
  .filterQueryFor(kind: kind)
99
85
  .limit(limit)
100
86
 
101
- return try execute(query) { try ZcashTransaction.Overview(row: $0) }
87
+ return try await execute(query) { try ZcashTransaction.Overview(row: $0) }
102
88
  }
103
89
 
104
90
  func find(from transaction: ZcashTransaction.Overview, limit: Int, kind: TransactionKind) async throws -> [ZcashTransaction.Overview] {
@@ -119,7 +105,7 @@ class TransactionSQLDAO: TransactionRepository {
119
105
  .filterQueryFor(kind: kind)
120
106
  .limit(limit)
121
107
 
122
- return try execute(query) { try ZcashTransaction.Overview(row: $0) }
108
+ return try await execute(query) { try ZcashTransaction.Overview(row: $0) }
123
109
  }
124
110
 
125
111
  func findReceived(offset: Int, limit: Int) async throws -> [ZcashTransaction.Overview] {
@@ -128,7 +114,7 @@ class TransactionSQLDAO: TransactionRepository {
128
114
  .order((ZcashTransaction.Overview.Column.minedHeight ?? BlockHeight.max).desc)
129
115
  .limit(limit, offset: offset)
130
116
 
131
- return try execute(query) { try ZcashTransaction.Overview(row: $0) }
117
+ return try await execute(query) { try ZcashTransaction.Overview(row: $0) }
132
118
  }
133
119
 
134
120
  func findSent(offset: Int, limit: Int) async throws -> [ZcashTransaction.Overview] {
@@ -137,7 +123,7 @@ class TransactionSQLDAO: TransactionRepository {
137
123
  .order((ZcashTransaction.Overview.Column.minedHeight ?? BlockHeight.max).desc)
138
124
  .limit(limit, offset: offset)
139
125
 
140
- return try execute(query) { try ZcashTransaction.Overview(row: $0) }
126
+ return try await execute(query) { try ZcashTransaction.Overview(row: $0) }
141
127
  }
142
128
 
143
129
  func findPendingTransactions(latestHeight: BlockHeight, offset: Int, limit: Int) async throws -> [ZcashTransaction.Overview] {
@@ -146,7 +132,7 @@ class TransactionSQLDAO: TransactionRepository {
146
132
  .order((ZcashTransaction.Overview.Column.minedHeight ?? BlockHeight.max).desc)
147
133
  .limit(limit, offset: offset)
148
134
 
149
- return try execute(query) { try ZcashTransaction.Overview(row: $0) }
135
+ return try await execute(query) { try ZcashTransaction.Overview(row: $0) }
150
136
  }
151
137
 
152
138
  func findMemos(for transaction: ZcashTransaction.Overview) async throws -> [Memo] {
@@ -162,23 +148,25 @@ class TransactionSQLDAO: TransactionRepository {
162
148
  let query = self.txOutputsView
163
149
  .filter(ZcashTransaction.Output.Column.rawID == Blob(bytes: rawID.bytes))
164
150
 
165
- return try execute(query) { try ZcashTransaction.Output(row: $0) }
151
+ return try await execute(query) { try ZcashTransaction.Output(row: $0) }
166
152
  }
167
153
 
168
154
  func getRecipients(for rawID: Data) async throws -> [TransactionRecipient] {
169
155
  try await getTransactionOutputs(for: rawID).map { $0.recipient }
170
156
  }
171
157
 
172
- private func execute<Entity>(_ query: View, createEntity: (Row) throws -> Entity) throws -> Entity {
173
- let entities: [Entity] = try execute(query, createEntity: createEntity)
174
- guard let entity = entities.first else { throw ZcashError.transactionRepositoryEntityNotFound }
158
+ private func execute<Entity>(_ query: View, createEntity: (Row) throws -> Entity) async throws -> Entity {
159
+ let entities: [Entity] = try await execute(query, createEntity: createEntity)
160
+
161
+ guard let entity = entities.first else {
162
+ throw ZcashError.transactionRepositoryEntityNotFound
163
+ }
164
+
175
165
  return entity
176
166
  }
177
167
 
178
- private func execute<Entity>(_ query: View, createEntity: (Row) throws -> Entity) throws -> [Entity] {
179
- globalDBLock.lock()
180
- defer { globalDBLock.unlock() }
181
-
168
+ @DBActor
169
+ private func execute<Entity>(_ query: View, createEntity: (Row) throws -> Entity) async throws -> [Entity] {
182
170
  do {
183
171
  let entities = try connection()
184
172
  .prepare(query)
@@ -8,25 +8,12 @@
8
8
  import Foundation
9
9
 
10
10
  struct UTXO: Decodable, Encodable {
11
- enum CodingKeys: String, CodingKey {
12
- case id = "id_utxo"
13
- case address
14
- case prevoutTxId = "prevout_txid"
15
- case prevoutIndex = "prevout_idx"
16
- case script
17
- case valueZat = "value_zat"
18
- case height
19
- case spentInTx = "spent_in_tx"
20
- }
21
-
22
- let id: Int?
23
11
  let address: String
24
12
  var prevoutTxId: Data
25
13
  var prevoutIndex: Int
26
14
  let script: Data
27
15
  let valueZat: Int
28
16
  let height: Int
29
- let spentInTx: Int?
30
17
  }
31
18
 
32
19
  extension UTXO: UnspentTransactionOutputEntity {
@@ -48,172 +35,3 @@ extension UTXO: UnspentTransactionOutputEntity {
48
35
  }
49
36
  }
50
37
  }
51
-
52
- extension UnspentTransactionOutputEntity {
53
- /**
54
- As UTXO, with id and spentIntTx set to __nil__
55
- */
56
- func asUTXO() -> UTXO {
57
- UTXO(
58
- id: nil,
59
- address: address,
60
- prevoutTxId: txid,
61
- prevoutIndex: index,
62
- script: script,
63
- valueZat: valueZat,
64
- height: height,
65
- spentInTx: nil
66
- )
67
- }
68
- }
69
- import SQLite
70
- class UnspentTransactionOutputSQLDAO: UnspentTransactionOutputRepository {
71
- enum TableColumns {
72
- static let id = Expression<Int>("id_utxo")
73
- static let address = Expression<String>("address")
74
- static let txid = Expression<Blob>("prevout_txid")
75
- static let index = Expression<Int>("prevout_idx")
76
- static let script = Expression<Blob>("script")
77
- static let valueZat = Expression<Int>("value_zat")
78
- static let height = Expression<Int>("height")
79
- static let spentInTx = Expression<Int?>("spent_in_tx")
80
- }
81
-
82
- let table = Table("utxos")
83
-
84
- let dbProvider: ConnectionProvider
85
-
86
- init(dbProvider: ConnectionProvider) {
87
- self.dbProvider = dbProvider
88
- }
89
-
90
- /// - Throws: `unspentTransactionOutputDAOCreateTable` if creation table fails.
91
- func initialise() async throws {
92
- try await createTableIfNeeded()
93
- }
94
-
95
- private func createTableIfNeeded() async throws {
96
- let stringStatement =
97
- """
98
- CREATE TABLE IF NOT EXISTS utxos (
99
- id_utxo INTEGER PRIMARY KEY,
100
- address TEXT NOT NULL,
101
- prevout_txid BLOB NOT NULL,
102
- prevout_idx INTEGER NOT NULL,
103
- script BLOB NOT NULL,
104
- value_zat INTEGER NOT NULL,
105
- height INTEGER NOT NULL,
106
- spent_in_tx INTEGER,
107
- FOREIGN KEY (spent_in_tx) REFERENCES transactions(id_tx),
108
- CONSTRAINT tx_outpoint UNIQUE (prevout_txid, prevout_idx)
109
- )
110
- """
111
- do {
112
- globalDBLock.lock()
113
- defer { globalDBLock.unlock() }
114
-
115
- try dbProvider.connection().run(stringStatement)
116
- } catch {
117
- throw ZcashError.unspentTransactionOutputDAOCreateTable(error)
118
- }
119
- }
120
-
121
- /// - Throws: `unspentTransactionOutputDAOStore` if sqlite query fails.
122
- func store(utxos: [UnspentTransactionOutputEntity]) async throws {
123
- do {
124
- globalDBLock.lock()
125
- defer { globalDBLock.unlock() }
126
-
127
- let db = try dbProvider.connection()
128
- try db.transaction {
129
- for utxo in utxos.map({ $0 as? UTXO ?? $0.asUTXO() }) {
130
- try db.run(table.insert(utxo))
131
- }
132
- }
133
- } catch {
134
- throw ZcashError.unspentTransactionOutputDAOStore(error)
135
- }
136
- }
137
-
138
- /// - Throws: `unspentTransactionOutputDAOClearAll` if sqlite query fails.
139
- func clearAll(address: String?) async throws {
140
- do {
141
- globalDBLock.lock()
142
- defer { globalDBLock.unlock() }
143
-
144
- if let tAddr = address {
145
- try dbProvider.connection().run(table.filter(TableColumns.address == tAddr).delete())
146
- } else {
147
- try dbProvider.connection().run(table.delete())
148
- }
149
- } catch {
150
- throw ZcashError.unspentTransactionOutputDAOClearAll(error)
151
- }
152
- }
153
-
154
- /// - Throws:
155
- /// - `unspentTransactionOutputDAOClearAll` if the data fetched from the DB can't be decoded to `UTXO` object.
156
- /// - `unspentTransactionOutputDAOGetAll` if sqlite query fails.
157
- func getAll(address: String?) async throws -> [UnspentTransactionOutputEntity] {
158
- do {
159
- if let tAddress = address {
160
- let allTxs: [UTXO] = try dbProvider.connection()
161
- .prepare(table.filter(TableColumns.address == tAddress))
162
- .map { row in
163
- do {
164
- return try row.decode()
165
- } catch {
166
- throw ZcashError.unspentTransactionOutputDAOGetAllCantDecode(error)
167
- }
168
- }
169
- return allTxs
170
- } else {
171
- let allTxs: [UTXO] = try dbProvider.connection()
172
- .prepare(table)
173
- .map { row in
174
- try row.decode()
175
- }
176
- return allTxs
177
- }
178
- } catch {
179
- if let error = error as? ZcashError {
180
- throw error
181
- } else {
182
- throw ZcashError.unspentTransactionOutputDAOGetAll(error)
183
- }
184
- }
185
- }
186
-
187
- /// - Throws: `unspentTransactionOutputDAOBalance` if sqlite query fails.
188
- func balance(address: String, latestHeight: BlockHeight) async throws -> WalletBalance {
189
- do {
190
- let verified = try dbProvider.connection().scalarLocked(
191
- table.select(TableColumns.valueZat.sum)
192
- .filter(TableColumns.address == address)
193
- .filter(TableColumns.height <= latestHeight - ZcashSDK.defaultStaleTolerance)
194
- ) ?? 0
195
- let total = try dbProvider.connection().scalarLocked(
196
- table.select(TableColumns.valueZat.sum)
197
- .filter(TableColumns.address == address)
198
- ) ?? 0
199
-
200
- return WalletBalance(
201
- verified: Zatoshi(Int64(verified)),
202
- total: Zatoshi(Int64(total))
203
- )
204
- } catch {
205
- throw ZcashError.unspentTransactionOutputDAOBalance(error)
206
- }
207
- }
208
- }
209
-
210
- struct TransparentBalance {
211
- var balance: WalletBalance
212
- var address: String
213
- }
214
-
215
- enum UTXORepositoryBuilder {
216
- static func build(initializer: Initializer) -> UnspentTransactionOutputRepository {
217
- return UnspentTransactionOutputSQLDAO(dbProvider: SimpleConnectionProvider(path: initializer.dataDbURL.path))
218
- }
219
- }