react-native-zcash 0.2.2 → 0.3.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # React Native Zcash
2
2
 
3
+ ## 0.3.1 (2022-12-15)
4
+
5
+ - Add `getBirthdayHeight` method to query blockheight without an active synchronizer
6
+ - iOS: Add missing `getLatestNetworkHeight` method
7
+ - RN: Remove unimplemented methods and POC comments
8
+ - Fix exported types
9
+
10
+ ## 0.2.3 (2022-08-07)
11
+
12
+ - iOS: Handle potential throw in synchronizer.latestHeight()
13
+
3
14
  ## 0.2.2 (2022-06-10)
4
15
 
5
16
  - Upgrade SDKs to NU5 compatible versions
package/README.md CHANGED
@@ -5,12 +5,27 @@
5
5
 
6
6
  ## React Native
7
7
 
8
- To use this library on React Native, simply run
8
+ To use this library on React Native, run `yarn add react-native-zcash` to install it. Then add these lines to your Podspec file, to work around certain compatiblity issues between the ZCash SDK and React Native:
9
+
10
+ ```ruby
11
+ pod 'CNIOAtomics', :modular_headers => true
12
+ pod 'CNIOBoringSSL', :modular_headers => true
13
+ pod 'CNIOBoringSSLShims', :modular_headers => true
14
+ pod 'CNIOLinux', :modular_headers => true
15
+ pod 'CNIODarwin', :modular_headers => true
16
+ pod 'CNIOHTTPParser', :modular_headers => true
17
+ pod 'CNIOWindows', :modular_headers => true
18
+ pod 'CGRPCZlib', :modular_headers => true
19
+ pod 'ZcashLightClientKit', :git => 'https://github.com/zcash/ZcashLightClientKit.git', :commit => '74f3ae20f26748e162c051e5fa343c71febc4294'
20
+ ```
21
+
22
+ Finally, you can use CocoaPods to integrate the library with your project:
9
23
 
10
24
  ```bash
11
- yarn add react-native-zcash
12
25
  cd ios
13
26
  pod install
14
27
  ```
15
28
 
16
29
  ## API overview
30
+
31
+ TODO
@@ -5,6 +5,7 @@ import cash.z.ecc.android.sdk.SdkSynchronizer
5
5
  import cash.z.ecc.android.sdk.Synchronizer
6
6
  import cash.z.ecc.android.sdk.db.entity.*
7
7
  import cash.z.ecc.android.sdk.ext.*
8
+ import cash.z.ecc.android.sdk.internal.service.LightWalletGrpcService
8
9
  import cash.z.ecc.android.sdk.internal.transaction.PagedTransactionRepository
9
10
  import cash.z.ecc.android.sdk.internal.*
10
11
  import cash.z.ecc.android.sdk.type.*
@@ -175,6 +176,18 @@ class RNZcashModule(private val reactContext: ReactApplicationContext) :
175
176
  wallet.synchronizer.latestHeight
176
177
  }
177
178
 
179
+ @ReactMethod
180
+ fun getBirthdayHeight(network: String = "mainnet", promise: Promise) = promise.wrap {
181
+ var networkInt = 1
182
+ if (network != "mainnet") {
183
+ networkInt = 0
184
+ }
185
+ var lightwalletService = LightWalletGrpcService(reactApplicationContext, ZcashNetwork.from(networkInt))
186
+ val height = lightwalletService?.getLatestBlockHeight()
187
+ lightwalletService?.shutdown()
188
+ height
189
+ }
190
+
178
191
  @ReactMethod
179
192
  fun getShieldedBalance(alias: String, promise: Promise) = promise.wrap {
180
193
  val wallet = getWallet(alias)
@@ -213,13 +226,9 @@ class RNZcashModule(private val reactContext: ReactApplicationContext) :
213
226
  promise.resolve(map)
214
227
  } else if (tx.isFailure()) {
215
228
  val map = Arguments.createMap()
216
- map.putInt("expiryHeight", tx.expiryHeight)
217
- map.putString("cancelled", tx.cancelled.toString())
218
- map.putString("encodeAttempts", tx.encodeAttempts.toString())
219
- map.putString("submitAttempts", tx.submitAttempts.toString())
220
229
  if (tx.errorMessage != null) map.putString("errorMessage", tx.errorMessage)
221
230
  if (tx.errorCode != null) map.putString("errorCode", tx.errorCode.toString())
222
- promise.resolve(false)
231
+ promise.resolve(map)
223
232
  }
224
233
  }
225
234
  } catch (t: Throwable) {
@@ -305,16 +314,6 @@ class RNZcashModule(private val reactContext: ReactApplicationContext) :
305
314
  .emit(eventName, args)
306
315
  }
307
316
 
308
- // TODO: move this to the SDK
309
- inline fun ByteArray?.toUtf8Memo(): String {
310
- return if (this == null || this[0] >= 0xF5) "" else try {
311
- // trim empty and "replacement characters" for codes that can't be represented in unicode
312
- String(this, StandardCharsets.UTF_8).trim('\u0000', '\uFFFD')
313
- } catch (t: Throwable) {
314
- "Unable to parse memo."
315
- }
316
- }
317
-
318
317
  inline fun ByteArray.toHexReversed(): String {
319
318
  val sb = StringBuilder(size * 2)
320
319
  var i = size - 1
package/ios/RNZcash.m CHANGED
@@ -26,6 +26,17 @@ resolver:(RCTPromiseResolveBlock)resolve
26
26
  rejecter:(RCTPromiseRejectBlock)reject
27
27
  )
28
28
 
29
+ RCT_EXTERN_METHOD(getLatestNetworkHeight:(NSString *)alias
30
+ resolver:(RCTPromiseResolveBlock)resolve
31
+ rejecter:(RCTPromiseRejectBlock)reject
32
+ )
33
+
34
+ RCT_EXTERN_METHOD(getBirthdayHeight:(NSString *)host
35
+ :(NSInteger *)port
36
+ resolver:(RCTPromiseResolveBlock)resolve
37
+ rejecter:(RCTPromiseRejectBlock)reject
38
+ )
39
+
29
40
  RCT_EXTERN_METHOD(spendToAddress:(NSString *)alias
30
41
  :(NSString *)zatoshi
31
42
  :(NSString *)toAddress
package/ios/RNZcash.swift CHANGED
@@ -142,6 +142,32 @@ class RNZcash : RCTEventEmitter {
142
142
  }
143
143
  }
144
144
 
145
+ @objc func getLatestNetworkHeight(_ alias: String, resolver resolve:@escaping RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock) {
146
+ if let wallet = SynchronizerMap[alias] {
147
+ do {
148
+ let height = try wallet.synchronizer.latestHeight()
149
+ resolve(height)
150
+ } catch {
151
+ reject("getLatestNetworkHeight", "Failed to query blockheight", error)
152
+ }
153
+ } else {
154
+ reject("getLatestNetworkHeightError", "Wallet does not exist", genericError)
155
+ }
156
+ }
157
+
158
+ // A convenience method to get the block height when the synchronizer isn't running
159
+ @objc func getBirthdayHeight(_ host: String, _ port: Int, resolver resolve:@escaping RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock) {
160
+ do {
161
+ let endpoint = LightWalletEndpoint(address: host, port: port, secure: true)
162
+ let lightwalletd: LightWalletService = LightWalletGRPCService(endpoint:endpoint)
163
+ let height = try lightwalletd.latestBlockHeight()
164
+ lightwalletd.closeConnection()
165
+ resolve(height)
166
+ } catch {
167
+ reject("getLatestNetworkHeightGrpc", "Failed to query blockheight", error)
168
+ }
169
+ }
170
+
145
171
  @objc func spendToAddress(_ alias: String, _ zatoshi: String, _ toAddress: String, _ memo: String, _ fromAccountIndex: Int, _ spendingKey: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) -> Void {
146
172
  if let wallet = SynchronizerMap[alias] {
147
173
  let amount = Int64(zatoshi)
@@ -398,7 +424,11 @@ class WalletSynchronizer : NSObject {
398
424
  self.processorState.lastDownloadedHeight = self.synchronizer.latestScannedHeight
399
425
  self.processorState.scanProgress = 100
400
426
  self.processorState.lastScannedHeight = self.synchronizer.latestScannedHeight
401
- self.processorState.networkBlockHeight = try! self.synchronizer.latestHeight()
427
+ do {
428
+ try self.processorState.networkBlockHeight = self.synchronizer.latestHeight()
429
+ } catch {
430
+ // ignore if synchronizer throws
431
+ }
402
432
  }
403
433
 
404
434
  if self.processorState.lastDownloadedHeight != prevLastDownloadedHeight || self.processorState.scanProgress != prevScanProgress ||
package/lib/rnzcash.rn.js CHANGED
@@ -40,26 +40,8 @@ function _asyncToGenerator(fn) {
40
40
  };
41
41
  }
42
42
 
43
- var SynchronizerStatus;
44
-
45
- (function (SynchronizerStatus) {
46
- SynchronizerStatus[SynchronizerStatus["STOPPED"] = 0] = "STOPPED";
47
- SynchronizerStatus[SynchronizerStatus["DISCONNECTED"] = 1] = "DISCONNECTED";
48
- SynchronizerStatus[SynchronizerStatus["DOWNLOADING"] = 2] = "DOWNLOADING";
49
- SynchronizerStatus[SynchronizerStatus["VALIDATING"] = 3] = "VALIDATING";
50
- SynchronizerStatus[SynchronizerStatus["SCANNING"] = 4] = "SCANNING";
51
- SynchronizerStatus[SynchronizerStatus["ENHANCING"] = 5] = "ENHANCING";
52
- SynchronizerStatus[SynchronizerStatus["SYNCED"] = 6] = "SYNCED";
53
- })(SynchronizerStatus || (SynchronizerStatus = {}));
54
-
55
43
  var RNZcash = reactNative.NativeModules.RNZcash;
56
-
57
- var snooze = function snooze(ms) {
58
- return new Promise(function (resolve) {
59
- return setTimeout(resolve, ms);
60
- });
61
- };
62
-
44
+ var isAndroid = reactNative.Platform.OS === 'android';
63
45
  var KeyTool = {
64
46
  deriveViewingKey: function () {
65
47
  var _deriveViewingKey = _asyncToGenerator(function* (seedBytesHex, network) {
@@ -84,6 +66,19 @@ var KeyTool = {
84
66
  }
85
67
 
86
68
  return deriveSpendingKey;
69
+ }(),
70
+ getBirthdayHeight: function () {
71
+ var _getBirthdayHeight = _asyncToGenerator(function* (network, host, port) {
72
+ var args = isAndroid ? [network] : [host, port];
73
+ var result = yield RNZcash.getBirthdayHeight.apply(RNZcash, args);
74
+ return result;
75
+ });
76
+
77
+ function getBirthdayHeight(_x5, _x6, _x7) {
78
+ return _getBirthdayHeight.apply(this, arguments);
79
+ }
80
+
81
+ return getBirthdayHeight;
87
82
  }()
88
83
  };
89
84
  var AddressTool = {
@@ -93,7 +88,7 @@ var AddressTool = {
93
88
  return result;
94
89
  });
95
90
 
96
- function deriveShieldedAddress(_x5, _x6) {
91
+ function deriveShieldedAddress(_x8, _x9) {
97
92
  return _deriveShieldedAddress.apply(this, arguments);
98
93
  }
99
94
 
@@ -109,7 +104,7 @@ var AddressTool = {
109
104
  return result;
110
105
  });
111
106
 
112
- function isValidShieldedAddress(_x7, _x8) {
107
+ function isValidShieldedAddress(_x10, _x11) {
113
108
  return _isValidShieldedAddress.apply(this, arguments);
114
109
  }
115
110
 
@@ -125,85 +120,24 @@ var AddressTool = {
125
120
  return result;
126
121
  });
127
122
 
128
- function isValidTransparentAddress(_x9, _x10) {
123
+ function isValidTransparentAddress(_x12, _x13) {
129
124
  return _isValidTransparentAddress.apply(this, arguments);
130
125
  }
131
126
 
132
127
  return isValidTransparentAddress;
133
128
  }()
134
129
  };
135
-
136
130
  var Synchronizer = /*#__PURE__*/function () {
137
131
  function Synchronizer(alias, network) {
138
132
  this.eventEmitter = new reactNative.NativeEventEmitter(RNZcash);
139
133
  this.subscriptions = [];
140
134
  this.alias = alias;
141
135
  this.network = network;
142
- } /// ////////////////////////////////////////////////////////////////
143
- // Start PoC behavior
144
- // Here are a few functions to demonstrate functionality but the final library should not have these functions
145
- //
146
-
136
+ }
147
137
 
148
138
  var _proto = Synchronizer.prototype;
149
139
 
150
- _proto.readyToSend =
151
- /*#__PURE__*/
152
- function () {
153
- var _readyToSend = _asyncToGenerator(function* () {
154
- var result = yield RNZcash.readyToSend();
155
- return result;
156
- });
157
-
158
- function readyToSend() {
159
- return _readyToSend.apply(this, arguments);
160
- }
161
-
162
- return readyToSend;
163
- }();
164
-
165
- _proto.sendTestTransaction = /*#__PURE__*/function () {
166
- var _sendTestTransaction = _asyncToGenerator(function* (key, address) {
167
- // send an amount that's guaranteed to be too large for our wallet and expect it to fail but at least show how this is done
168
- // simply change these two values to send a real transaction but ensure the function isn't called too often (although funds can't be spent if notes are unconfirmed)
169
- var invalidValue = '9223372036854775807'; // Max long value (change this to 10000 to send a small transaction equal to the miner's fee on every reload and you could send 10,000 of those before it equals 1 ZEC)
170
-
171
- var invalidAccount = 99; // should be 0
172
-
173
- return this.sendToAddress({
174
- zatoshi: invalidValue,
175
- toAddress: address,
176
- memo: 'this is a test transaction that will fail',
177
- fromAccountIndex: invalidAccount,
178
- spendingKey: key
179
- });
180
- });
181
-
182
- function sendTestTransaction(_x11, _x12) {
183
- return _sendTestTransaction.apply(this, arguments);
184
- }
185
-
186
- return sendTestTransaction;
187
- }();
188
-
189
- _proto.getBlockCount = /*#__PURE__*/function () {
190
- var _getBlockCount = _asyncToGenerator(function* () {
191
- var result = yield RNZcash.getBlockCount();
192
- return result;
193
- });
194
-
195
- function getBlockCount() {
196
- return _getBlockCount.apply(this, arguments);
197
- }
198
-
199
- return getBlockCount;
200
- }() // End PoC behavior
201
- /// ////////////////////////////////////////////////////////////////
202
- ;
203
-
204
- _proto.start =
205
- /*#__PURE__*/
206
- function () {
140
+ _proto.start = /*#__PURE__*/function () {
207
141
  var _start = _asyncToGenerator(function* () {
208
142
  var result = yield RNZcash.start(this.alias);
209
143
  return result;
@@ -235,7 +169,7 @@ var Synchronizer = /*#__PURE__*/function () {
235
169
  yield RNZcash.initialize(initializerConfig.fullViewingKey.extfvk, initializerConfig.fullViewingKey.extpub, initializerConfig.birthdayHeight, initializerConfig.alias, initializerConfig.networkName, initializerConfig.defaultHost, initializerConfig.defaultPort);
236
170
  });
237
171
 
238
- function initialize(_x13) {
172
+ function initialize(_x14) {
239
173
  return _initialize.apply(this, arguments);
240
174
  }
241
175
 
@@ -248,52 +182,13 @@ var Synchronizer = /*#__PURE__*/function () {
248
182
  return result;
249
183
  });
250
184
 
251
- function getLatestNetworkHeight(_x14) {
185
+ function getLatestNetworkHeight(_x15) {
252
186
  return _getLatestNetworkHeight.apply(this, arguments);
253
187
  }
254
188
 
255
189
  return getLatestNetworkHeight;
256
190
  }();
257
191
 
258
- _proto.getLatestScannedHeight = /*#__PURE__*/function () {
259
- var _getLatestScannedHeight = _asyncToGenerator(function* () {
260
- var result = yield RNZcash.getLatestScannedHeight();
261
- return result;
262
- });
263
-
264
- function getLatestScannedHeight() {
265
- return _getLatestScannedHeight.apply(this, arguments);
266
- }
267
-
268
- return getLatestScannedHeight;
269
- }();
270
-
271
- _proto.getProgress = /*#__PURE__*/function () {
272
- var _getProgress = _asyncToGenerator(function* () {
273
- var result = yield RNZcash.getProgress();
274
- return result;
275
- });
276
-
277
- function getProgress() {
278
- return _getProgress.apply(this, arguments);
279
- }
280
-
281
- return getProgress;
282
- }();
283
-
284
- _proto.getStatus = /*#__PURE__*/function () {
285
- var _getStatus = _asyncToGenerator(function* () {
286
- var result = yield RNZcash.getStatus();
287
- return SynchronizerStatus[result.name];
288
- });
289
-
290
- function getStatus() {
291
- return _getStatus.apply(this, arguments);
292
- }
293
-
294
- return getStatus;
295
- }();
296
-
297
192
  _proto.getShieldedBalance = /*#__PURE__*/function () {
298
193
  var _getShieldedBalance = _asyncToGenerator(function* () {
299
194
  var result = yield RNZcash.getShieldedBalance(this.alias);
@@ -307,31 +202,13 @@ var Synchronizer = /*#__PURE__*/function () {
307
202
  return getShieldedBalance;
308
203
  }();
309
204
 
310
- _proto.getTransparentBalance = /*#__PURE__*/function () {
311
- var _getTransparentBalance = _asyncToGenerator(function* () {
312
- // TODO: integrate with lightwalletd service to provide taddr balance. Edge probably doesn't need this, though so it can wait.
313
- yield snooze(0); // Hack to make typescript happy
314
-
315
- return {
316
- availableZatoshi: '0',
317
- totalZatoshi: '0'
318
- };
319
- });
320
-
321
- function getTransparentBalance() {
322
- return _getTransparentBalance.apply(this, arguments);
323
- }
324
-
325
- return getTransparentBalance;
326
- }();
327
-
328
205
  _proto.getTransactions = /*#__PURE__*/function () {
329
206
  var _getTransactions = _asyncToGenerator(function* (range) {
330
207
  var result = yield RNZcash.getTransactions(this.alias, range.first, range.last);
331
208
  return result;
332
209
  });
333
210
 
334
- function getTransactions(_x15) {
211
+ function getTransactions(_x16) {
335
212
  return _getTransactions.apply(this, arguments);
336
213
  }
337
214
 
@@ -344,21 +221,16 @@ var Synchronizer = /*#__PURE__*/function () {
344
221
 
345
222
  _proto.sendToAddress = /*#__PURE__*/function () {
346
223
  var _sendToAddress = _asyncToGenerator(function* (spendInfo) {
347
- var result = yield RNZcash.spendToAddress(this.alias, spendInfo.zatoshi, spendInfo.toAddress, spendInfo.memo, spendInfo.fromAccountIndex, // TODO: ask is it okay to send this across the boundary or should it live on the native side and never leave?
348
- spendInfo.spendingKey);
224
+ var result = yield RNZcash.spendToAddress(this.alias, spendInfo.zatoshi, spendInfo.toAddress, spendInfo.memo, spendInfo.fromAccountIndex, spendInfo.spendingKey);
349
225
  return result;
350
226
  });
351
227
 
352
- function sendToAddress(_x16) {
228
+ function sendToAddress(_x17) {
353
229
  return _sendToAddress.apply(this, arguments);
354
230
  }
355
231
 
356
232
  return sendToAddress;
357
- }() // estimateFee (spendInfo: SpendInfo): string
358
- // sendToAddress (spendInfo: SpendInfo): void
359
- // getPendingTransactions (): PendingTransactions[]
360
- // getConfirmedTransactions (query: TransactionQuery): ZcashTransaction[]
361
- // Events
233
+ }() // Events
362
234
  ;
363
235
 
364
236
  _proto.subscribe = function subscribe(_ref) {
@@ -390,7 +262,6 @@ var Synchronizer = /*#__PURE__*/function () {
390
262
 
391
263
  return Synchronizer;
392
264
  }();
393
-
394
265
  var makeSynchronizer = /*#__PURE__*/function () {
395
266
  var _ref2 = _asyncToGenerator(function* (initializerConfig) {
396
267
  var synchronizer = new Synchronizer(initializerConfig.alias, initializerConfig.networkName);
@@ -398,12 +269,13 @@ var makeSynchronizer = /*#__PURE__*/function () {
398
269
  return synchronizer;
399
270
  });
400
271
 
401
- return function makeSynchronizer(_x17) {
272
+ return function makeSynchronizer(_x18) {
402
273
  return _ref2.apply(this, arguments);
403
274
  };
404
275
  }();
405
276
 
406
277
  exports.AddressTool = AddressTool;
407
278
  exports.KeyTool = KeyTool;
279
+ exports.Synchronizer = Synchronizer;
408
280
  exports.makeSynchronizer = makeSynchronizer;
409
281
  //# sourceMappingURL=rnzcash.rn.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"rnzcash.rn.js","sources":["../src/types.ts","../src/react-native.ts"],"sourcesContent":["export type Network = 'mainnet' | 'testnet'\n\nexport interface WalletBalance {\n availableZatoshi: string\n totalZatoshi: string\n}\n\nexport interface InitializerConfig {\n networkName: Network\n defaultHost: string\n defaultPort: number\n fullViewingKey: UnifiedViewingKey\n alias: string\n birthdayHeight: number\n}\n\nexport interface SpendInfo {\n zatoshi: string\n toAddress: string\n memo: string\n fromAccountIndex: number\n spendingKey?: string\n}\n\nexport interface TransactionQuery {\n offset?: number\n limit?: number\n startDate?: number\n endDate?: number\n}\n\nexport interface ZcashTransaction {\n txId: string\n accountIndex: number\n fee: string\n value: string\n direction: 'inbound' | 'outbound'\n toAddress: string\n memo?: string\n minedHeight: number // 0 for unconfirmed\n blockTime: number // UNIX timestamp\n}\n\nexport type PendingTransaction = ZcashTransaction & {\n expiryHeight: number\n cancelled: number\n submitAttempts: number\n errorMessage?: string\n errorCode?: number\n createTime: number\n}\n\nexport enum SynchronizerStatus {\n /** Indicates that [stop] has been called on this Synchronizer and it will no longer be used. */\n STOPPED,\n /** Indicates that this Synchronizer is disconnected from its lightwalletd server. When set, a UI element may want to turn red. */\n DISCONNECTED,\n /** Indicates that this Synchronizer is actively downloading new blocks from the server. */\n DOWNLOADING,\n /** Indicates that this Synchronizer is actively validating new blocks that were downloaded from the server. Blocks need to be verified before they are scanned. This confirms that each block is chain-sequential, thereby detecting missing blocks and reorgs. */\n VALIDATING,\n /** Indicates that this Synchronizer is actively decrypting new blocks that were downloaded from the server. */\n SCANNING,\n /** Indicates that this Synchronizer is actively enhancing newly scanned blocks with additional transaction details, fetched from the server. */\n ENHANCING,\n /** Indicates that this Synchronizer is fully up to date and ready for all wallet functions. When set, a UI element may want to turn green. In this state, the balance can be trusted. */\n SYNCED\n}\n\nexport interface UnifiedViewingKey {\n extfvk: string\n extpub: string\n}\n\nexport interface UpdateEvent {\n lastDownloadedHeight: number\n lastScannedHeight: number\n scanProgress: number // 0 - 100\n networkBlockHeight: number\n}\n\nexport interface SynchronizerCallbacks {\n onShieldedBalanceChanged(walletBalance: WalletBalance): void\n onStatusChanged(status: SynchronizerStatus): void\n onUpdate(event: UpdateEvent): void\n onTransactionsChanged(count: number): void\n onPendingTransactionUpdated(tx: PendingTransaction): void\n}\n\nexport interface BlockRange {\n first: number\n last: number\n}\n\nexport interface ConfirmedTransaction {\n value: string\n memo?: string\n minedHeight: number\n rawTransactionId: string\n toAddress?: string\n}\n","import {\n EventSubscription,\n NativeEventEmitter,\n NativeModules\n} from 'react-native'\n\nimport {\n BlockRange,\n ConfirmedTransaction,\n InitializerConfig,\n Network,\n PendingTransaction,\n SpendInfo,\n SynchronizerCallbacks,\n SynchronizerStatus,\n UnifiedViewingKey,\n WalletBalance\n} from './types'\n\nconst { RNZcash } = NativeModules\n\nconst snooze: Function = (ms: number) =>\n new Promise((resolve: Function) => setTimeout(resolve, ms))\n\ntype Callback = (...args: any[]) => any\n\nexport const KeyTool = {\n deriveViewingKey: async (\n seedBytesHex: string,\n network: Network\n ): Promise<UnifiedViewingKey> => {\n const result = await RNZcash.deriveViewingKey(seedBytesHex, network)\n return result\n },\n deriveSpendingKey: async (\n seedBytesHex: string,\n network: Network\n ): Promise<string> => {\n const result = await RNZcash.deriveSpendingKey(seedBytesHex, network)\n return result\n }\n}\n\nexport const AddressTool = {\n deriveShieldedAddress: async (\n viewingKey: string,\n network: Network\n ): Promise<string> => {\n const result = await RNZcash.deriveShieldedAddress(viewingKey, network)\n return result\n },\n isValidShieldedAddress: async (\n address: string,\n network: Network = 'mainnet'\n ): Promise<boolean> => {\n const result = await RNZcash.isValidShieldedAddress(address, network)\n return result\n },\n isValidTransparentAddress: async (\n address: string,\n network: Network = 'mainnet'\n ): Promise<boolean> => {\n const result = await RNZcash.isValidTransparentAddress(address, network)\n return result\n }\n}\n\nclass Synchronizer {\n eventEmitter: NativeEventEmitter\n subscriptions: EventSubscription[]\n alias: string\n network: Network\n\n constructor(alias: string, network: Network) {\n this.eventEmitter = new NativeEventEmitter(RNZcash)\n this.subscriptions = []\n this.alias = alias\n this.network = network\n }\n\n /// ////////////////////////////////////////////////////////////////\n // Start PoC behavior\n // Here are a few functions to demonstrate functionality but the final library should not have these functions\n //\n async readyToSend(): Promise<boolean> {\n const result = await RNZcash.readyToSend()\n return result\n }\n\n async sendTestTransaction(\n key: string,\n address: string\n ): Promise<PendingTransaction> {\n // send an amount that's guaranteed to be too large for our wallet and expect it to fail but at least show how this is done\n // simply change these two values to send a real transaction but ensure the function isn't called too often (although funds can't be spent if notes are unconfirmed)\n const invalidValue = '9223372036854775807' // Max long value (change this to 10000 to send a small transaction equal to the miner's fee on every reload and you could send 10,000 of those before it equals 1 ZEC)\n const invalidAccount = 99 // should be 0\n return this.sendToAddress({\n zatoshi: invalidValue,\n toAddress: address,\n memo: 'this is a test transaction that will fail',\n fromAccountIndex: invalidAccount,\n spendingKey: key\n })\n }\n\n async getBlockCount(): Promise<number> {\n const result = await RNZcash.getBlockCount()\n return result\n }\n // End PoC behavior\n /// ////////////////////////////////////////////////////////////////\n\n async start(): Promise<String> {\n const result = await RNZcash.start(this.alias)\n return result\n }\n\n async stop(): Promise<String> {\n this.unsubscribe()\n const result = await RNZcash.stop(this.alias)\n return result\n }\n\n async initialize(initializerConfig: InitializerConfig): Promise<void> {\n await RNZcash.initialize(\n initializerConfig.fullViewingKey.extfvk,\n initializerConfig.fullViewingKey.extpub,\n initializerConfig.birthdayHeight,\n initializerConfig.alias,\n initializerConfig.networkName,\n initializerConfig.defaultHost,\n initializerConfig.defaultPort\n )\n }\n\n async getLatestNetworkHeight(alias: string): Promise<number> {\n const result = await RNZcash.getLatestNetworkHeight(alias)\n return result\n }\n\n async getLatestScannedHeight(): Promise<number> {\n const result = await RNZcash.getLatestScannedHeight()\n return result\n }\n\n async getProgress(): Promise<number> {\n const result = await RNZcash.getProgress()\n return result\n }\n\n async getStatus(): Promise<SynchronizerStatus> {\n const result = await RNZcash.getStatus()\n return SynchronizerStatus[result.name as keyof typeof SynchronizerStatus]\n }\n\n async getShieldedBalance(): Promise<WalletBalance> {\n const result = await RNZcash.getShieldedBalance(this.alias)\n return result\n }\n\n async getTransparentBalance(): Promise<WalletBalance> {\n // TODO: integrate with lightwalletd service to provide taddr balance. Edge probably doesn't need this, though so it can wait.\n\n await snooze(0) // Hack to make typescript happy\n return {\n availableZatoshi: '0',\n totalZatoshi: '0'\n }\n }\n\n async getTransactions(range: BlockRange): Promise<ConfirmedTransaction[]> {\n const result = await RNZcash.getTransactions(\n this.alias,\n range.first,\n range.last\n )\n return result\n }\n\n rescan(height: number): void {\n RNZcash.rescan(this.alias, height)\n }\n\n async sendToAddress(spendInfo: SpendInfo): Promise<PendingTransaction> {\n const result = await RNZcash.spendToAddress(\n this.alias,\n spendInfo.zatoshi,\n spendInfo.toAddress,\n spendInfo.memo,\n spendInfo.fromAccountIndex,\n // TODO: ask is it okay to send this across the boundary or should it live on the native side and never leave?\n spendInfo.spendingKey\n )\n return result\n }\n\n // estimateFee (spendInfo: SpendInfo): string\n // sendToAddress (spendInfo: SpendInfo): void\n\n // getPendingTransactions (): PendingTransactions[]\n // getConfirmedTransactions (query: TransactionQuery): ZcashTransaction[]\n\n // Events\n\n subscribe({ onStatusChanged, onUpdate }: SynchronizerCallbacks): void {\n this.setListener('StatusEvent', onStatusChanged)\n this.setListener('UpdateEvent', onUpdate)\n }\n\n private setListener<T>(\n eventName: string,\n callback: Callback = (t: any) => null\n ): void {\n this.subscriptions.push(\n this.eventEmitter.addListener(eventName, arg =>\n arg.alias === this.alias ? callback(arg) : null\n )\n )\n }\n\n unsubscribe(): void {\n this.subscriptions.forEach(subscription => {\n subscription.remove()\n })\n }\n}\n\nexport const makeSynchronizer = async (\n initializerConfig: InitializerConfig\n): Promise<Synchronizer> => {\n const synchronizer = new Synchronizer(\n initializerConfig.alias,\n initializerConfig.networkName\n )\n await synchronizer.initialize(initializerConfig)\n return synchronizer\n}\n"],"names":["SynchronizerStatus","RNZcash","NativeModules","snooze","ms","Promise","resolve","setTimeout","KeyTool","deriveViewingKey","seedBytesHex","network","result","deriveSpendingKey","AddressTool","deriveShieldedAddress","viewingKey","isValidShieldedAddress","address","isValidTransparentAddress","Synchronizer","alias","eventEmitter","NativeEventEmitter","subscriptions","readyToSend","sendTestTransaction","key","invalidValue","invalidAccount","sendToAddress","zatoshi","toAddress","memo","fromAccountIndex","spendingKey","getBlockCount","start","stop","unsubscribe","initialize","initializerConfig","fullViewingKey","extfvk","extpub","birthdayHeight","networkName","defaultHost","defaultPort","getLatestNetworkHeight","getLatestScannedHeight","getProgress","getStatus","name","getShieldedBalance","getTransparentBalance","availableZatoshi","totalZatoshi","getTransactions","range","first","last","rescan","height","spendInfo","spendToAddress","subscribe","onStatusChanged","onUpdate","setListener","eventName","callback","t","push","addListener","arg","forEach","subscription","remove","makeSynchronizer","synchronizer"],"mappings":"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"}
1
+ {"version":3,"file":"rnzcash.rn.js","sources":["../src/react-native.ts"],"sourcesContent":["import {\n EventSubscription,\n NativeEventEmitter,\n NativeModules,\n Platform\n} from 'react-native'\n\nimport {\n BlockRange,\n ConfirmedTransaction,\n InitializerConfig,\n Network,\n SpendFailure,\n SpendInfo,\n SpendSuccess,\n SynchronizerCallbacks,\n UnifiedViewingKey,\n WalletBalance\n} from './types'\n\nconst { RNZcash } = NativeModules\n\ntype Callback = (...args: any[]) => any\n\nconst isAndroid = Platform.OS === 'android'\n\nexport const KeyTool = {\n deriveViewingKey: async (\n seedBytesHex: string,\n network: Network\n ): Promise<UnifiedViewingKey> => {\n const result = await RNZcash.deriveViewingKey(seedBytesHex, network)\n return result\n },\n deriveSpendingKey: async (\n seedBytesHex: string,\n network: Network\n ): Promise<string> => {\n const result = await RNZcash.deriveSpendingKey(seedBytesHex, network)\n return result\n },\n getBirthdayHeight: async (\n network: 'mainnet' | 'testnet',\n host: string,\n port: number\n ): Promise<number> => {\n const args = isAndroid ? [network] : [host, port]\n const result = await RNZcash.getBirthdayHeight(...args)\n return result\n }\n}\n\nexport const AddressTool = {\n deriveShieldedAddress: async (\n viewingKey: string,\n network: Network\n ): Promise<string> => {\n const result = await RNZcash.deriveShieldedAddress(viewingKey, network)\n return result\n },\n isValidShieldedAddress: async (\n address: string,\n network: Network = 'mainnet'\n ): Promise<boolean> => {\n const result = await RNZcash.isValidShieldedAddress(address, network)\n return result\n },\n isValidTransparentAddress: async (\n address: string,\n network: Network = 'mainnet'\n ): Promise<boolean> => {\n const result = await RNZcash.isValidTransparentAddress(address, network)\n return result\n }\n}\n\nexport class Synchronizer {\n eventEmitter: NativeEventEmitter\n subscriptions: EventSubscription[]\n alias: string\n network: Network\n\n constructor(alias: string, network: Network) {\n this.eventEmitter = new NativeEventEmitter(RNZcash)\n this.subscriptions = []\n this.alias = alias\n this.network = network\n }\n\n async start(): Promise<String> {\n const result = await RNZcash.start(this.alias)\n return result\n }\n\n async stop(): Promise<String> {\n this.unsubscribe()\n const result = await RNZcash.stop(this.alias)\n return result\n }\n\n async initialize(initializerConfig: InitializerConfig): Promise<void> {\n await RNZcash.initialize(\n initializerConfig.fullViewingKey.extfvk,\n initializerConfig.fullViewingKey.extpub,\n initializerConfig.birthdayHeight,\n initializerConfig.alias,\n initializerConfig.networkName,\n initializerConfig.defaultHost,\n initializerConfig.defaultPort\n )\n }\n\n async getLatestNetworkHeight(alias: string): Promise<number> {\n const result = await RNZcash.getLatestNetworkHeight(alias)\n return result\n }\n\n async getShieldedBalance(): Promise<WalletBalance> {\n const result = await RNZcash.getShieldedBalance(this.alias)\n return result\n }\n\n async getTransactions(range: BlockRange): Promise<ConfirmedTransaction[]> {\n const result = await RNZcash.getTransactions(\n this.alias,\n range.first,\n range.last\n )\n return result\n }\n\n rescan(height: number): void {\n RNZcash.rescan(this.alias, height)\n }\n\n async sendToAddress(\n spendInfo: SpendInfo\n ): Promise<SpendSuccess | SpendFailure> {\n const result = await RNZcash.spendToAddress(\n this.alias,\n spendInfo.zatoshi,\n spendInfo.toAddress,\n spendInfo.memo,\n spendInfo.fromAccountIndex,\n spendInfo.spendingKey\n )\n return result\n }\n\n // Events\n\n subscribe({ onStatusChanged, onUpdate }: SynchronizerCallbacks): void {\n this.setListener('StatusEvent', onStatusChanged)\n this.setListener('UpdateEvent', onUpdate)\n }\n\n private setListener<T>(\n eventName: string,\n callback: Callback = (t: any) => null\n ): void {\n this.subscriptions.push(\n this.eventEmitter.addListener(eventName, arg =>\n arg.alias === this.alias ? callback(arg) : null\n )\n )\n }\n\n unsubscribe(): void {\n this.subscriptions.forEach(subscription => {\n subscription.remove()\n })\n }\n}\n\nexport const makeSynchronizer = async (\n initializerConfig: InitializerConfig\n): Promise<Synchronizer> => {\n const synchronizer = new Synchronizer(\n initializerConfig.alias,\n initializerConfig.networkName\n )\n await synchronizer.initialize(initializerConfig)\n return synchronizer\n}\n"],"names":["RNZcash","NativeModules","isAndroid","Platform","OS","KeyTool","deriveViewingKey","seedBytesHex","network","result","deriveSpendingKey","getBirthdayHeight","host","port","args","AddressTool","deriveShieldedAddress","viewingKey","isValidShieldedAddress","address","isValidTransparentAddress","Synchronizer","alias","eventEmitter","NativeEventEmitter","subscriptions","start","stop","unsubscribe","initialize","initializerConfig","fullViewingKey","extfvk","extpub","birthdayHeight","networkName","defaultHost","defaultPort","getLatestNetworkHeight","getShieldedBalance","getTransactions","range","first","last","rescan","height","sendToAddress","spendInfo","spendToAddress","zatoshi","toAddress","memo","fromAccountIndex","spendingKey","subscribe","onStatusChanged","onUpdate","setListener","eventName","callback","t","push","addListener","arg","forEach","subscription","remove","makeSynchronizer","synchronizer"],"mappings":"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"}
@@ -1,38 +1,31 @@
1
1
  import { EventSubscription, NativeEventEmitter } from 'react-native';
2
- import { BlockRange, ConfirmedTransaction, InitializerConfig, Network, PendingTransaction, SpendInfo, SynchronizerCallbacks, SynchronizerStatus, UnifiedViewingKey, WalletBalance } from './types';
2
+ import { BlockRange, ConfirmedTransaction, InitializerConfig, Network, SpendFailure, SpendInfo, SpendSuccess, SynchronizerCallbacks, UnifiedViewingKey, WalletBalance } from './types';
3
3
  export declare const KeyTool: {
4
4
  deriveViewingKey: (seedBytesHex: string, network: Network) => Promise<UnifiedViewingKey>;
5
5
  deriveSpendingKey: (seedBytesHex: string, network: Network) => Promise<string>;
6
+ getBirthdayHeight: (network: 'mainnet' | 'testnet', host: string, port: number) => Promise<number>;
6
7
  };
7
8
  export declare const AddressTool: {
8
9
  deriveShieldedAddress: (viewingKey: string, network: Network) => Promise<string>;
9
10
  isValidShieldedAddress: (address: string, network?: Network) => Promise<boolean>;
10
11
  isValidTransparentAddress: (address: string, network?: Network) => Promise<boolean>;
11
12
  };
12
- declare class Synchronizer {
13
+ export declare class Synchronizer {
13
14
  eventEmitter: NativeEventEmitter;
14
15
  subscriptions: EventSubscription[];
15
16
  alias: string;
16
17
  network: Network;
17
18
  constructor(alias: string, network: Network);
18
- readyToSend(): Promise<boolean>;
19
- sendTestTransaction(key: string, address: string): Promise<PendingTransaction>;
20
- getBlockCount(): Promise<number>;
21
19
  start(): Promise<String>;
22
20
  stop(): Promise<String>;
23
21
  initialize(initializerConfig: InitializerConfig): Promise<void>;
24
22
  getLatestNetworkHeight(alias: string): Promise<number>;
25
- getLatestScannedHeight(): Promise<number>;
26
- getProgress(): Promise<number>;
27
- getStatus(): Promise<SynchronizerStatus>;
28
23
  getShieldedBalance(): Promise<WalletBalance>;
29
- getTransparentBalance(): Promise<WalletBalance>;
30
24
  getTransactions(range: BlockRange): Promise<ConfirmedTransaction[]>;
31
25
  rescan(height: number): void;
32
- sendToAddress(spendInfo: SpendInfo): Promise<PendingTransaction>;
26
+ sendToAddress(spendInfo: SpendInfo): Promise<SpendSuccess | SpendFailure>;
33
27
  subscribe({ onStatusChanged, onUpdate }: SynchronizerCallbacks): void;
34
28
  private setListener;
35
29
  unsubscribe(): void;
36
30
  }
37
31
  export declare const makeSynchronizer: (initializerConfig: InitializerConfig) => Promise<Synchronizer>;
38
- export {};
@@ -16,74 +16,50 @@ export interface SpendInfo {
16
16
  toAddress: string;
17
17
  memo: string;
18
18
  fromAccountIndex: number;
19
- spendingKey?: string;
19
+ spendingKey: string;
20
20
  }
21
- export interface TransactionQuery {
22
- offset?: number;
23
- limit?: number;
24
- startDate?: number;
25
- endDate?: number;
26
- }
27
- export interface ZcashTransaction {
21
+ export interface SpendSuccess {
28
22
  txId: string;
29
- accountIndex: number;
30
- fee: string;
31
- value: string;
32
- direction: 'inbound' | 'outbound';
33
- toAddress: string;
34
- memo?: string;
35
- minedHeight: number;
36
- blockTime: number;
23
+ raw: string;
37
24
  }
38
- export declare type PendingTransaction = ZcashTransaction & {
39
- expiryHeight: number;
40
- cancelled: number;
41
- submitAttempts: number;
25
+ export interface SpendFailure {
42
26
  errorMessage?: string;
43
- errorCode?: number;
44
- createTime: number;
45
- };
46
- export declare enum SynchronizerStatus {
47
- /** Indicates that [stop] has been called on this Synchronizer and it will no longer be used. */
48
- STOPPED = 0,
49
- /** Indicates that this Synchronizer is disconnected from its lightwalletd server. When set, a UI element may want to turn red. */
50
- DISCONNECTED = 1,
51
- /** Indicates that this Synchronizer is actively downloading new blocks from the server. */
52
- DOWNLOADING = 2,
53
- /** Indicates that this Synchronizer is actively validating new blocks that were downloaded from the server. Blocks need to be verified before they are scanned. This confirms that each block is chain-sequential, thereby detecting missing blocks and reorgs. */
54
- VALIDATING = 3,
55
- /** Indicates that this Synchronizer is actively decrypting new blocks that were downloaded from the server. */
56
- SCANNING = 4,
57
- /** Indicates that this Synchronizer is actively enhancing newly scanned blocks with additional transaction details, fetched from the server. */
58
- ENHANCING = 5,
59
- /** Indicates that this Synchronizer is fully up to date and ready for all wallet functions. When set, a UI element may want to turn green. In this state, the balance can be trusted. */
60
- SYNCED = 6
27
+ errorCode?: string;
28
+ }
29
+ export interface SynchronizerStatus {
30
+ alias: string;
31
+ name: 'STOPPED' /** Indicates that [stop] has been called on this Synchronizer and it will no longer be used. */ | 'DISCONNECTED' /** Indicates that this Synchronizer is disconnected from its lightwalletd server. When set, a UI element may want to turn red. */ | 'DOWNLOADING' /** Indicates that this Synchronizer is actively downloading new blocks from the server. */ | 'VALIDATING' /** Indicates that this Synchronizer is actively validating new blocks that were downloaded from the server. Blocks need to be verified before they are scanned. This confirms that each block is chain-sequential, thereby detecting missing blocks and reorgs. */ | 'SCANNING' /** Indicates that this Synchronizer is actively decrypting new blocks that were downloaded from the server. */ | 'ENHANCING' /** Indicates that this Synchronizer is actively enhancing newly scanned blocks with additional transaction details, fetched from the server. */ | 'SYNCED'; /** Indicates that this Synchronizer is fully up to date and ready for all wallet functions. When set, a UI element may want to turn green. In this state, the balance can be trusted. */
61
32
  }
62
33
  export interface UnifiedViewingKey {
63
34
  extfvk: string;
64
35
  extpub: string;
65
36
  }
37
+ export interface StatusEvent {
38
+ alias: string;
39
+ name: SynchronizerStatus;
40
+ }
66
41
  export interface UpdateEvent {
42
+ alias: string;
43
+ isDownloading: boolean;
44
+ isScanning: boolean;
67
45
  lastDownloadedHeight: number;
68
46
  lastScannedHeight: number;
69
47
  scanProgress: number;
70
48
  networkBlockHeight: number;
71
49
  }
72
50
  export interface SynchronizerCallbacks {
73
- onShieldedBalanceChanged(walletBalance: WalletBalance): void;
74
51
  onStatusChanged(status: SynchronizerStatus): void;
75
52
  onUpdate(event: UpdateEvent): void;
76
- onTransactionsChanged(count: number): void;
77
- onPendingTransactionUpdated(tx: PendingTransaction): void;
78
53
  }
79
54
  export interface BlockRange {
80
55
  first: number;
81
56
  last: number;
82
57
  }
83
58
  export interface ConfirmedTransaction {
84
- value: string;
85
- memo?: string;
86
- minedHeight: number;
87
59
  rawTransactionId: string;
60
+ blockTimeInSeconds: number;
61
+ minedHeight: number;
62
+ value: string;
88
63
  toAddress?: string;
64
+ memo?: string;
89
65
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-zcash",
3
- "version": "0.2.2",
3
+ "version": "0.3.1",
4
4
  "description": "Zcash library for React Native",
5
5
  "homepage": "https://github.com/EdgeApp/react-native-zcash",
6
6
  "repository": {
@@ -31,7 +31,7 @@
31
31
  "src"
32
32
  ],
33
33
  "main": "lib/rnzcash.rn.js",
34
- "types": "lib/src/index.d.ts",
34
+ "types": "lib/src/react-native.d.ts",
35
35
  "scripts": {
36
36
  "fix": "npm run lint -- --fix",
37
37
  "lint": "eslint .",
@@ -1,7 +1,8 @@
1
1
  import {
2
2
  EventSubscription,
3
3
  NativeEventEmitter,
4
- NativeModules
4
+ NativeModules,
5
+ Platform
5
6
  } from 'react-native'
6
7
 
7
8
  import {
@@ -9,21 +10,20 @@ import {
9
10
  ConfirmedTransaction,
10
11
  InitializerConfig,
11
12
  Network,
12
- PendingTransaction,
13
+ SpendFailure,
13
14
  SpendInfo,
15
+ SpendSuccess,
14
16
  SynchronizerCallbacks,
15
- SynchronizerStatus,
16
17
  UnifiedViewingKey,
17
18
  WalletBalance
18
19
  } from './types'
19
20
 
20
21
  const { RNZcash } = NativeModules
21
22
 
22
- const snooze: Function = (ms: number) =>
23
- new Promise((resolve: Function) => setTimeout(resolve, ms))
24
-
25
23
  type Callback = (...args: any[]) => any
26
24
 
25
+ const isAndroid = Platform.OS === 'android'
26
+
27
27
  export const KeyTool = {
28
28
  deriveViewingKey: async (
29
29
  seedBytesHex: string,
@@ -38,6 +38,15 @@ export const KeyTool = {
38
38
  ): Promise<string> => {
39
39
  const result = await RNZcash.deriveSpendingKey(seedBytesHex, network)
40
40
  return result
41
+ },
42
+ getBirthdayHeight: async (
43
+ network: 'mainnet' | 'testnet',
44
+ host: string,
45
+ port: number
46
+ ): Promise<number> => {
47
+ const args = isAndroid ? [network] : [host, port]
48
+ const result = await RNZcash.getBirthdayHeight(...args)
49
+ return result
41
50
  }
42
51
  }
43
52
 
@@ -65,7 +74,7 @@ export const AddressTool = {
65
74
  }
66
75
  }
67
76
 
68
- class Synchronizer {
77
+ export class Synchronizer {
69
78
  eventEmitter: NativeEventEmitter
70
79
  subscriptions: EventSubscription[]
71
80
  alias: string
@@ -78,39 +87,6 @@ class Synchronizer {
78
87
  this.network = network
79
88
  }
80
89
 
81
- /// ////////////////////////////////////////////////////////////////
82
- // Start PoC behavior
83
- // Here are a few functions to demonstrate functionality but the final library should not have these functions
84
- //
85
- async readyToSend(): Promise<boolean> {
86
- const result = await RNZcash.readyToSend()
87
- return result
88
- }
89
-
90
- async sendTestTransaction(
91
- key: string,
92
- address: string
93
- ): Promise<PendingTransaction> {
94
- // send an amount that's guaranteed to be too large for our wallet and expect it to fail but at least show how this is done
95
- // simply change these two values to send a real transaction but ensure the function isn't called too often (although funds can't be spent if notes are unconfirmed)
96
- const invalidValue = '9223372036854775807' // Max long value (change this to 10000 to send a small transaction equal to the miner's fee on every reload and you could send 10,000 of those before it equals 1 ZEC)
97
- const invalidAccount = 99 // should be 0
98
- return this.sendToAddress({
99
- zatoshi: invalidValue,
100
- toAddress: address,
101
- memo: 'this is a test transaction that will fail',
102
- fromAccountIndex: invalidAccount,
103
- spendingKey: key
104
- })
105
- }
106
-
107
- async getBlockCount(): Promise<number> {
108
- const result = await RNZcash.getBlockCount()
109
- return result
110
- }
111
- // End PoC behavior
112
- /// ////////////////////////////////////////////////////////////////
113
-
114
90
  async start(): Promise<String> {
115
91
  const result = await RNZcash.start(this.alias)
116
92
  return result
@@ -139,36 +115,11 @@ class Synchronizer {
139
115
  return result
140
116
  }
141
117
 
142
- async getLatestScannedHeight(): Promise<number> {
143
- const result = await RNZcash.getLatestScannedHeight()
144
- return result
145
- }
146
-
147
- async getProgress(): Promise<number> {
148
- const result = await RNZcash.getProgress()
149
- return result
150
- }
151
-
152
- async getStatus(): Promise<SynchronizerStatus> {
153
- const result = await RNZcash.getStatus()
154
- return SynchronizerStatus[result.name as keyof typeof SynchronizerStatus]
155
- }
156
-
157
118
  async getShieldedBalance(): Promise<WalletBalance> {
158
119
  const result = await RNZcash.getShieldedBalance(this.alias)
159
120
  return result
160
121
  }
161
122
 
162
- async getTransparentBalance(): Promise<WalletBalance> {
163
- // TODO: integrate with lightwalletd service to provide taddr balance. Edge probably doesn't need this, though so it can wait.
164
-
165
- await snooze(0) // Hack to make typescript happy
166
- return {
167
- availableZatoshi: '0',
168
- totalZatoshi: '0'
169
- }
170
- }
171
-
172
123
  async getTransactions(range: BlockRange): Promise<ConfirmedTransaction[]> {
173
124
  const result = await RNZcash.getTransactions(
174
125
  this.alias,
@@ -182,25 +133,20 @@ class Synchronizer {
182
133
  RNZcash.rescan(this.alias, height)
183
134
  }
184
135
 
185
- async sendToAddress(spendInfo: SpendInfo): Promise<PendingTransaction> {
136
+ async sendToAddress(
137
+ spendInfo: SpendInfo
138
+ ): Promise<SpendSuccess | SpendFailure> {
186
139
  const result = await RNZcash.spendToAddress(
187
140
  this.alias,
188
141
  spendInfo.zatoshi,
189
142
  spendInfo.toAddress,
190
143
  spendInfo.memo,
191
144
  spendInfo.fromAccountIndex,
192
- // TODO: ask is it okay to send this across the boundary or should it live on the native side and never leave?
193
145
  spendInfo.spendingKey
194
146
  )
195
147
  return result
196
148
  }
197
149
 
198
- // estimateFee (spendInfo: SpendInfo): string
199
- // sendToAddress (spendInfo: SpendInfo): void
200
-
201
- // getPendingTransactions (): PendingTransactions[]
202
- // getConfirmedTransactions (query: TransactionQuery): ZcashTransaction[]
203
-
204
150
  // Events
205
151
 
206
152
  subscribe({ onStatusChanged, onUpdate }: SynchronizerCallbacks): void {
package/src/types.ts CHANGED
@@ -19,52 +19,29 @@ export interface SpendInfo {
19
19
  toAddress: string
20
20
  memo: string
21
21
  fromAccountIndex: number
22
- spendingKey?: string
22
+ spendingKey: string
23
23
  }
24
24
 
25
- export interface TransactionQuery {
26
- offset?: number
27
- limit?: number
28
- startDate?: number
29
- endDate?: number
30
- }
31
-
32
- export interface ZcashTransaction {
25
+ export interface SpendSuccess {
33
26
  txId: string
34
- accountIndex: number
35
- fee: string
36
- value: string
37
- direction: 'inbound' | 'outbound'
38
- toAddress: string
39
- memo?: string
40
- minedHeight: number // 0 for unconfirmed
41
- blockTime: number // UNIX timestamp
27
+ raw: string
42
28
  }
43
29
 
44
- export type PendingTransaction = ZcashTransaction & {
45
- expiryHeight: number
46
- cancelled: number
47
- submitAttempts: number
30
+ export interface SpendFailure {
48
31
  errorMessage?: string
49
- errorCode?: number
50
- createTime: number
32
+ errorCode?: string
51
33
  }
52
34
 
53
- export enum SynchronizerStatus {
54
- /** Indicates that [stop] has been called on this Synchronizer and it will no longer be used. */
55
- STOPPED,
56
- /** Indicates that this Synchronizer is disconnected from its lightwalletd server. When set, a UI element may want to turn red. */
57
- DISCONNECTED,
58
- /** Indicates that this Synchronizer is actively downloading new blocks from the server. */
59
- DOWNLOADING,
60
- /** Indicates that this Synchronizer is actively validating new blocks that were downloaded from the server. Blocks need to be verified before they are scanned. This confirms that each block is chain-sequential, thereby detecting missing blocks and reorgs. */
61
- VALIDATING,
62
- /** Indicates that this Synchronizer is actively decrypting new blocks that were downloaded from the server. */
63
- SCANNING,
64
- /** Indicates that this Synchronizer is actively enhancing newly scanned blocks with additional transaction details, fetched from the server. */
65
- ENHANCING,
66
- /** Indicates that this Synchronizer is fully up to date and ready for all wallet functions. When set, a UI element may want to turn green. In this state, the balance can be trusted. */
67
- SYNCED
35
+ export interface SynchronizerStatus {
36
+ alias: string
37
+ name:
38
+ | 'STOPPED' /** Indicates that [stop] has been called on this Synchronizer and it will no longer be used. */
39
+ | 'DISCONNECTED' /** Indicates that this Synchronizer is disconnected from its lightwalletd server. When set, a UI element may want to turn red. */
40
+ | 'DOWNLOADING' /** Indicates that this Synchronizer is actively downloading new blocks from the server. */
41
+ | 'VALIDATING' /** Indicates that this Synchronizer is actively validating new blocks that were downloaded from the server. Blocks need to be verified before they are scanned. This confirms that each block is chain-sequential, thereby detecting missing blocks and reorgs. */
42
+ | 'SCANNING' /** Indicates that this Synchronizer is actively decrypting new blocks that were downloaded from the server. */
43
+ | 'ENHANCING' /** Indicates that this Synchronizer is actively enhancing newly scanned blocks with additional transaction details, fetched from the server. */
44
+ | 'SYNCED' /** Indicates that this Synchronizer is fully up to date and ready for all wallet functions. When set, a UI element may want to turn green. In this state, the balance can be trusted. */
68
45
  }
69
46
 
70
47
  export interface UnifiedViewingKey {
@@ -72,7 +49,15 @@ export interface UnifiedViewingKey {
72
49
  extpub: string
73
50
  }
74
51
 
52
+ export interface StatusEvent {
53
+ alias: string
54
+ name: SynchronizerStatus
55
+ }
56
+
75
57
  export interface UpdateEvent {
58
+ alias: string
59
+ isDownloading: boolean
60
+ isScanning: boolean
76
61
  lastDownloadedHeight: number
77
62
  lastScannedHeight: number
78
63
  scanProgress: number // 0 - 100
@@ -80,11 +65,8 @@ export interface UpdateEvent {
80
65
  }
81
66
 
82
67
  export interface SynchronizerCallbacks {
83
- onShieldedBalanceChanged(walletBalance: WalletBalance): void
84
68
  onStatusChanged(status: SynchronizerStatus): void
85
69
  onUpdate(event: UpdateEvent): void
86
- onTransactionsChanged(count: number): void
87
- onPendingTransactionUpdated(tx: PendingTransaction): void
88
70
  }
89
71
 
90
72
  export interface BlockRange {
@@ -93,9 +75,10 @@ export interface BlockRange {
93
75
  }
94
76
 
95
77
  export interface ConfirmedTransaction {
96
- value: string
97
- memo?: string
98
- minedHeight: number
99
78
  rawTransactionId: string
79
+ blockTimeInSeconds: number
80
+ minedHeight: number
81
+ value: string
100
82
  toAddress?: string
83
+ memo?: string
101
84
  }