react-native-zcash 0.9.12 → 0.10.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 (281) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/android/build.gradle +6 -6
  3. package/android/src/main/assets/co.electriccoin.zcash/checkpoint/mainnet/3100000.json +8 -0
  4. package/android/src/main/assets/co.electriccoin.zcash/checkpoint/mainnet/3110000.json +8 -0
  5. package/android/src/main/assets/co.electriccoin.zcash/checkpoint/mainnet/3120000.json +8 -0
  6. package/android/src/main/assets/co.electriccoin.zcash/checkpoint/mainnet/3130000.json +8 -0
  7. package/android/src/main/java/app/edge/rnzcash/RNZcashModule.kt +126 -69
  8. package/ios/RNZcash.m +0 -5
  9. package/ios/RNZcash.swift +153 -104
  10. package/ios/ZCashLightClientKit/Account/Account.swift +48 -0
  11. package/ios/ZCashLightClientKit/Account/AccountMetadataKey.swift +96 -0
  12. package/ios/ZCashLightClientKit/Block/Actions/ScanAction.swift +23 -4
  13. package/ios/ZCashLightClientKit/Block/Actions/UpdateChainTipAction.swift +6 -2
  14. package/ios/ZCashLightClientKit/Block/Actions/UpdateSubtreeRootsAction.swift +4 -2
  15. package/ios/ZCashLightClientKit/Block/Actions/ValidateServerAction.swift +4 -1
  16. package/ios/ZCashLightClientKit/Block/CompactBlockProcessor.swift +83 -16
  17. package/ios/ZCashLightClientKit/Block/Download/BlockDownloader.swift +4 -2
  18. package/ios/ZCashLightClientKit/Block/Download/BlockDownloaderService.swift +22 -19
  19. package/ios/ZCashLightClientKit/Block/Enhance/BlockEnhancer.swift +50 -19
  20. package/ios/ZCashLightClientKit/Block/FetchUnspentTxOutputs/UTXOFetcher.swift +5 -3
  21. package/ios/ZCashLightClientKit/Block/SaplingParameters/SaplingParametersHandler.swift +22 -5
  22. package/ios/ZCashLightClientKit/Block/Scan/BlockScanner.swift +2 -1
  23. package/ios/ZCashLightClientKit/Block/Utils/CompactBlockProgress.swift +5 -3
  24. package/ios/ZCashLightClientKit/Checkpoint/BundleCheckpointSource.swift +88 -0
  25. package/ios/ZCashLightClientKit/Checkpoint/CheckpointSource.swift +4 -0
  26. package/ios/ZCashLightClientKit/ClosureSynchronizer.swift +52 -21
  27. package/ios/ZCashLightClientKit/CombineSynchronizer.swift +49 -27
  28. package/ios/ZCashLightClientKit/Constants/ZcashSDK.swift +8 -2
  29. package/ios/ZCashLightClientKit/DAO/BlockDao.swift +65 -0
  30. package/ios/ZCashLightClientKit/DAO/TransactionDao.swift +86 -1
  31. package/ios/ZCashLightClientKit/Entity/AccountEntity.swift +4 -4
  32. package/ios/ZCashLightClientKit/Entity/Pczt.swift +10 -0
  33. package/ios/ZCashLightClientKit/Entity/SentNoteEntity.swift +2 -2
  34. package/ios/ZCashLightClientKit/Entity/TransactionEntity.swift +40 -16
  35. package/ios/ZCashLightClientKit/Error/Sourcery/generateErrorCode.sh +1 -1
  36. package/ios/ZCashLightClientKit/Error/ZcashError.swift +182 -14
  37. package/ios/ZCashLightClientKit/Error/ZcashErrorCode.swift +63 -5
  38. package/ios/ZCashLightClientKit/Error/ZcashErrorCodeDefinition.swift +122 -12
  39. package/ios/ZCashLightClientKit/Initializer.swift +49 -14
  40. package/ios/ZCashLightClientKit/Metrics/SDKMetrics.swift +15 -6
  41. package/ios/ZCashLightClientKit/Model/SingleUseTransparentAddress.swift +29 -0
  42. package/ios/ZCashLightClientKit/Model/TransactionDataRequest.swift +83 -2
  43. package/ios/ZCashLightClientKit/Model/WalletSummary.swift +21 -4
  44. package/ios/ZCashLightClientKit/Model/WalletTypes.swift +38 -8
  45. package/ios/ZCashLightClientKit/Modules/Service/GRPC/LightWalletGRPCService.swift +177 -45
  46. package/ios/ZCashLightClientKit/Modules/Service/LightWalletService.swift +63 -16
  47. package/ios/ZCashLightClientKit/Modules/Service/Tor/LightWalletGRPCServiceOverTor.swift +273 -0
  48. package/ios/ZCashLightClientKit/Providers/LatestBlocksDataProvider.swift +5 -2
  49. package/ios/ZCashLightClientKit/Repository/TransactionRepository.swift +2 -0
  50. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2675000.json +8 -0
  51. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2677500.json +8 -0
  52. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2682500.json +8 -0
  53. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2685000.json +8 -0
  54. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2687500.json +8 -0
  55. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2692500.json +8 -0
  56. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2695000.json +8 -0
  57. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2697500.json +8 -0
  58. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2702500.json +8 -0
  59. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2705000.json +8 -0
  60. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2707500.json +8 -0
  61. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2712500.json +8 -0
  62. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2715000.json +8 -0
  63. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2717500.json +8 -0
  64. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2722500.json +8 -0
  65. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2725000.json +8 -0
  66. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2727500.json +8 -0
  67. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2732500.json +8 -0
  68. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2735000.json +8 -0
  69. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2737500.json +8 -0
  70. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2742500.json +8 -0
  71. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2745000.json +8 -0
  72. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2747500.json +8 -0
  73. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2752500.json +8 -0
  74. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2755000.json +8 -0
  75. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2757500.json +8 -0
  76. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2762500.json +8 -0
  77. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2765000.json +8 -0
  78. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2767500.json +8 -0
  79. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2772500.json +8 -0
  80. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2775000.json +8 -0
  81. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2777500.json +8 -0
  82. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2782500.json +8 -0
  83. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2785000.json +8 -0
  84. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2787500.json +8 -0
  85. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2792500.json +8 -0
  86. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2795000.json +8 -0
  87. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2797500.json +8 -0
  88. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2802500.json +8 -0
  89. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2805000.json +8 -0
  90. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2807500.json +8 -0
  91. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2812500.json +8 -0
  92. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2815000.json +8 -0
  93. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2817500.json +8 -0
  94. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2822500.json +8 -0
  95. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2825000.json +8 -0
  96. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2827500.json +8 -0
  97. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2832500.json +8 -0
  98. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2835000.json +8 -0
  99. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2837500.json +8 -0
  100. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2842500.json +8 -0
  101. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2845000.json +8 -0
  102. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2847500.json +8 -0
  103. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2852500.json +8 -0
  104. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2855000.json +8 -0
  105. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2857500.json +8 -0
  106. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2862500.json +8 -0
  107. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2865000.json +8 -0
  108. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2867500.json +8 -0
  109. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2872500.json +8 -0
  110. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2875000.json +8 -0
  111. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2877500.json +8 -0
  112. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2882500.json +8 -0
  113. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2885000.json +8 -0
  114. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2887500.json +8 -0
  115. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2892500.json +8 -0
  116. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2895000.json +8 -0
  117. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2897500.json +8 -0
  118. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2902500.json +8 -0
  119. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2905000.json +8 -0
  120. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2907500.json +8 -0
  121. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2912500.json +8 -0
  122. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2915000.json +8 -0
  123. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2917500.json +8 -0
  124. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2922500.json +8 -0
  125. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2925000.json +8 -0
  126. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2927500.json +8 -0
  127. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2932500.json +8 -0
  128. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2935000.json +8 -0
  129. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2937500.json +8 -0
  130. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2942500.json +8 -0
  131. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2945000.json +8 -0
  132. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2947500.json +8 -0
  133. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2952500.json +8 -0
  134. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2955000.json +8 -0
  135. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2957500.json +8 -0
  136. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2962500.json +8 -0
  137. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2965000.json +8 -0
  138. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2967500.json +8 -0
  139. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2972500.json +8 -0
  140. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2975000.json +8 -0
  141. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2977500.json +8 -0
  142. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2982500.json +8 -0
  143. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2985000.json +8 -0
  144. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2987500.json +8 -0
  145. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2992500.json +8 -0
  146. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2995000.json +8 -0
  147. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2997500.json +8 -0
  148. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3002500.json +8 -0
  149. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3005000.json +8 -0
  150. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3007500.json +8 -0
  151. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3012500.json +8 -0
  152. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3015000.json +8 -0
  153. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3017500.json +8 -0
  154. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3022500.json +8 -0
  155. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3025000.json +8 -0
  156. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3027500.json +8 -0
  157. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3032500.json +8 -0
  158. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3035000.json +8 -0
  159. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3037500.json +8 -0
  160. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3042500.json +8 -0
  161. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3045000.json +8 -0
  162. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3047500.json +8 -0
  163. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3052500.json +8 -0
  164. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3055000.json +8 -0
  165. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3057500.json +8 -0
  166. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3062500.json +8 -0
  167. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3065000.json +8 -0
  168. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3067500.json +8 -0
  169. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3072500.json +8 -0
  170. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3075000.json +8 -0
  171. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3077500.json +8 -0
  172. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3082500.json +8 -0
  173. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3085000.json +8 -0
  174. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3087500.json +8 -0
  175. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3092500.json +8 -0
  176. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3095000.json +8 -0
  177. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3097500.json +8 -0
  178. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3100000.json +8 -0
  179. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3102500.json +8 -0
  180. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3105000.json +8 -0
  181. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3107500.json +8 -0
  182. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3110000.json +8 -0
  183. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3112500.json +8 -0
  184. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3115000.json +8 -0
  185. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3117500.json +8 -0
  186. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3120000.json +8 -0
  187. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3122500.json +8 -0
  188. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3125000.json +8 -0
  189. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3127500.json +8 -0
  190. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3130000.json +8 -0
  191. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3010000.json +8 -0
  192. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3020000.json +8 -0
  193. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3030000.json +8 -0
  194. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3040000.json +8 -0
  195. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3050000.json +8 -0
  196. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3060000.json +8 -0
  197. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3070000.json +8 -0
  198. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3080000.json +8 -0
  199. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3090000.json +8 -0
  200. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3100000.json +8 -0
  201. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3110000.json +8 -0
  202. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3120000.json +8 -0
  203. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3130000.json +8 -0
  204. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3140000.json +8 -0
  205. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3150000.json +8 -0
  206. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3160000.json +8 -0
  207. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3170000.json +8 -0
  208. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3180000.json +8 -0
  209. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3190000.json +8 -0
  210. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3200000.json +8 -0
  211. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3210000.json +8 -0
  212. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3220000.json +8 -0
  213. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3230000.json +8 -0
  214. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3240000.json +8 -0
  215. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3250000.json +8 -0
  216. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3260000.json +8 -0
  217. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3270000.json +8 -0
  218. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3280000.json +8 -0
  219. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3290000.json +8 -0
  220. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3300000.json +8 -0
  221. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3310000.json +8 -0
  222. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3320000.json +8 -0
  223. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3330000.json +8 -0
  224. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3340000.json +8 -0
  225. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3350000.json +8 -0
  226. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3360000.json +8 -0
  227. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3370000.json +8 -0
  228. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3380000.json +8 -0
  229. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3390000.json +8 -0
  230. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3400000.json +8 -0
  231. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3410000.json +8 -0
  232. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3420000.json +8 -0
  233. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3430000.json +8 -0
  234. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3440000.json +8 -0
  235. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3450000.json +8 -0
  236. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3460000.json +8 -0
  237. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3470000.json +8 -0
  238. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3480000.json +8 -0
  239. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3490000.json +8 -0
  240. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3500000.json +8 -0
  241. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3510000.json +8 -0
  242. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3520000.json +8 -0
  243. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3530000.json +8 -0
  244. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3540000.json +8 -0
  245. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3550000.json +8 -0
  246. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3560000.json +8 -0
  247. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3570000.json +8 -0
  248. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3580000.json +8 -0
  249. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3590000.json +8 -0
  250. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3600000.json +8 -0
  251. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3610000.json +8 -0
  252. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3620000.json +8 -0
  253. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3630000.json +8 -0
  254. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3640000.json +8 -0
  255. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3650000.json +8 -0
  256. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3660000.json +8 -0
  257. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3670000.json +8 -0
  258. package/ios/ZCashLightClientKit/Rust/ZcashKeyDerivationBackend.swift +89 -10
  259. package/ios/ZCashLightClientKit/Rust/ZcashKeyDerivationBackendWelding.swift +39 -3
  260. package/ios/ZCashLightClientKit/Rust/ZcashRustBackend.swift +532 -74
  261. package/ios/ZCashLightClientKit/Rust/ZcashRustBackendWelding.swift +97 -14
  262. package/ios/ZCashLightClientKit/Synchronizer/ClosureSDKSynchronizer.swift +104 -28
  263. package/ios/ZCashLightClientKit/Synchronizer/CombineSDKSynchronizer.swift +105 -31
  264. package/ios/ZCashLightClientKit/Synchronizer/Dependencies.swift +36 -9
  265. package/ios/ZCashLightClientKit/Synchronizer/SDKSynchronizer.swift +401 -175
  266. package/ios/ZCashLightClientKit/Synchronizer.swift +192 -69
  267. package/ios/ZCashLightClientKit/Tool/DerivationTool.swift +69 -12
  268. package/ios/ZCashLightClientKit/Tor/TorClient.swift +502 -11
  269. package/ios/ZCashLightClientKit/Transaction/TransactionEncoder.swift +10 -6
  270. package/ios/ZCashLightClientKit/Transaction/WalletTransactionEncoder.swift +24 -9
  271. package/ios/ZCashLightClientKit/Utils/SDKFlags.swift +71 -0
  272. package/ios/libzcashlc.xcframework/Info.plist +5 -5
  273. package/ios/libzcashlc.xcframework/ios-arm64/libzcashlc.a +0 -0
  274. package/ios/libzcashlc.xcframework/ios-arm64_x86_64-simulator/libzcashlc.a +0 -0
  275. package/ios/zcashlc.h +1640 -378
  276. package/lib/rnzcash.rn.js.map +1 -1
  277. package/lib/src/react-native.d.ts +2 -2
  278. package/lib/src/types.d.ts +2 -0
  279. package/package.json +1 -1
  280. package/src/react-native.ts +2 -3
  281. package/src/types.ts +2 -0
package/ios/RNZcash.swift CHANGED
@@ -4,7 +4,24 @@ import MnemonicSwift
4
4
  import SwiftProtobuf
5
5
  import os
6
6
 
7
- var SynchronizerMap = [String: WalletSynchronizer]()
7
+ actor SynchronizerStore {
8
+ private var map: [String: WalletSynchronizer] = [:]
9
+
10
+ func get(_ alias: String) -> WalletSynchronizer? {
11
+ map[alias]
12
+ }
13
+
14
+ func set(_ wallet: WalletSynchronizer, for alias: String) {
15
+ map[alias] = wallet
16
+ }
17
+
18
+ func remove(_ alias: String) {
19
+ map.removeValue(forKey: alias)
20
+ }
21
+
22
+ }
23
+
24
+ let synchronizerStore = SynchronizerStore()
8
25
 
9
26
  struct ConfirmedTx {
10
27
  var minedHeight: Int
@@ -14,6 +31,8 @@ struct ConfirmedTx {
14
31
  var blockTimeInSeconds: Int
15
32
  var value: String
16
33
  var fee: String?
34
+ var isShielding: Bool
35
+ var isExpired: Bool
17
36
  var memos: [String]?
18
37
  var dictionary: [String: Any?] {
19
38
  return [
@@ -25,28 +44,8 @@ struct ConfirmedTx {
25
44
  "value": value,
26
45
  "fee": fee,
27
46
  "memos": memos ?? [],
28
- ]
29
- }
30
- var nsDictionary: NSDictionary {
31
- return dictionary as NSDictionary
32
- }
33
- }
34
-
35
- struct TotalBalances {
36
- var transparentAvailableZatoshi: Zatoshi
37
- var transparentTotalZatoshi: Zatoshi
38
- var saplingAvailableZatoshi: Zatoshi
39
- var saplingTotalZatoshi: Zatoshi
40
- var orchardAvailableZatoshi: Zatoshi
41
- var orchardTotalZatoshi: Zatoshi
42
- var dictionary: [String: Any] {
43
- return [
44
- "transparentAvailableZatoshi": String(transparentAvailableZatoshi.amount),
45
- "transparentTotalZatoshi": String(transparentTotalZatoshi.amount),
46
- "saplingAvailableZatoshi": String(saplingAvailableZatoshi.amount),
47
- "saplingTotalZatoshi": String(saplingTotalZatoshi.amount),
48
- "orchardAvailableZatoshi": String(orchardAvailableZatoshi.amount),
49
- "orchardTotalZatoshi": String(orchardTotalZatoshi.amount),
47
+ "isShielding": isShielding,
48
+ "isExpired": isExpired,
50
49
  ]
51
50
  }
52
51
  var nsDictionary: NSDictionary {
@@ -109,9 +108,11 @@ class RNZcash: RCTEventEmitter {
109
108
  spendParamsURL: try! spendParamsURLHelper(alias),
110
109
  outputParamsURL: try! outputParamsURLHelper(alias),
111
110
  saplingParamsSourceURL: SaplingParamsSourceURL.default,
112
- alias: ZcashSynchronizerAlias.custom(alias)
111
+ alias: ZcashSynchronizerAlias.custom(alias),
112
+ isTorEnabled: false,
113
+ isExchangeRateEnabled: false
113
114
  )
114
- if SynchronizerMap[alias] == nil {
115
+ if await synchronizerStore.get(alias) == nil {
115
116
  do {
116
117
  let wallet = try WalletSynchronizer(
117
118
  alias: alias, initializer: initializer, emitter: sendToJs)
@@ -121,11 +122,16 @@ class RNZcash: RCTEventEmitter {
121
122
  _ = try await wallet.synchronizer.prepare(
122
123
  with: seedBytes,
123
124
  walletBirthday: birthdayHeight,
124
- for: initMode
125
+ for: initMode,
126
+ name: alias,
127
+ keySource: nil
125
128
  )
129
+ let accounts = try await wallet.synchronizer.listAccounts()
130
+ let accountUUID = accounts.first(where: { $0.name == alias })?.id
131
+ wallet.accountUUID = accountUUID
126
132
  try await wallet.synchronizer.start()
127
133
  wallet.subscribe()
128
- SynchronizerMap[alias] = wallet
134
+ await synchronizerStore.set(wallet, for: alias)
129
135
  resolve(nil)
130
136
  } catch {
131
137
  reject("InitializeError", "Synchronizer failed to initialize", error)
@@ -137,45 +143,28 @@ class RNZcash: RCTEventEmitter {
137
143
  }
138
144
  }
139
145
 
140
- @objc func start(
146
+ @objc func stop(
141
147
  _ alias: String, resolver resolve: @escaping RCTPromiseResolveBlock,
142
148
  rejecter reject: @escaping RCTPromiseRejectBlock
143
149
  ) {
144
150
  Task {
145
- if let wallet = SynchronizerMap[alias] {
146
- do {
147
- try await wallet.synchronizer.start()
148
- wallet.subscribe()
149
- } catch {
150
- reject("StartError", "Synchronizer failed to start", error)
151
- }
151
+ if let wallet = await synchronizerStore.get(alias) {
152
+ wallet.synchronizer.stop()
153
+ wallet.cancellables.forEach { $0.cancel() }
154
+ await synchronizerStore.remove(alias)
152
155
  resolve(nil)
153
156
  } else {
154
- reject("StartError", "Wallet does not exist", genericError)
157
+ reject("StopError", "Wallet does not exist", genericError)
155
158
  }
156
159
  }
157
160
  }
158
161
 
159
- @objc func stop(
160
- _ alias: String, resolver resolve: @escaping RCTPromiseResolveBlock,
161
- rejecter reject: @escaping RCTPromiseRejectBlock
162
- ) {
163
- if let wallet = SynchronizerMap[alias] {
164
- wallet.synchronizer.stop()
165
- wallet.cancellables.forEach { $0.cancel() }
166
- SynchronizerMap[alias] = nil
167
- resolve(nil)
168
- } else {
169
- reject("StopError", "Wallet does not exist", genericError)
170
- }
171
- }
172
-
173
162
  @objc func getLatestNetworkHeight(
174
163
  _ alias: String, resolver resolve: @escaping RCTPromiseResolveBlock,
175
164
  rejecter reject: @escaping RCTPromiseRejectBlock
176
165
  ) {
177
166
  Task {
178
- if let wallet = SynchronizerMap[alias] {
167
+ if let wallet = await synchronizerStore.get(alias) {
179
168
  do {
180
169
  let height = try await wallet.synchronizer.latestHeight()
181
170
  resolve(height)
@@ -197,8 +186,8 @@ class RNZcash: RCTEventEmitter {
197
186
  do {
198
187
  let endpoint = LightWalletEndpoint(address: host, port: port, secure: true)
199
188
  let lightwalletd: LightWalletService = LightWalletGRPCService(endpoint: endpoint)
200
- let height = try await lightwalletd.latestBlockHeight()
201
- lightwalletd.closeConnection()
189
+ let height = try await lightwalletd.latestBlockHeight(mode: ServiceMode.direct)
190
+ await lightwalletd.closeConnections()
202
191
  resolve(height)
203
192
  } catch {
204
193
  reject("getLatestNetworkHeightGrpc", "Failed to query blockheight", error)
@@ -212,7 +201,7 @@ class RNZcash: RCTEventEmitter {
212
201
  rejecter reject: @escaping RCTPromiseRejectBlock
213
202
  ) {
214
203
  Task {
215
- if let wallet = SynchronizerMap[alias] {
204
+ if let wallet = await synchronizerStore.get(alias) {
216
205
  let amount = Int64(zatoshi)
217
206
  if amount == nil {
218
207
  reject("ProposeTransferError", "Amount is invalid", genericError)
@@ -224,8 +213,12 @@ class RNZcash: RCTEventEmitter {
224
213
  if memo != "" {
225
214
  sdkMemo = try Memo(string: memo)
226
215
  }
216
+ guard let accountUUID = wallet.accountUUID else {
217
+ reject("ProposeTransferError", "Account UUID not found", genericError)
218
+ return
219
+ }
227
220
  let proposal = try await wallet.synchronizer.proposeTransfer(
228
- accountIndex: 0,
221
+ accountUUID: accountUUID,
229
222
  recipient: Recipient(toAddress, network: wallet.synchronizer.network.networkType),
230
223
  amount: Zatoshi(amount!),
231
224
  memo: sdkMemo
@@ -259,7 +252,7 @@ class RNZcash: RCTEventEmitter {
259
252
  rejecter reject: @escaping RCTPromiseRejectBlock
260
253
  ) {
261
254
  Task {
262
- if let wallet = SynchronizerMap[alias] {
255
+ if let wallet = await synchronizerStore.get(alias) {
263
256
  do {
264
257
  let spendingKey = try deriveUnifiedSpendingKey(seed, wallet.synchronizer.network)
265
258
  let data = Data.init(base64Encoded: proposalBase64)!
@@ -278,7 +271,7 @@ class RNZcash: RCTEventEmitter {
278
271
  case .success(let txId):
279
272
  lastTxid = txId.toHexStringTxId()
280
273
  continue
281
- case let .submitFailure(txId: _, code: code, description: description):
274
+ case .submitFailure(txId: _, let code, let description):
282
275
  throw NSError(
283
276
  domain:
284
277
  "transaction failed to submit with code: \(code) - description: \(description)",
@@ -304,7 +297,7 @@ class RNZcash: RCTEventEmitter {
304
297
  rejecter reject: @escaping RCTPromiseRejectBlock
305
298
  ) {
306
299
  Task {
307
- if let wallet = SynchronizerMap[alias] {
300
+ if let wallet = await synchronizerStore.get(alias) {
308
301
  if !wallet.fullySynced {
309
302
  reject("shieldFunds", "Wallet is not synced", genericError)
310
303
  return
@@ -315,17 +308,52 @@ class RNZcash: RCTEventEmitter {
315
308
  let sdkMemo = try Memo(string: memo)
316
309
  let shieldingThreshold = Int64(threshold) ?? 10000
317
310
 
318
- let tx = try await wallet.synchronizer.shieldFunds(
319
- spendingKey: spendingKey,
320
- memo: sdkMemo,
321
- shieldingThreshold: Zatoshi(shieldingThreshold)
311
+ guard let accountUUID = wallet.accountUUID else {
312
+ reject("shieldFunds", "Account UUID not found", genericError)
313
+ return
314
+ }
315
+
316
+ guard
317
+ let proposal = try await wallet.synchronizer.proposeShielding(
318
+ accountUUID: accountUUID,
319
+ shieldingThreshold: Zatoshi(shieldingThreshold),
320
+ memo: sdkMemo
321
+ )
322
+ else {
323
+ throw NSError(
324
+ domain: "shieldFunds",
325
+ code: -1,
326
+ userInfo: [NSLocalizedDescriptionKey: "Proposal was nil"]
327
+ )
328
+
329
+ }
330
+
331
+ let stream = try await wallet.synchronizer.createProposedTransactions(
332
+ proposal: proposal,
333
+ spendingKey: spendingKey
322
334
  )
323
335
 
324
- var confTx = await wallet.parseTx(tx: tx)
336
+ if let result = try await stream.first(where: { _ in true }) {
337
+ switch result {
338
+ case .success(let txId):
339
+ resolve(txId.toHexStringTxId())
340
+ return
325
341
 
326
- // Hack: Memos aren't ready to be queried right after broadcast
327
- confTx.memos = [memo]
328
- resolve(confTx.nsDictionary)
342
+ default:
343
+ throw NSError(
344
+ domain: "shieldFunds",
345
+ code: -1,
346
+ userInfo: [NSLocalizedDescriptionKey: "Failed: \(result)"]
347
+ )
348
+ }
349
+ } else {
350
+ // Stream ended without producing any result
351
+ throw NSError(
352
+ domain: "shieldFunds",
353
+ code: -1,
354
+ userInfo: [NSLocalizedDescriptionKey: "No result returned"]
355
+ )
356
+ }
329
357
  } catch {
330
358
  reject("shieldFunds", "Failed to shield funds", genericError)
331
359
  }
@@ -340,7 +368,7 @@ class RNZcash: RCTEventEmitter {
340
368
  rejecter reject: @escaping RCTPromiseRejectBlock
341
369
  ) {
342
370
  Task {
343
- if let wallet = SynchronizerMap[alias] {
371
+ if let wallet = await synchronizerStore.get(alias) {
344
372
  wallet.synchronizer.rewind(.birthday).sink(
345
373
  receiveCompletion: { completion in
346
374
  Task {
@@ -353,6 +381,8 @@ class RNZcash: RCTEventEmitter {
353
381
  wallet.cancellables.forEach { $0.cancel() }
354
382
  try await wallet.synchronizer.start()
355
383
  wallet.subscribe()
384
+ let txs = try await wallet.synchronizer.allTransactions()
385
+ wallet.emitTxs(transactions: txs)
356
386
  resolve(nil)
357
387
  case .failure:
358
388
  reject("RescanError", "Failed to rescan wallet", genericError)
@@ -381,7 +411,8 @@ class RNZcash: RCTEventEmitter {
381
411
  {
382
412
  let derivationTool = DerivationTool(networkType: network.networkType)
383
413
  let seedBytes = try Mnemonic.deterministicSeedBytes(from: seed)
384
- let spendingKey = try derivationTool.deriveUnifiedSpendingKey(seed: seedBytes, accountIndex: 0)
414
+ let spendingKey = try derivationTool.deriveUnifiedSpendingKey(
415
+ seed: seedBytes, accountIndex: Zip32AccountIndex(0))
385
416
  return spendingKey
386
417
  }
387
418
 
@@ -412,12 +443,18 @@ class RNZcash: RCTEventEmitter {
412
443
  rejecter reject: @escaping RCTPromiseRejectBlock
413
444
  ) {
414
445
  Task {
415
- if let wallet = SynchronizerMap[alias] {
446
+ if let wallet = await synchronizerStore.get(alias) {
416
447
  do {
417
- let unifiedAddress = try await wallet.synchronizer.getUnifiedAddress(accountIndex: 0)
418
- let saplingAddress = try await wallet.synchronizer.getSaplingAddress(accountIndex: 0)
448
+ guard let accountUUID = wallet.accountUUID else {
449
+ reject("deriveUnifiedAddress", "Account UUID not found", genericError)
450
+ return
451
+ }
452
+ let unifiedAddress = try await wallet.synchronizer.getUnifiedAddress(
453
+ accountUUID: accountUUID)
454
+ let saplingAddress = try await wallet.synchronizer.getSaplingAddress(
455
+ accountUUID: accountUUID)
419
456
  let transparentAddress = try await wallet.synchronizer.getTransparentAddress(
420
- accountIndex: 0)
457
+ accountUUID: accountUUID)
421
458
  let addresses: NSDictionary = [
422
459
  "unifiedAddress": unifiedAddress.stringEncoded,
423
460
  "saplingAddress": saplingAddress.stringEncoded,
@@ -472,6 +509,7 @@ class RNZcash: RCTEventEmitter {
472
509
 
473
510
  class WalletSynchronizer: NSObject {
474
511
  public var alias: String
512
+ public var accountUUID: AccountUUID?
475
513
  public var synchronizer: SDKSynchronizer
476
514
  var status: String
477
515
  var emit: (String, Any) -> Void
@@ -479,7 +517,6 @@ class WalletSynchronizer: NSObject {
479
517
  var restart: Bool
480
518
  var processorState: ProcessorState
481
519
  var cancellables: [AnyCancellable] = []
482
- var balances: TotalBalances
483
520
 
484
521
  init(alias: String, initializer: Initializer, emitter: @escaping (String, Any) -> Void) throws {
485
522
  self.alias = alias
@@ -492,13 +529,6 @@ class WalletSynchronizer: NSObject {
492
529
  scanProgress: 0,
493
530
  networkBlockHeight: 0
494
531
  )
495
- self.balances = TotalBalances(
496
- transparentAvailableZatoshi: Zatoshi(0),
497
- transparentTotalZatoshi: Zatoshi(0),
498
- saplingAvailableZatoshi: Zatoshi(0),
499
- saplingTotalZatoshi: Zatoshi(0),
500
- orchardAvailableZatoshi: Zatoshi(0),
501
- orchardTotalZatoshi: Zatoshi(0))
502
532
  }
503
533
 
504
534
  public func subscribe() {
@@ -567,7 +597,7 @@ class WalletSynchronizer: NSObject {
567
597
  var scanProgress = 0
568
598
 
569
599
  switch event.internalSyncStatus {
570
- case .syncing(let progress):
600
+ case .syncing(let progress, _):
571
601
  scanProgress = Int(floor(progress * 100))
572
602
  case .synced:
573
603
  scanProgress = 100
@@ -598,19 +628,22 @@ class WalletSynchronizer: NSObject {
598
628
  scanProgress: 0,
599
629
  networkBlockHeight: 0
600
630
  )
601
- self.balances = TotalBalances(
602
- transparentAvailableZatoshi: Zatoshi(0),
603
- transparentTotalZatoshi: Zatoshi(0),
604
- saplingAvailableZatoshi: Zatoshi(0),
605
- saplingTotalZatoshi: Zatoshi(0),
606
- orchardAvailableZatoshi: Zatoshi(0),
607
- orchardTotalZatoshi: Zatoshi(0))
608
631
  }
609
632
 
610
633
  func updateBalanceState(event: SynchronizerState) {
611
- let transparentBalance = event.accountBalance?.unshielded ?? Zatoshi(0)
612
- let shieldedBalance = event.accountBalance?.saplingBalance ?? PoolBalance.zero
613
- let orchardBalance = event.accountBalance?.orchardBalance ?? PoolBalance.zero
634
+ guard let accountUUID = self.accountUUID else {
635
+ return
636
+ }
637
+
638
+ // Safely check if the account exists in the balances dictionary
639
+ guard let accountBalance = event.accountsBalances[accountUUID] else {
640
+ return
641
+ }
642
+
643
+ // Account exists, safely access the balance properties
644
+ let transparentBalance = accountBalance.unshielded
645
+ let shieldedBalance = accountBalance.saplingBalance
646
+ let orchardBalance = accountBalance.orchardBalance
614
647
 
615
648
  let transparentAvailableZatoshi = transparentBalance
616
649
  let transparentTotalZatoshi = transparentBalance
@@ -621,16 +654,15 @@ class WalletSynchronizer: NSObject {
621
654
  let orchardAvailableZatoshi = orchardBalance.spendableValue
622
655
  let orchardTotalZatoshi = orchardBalance.total()
623
656
 
624
- self.balances = TotalBalances(
625
- transparentAvailableZatoshi: transparentAvailableZatoshi,
626
- transparentTotalZatoshi: transparentTotalZatoshi,
627
- saplingAvailableZatoshi: saplingAvailableZatoshi,
628
- saplingTotalZatoshi: saplingTotalZatoshi,
629
- orchardAvailableZatoshi: orchardAvailableZatoshi,
630
- orchardTotalZatoshi: orchardTotalZatoshi
631
- )
632
- let data = NSMutableDictionary(dictionary: self.balances.nsDictionary)
633
- data["alias"] = self.alias
657
+ let data: NSDictionary = [
658
+ "alias": self.alias,
659
+ "transparentAvailableZatoshi": String(transparentAvailableZatoshi.amount),
660
+ "transparentTotalZatoshi": String(transparentTotalZatoshi.amount),
661
+ "saplingAvailableZatoshi": String(saplingAvailableZatoshi.amount),
662
+ "saplingTotalZatoshi": String(saplingTotalZatoshi.amount),
663
+ "orchardAvailableZatoshi": String(orchardAvailableZatoshi.amount),
664
+ "orchardTotalZatoshi": String(orchardTotalZatoshi.amount),
665
+ ]
634
666
  emit("BalanceEvent", data)
635
667
  }
636
668
 
@@ -639,7 +671,9 @@ class WalletSynchronizer: NSObject {
639
671
  minedHeight: tx.minedHeight ?? 0,
640
672
  rawTransactionId: (tx.rawID.toHexStringTxId()),
641
673
  blockTimeInSeconds: Int(tx.blockTime ?? 0),
642
- value: String(describing: abs(tx.value.amount))
674
+ value: String(describing: abs(tx.value.amount)),
675
+ isShielding: tx.isShielding,
676
+ isExpired: tx.isExpiredUmined ?? false
643
677
  )
644
678
  if tx.raw != nil {
645
679
  confTx.raw = tx.raw!.hexEncodedString()
@@ -651,7 +685,7 @@ class WalletSynchronizer: NSObject {
651
685
  let recipients = await self.synchronizer.getRecipients(for: tx)
652
686
  if recipients.count > 0 {
653
687
  let addresses = recipients.compactMap {
654
- if case let .address(address) = $0 {
688
+ if case .address(let address) = $0 {
655
689
  return address
656
690
  } else {
657
691
  return nil
@@ -676,7 +710,6 @@ class WalletSynchronizer: NSObject {
676
710
  Task {
677
711
  var out: [NSDictionary] = []
678
712
  for tx in transactions {
679
- if tx.isExpiredUmined ?? false { continue }
680
713
  let confTx = await parseTx(tx: tx)
681
714
  out.append(confTx.nsDictionary)
682
715
  }
@@ -687,6 +720,22 @@ class WalletSynchronizer: NSObject {
687
720
  }
688
721
  }
689
722
 
723
+ extension AccountUUID {
724
+ static func fromAlias(_ alias: String) -> AccountUUID {
725
+ let bytes = Array(alias.utf8)
726
+ let folded = foldTo16Bytes(bytes)
727
+ return AccountUUID(id: folded)
728
+ }
729
+ }
730
+
731
+ func foldTo16Bytes(_ bytes: [UInt8]) -> [UInt8] {
732
+ var out = [UInt8](repeating: 0, count: 16)
733
+ for (i, b) in bytes.enumerated() {
734
+ out[i % 16] ^= b
735
+ }
736
+ return out
737
+ }
738
+
690
739
  // Local file helper funcs
691
740
  func documentsDirectoryHelper() throws -> URL {
692
741
  try FileManager.default.url(
@@ -0,0 +1,48 @@
1
+ //
2
+ // Account.swift
3
+ // ZcashLightClientKit
4
+ //
5
+ // Created by Lukáš Korba on 2024-11-19.
6
+ //
7
+
8
+ /// A [ZIP 32](https://zips.z.cash/zip-0032) account index.
9
+ ///
10
+ /// This index must be paired with a seed, or other context that determines a seed,
11
+ /// in order to identify a ZIP 32 *account*.
12
+ public struct Zip32AccountIndex: Equatable, Codable, Hashable {
13
+ public let index: UInt32
14
+
15
+ /// - Parameter index: the ZIP 32 account index, which must be less than ``1<<31``.
16
+ public init(_ index: UInt32) {
17
+ guard index < (1 << 31) else {
18
+ fatalError("Account index must be less than 1<<31. Input value is \(index).")
19
+ }
20
+
21
+ self.index = index
22
+ }
23
+ }
24
+
25
+ public struct AccountId: Equatable, Codable, Hashable {
26
+ public let id: Int
27
+
28
+ /// - Parameter id: the local account id, which must be nonnegative.
29
+ public init(_ id: Int) {
30
+ guard id >= 0 else {
31
+ fatalError("Account id must be >= 0. Input value is \(id).")
32
+ }
33
+
34
+ self.id = id
35
+ }
36
+ }
37
+
38
+ public struct AccountUUID: Equatable, Codable, Hashable, Identifiable {
39
+ public let id: [UInt8]
40
+
41
+ init(id: [UInt8]) {
42
+ guard id.count == 16 else {
43
+ fatalError("Account UUID must be 16 bytes long. Input value is \(id).")
44
+ }
45
+
46
+ self.id = id
47
+ }
48
+ }
@@ -0,0 +1,96 @@
1
+ //
2
+ // AccountMetadataKey.swift
3
+ // ZcashLightClientKit
4
+ //
5
+ // Created by Jack Grigg on 25/02/2025.
6
+ //
7
+
8
+ import Foundation
9
+
10
+
11
+ /// A ZIP 325 Account Metadata Key.
12
+ public class AccountMetadataKey {
13
+ private let accountMetadataKeyPtr: OpaquePointer
14
+ private let networkType: NetworkType
15
+
16
+ /// Derives a ZIP 325 Account Metadata Key from the given seed.
17
+ public init(
18
+ from seed: [UInt8],
19
+ accountIndex: Zip32AccountIndex,
20
+ networkType: NetworkType
21
+ ) throws {
22
+ let accountMetadataKeyPtr = seed.withUnsafeBufferPointer { seedBufferPtr in
23
+ return zcashlc_derive_account_metadata_key(
24
+ seedBufferPtr.baseAddress,
25
+ UInt(seed.count),
26
+ LCZip32Index(accountIndex.index),
27
+ networkType.networkId
28
+ )
29
+ }
30
+
31
+ guard let accountMetadataKeyPtr else {
32
+ throw ZcashError.rustDeriveAccountMetadataKey(lastErrorMessage(fallback: "`deriveAccountMetadataKey` failed with unknown error"))
33
+ }
34
+
35
+ self.accountMetadataKeyPtr = accountMetadataKeyPtr
36
+ self.networkType = networkType
37
+ }
38
+
39
+ deinit {
40
+ zcashlc_free_account_metadata_key(accountMetadataKeyPtr)
41
+ }
42
+
43
+ /// Derives a metadata key for private use from this ZIP 325 Account Metadata Key.
44
+ ///
45
+ /// - Parameter ufvk: the external UFVK for which a metadata key is required, or `null` if the
46
+ /// metadata key is "inherent" (for the same account as the Account Metadata Key).
47
+ /// - Parameter privateUseSubject: a globally unique non-empty sequence of at most 252 bytes
48
+ /// that identifies the desired private-use context.
49
+ ///
50
+ /// If `ufvk` is null, this function will return a single 32-byte metadata key.
51
+ ///
52
+ /// If `ufvk` is non-null, this function will return one metadata key for every FVK item
53
+ /// contained within the UFVK, in preference order. As UFVKs may in general change over
54
+ /// time (due to the inclusion of new higher-preference FVK items, or removal of older
55
+ /// deprecated FVK items), private usage of these keys should always follow preference
56
+ /// order:
57
+ /// - For encryption-like private usage, the first key in the array should always be
58
+ /// used, and all other keys ignored.
59
+ /// - For decryption-like private usage, each key in the array should be tried in turn
60
+ /// until metadata can be recovered, and then the metadata should be re-encrypted
61
+ /// under the first key.
62
+ public func derivePrivateUseMetadataKey(
63
+ ufvk: UnifiedFullViewingKey?,
64
+ privateUseSubject: [UInt8]
65
+ ) throws -> [Data] {
66
+ var kSource: [CChar]?
67
+ if let ufvk {
68
+ kSource = [CChar](ufvk.stringEncoded.utf8CString)
69
+ }
70
+
71
+ let keysPtr = privateUseSubject.withUnsafeBufferPointer { privateUseSubjectBufferPtr in
72
+ return zcashlc_derive_private_use_metadata_key(
73
+ accountMetadataKeyPtr,
74
+ kSource,
75
+ privateUseSubjectBufferPtr.baseAddress,
76
+ UInt(privateUseSubject.count),
77
+ networkType.networkId
78
+ )
79
+ }
80
+
81
+ guard let keysPtr else {
82
+ throw ZcashError.rustDerivePrivateUseMetadataKey(lastErrorMessage(fallback: "`derivePrivateUseMetadataKey` failed with unknown error"))
83
+ }
84
+
85
+ defer { zcashlc_free_txids(keysPtr) }
86
+
87
+ var keys: [Data] = []
88
+
89
+ for i in (0 ..< Int(keysPtr.pointee.len)) {
90
+ let txId = FfiTxId(tuple: keysPtr.pointee.ptr.advanced(by: i).pointee)
91
+ keys.append(Data(txId.array))
92
+ }
93
+
94
+ return keys
95
+ }
96
+ }
@@ -73,13 +73,32 @@ extension ScanAction: Action {
73
73
  // Proper solution is handled in
74
74
  // TODO: [#1353] Advanced progress reporting, https://github.com/Electric-Coin-Company/zcash-swift-wallet-sdk/issues/1353
75
75
  if progressReportReducer == 0 {
76
+ let walletSummary = try? await rustBackend.getWalletSummary()
77
+ let recoveryProgress = walletSummary?.recoveryProgress
78
+
76
79
  // report scan progress only if it's available
77
- if let scanProgress = try? await rustBackend.getWalletSummary()?.scanProgress {
78
- logger.debug("progress ratio: \(scanProgress.numerator)/\(scanProgress.denominator)")
79
- let progress = try scanProgress.progress()
80
+ if let scanProgress = walletSummary?.scanProgress {
81
+ let composedNumerator = Float(scanProgress.numerator) + Float(recoveryProgress?.numerator ?? 0)
82
+ let composedDenominator = Float(scanProgress.denominator) + Float(recoveryProgress?.denominator ?? 0)
83
+
84
+ logger.debug("progress ratio: \(composedNumerator)/\(composedDenominator)")
85
+
86
+ let progress: Float
87
+ if composedDenominator == 0 {
88
+ progress = 1.0
89
+ } else {
90
+ progress = composedNumerator / composedDenominator
91
+ }
92
+
93
+ // this shouldn't happen but if it does, we need to get notified by clients and work on a fix
94
+ if progress > 1.0 {
95
+ throw ZcashError.rustScanProgressOutOfRange("\(progress)")
96
+ }
97
+
80
98
  logger.debug("progress float: \(progress)")
81
- await didUpdate(.syncProgress(progress))
99
+ await didUpdate(.syncProgress(progress, scanProgress.isComplete))
82
100
  }
101
+
83
102
  progressReportReducer = Constants.reportDelay
84
103
  } else {
85
104
  progressReportReducer -= 1
@@ -13,6 +13,7 @@ final class UpdateChainTipAction {
13
13
  var service: LightWalletService
14
14
  var latestBlocksDataProvider: LatestBlocksDataProvider
15
15
  let logger: Logger
16
+ let sdkFlags: SDKFlags
16
17
 
17
18
  init(container: DIContainer) {
18
19
  service = container.resolve(LightWalletService.self)
@@ -20,11 +21,13 @@ final class UpdateChainTipAction {
20
21
  rustBackend = container.resolve(ZcashRustBackendWelding.self)
21
22
  latestBlocksDataProvider = container.resolve(LatestBlocksDataProvider.self)
22
23
  logger = container.resolve(Logger.self)
24
+ sdkFlags = container.resolve(SDKFlags.self)
23
25
  }
24
26
 
25
27
  func updateChainTip(_ context: ActionContext, time: TimeInterval) async throws {
26
- let latestBlockHeight = try await service.latestBlockHeight()
27
-
28
+ // called each sync, right after getInfo in ValidateServerAction
29
+ let latestBlockHeight = try await service.latestBlockHeight(mode: await sdkFlags.ifTor(.defaultTor))
30
+
28
31
  logger.debug("Latest block height is \(latestBlockHeight)")
29
32
  try await rustBackend.updateChainTip(height: Int32(latestBlockHeight))
30
33
  await context.update(lastChainTipUpdateTime: time)
@@ -43,6 +46,7 @@ extension UpdateChainTipAction: Action {
43
46
  if await context.prevState == .updateSubtreeRoots || now - lastChainTipUpdateTime > 600 {
44
47
  await downloader.stopDownload()
45
48
  try await updateChainTip(context, time: now)
49
+ await sdkFlags.markChainTipAsUpdated()
46
50
  await context.update(state: .clearCache)
47
51
  } else if await context.prevState == .txResubmission {
48
52
  await context.update(state: .download)