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
package/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.7.0 (2024-04-22)
6
+
7
+ - added: Support Orchard pool
8
+ - added: Support ZIP-317 fees
9
+ - changed: (Android) Upgrade zcash-android-sdk to v2.1.0
10
+ - changed: (iOS) Upgrade zcash-swift-wallet-sdk to v2.1.5
11
+ - changed: Updated checkpoints
12
+
13
+ ## 0.6.14 (2024-04-12)
14
+
15
+ - fixed: Include missing Rust header file.
16
+
5
17
  ## 0.6.13 (2024-04-12)
6
18
 
7
19
  - fixed: Update the packaging scripts to clean leftover files.
@@ -45,12 +45,12 @@ dependencies {
45
45
  implementation 'com.facebook.react:react-native:+'
46
46
 
47
47
  // Compiler plugin for Room annotation support:
48
- kapt 'androidx.room:room-compiler:2.3.0'
48
+ kapt 'androidx.room:room-compiler:2.5.1'
49
49
 
50
- implementation 'androidx.appcompat:appcompat:1.4.1'
50
+ implementation 'androidx.appcompat:appcompat:1.6.1'
51
51
  implementation 'androidx.paging:paging-runtime-ktx:2.1.2'
52
- implementation 'cash.z.ecc.android:zcash-android-sdk:2.0.1'
53
- implementation 'cash.z.ecc.android:zcash-android-sdk-incubator:2.0.1'
52
+ implementation 'cash.z.ecc.android:zcash-android-sdk:2.1.0'
53
+ implementation 'cash.z.ecc.android:zcash-android-sdk-incubator:2.1.0'
54
54
  implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3"
55
55
  implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3"
56
56
  }
@@ -0,0 +1,8 @@
1
+ {
2
+ "network": "main",
3
+ "height": "2470000",
4
+ "hash": "000000000075b3a97ae9743e0bd3c08c704260c36a4bbfa6afc4baef1b1a04cb",
5
+ "time": 1713034443,
6
+ "saplingTree": "0163c99ed4e459cddcec67a85ea52be38666dd5759e5d335bc56ee26772c5fb81a001a000001483d8ab93ab8d9cd2f59fe85fbc10a173289f44bd23ed9ab0a27f9d7a5ec393b01416578326834c62775610da56b8fce12a2d3de4f9548559689016462f00379630001d831b91c6d25e49e000182144353c256a3ea80496209e496fd9200c487a46e2b01d8f20b7f6c982b7adbdf7a1c5028f760e7123af82bbf7e66542bb7322e3fc92800015ba0bd2b1b6c7bde0dd6a4ffac86bba86abc2938415d57d8cf3c4f70376d902f000001f5b1b613f54794f437ed0a2b77e4fe97ecefb18c2476bf5d3ec87f3c94903d2901067187080be7f0b7273e4331b7505d7c985974c9c461fa602d80cc999289432501e3644c42c5d7ecd832a2c662dcd397824930ebe37b37bc61ec5af84f724c2571000132c525343fc4ebe79ab6515e9d9fceb916d920394bad5926a1afe7f46badef420001d1b36bbba8e6e1be8f09baf2b829bafc4ccd89ad25fb730d2b8a995b60fc3a6701d8ccea507421a590ed38116b834189cdc22421b4764179fa4e364803dfa66d56018cf6f5034a55fed59d1d832620916a43c756d2379e50ef9440fc4c3e7a29aa2300011619f99023a69bb647eab2d2aa1a73c3673c74bb033c3c4930eacda19e6fd93b0000000160272b134ca494b602137d89e528c751c06d3ef4a87a45f33af343c15060cc1e",
7
+ "orchardTree": "01d55eef517b7c62fa57229ff715d585c230dc206a10bc9b1bbbf62d0078f25f1f001f000109a4066c261033c9a8abcf6ad56fca73f2af97b5f35bc26830b934ef728fd31500013aef4b4b3e74e991b27731803a64d511171a12bc4061cc42c1cc95d1d9047c340000000156f8dd022692afceae0cc5507a36dc2b92884a365694bde5ed3dbb696d0c9b000001c46f981379e9f178d47f609374ca4ef05bd411d838bf9e675f6246b0c1da521f010d2fb3b0880ce34e264318a8faeace5e051b47afcbcba1edfab81aa66bd7ff2f00000001be7e4675134c4441539879962acf4c9ce2523471c82f11a2bfe90d910e5ac11901d386508c9fabdc60836bfe3c7251fcbdd4617180a804d40fa29dc25fb9c0aa3401cf3bf92f69798e68555548afcce1648add1fb2548d64fa9a1ec22a3e26e7890101e637281deb58dff0c44ba13149b784a95da1b493005efd057e6f4ac20ef5d81d000001cc2dcaa338b312112db04b435a706d63244dd435238f0aa1e9e1598d35470810012dcc4273c8a0ed2337ecf7879380a07e7d427c7f9d82e538002bd1442978402c01daf63debf5b40df902dae98dadc029f281474d190cddecef1b10653248a234150001e2bca6a8d987d668defba89dc082196a922634ed88e065c669e526bb8815ee1b000000000000"
8
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "network": "main",
3
+ "height": "2480000",
4
+ "hash": "0000000000c9d82d89812e8dd92035a21014979a15f663fc47a3e36d1e9b5999",
5
+ "time": 1713789086,
6
+ "saplingTree": "016764311f2bcdc08178b70c45f2e0036e7415748abae5d283abf678ea993b385b0122147fa534811350be14f8128c36ae9748fe8b9348664d416f51185cc4771b491a01fcad5b9796a4e485473ff204e651721b8d201a07d497af24ee406c6e63b2ac1201b25001f285610ec59bc277e9caa360738d2d184a952358192721d4238f4ad2310148ce5a2c88f987b9c7a2994a046613a6de26f8274cd2037ca0754e6812248736017a705085e7f0d3e22e2e456b53fe3f478110ef8cf03325aa0a58974dbe257a68000105382ab4538fcc9cd96ea85754f12b48c52c0b453b09e97749c4b7559f1fd20101dbca9b9a6301c072b891237ef43a80a59bd9dd9148538b40ffd995f5cc4f9a50000156b0ed98cda39d7e743782d5fa1742982377b9e59e8c67e2231f024d416d596101fafaacfbbd8774b6d01b3ff414e8613c8102c09e4b19162b4e35b8f7b51feb6e01ea04ea034fd3c1b70d410a22e513c055c5483588af5cda888abd76040b8fd12701f5b1b613f54794f437ed0a2b77e4fe97ecefb18c2476bf5d3ec87f3c94903d2901067187080be7f0b7273e4331b7505d7c985974c9c461fa602d80cc999289432501e3644c42c5d7ecd832a2c662dcd397824930ebe37b37bc61ec5af84f724c2571000132c525343fc4ebe79ab6515e9d9fceb916d920394bad5926a1afe7f46badef420001d1b36bbba8e6e1be8f09baf2b829bafc4ccd89ad25fb730d2b8a995b60fc3a6701d8ccea507421a590ed38116b834189cdc22421b4764179fa4e364803dfa66d56018cf6f5034a55fed59d1d832620916a43c756d2379e50ef9440fc4c3e7a29aa2300011619f99023a69bb647eab2d2aa1a73c3673c74bb033c3c4930eacda19e6fd93b0000000160272b134ca494b602137d89e528c751c06d3ef4a87a45f33af343c15060cc1e",
7
+ "orchardTree": "01437c83292178db1c0adb262eab5ce220269f2c55523ee427413bf30a0f594f1a0196022aec683abc3de284a9cc85186347c419610970cf8bf00acbad0924d73d3e1f0196bfd1734a258888c224a7b39c75e44e0d8ccfddb272b65b3cb91cf039a7031401f4e3bf0855258c2752008afb4c7f8334521379087cec2745b810f0a230305e1b000000012e329c7688092669ad8be25844685dee10810959e91e4d01164b8ccd18474a3301ab5bf46915e350066d80126c6ec36ac4c5d09d3afdca9304ee4f6383fece272c01ed5675ead46b058d3a6f4062e88f59500a5ecc9d235c9d33e0da7079d6ebbb0c01c119e15e2a70c3bc260295fe011d91c7d2d263855e253b8b10f181150640803a01ff08f5bb1e2ae3b402ef21e37147c68d743f55b7de2db824185130034e6bf31e00019e4bd7faca983514223540eef98c238cd36e4eb7d81d6273274e8d095611651b000001be7e4675134c4441539879962acf4c9ce2523471c82f11a2bfe90d910e5ac11901d386508c9fabdc60836bfe3c7251fcbdd4617180a804d40fa29dc25fb9c0aa3401cf3bf92f69798e68555548afcce1648add1fb2548d64fa9a1ec22a3e26e7890101e637281deb58dff0c44ba13149b784a95da1b493005efd057e6f4ac20ef5d81d000001cc2dcaa338b312112db04b435a706d63244dd435238f0aa1e9e1598d35470810012dcc4273c8a0ed2337ecf7879380a07e7d427c7f9d82e538002bd1442978402c01daf63debf5b40df902dae98dadc029f281474d190cddecef1b10653248a234150001e2bca6a8d987d668defba89dc082196a922634ed88e065c669e526bb8815ee1b000000000000"
8
+ }
@@ -107,29 +107,37 @@ class RNZcashModule(private val reactContext: ReactApplicationContext) :
107
107
  }
108
108
  }
109
109
  combine(
110
- wallet.transparentBalances,
110
+ wallet.transparentBalance,
111
111
  wallet.saplingBalances,
112
- ) { transparentBalances, saplingBalances ->
113
- return@combine mapOf(
114
- "transparentBalances" to transparentBalances,
115
- "saplingBalances" to saplingBalances,
112
+ wallet.orchardBalances,
113
+ ) { transparentBalance: Zatoshi?, saplingBalances: WalletBalance?, orchardBalances: WalletBalance? ->
114
+ return@combine Balances(
115
+ transparentBalance = transparentBalance,
116
+ saplingBalances = saplingBalances,
117
+ orchardBalances = orchardBalances,
116
118
  )
117
119
  }.collectWith(scope) { map ->
118
- val transparentBalances = map["transparentBalances"]
119
- val saplingBalances = map["saplingBalances"]
120
+ val transparentBalance = map.transparentBalance
121
+ val saplingBalances = map.saplingBalances
122
+ val orchardBalances = map.orchardBalances
120
123
 
121
- val transparentAvailableZatoshi = transparentBalances?.available ?: Zatoshi(0L)
122
- val transparentTotalZatoshi = transparentBalances?.total ?: Zatoshi(0L)
124
+ val transparentAvailableZatoshi = transparentBalance ?: Zatoshi(0L)
125
+ val transparentTotalZatoshi = transparentBalance ?: Zatoshi(0L)
123
126
 
124
127
  val saplingAvailableZatoshi = saplingBalances?.available ?: Zatoshi(0L)
125
128
  val saplingTotalZatoshi = saplingBalances?.total ?: Zatoshi(0L)
126
129
 
130
+ val orchardAvailableZatoshi = orchardBalances?.available ?: Zatoshi(0L)
131
+ val orchardTotalZatoshi = orchardBalances?.total ?: Zatoshi(0L)
132
+
127
133
  sendEvent("BalanceEvent") { args ->
128
134
  args.putString("alias", alias)
129
135
  args.putString("transparentAvailableZatoshi", transparentAvailableZatoshi.value.toString())
130
136
  args.putString("transparentTotalZatoshi", transparentTotalZatoshi.value.toString())
131
137
  args.putString("saplingAvailableZatoshi", saplingAvailableZatoshi.value.toString())
132
138
  args.putString("saplingTotalZatoshi", saplingTotalZatoshi.value.toString())
139
+ args.putString("orchardAvailableZatoshi", orchardAvailableZatoshi.value.toString())
140
+ args.putString("orchardTotalZatoshi", orchardTotalZatoshi.value.toString())
133
141
  }
134
142
  }
135
143
  return@wrap null
@@ -261,6 +269,34 @@ class RNZcashModule(private val reactContext: ReactApplicationContext) :
261
269
  }
262
270
  }
263
271
 
272
+ @ReactMethod
273
+ fun proposeTransfer(
274
+ alias: String,
275
+ zatoshi: String,
276
+ toAddress: String,
277
+ memo: String = "",
278
+ promise: Promise,
279
+ ) {
280
+ val wallet = getWallet(alias)
281
+ wallet.coroutineScope.launch {
282
+ try {
283
+ val proposal =
284
+ wallet.proposeTransfer(
285
+ Account.DEFAULT,
286
+ toAddress,
287
+ Zatoshi(zatoshi.toLong()),
288
+ memo,
289
+ )
290
+ val map = Arguments.createMap()
291
+ map.putInt("transactionCount", proposal.transactionCount())
292
+ map.putString("totalFee", proposal.totalFeeRequired().value.toString())
293
+ promise.resolve(map)
294
+ } catch (t: Throwable) {
295
+ promise.reject("Err", t)
296
+ }
297
+ }
298
+ }
299
+
264
300
  @ReactMethod
265
301
  fun sendToAddress(
266
302
  alias: String,
@@ -411,4 +447,10 @@ class RNZcashModule(private val reactContext: ReactApplicationContext) :
411
447
  sb.append(String.format("%02x", this[i--]))
412
448
  return sb.toString()
413
449
  }
450
+
451
+ data class Balances(
452
+ val transparentBalance: Zatoshi?,
453
+ val saplingBalances: WalletBalance?,
454
+ val orchardBalances: WalletBalance?,
455
+ )
414
456
  }
package/ios/RNZcash.m CHANGED
@@ -36,6 +36,14 @@ resolver:(RCTPromiseResolveBlock)resolve
36
36
  rejecter:(RCTPromiseRejectBlock)reject
37
37
  )
38
38
 
39
+ RCT_EXTERN_METHOD(proposeTransfer:(NSString *)alias
40
+ :(NSString *)zatoshi
41
+ :(NSString *)toAddress
42
+ :(NSString *)memo
43
+ resolver:(RCTPromiseResolveBlock)resolve
44
+ rejecter:(RCTPromiseRejectBlock)reject
45
+ )
46
+
39
47
  RCT_EXTERN_METHOD(sendToAddress:(NSString *)alias
40
48
  :(NSString *)zatoshi
41
49
  :(NSString *)toAddress
package/ios/RNZcash.swift CHANGED
@@ -36,12 +36,16 @@ struct TotalBalances {
36
36
  var transparentTotalZatoshi: Zatoshi
37
37
  var saplingAvailableZatoshi: Zatoshi
38
38
  var saplingTotalZatoshi: Zatoshi
39
+ var orchardAvailableZatoshi: Zatoshi
40
+ var orchardTotalZatoshi: Zatoshi
39
41
  var dictionary: [String: Any] {
40
42
  return [
41
43
  "transparentAvailableZatoshi": String(transparentAvailableZatoshi.amount),
42
44
  "transparentTotalZatoshi": String(transparentTotalZatoshi.amount),
43
45
  "saplingAvailableZatoshi": String(saplingAvailableZatoshi.amount),
44
46
  "saplingTotalZatoshi": String(saplingTotalZatoshi.amount),
47
+ "orchardAvailableZatoshi": String(orchardAvailableZatoshi.amount),
48
+ "orchardTotalZatoshi": String(orchardTotalZatoshi.amount),
45
49
  ]
46
50
  }
47
51
  var nsDictionary: NSDictionary {
@@ -199,6 +203,50 @@ class RNZcash: RCTEventEmitter {
199
203
  }
200
204
  }
201
205
 
206
+ @objc func proposeTransfer(
207
+ _ alias: String, _ zatoshi: String, _ toAddress: String, _ memo: String,
208
+ resolver resolve: @escaping RCTPromiseResolveBlock,
209
+ rejecter reject: @escaping RCTPromiseRejectBlock
210
+ ) {
211
+ Task {
212
+ if let wallet = SynchronizerMap[alias] {
213
+ let amount = Int64(zatoshi)
214
+ if amount == nil {
215
+ reject("ProposeTransferError", "Amount is invalid", genericError)
216
+ return
217
+ }
218
+
219
+ do {
220
+ var sdkMemo: Memo? = nil
221
+ if memo != "" {
222
+ sdkMemo = try Memo(string: memo)
223
+ }
224
+ let proposal = try await wallet.synchronizer.proposeTransfer(
225
+ accountIndex: 0,
226
+ recipient: Recipient(toAddress, network: wallet.synchronizer.network.networkType),
227
+ amount: Zatoshi(amount!),
228
+ memo: sdkMemo
229
+ )
230
+
231
+ let out: NSMutableDictionary = [
232
+ "transactionCount": proposal.transactionCount(),
233
+ "totalFee": String(proposal.totalFeeRequired().amount),
234
+ ]
235
+ resolve(out)
236
+ } catch let error as ZcashError {
237
+ if case .rustCreateToAddress(let message) = error {
238
+ // error message with amounts
239
+ reject("proposeTransferError", message, error)
240
+ } else {
241
+ reject("proposeTransferError", "Failed to propose transfer", error)
242
+ }
243
+ }
244
+ } else {
245
+ reject("ProposeTransferError", "Wallet does not exist", genericError)
246
+ }
247
+ }
248
+ }
249
+
202
250
  @objc func sendToAddress(
203
251
  _ alias: String, _ zatoshi: String, _ toAddress: String, _ memo: String, _ seed: String,
204
252
  resolver resolve: @escaping RCTPromiseResolveBlock,
@@ -426,7 +474,9 @@ class WalletSynchronizer: NSObject {
426
474
  transparentAvailableZatoshi: Zatoshi(0),
427
475
  transparentTotalZatoshi: Zatoshi(0),
428
476
  saplingAvailableZatoshi: Zatoshi(0),
429
- saplingTotalZatoshi: Zatoshi(0))
477
+ saplingTotalZatoshi: Zatoshi(0),
478
+ orchardAvailableZatoshi: Zatoshi(0),
479
+ orchardTotalZatoshi: Zatoshi(0))
430
480
  }
431
481
 
432
482
  public func subscribe() {
@@ -516,32 +566,32 @@ class WalletSynchronizer: NSObject {
516
566
  transparentAvailableZatoshi: Zatoshi(0),
517
567
  transparentTotalZatoshi: Zatoshi(0),
518
568
  saplingAvailableZatoshi: Zatoshi(0),
519
- saplingTotalZatoshi: Zatoshi(0))
569
+ saplingTotalZatoshi: Zatoshi(0),
570
+ orchardAvailableZatoshi: Zatoshi(0),
571
+ orchardTotalZatoshi: Zatoshi(0))
520
572
  }
521
573
 
522
574
  func updateBalanceState(event: SynchronizerState) {
523
- let transparentBalance = event.transparentBalance
524
- let shieldedBalance = event.shieldedBalance
575
+ let transparentBalance = event.accountBalance?.unshielded ?? Zatoshi(0)
576
+ let shieldedBalance = event.accountBalance?.saplingBalance ?? PoolBalance.zero
577
+ let orchardBalance = event.accountBalance?.orchardBalance ?? PoolBalance.zero
525
578
 
526
- let transparentAvailableZatoshi = transparentBalance.verified
527
- let transparentTotalZatoshi = transparentBalance.total
579
+ let transparentAvailableZatoshi = transparentBalance
580
+ let transparentTotalZatoshi = transparentBalance
528
581
 
529
- let saplingAvailableZatoshi = shieldedBalance.verified
530
- let saplingTotalZatoshi = shieldedBalance.total
582
+ let saplingAvailableZatoshi = shieldedBalance.spendableValue
583
+ let saplingTotalZatoshi = shieldedBalance.total()
531
584
 
532
- if transparentAvailableZatoshi == self.balances.transparentAvailableZatoshi
533
- && transparentTotalZatoshi == self.balances.transparentTotalZatoshi
534
- && saplingAvailableZatoshi == self.balances.saplingAvailableZatoshi
535
- && saplingTotalZatoshi == self.balances.saplingTotalZatoshi
536
- {
537
- return
538
- }
585
+ let orchardAvailableZatoshi = orchardBalance.spendableValue
586
+ let orchardTotalZatoshi = orchardBalance.total()
539
587
 
540
588
  self.balances = TotalBalances(
541
589
  transparentAvailableZatoshi: transparentAvailableZatoshi,
542
590
  transparentTotalZatoshi: transparentTotalZatoshi,
543
591
  saplingAvailableZatoshi: saplingAvailableZatoshi,
544
- saplingTotalZatoshi: saplingTotalZatoshi
592
+ saplingTotalZatoshi: saplingTotalZatoshi,
593
+ orchardAvailableZatoshi: orchardAvailableZatoshi,
594
+ orchardTotalZatoshi: orchardTotalZatoshi
545
595
  )
546
596
  let data = NSMutableDictionary(dictionary: self.balances.nsDictionary)
547
597
  data["alias"] = self.alias
@@ -9,7 +9,7 @@ import Foundation
9
9
 
10
10
  final class DownloadAction {
11
11
  let configProvider: CompactBlockProcessor.ConfigProvider
12
- let downloader: BlockDownloader
12
+ var downloader: BlockDownloader
13
13
  let transactionRepository: TransactionRepository
14
14
  let logger: Logger
15
15
 
@@ -8,7 +8,7 @@
8
8
  import Foundation
9
9
 
10
10
  final class EnhanceAction {
11
- let blockEnhancer: BlockEnhancer
11
+ var blockEnhancer: BlockEnhancer
12
12
  let configProvider: CompactBlockProcessor.ConfigProvider
13
13
  let logger: Logger
14
14
 
@@ -88,6 +88,8 @@ extension EnhanceAction: Action {
88
88
  if let transactions {
89
89
  await didUpdate(.foundTransactions(transactions, enhanceRange))
90
90
  }
91
+ } else {
92
+ logger.sync("Action called but skipped for not enough blocks scanned from the last time.")
91
93
  }
92
94
 
93
95
  return await decideWhatToDoNext(context: context, lastScannedHeight: lastScannedHeight)
@@ -8,7 +8,7 @@
8
8
  import Foundation
9
9
 
10
10
  final class FetchUTXOsAction {
11
- let utxoFetcher: UTXOFetcher
11
+ var utxoFetcher: UTXOFetcher
12
12
  let logger: Logger
13
13
 
14
14
  init(container: DIContainer) {
@@ -9,13 +9,15 @@ import Foundation
9
9
 
10
10
  final class ProcessSuggestedScanRangesAction {
11
11
  let rustBackend: ZcashRustBackendWelding
12
- let service: LightWalletService
12
+ var service: LightWalletService
13
13
  let logger: Logger
14
+ let metrics: SDKMetrics
14
15
 
15
16
  init(container: DIContainer) {
16
17
  service = container.resolve(LightWalletService.self)
17
18
  rustBackend = container.resolve(ZcashRustBackendWelding.self)
18
19
  logger = container.resolve(Logger.self)
20
+ metrics = container.resolve(SDKMetrics.self)
19
21
  }
20
22
  }
21
23
 
@@ -23,10 +25,17 @@ extension ProcessSuggestedScanRangesAction: Action {
23
25
  var removeBlocksCacheWhenFailed: Bool { false }
24
26
 
25
27
  func run(with context: ActionContext, didUpdate: @escaping (CompactBlockProcessor.Event) async -> Void) async throws -> ActionContext {
26
- logger.info("Getting the suggested scan ranges from the wallet database.")
28
+ logger.debug("Getting the suggested scan ranges from the wallet database.")
27
29
  let scanRanges = try await rustBackend.suggestScanRanges()
28
30
 
31
+ logger.sync("CALL suggestScanRanges \(scanRanges)")
32
+
33
+ for scanRange in scanRanges {
34
+ metrics.actionDetail("range \(scanRange.priority) \(scanRange.range)", for: .processSuggestedScanRanges)
35
+ }
36
+
29
37
  if let firstRange = scanRanges.first {
38
+ logger.sync("PROCESSING range \(firstRange.priority) \(firstRange.range)")
30
39
  let rangeStartExclusive = firstRange.range.lowerBound - 1
31
40
  let rangeEndInclusive = firstRange.range.upperBound - 1
32
41
 
@@ -8,9 +8,9 @@
8
8
  import Foundation
9
9
 
10
10
  final class RewindAction {
11
- let downloader: BlockDownloader
11
+ var downloader: BlockDownloader
12
12
  let rustBackend: ZcashRustBackendWelding
13
- let downloaderService: BlockDownloaderService
13
+ var downloaderService: BlockDownloaderService
14
14
  let logger: Logger
15
15
 
16
16
  init(container: DIContainer) {
@@ -8,11 +8,16 @@
8
8
  import Foundation
9
9
 
10
10
  final class ScanAction {
11
+ enum Constants {
12
+ static let reportDelay = 5
13
+ }
14
+
11
15
  let configProvider: CompactBlockProcessor.ConfigProvider
12
16
  let blockScanner: BlockScanner
13
17
  let rustBackend: ZcashRustBackendWelding
14
- let latestBlocksDataProvider: LatestBlocksDataProvider
18
+ var latestBlocksDataProvider: LatestBlocksDataProvider
15
19
  let logger: Logger
20
+ var progressReportReducer = 0
16
21
 
17
22
  init(container: DIContainer, configProvider: CompactBlockProcessor.ConfigProvider) {
18
23
  self.configProvider = configProvider
@@ -50,23 +55,33 @@ extension ScanAction: Action {
50
55
  let batchRange = batchRangeStart...batchRangeEnd
51
56
 
52
57
  logger.debug("Starting scan blocks with range: \(batchRange.lowerBound)...\(batchRange.upperBound)")
53
-
58
+ logger.sync("Starting scan blocks with range \(batchRange.lowerBound)...\(batchRange.upperBound)")
59
+
54
60
  do {
55
61
  try await blockScanner.scanBlocks(at: batchRange) { [weak self] lastScannedHeight, increment in
56
62
  let processedHeight = await context.processedHeight
57
- let incrementedprocessedHeight = processedHeight + BlockHeight(increment)
58
- await context.update(processedHeight: incrementedprocessedHeight)
63
+ let incrementedProcessedHeight = processedHeight + BlockHeight(increment)
64
+ await context.update(processedHeight: incrementedProcessedHeight)
59
65
  await self?.latestBlocksDataProvider.updateScannedData()
60
-
66
+
67
+ // ScanAction is controlled locally so it must report back the updated scanned height
68
+ await context.update(lastScannedHeight: lastScannedHeight)
69
+ }
70
+
71
+ // This is a simple change that reduced the synchronization time significantly while affecting the UX only a bit.
72
+ // The frequency of UI progress update is lowered x5 times.
73
+ // Proper solution is handled in
74
+ // TODO: [#1353] Advanced progress reporting, https://github.com/Electric-Coin-Company/zcash-swift-wallet-sdk/issues/1353
75
+ if progressReportReducer == 0 {
61
76
  // report scan progress only if it's available
62
- if let scanProgress = try? await self?.rustBackend.getScanProgress() {
77
+ if let scanProgress = try? await rustBackend.getWalletSummary()?.scanProgress {
63
78
  let progress = try scanProgress.progress()
64
- self?.logger.debug("progress: \(progress)")
79
+ logger.debug("progress: \(progress)")
65
80
  await didUpdate(.syncProgress(progress))
66
81
  }
67
-
68
- // ScanAction is controlled locally so it must report back the updated scanned height
69
- await context.update(lastScannedHeight: lastScannedHeight)
82
+ progressReportReducer = Constants.reportDelay
83
+ } else {
84
+ progressReportReducer -= 1
70
85
  }
71
86
  } catch ZcashError.rustScanBlocks(let errorMsg) {
72
87
  if isContinuityError(errorMsg) {
@@ -83,7 +98,9 @@ extension ScanAction: Action {
83
98
  return await update(context: context)
84
99
  }
85
100
 
86
- func stop() async { }
101
+ func stop() async {
102
+ progressReportReducer = 0
103
+ }
87
104
  }
88
105
 
89
106
  private extension ScanAction {
@@ -9,9 +9,9 @@ import Foundation
9
9
 
10
10
  final class UpdateChainTipAction {
11
11
  let rustBackend: ZcashRustBackendWelding
12
- let downloader: BlockDownloader
13
- let service: LightWalletService
14
- let latestBlocksDataProvider: LatestBlocksDataProvider
12
+ var downloader: BlockDownloader
13
+ var service: LightWalletService
14
+ var latestBlocksDataProvider: LatestBlocksDataProvider
15
15
  let logger: Logger
16
16
 
17
17
  init(container: DIContainer) {
@@ -25,7 +25,7 @@ final class UpdateChainTipAction {
25
25
  func updateChainTip(_ context: ActionContext, time: TimeInterval) async throws {
26
26
  let latestBlockHeight = try await service.latestBlockHeight()
27
27
 
28
- logger.info("Latest block height is \(latestBlockHeight)")
28
+ logger.debug("Latest block height is \(latestBlockHeight)")
29
29
  try await rustBackend.updateChainTip(height: Int32(latestBlockHeight))
30
30
  await context.update(lastChainTipUpdateTime: time)
31
31
  await latestBlocksDataProvider.update(latestBlockHeight)
@@ -10,7 +10,7 @@ import Foundation
10
10
  final class UpdateSubtreeRootsAction {
11
11
  let configProvider: CompactBlockProcessor.ConfigProvider
12
12
  let rustBackend: ZcashRustBackendWelding
13
- let service: LightWalletService
13
+ var service: LightWalletService
14
14
  let logger: Logger
15
15
 
16
16
  init(container: DIContainer, configProvider: CompactBlockProcessor.ConfigProvider) {
@@ -28,29 +28,58 @@ extension UpdateSubtreeRootsAction: Action {
28
28
  var request = GetSubtreeRootsArg()
29
29
  request.shieldedProtocol = .sapling
30
30
 
31
- logger.info("Attempt to get subtree roots, this may fail because lightwalletd may not support Spend before Sync.")
31
+ logger.debug("Attempt to get subtree roots, this may fail because lightwalletd may not support Spend before Sync.")
32
32
  let stream = service.getSubtreeRoots(request)
33
33
 
34
- var roots: [SubtreeRoot] = []
34
+ var saplingRoots: [SubtreeRoot] = []
35
35
 
36
36
  do {
37
37
  for try await subtreeRoot in stream {
38
- roots.append(subtreeRoot)
38
+ saplingRoots.append(subtreeRoot)
39
39
  }
40
40
  } catch ZcashError.serviceSubtreeRootsStreamFailed(LightWalletServiceError.timeOut) {
41
41
  throw ZcashError.serviceSubtreeRootsStreamFailed(LightWalletServiceError.timeOut)
42
42
  }
43
43
 
44
- logger.info("Sapling tree has \(roots.count) subtrees")
44
+ logger.debug("Sapling tree has \(saplingRoots.count) subtrees")
45
45
  do {
46
- try await rustBackend.putSaplingSubtreeRoots(startIndex: UInt64(request.startIndex), roots: roots)
46
+ try await rustBackend.putSaplingSubtreeRoots(startIndex: UInt64(request.startIndex), roots: saplingRoots)
47
47
 
48
48
  await context.update(state: .updateChainTip)
49
49
  } catch {
50
50
  logger.debug("putSaplingSubtreeRoots failed with error \(error.localizedDescription)")
51
51
  throw ZcashError.compactBlockProcessorPutSaplingSubtreeRoots(error)
52
52
  }
53
-
53
+
54
+ if !saplingRoots.isEmpty {
55
+ logger.debug("Found Sapling subtree roots, SbS supported, fetching Orchard subtree roots")
56
+
57
+ var orchardRequest = GetSubtreeRootsArg()
58
+ orchardRequest.shieldedProtocol = .orchard
59
+
60
+ let stream = service.getSubtreeRoots(orchardRequest)
61
+
62
+ var orchardRoots: [SubtreeRoot] = []
63
+
64
+ do {
65
+ for try await subtreeRoot in stream {
66
+ orchardRoots.append(subtreeRoot)
67
+ }
68
+ } catch ZcashError.serviceSubtreeRootsStreamFailed(LightWalletServiceError.timeOut) {
69
+ throw ZcashError.serviceSubtreeRootsStreamFailed(LightWalletServiceError.timeOut)
70
+ }
71
+
72
+ logger.debug("Orchard tree has \(orchardRoots.count) subtrees")
73
+ do {
74
+ try await rustBackend.putOrchardSubtreeRoots(startIndex: UInt64(orchardRequest.startIndex), roots: orchardRoots)
75
+
76
+ await context.update(state: .updateChainTip)
77
+ } catch {
78
+ logger.debug("putOrchardSubtreeRoots failed with error \(error.localizedDescription)")
79
+ throw ZcashError.compactBlockProcessorPutOrchardSubtreeRoots(error)
80
+ }
81
+ }
82
+
54
83
  return context
55
84
  }
56
85
 
@@ -10,7 +10,7 @@ import Foundation
10
10
  final class ValidateServerAction {
11
11
  let configProvider: CompactBlockProcessor.ConfigProvider
12
12
  let rustBackend: ZcashRustBackendWelding
13
- let service: LightWalletService
13
+ var service: LightWalletService
14
14
 
15
15
  init(container: DIContainer, configProvider: CompactBlockProcessor.ConfigProvider) {
16
16
  self.configProvider = configProvider