react-native-zcash 0.8.1 → 0.9.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 (124) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/android/build.gradle +3 -3
  3. package/android/src/main/assets/co.electriccoin.zcash/checkpoint/mainnet/2650000.json +8 -0
  4. package/android/src/main/assets/co.electriccoin.zcash/checkpoint/mainnet/2660000.json +8 -0
  5. package/android/src/main/java/app/edge/rnzcash/RNZcashModule.kt +15 -25
  6. package/ios/RNZcash.m +3 -5
  7. package/ios/RNZcash.swift +42 -23
  8. package/ios/RNZcash.xcodeproj/xcuserdata/samholmes.xcuserdatad/xcschemes/xcschememanagement.plist +14 -0
  9. package/ios/RNZcash.xcworkspace/xcuserdata/samholmes.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  10. package/ios/ZCashLightClientKit/Block/Actions/Action.swift +1 -0
  11. package/ios/ZCashLightClientKit/Block/Actions/EnhanceAction.swift +1 -1
  12. package/ios/ZCashLightClientKit/Block/Actions/ProcessSuggestedScanRangesAction.swift +1 -1
  13. package/ios/ZCashLightClientKit/Block/Actions/ScanAction.swift +1 -1
  14. package/ios/ZCashLightClientKit/Block/Actions/TxResubmissionAction.swift +75 -0
  15. package/ios/ZCashLightClientKit/Block/Actions/UpdateChainTipAction.swift +1 -1
  16. package/ios/ZCashLightClientKit/Block/Actions/UpdateSubtreeRootsAction.swift +3 -1
  17. package/ios/ZCashLightClientKit/Block/CompactBlockProcessor.swift +14 -0
  18. package/ios/ZCashLightClientKit/Block/Download/BlockDownloaderService.swift +2 -2
  19. package/ios/ZCashLightClientKit/Block/Enhance/BlockEnhancer.swift +54 -49
  20. package/ios/ZCashLightClientKit/Checkpoint/BundleCheckpointSource.swift +1 -6
  21. package/ios/ZCashLightClientKit/Checkpoint/CheckpointSourceFactory.swift +1 -1
  22. package/ios/ZCashLightClientKit/ClosureSynchronizer.swift +3 -1
  23. package/ios/ZCashLightClientKit/CombineSynchronizer.swift +6 -2
  24. package/ios/ZCashLightClientKit/Constants/ZcashSDK.swift +15 -0
  25. package/ios/ZCashLightClientKit/DAO/TransactionDao.swift +20 -4
  26. package/ios/ZCashLightClientKit/Entity/TransactionEntity.swift +27 -24
  27. package/ios/ZCashLightClientKit/Error/Sourcery/generateErrorCode.sh +2 -2
  28. package/ios/ZCashLightClientKit/Error/ZcashError.swift +32 -1
  29. package/ios/ZCashLightClientKit/Error/ZcashErrorCode.swift +11 -1
  30. package/ios/ZCashLightClientKit/Error/ZcashErrorCodeDefinition.swift +18 -0
  31. package/ios/ZCashLightClientKit/Initializer.swift +22 -14
  32. package/ios/ZCashLightClientKit/Metrics/SDKMetrics.swift +0 -1
  33. package/ios/ZCashLightClientKit/Model/FiatCurrencyResult.swift +25 -0
  34. package/ios/ZCashLightClientKit/Model/Proposal.swift +1 -1
  35. package/ios/ZCashLightClientKit/Model/TransactionDataRequest.swift +26 -0
  36. package/ios/ZCashLightClientKit/Model/WalletTypes.swift +39 -1
  37. package/ios/ZCashLightClientKit/Model/Zatoshi.swift +1 -1
  38. package/ios/ZCashLightClientKit/Modules/Service/GRPC/LightWalletGRPCService.swift +39 -2
  39. package/ios/ZCashLightClientKit/Modules/Service/GRPC/ProtoBuf/proto/service.proto +5 -4
  40. package/ios/ZCashLightClientKit/Modules/Service/GRPC/ProtoBuf/service.grpc.swift +819 -3
  41. package/ios/ZCashLightClientKit/Modules/Service/GRPC/ProtoBuf/service.pb.swift +2 -2
  42. package/ios/ZCashLightClientKit/Modules/Service/LightWalletService.swift +3 -1
  43. package/ios/ZCashLightClientKit/Providers/ResourceProvider.swift +10 -0
  44. package/ios/ZCashLightClientKit/Repository/TransactionRepository.swift +4 -0
  45. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2475000.json +8 -0
  46. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2477500.json +8 -0
  47. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2482500.json +8 -0
  48. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2485000.json +8 -0
  49. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2487500.json +8 -0
  50. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2492500.json +8 -0
  51. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2495000.json +8 -0
  52. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2497500.json +8 -0
  53. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2502500.json +8 -0
  54. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2505000.json +8 -0
  55. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2507500.json +8 -0
  56. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2512500.json +8 -0
  57. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2515000.json +8 -0
  58. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2517500.json +8 -0
  59. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2522500.json +8 -0
  60. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2525000.json +8 -0
  61. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2527500.json +8 -0
  62. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2532500.json +8 -0
  63. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2535000.json +8 -0
  64. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2537500.json +8 -0
  65. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2542500.json +8 -0
  66. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2545000.json +8 -0
  67. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2547500.json +8 -0
  68. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2552500.json +8 -0
  69. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2555000.json +8 -0
  70. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2557500.json +8 -0
  71. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2562500.json +8 -0
  72. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2565000.json +8 -0
  73. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2567500.json +8 -0
  74. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2572500.json +8 -0
  75. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2575000.json +8 -0
  76. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2577500.json +8 -0
  77. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2582500.json +8 -0
  78. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2585000.json +8 -0
  79. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2587500.json +8 -0
  80. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2592500.json +8 -0
  81. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2595000.json +8 -0
  82. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2597500.json +8 -0
  83. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2602500.json +8 -0
  84. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2605000.json +8 -0
  85. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2607500.json +8 -0
  86. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2612500.json +8 -0
  87. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2615000.json +8 -0
  88. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2617500.json +8 -0
  89. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2622500.json +8 -0
  90. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2625000.json +8 -0
  91. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2627500.json +8 -0
  92. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2632500.json +8 -0
  93. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2635000.json +8 -0
  94. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2637500.json +8 -0
  95. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2642500.json +8 -0
  96. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2645000.json +8 -0
  97. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2647500.json +8 -0
  98. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2650000.json +8 -0
  99. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2660000.json +8 -0
  100. package/ios/ZCashLightClientKit/Rust/ZcashKeyDerivationBackend.swift +4 -24
  101. package/ios/ZCashLightClientKit/Rust/ZcashKeyDerivationBackendWelding.swift +0 -15
  102. package/ios/ZCashLightClientKit/Rust/ZcashRustBackend.swift +133 -32
  103. package/ios/ZCashLightClientKit/Rust/ZcashRustBackendWelding.swift +18 -1
  104. package/ios/ZCashLightClientKit/Synchronizer/ClosureSDKSynchronizer.swift +4 -0
  105. package/ios/ZCashLightClientKit/Synchronizer/CombineSDKSynchronizer.swift +5 -1
  106. package/ios/ZCashLightClientKit/Synchronizer/Dependencies.swift +53 -3
  107. package/ios/ZCashLightClientKit/Synchronizer/SDKSynchronizer.swift +236 -7
  108. package/ios/ZCashLightClientKit/Synchronizer.swift +28 -0
  109. package/ios/ZCashLightClientKit/Tool/DerivationTool.swift +29 -5
  110. package/ios/ZCashLightClientKit/Tor/TorClient.swift +57 -0
  111. package/ios/ZCashLightClientKit/Utils/LoggingProxy.swift +4 -0
  112. package/ios/ZCashLightClientKit/Utils/OSLogger.swift +4 -0
  113. package/ios/lib/libzcashlc.a +0 -0
  114. package/ios/libzcashlc.xcframework/Info.plist +5 -5
  115. package/ios/libzcashlc.xcframework/ios-arm64/libzcashlc.a +0 -0
  116. package/ios/libzcashlc.xcframework/ios-arm64_x86_64-simulator/libzcashlc.a +0 -0
  117. package/ios/zcashlc.h +287 -42
  118. package/lib/rnzcash.rn.js +8 -8
  119. package/lib/rnzcash.rn.js.map +1 -1
  120. package/lib/src/react-native.d.ts +3 -3
  121. package/lib/src/types.d.ts +4 -2
  122. package/package.json +1 -1
  123. package/src/react-native.ts +13 -18
  124. package/src/types.ts +5 -2
@@ -90,6 +90,7 @@ public class Initializer {
90
90
  struct URLs {
91
91
  let fsBlockDbRoot: URL
92
92
  let dataDbURL: URL
93
+ let torDirURL: URL
93
94
  let generalStorageURL: URL
94
95
  let spendParamsURL: URL
95
96
  let outputParamsURL: URL
@@ -115,6 +116,7 @@ public class Initializer {
115
116
  let fsBlockDbRoot: URL
116
117
  let generalStorageURL: URL
117
118
  let dataDbURL: URL
119
+ let torDirURL: URL
118
120
  let spendParamsURL: URL
119
121
  let outputParamsURL: URL
120
122
  let saplingParamsSourceURL: SaplingParamsSourceURL
@@ -158,14 +160,14 @@ public class Initializer {
158
160
  fsBlockDbRoot: URL,
159
161
  generalStorageURL: URL,
160
162
  dataDbURL: URL,
163
+ torDirURL: URL,
161
164
  endpoint: LightWalletEndpoint,
162
165
  network: ZcashNetwork,
163
166
  spendParamsURL: URL,
164
167
  outputParamsURL: URL,
165
168
  saplingParamsSourceURL: SaplingParamsSourceURL,
166
169
  alias: ZcashSynchronizerAlias = .default,
167
- loggingPolicy: LoggingPolicy = .default(.debug),
168
- enableBackendTracing: Bool = false
170
+ loggingPolicy: LoggingPolicy = .default(.debug)
169
171
  ) {
170
172
  let container = DIContainer()
171
173
 
@@ -177,14 +179,14 @@ public class Initializer {
177
179
  fsBlockDbRoot: fsBlockDbRoot,
178
180
  generalStorageURL: generalStorageURL,
179
181
  dataDbURL: dataDbURL,
182
+ torDirURL: torDirURL,
180
183
  endpoint: endpoint,
181
184
  network: network,
182
185
  spendParamsURL: spendParamsURL,
183
186
  outputParamsURL: outputParamsURL,
184
187
  saplingParamsSourceURL: saplingParamsSourceURL,
185
188
  alias: alias,
186
- loggingPolicy: loggingPolicy,
187
- enableBackendTracing: enableBackendTracing
189
+ loggingPolicy: loggingPolicy
188
190
  )
189
191
 
190
192
  self.init(
@@ -207,14 +209,14 @@ public class Initializer {
207
209
  fsBlockDbRoot: URL,
208
210
  generalStorageURL: URL,
209
211
  dataDbURL: URL,
212
+ torDirURL: URL,
210
213
  endpoint: LightWalletEndpoint,
211
214
  network: ZcashNetwork,
212
215
  spendParamsURL: URL,
213
216
  outputParamsURL: URL,
214
217
  saplingParamsSourceURL: SaplingParamsSourceURL,
215
218
  alias: ZcashSynchronizerAlias = .default,
216
- loggingPolicy: LoggingPolicy = .default(.debug),
217
- enableBackendTracing: Bool = false
219
+ loggingPolicy: LoggingPolicy = .default(.debug)
218
220
  ) {
219
221
  // It's not possible to fail from constructor. Technically it's possible but it can be pain for the client apps to handle errors thrown
220
222
  // from constructor. So `parsingError` is just stored in initializer and `SDKSynchronizer.prepare()` throw this error if it exists.
@@ -224,14 +226,14 @@ public class Initializer {
224
226
  fsBlockDbRoot: fsBlockDbRoot,
225
227
  generalStorageURL: generalStorageURL,
226
228
  dataDbURL: dataDbURL,
229
+ torDirURL: torDirURL,
227
230
  endpoint: endpoint,
228
231
  network: network,
229
232
  spendParamsURL: spendParamsURL,
230
233
  outputParamsURL: outputParamsURL,
231
234
  saplingParamsSourceURL: saplingParamsSourceURL,
232
235
  alias: alias,
233
- loggingPolicy: loggingPolicy,
234
- enableBackendTracing: enableBackendTracing
236
+ loggingPolicy: loggingPolicy
235
237
  )
236
238
 
237
239
  self.init(
@@ -264,6 +266,7 @@ public class Initializer {
264
266
  self.fsBlockDbRoot = urls.fsBlockDbRoot
265
267
  self.generalStorageURL = urls.generalStorageURL
266
268
  self.dataDbURL = urls.dataDbURL
269
+ self.torDirURL = urls.torDirURL
267
270
  self.endpoint = endpoint
268
271
  self.spendParamsURL = urls.spendParamsURL
269
272
  self.outputParamsURL = urls.outputParamsURL
@@ -286,18 +289,19 @@ public class Initializer {
286
289
  fsBlockDbRoot: URL,
287
290
  generalStorageURL: URL,
288
291
  dataDbURL: URL,
292
+ torDirURL: URL,
289
293
  endpoint: LightWalletEndpoint,
290
294
  network: ZcashNetwork,
291
295
  spendParamsURL: URL,
292
296
  outputParamsURL: URL,
293
297
  saplingParamsSourceURL: SaplingParamsSourceURL,
294
298
  alias: ZcashSynchronizerAlias,
295
- loggingPolicy: LoggingPolicy = .default(.debug),
296
- enableBackendTracing: Bool = false
299
+ loggingPolicy: LoggingPolicy = .default(.debug)
297
300
  ) -> (URLs, ZcashError?) {
298
301
  let urls = URLs(
299
302
  fsBlockDbRoot: fsBlockDbRoot,
300
303
  dataDbURL: dataDbURL,
304
+ torDirURL: torDirURL,
301
305
  generalStorageURL: generalStorageURL,
302
306
  spendParamsURL: spendParamsURL,
303
307
  outputParamsURL: outputParamsURL
@@ -313,8 +317,7 @@ public class Initializer {
313
317
  alias: alias,
314
318
  networkType: network.networkType,
315
319
  endpoint: endpoint,
316
- loggingPolicy: loggingPolicy,
317
- enableBackendTracing: enableBackendTracing
320
+ loggingPolicy: loggingPolicy
318
321
  )
319
322
 
320
323
  return (updatedURLs, parsingError)
@@ -362,6 +365,10 @@ public class Initializer {
362
365
  return .failure(.initializerCantUpdateURLWithAlias(urls.dataDbURL))
363
366
  }
364
367
 
368
+ guard let updatedTorDirURL = urls.torDirURL.updateLastPathComponent(with: alias) else {
369
+ return .failure(.initializerCantUpdateURLWithAlias(urls.torDirURL))
370
+ }
371
+
365
372
  guard let updatedSpendParamsURL = urls.spendParamsURL.updateLastPathComponent(with: alias) else {
366
373
  return .failure(.initializerCantUpdateURLWithAlias(urls.spendParamsURL))
367
374
  }
@@ -378,6 +385,7 @@ public class Initializer {
378
385
  URLs(
379
386
  fsBlockDbRoot: updatedFsBlockDbRoot,
380
387
  dataDbURL: updatedDataDbURL,
388
+ torDirURL: updatedTorDirURL,
381
389
  generalStorageURL: updatedGeneralStorageURL,
382
390
  spendParamsURL: updatedSpendParamsURL,
383
391
  outputParamsURL: updateOutputParamsURL
@@ -415,8 +423,8 @@ public class Initializer {
415
423
  if let seed, try await rustBackend.listAccounts().isEmpty {
416
424
  var chainTip: UInt32?
417
425
 
418
- if walletMode == .restoreWallet {
419
- chainTip = UInt32(try await lightWalletService.latestBlockHeight())
426
+ if walletMode == .restoreWallet, let latestBlockHeight = try? await lightWalletService.latestBlockHeight() {
427
+ chainTip = UInt32(latestBlockHeight)
420
428
  }
421
429
 
422
430
  _ = try await rustBackend.createAccount(
@@ -118,7 +118,6 @@ final class SDKMetricsImpl: SDKMetrics {
118
118
  try? await Task.sleep(nanoseconds: 100_000)
119
119
 
120
120
  for action in cbpOverview {
121
-
122
121
  let report = action.value
123
122
 
124
123
  var resText = """
@@ -0,0 +1,25 @@
1
+ //
2
+ // FiatCurrencyResult.swift
3
+ //
4
+ //
5
+ // Created by Lukáš Korba on 31.07.2024.
6
+ //
7
+
8
+ import Foundation
9
+
10
+ /// The model representing currency for ZEC-XXX conversion. Initial implementation
11
+ /// provides only USD value.
12
+ public struct FiatCurrencyResult: Equatable {
13
+ public enum State: Equatable {
14
+ /// Last fetch failed, cached value is returned instead.
15
+ case error
16
+ /// Refresh has been triggered, returning cached value but informing about request in flight.
17
+ case fetching
18
+ /// Fetch of the value ended up as success so new value in returned.
19
+ case success
20
+ }
21
+
22
+ public let date: Date
23
+ public let rate: NSDecimalNumber
24
+ public var state: State
25
+ }
@@ -35,7 +35,7 @@ public extension Proposal {
35
35
  /// passed to `Synchronizer.createProposedTransactions`. It should never be called in
36
36
  /// production code.
37
37
  static func testOnlyFakeProposal(totalFee: UInt64) -> Self {
38
- var ffiProposal = FfiProposal()
38
+ let ffiProposal = FfiProposal()
39
39
  var balance = FfiTransactionBalance()
40
40
 
41
41
  balance.feeRequired = totalFee
@@ -0,0 +1,26 @@
1
+ //
2
+ // TransactionDataRequest.swift
3
+ //
4
+ //
5
+ // Created by Lukáš Korba on 08-15-2024.
6
+ //
7
+
8
+ import Foundation
9
+
10
+ struct SpendsFromAddress: Equatable {
11
+ let address: String
12
+ let blockRangeStart: UInt32
13
+ let blockRangeEnd: UInt32?
14
+ }
15
+
16
+ enum TransactionDataRequest: Equatable {
17
+ case getStatus([UInt8])
18
+ case enhancement([UInt8])
19
+ case spendsFromAddress(SpendsFromAddress)
20
+ }
21
+
22
+ enum TransactionStatus: Equatable {
23
+ case txidNotRecognized
24
+ case notInMainChain
25
+ case mined(BlockHeight)
26
+ }
@@ -89,13 +89,15 @@ public enum AddressType: Equatable {
89
89
  case p2sh
90
90
  case sapling
91
91
  case unified
92
-
92
+ case tex
93
+
93
94
  var id: UInt32 {
94
95
  switch self {
95
96
  case .p2pkh: return 0
96
97
  case .p2sh: return 1
97
98
  case .sapling: return 2
98
99
  case .unified: return 3
100
+ case .tex: return 4
99
101
  }
100
102
  }
101
103
  }
@@ -107,6 +109,7 @@ extension AddressType {
107
109
  case 1: return .p2sh
108
110
  case 2: return .sapling
109
111
  case 3: return .unified
112
+ case 4: return .tex
110
113
  default: return nil
111
114
  }
112
115
  }
@@ -213,6 +216,35 @@ public struct UnifiedAddress: Equatable, StringEncoded {
213
216
  }
214
217
  }
215
218
 
219
+ /// A transparent-source-only (TEX) Address that can be encoded as a String
220
+ ///
221
+ /// Transactions sent to this address are totally visible in the public
222
+ /// ledger. See "Multiple transaction types" in https://z.cash/technology/
223
+ ///
224
+ /// Transactions sent to this address must only have transparent inputs. See ZIP 320: https://zips.z.cash/zip-0320
225
+ public struct TexAddress: Equatable, StringEncoded, Comparable {
226
+ let encoding: String
227
+
228
+ public var stringEncoded: String { encoding }
229
+
230
+ /// Initializes a new TexAddress from the provided string encoding
231
+ ///
232
+ /// - parameter encoding: String encoding of the TEX address
233
+ /// - parameter network: `NetworkType` corresponding to the encoding (Mainnet or Testnet)
234
+ /// - Throws: `texAddressInvalidInput`when the provided encoding is found to be invalid
235
+ public init(encoding: String, network: NetworkType) throws {
236
+ guard DerivationTool(networkType: network).isValidTexAddress(encoding) else {
237
+ throw ZcashError.texAddressInvalidInput
238
+ }
239
+
240
+ self.encoding = encoding
241
+ }
242
+
243
+ public static func < (lhs: TexAddress, rhs: TexAddress) -> Bool {
244
+ return lhs.encoding < rhs.encoding
245
+ }
246
+ }
247
+
216
248
  public enum TransactionRecipient: Equatable {
217
249
  case address(Recipient)
218
250
  case internalAccount(UInt32)
@@ -223,6 +255,7 @@ public enum Recipient: Equatable, StringEncoded {
223
255
  case transparent(TransparentAddress)
224
256
  case sapling(SaplingAddress)
225
257
  case unified(UnifiedAddress)
258
+ case tex(TexAddress)
226
259
 
227
260
  public var stringEncoded: String {
228
261
  switch self {
@@ -232,6 +265,8 @@ public enum Recipient: Equatable, StringEncoded {
232
265
  return zAddr.stringEncoded
233
266
  case .unified(let uAddr):
234
267
  return uAddr.stringEncoded
268
+ case .tex(let texAddr):
269
+ return texAddr.stringEncoded
235
270
  }
236
271
  }
237
272
 
@@ -246,6 +281,8 @@ public enum Recipient: Equatable, StringEncoded {
246
281
  self = .sapling(sapling)
247
282
  } else if let transparent = try? TransparentAddress(encoding: string, network: network) {
248
283
  self = .transparent(transparent)
284
+ } else if let tex = try? TexAddress(encoding: string, network: network) {
285
+ self = .tex(tex)
249
286
  } else {
250
287
  throw ZcashError.recipientInvalidInput
251
288
  }
@@ -259,6 +296,7 @@ public enum Recipient: Equatable, StringEncoded {
259
296
  case .p2sh: return (.transparent(TransparentAddress(validatedEncoding: encoded)), metadata.networkType)
260
297
  case .sapling: return (.sapling(SaplingAddress(validatedEncoding: encoded)), metadata.networkType)
261
298
  case .unified: return (.unified(UnifiedAddress(validatedEncoding: encoded, networkType: metadata.networkType)), metadata.networkType)
299
+ case .tex: return (.tex(TexAddress(validatedEncoding: encoded)), metadata.networkType)
262
300
  }
263
301
  }
264
302
  }
@@ -42,7 +42,7 @@ public struct Zatoshi {
42
42
  }
43
43
 
44
44
  /// Converts `Decimal` to `Zatoshi`
45
- public static func from(decimal: Decimal) -> Zatoshi {
45
+ public static func from(decimal: Foundation.Decimal) -> Zatoshi {
46
46
  let roundedZec = NSDecimalNumber(decimal: decimal).roundedZec
47
47
  let zec2zatoshi = Decimal(Constants.oneZecInZatoshi) * roundedZec.decimalValue
48
48
  return Zatoshi(NSDecimalNumber(decimal: zec2zatoshi).int64Value)
@@ -187,13 +187,35 @@ extension LightWalletGRPCService: LightWalletService {
187
187
  }
188
188
  }
189
189
 
190
- func fetchTransaction(txId: Data) async throws -> ZcashTransaction.Fetched {
190
+ func fetchTransaction(txId: Data) async throws -> (tx: ZcashTransaction.Fetched?, status: TransactionStatus) {
191
191
  var txFilter = TxFilter()
192
192
  txFilter.hash = txId
193
193
 
194
194
  do {
195
195
  let rawTx = try await compactTxStreamer.getTransaction(txFilter)
196
- return ZcashTransaction.Fetched(rawID: txId, minedHeight: BlockHeight(rawTx.height), raw: rawTx.data)
196
+
197
+ let isNotMined = rawTx.height == 0 || rawTx.height > UInt32.max
198
+
199
+ return (
200
+ tx:
201
+ ZcashTransaction.Fetched(
202
+ rawID: txId,
203
+ minedHeight: isNotMined ? nil : UInt32(rawTx.height),
204
+ raw: rawTx.data
205
+ ),
206
+ status: isNotMined ? .notInMainChain : .mined(Int(rawTx.height))
207
+ )
208
+ } catch let error as GRPCStatus {
209
+ if error.makeGRPCStatus().code == .notFound {
210
+ return (tx: nil, .txidNotRecognized)
211
+ } else if let notFound = error.message?.contains("Transaction not found"), notFound {
212
+ return (tx: nil, .txidNotRecognized)
213
+ } else if let notFound = error.message?.contains("No such mempool or blockchain transaction. Use gettransaction for wallet transactions."), notFound {
214
+ return (tx: nil, .txidNotRecognized)
215
+ } else {
216
+ let serviceError = error.mapToServiceError()
217
+ throw ZcashError.serviceFetchTransactionFailed(serviceError)
218
+ }
197
219
  } catch {
198
220
  let serviceError = error.mapToServiceError()
199
221
  throw ZcashError.serviceFetchTransactionFailed(serviceError)
@@ -280,6 +302,21 @@ extension LightWalletGRPCService: LightWalletService {
280
302
  try await compactTxStreamer.getTreeState(id)
281
303
  }
282
304
 
305
+ func getTaddressTxids(_ request: TransparentAddressBlockFilter) -> AsyncThrowingStream<RawTransaction, Error> {
306
+ let stream = compactTxStreamer.getTaddressTxids(request)
307
+ var iterator = stream.makeAsyncIterator()
308
+
309
+ return AsyncThrowingStream() {
310
+ do {
311
+ guard let rawTransaction = try await iterator.next() else { return nil }
312
+ return rawTransaction
313
+ } catch {
314
+ let serviceError = error.mapToServiceError()
315
+ throw ZcashError.serviceGetTaddressTxidsFailed(serviceError)
316
+ }
317
+ }
318
+ }
319
+
283
320
  func closeConnection() {
284
321
  _ = channel.close()
285
322
  }
@@ -31,7 +31,7 @@ message TxFilter {
31
31
  bytes hash = 3; // transaction ID (hash, txid)
32
32
  }
33
33
 
34
- // RawTransaction contains the complete transaction data. It also optionally includes
34
+ // RawTransaction contains the complete transaction data. It also optionally includes
35
35
  // the block height in which the transaction was included, or, when returned
36
36
  // by GetMempoolStream(), the latest block height.
37
37
  message RawTransaction {
@@ -170,7 +170,8 @@ service CompactTxStreamer {
170
170
  // Submit the given transaction to the Zcash network
171
171
  rpc SendTransaction(RawTransaction) returns (SendResponse) {}
172
172
 
173
- // Return the txids corresponding to the given t-address within the given block range
173
+ // Return the transactions corresponding to the given t-address within the given block range
174
+ // NB - this method is misnamed, it returns transactions, not transaction IDs.
174
175
  rpc GetTaddressTxids(TransparentAddressBlockFilter) returns (stream RawTransaction) {}
175
176
  rpc GetTaddressBalance(AddressList) returns (Balance) {}
176
177
  rpc GetTaddressBalanceStream(stream Address) returns (Balance) {}
@@ -197,8 +198,8 @@ service CompactTxStreamer {
197
198
  rpc GetTreeState(BlockID) returns (TreeState) {}
198
199
  rpc GetLatestTreeState(Empty) returns (TreeState) {}
199
200
 
200
- // Returns a stream of information about roots of subtrees of the Sapling and Orchard
201
- // note commitment trees.
201
+ // Returns a stream of information about roots of subtrees of the note commitment tree
202
+ // for the specified shielded protocol (Sapling or Orchard).
202
203
  rpc GetSubtreeRoots(GetSubtreeRootsArg) returns (stream SubtreeRoot) {}
203
204
 
204
205
  rpc GetAddressUtxos(GetAddressUtxosArg) returns (GetAddressUtxosReplyList) {}