react-native-zcash 0.1.0 → 0.2.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # React Native Zcash
2
2
 
3
+ ## 0.2.0 (2022-01-10)
4
+
5
+ - Add iOS support
6
+ - Android: Cleanup unused methods
7
+
3
8
  ## 0.1.0 (2021-11-09)
4
9
 
5
10
  - Initial release
@@ -0,0 +1,23 @@
1
+ #!/bin/bash
2
+
3
+ BASEPATH="${PWD}"
4
+ TARGET_DIR="target"
5
+
6
+
7
+ LIB_PATH="ZcashLightClientKit/$FLAVOR_FOLDER/zcashlc"
8
+ echo "++++ Building librustzcash $NETWORK_TYPE library ++++"
9
+
10
+
11
+ if [ -f $TARGET_DIR ]; then
12
+ rm -rf $TARGET_DIR
13
+ fi
14
+
15
+ cargo lipo --manifest-path ${PODS_TARGET_SRCROOT}/Cargo.toml --release
16
+
17
+
18
+ if [ -f $LIB_PATH ]; then
19
+ rm -rf $LIB_PATH
20
+ mkdir -p $LIB_PATH
21
+ fi
22
+
23
+ cp -rf $TARGET_DIR/universal/release/* $LIB_PATH
@@ -0,0 +1,64 @@
1
+ #!/bin/sh
2
+
3
+ set -x
4
+
5
+ SCRIPT_COMMONS="${PODS_TARGET_SRCROOT}/Scripts/script_commons.sh"
6
+ if [ ! -f $SCRIPT_COMMONS ]; then
7
+ echo "Failed to load $SCRIPT_COMMONS"
8
+ exit 1
9
+ fi
10
+ source $SCRIPT_COMMONS
11
+
12
+ if [ "$ACTION" = "clean" ]; then
13
+ echo "CLEAN DETECTED"
14
+ clean
15
+ exit 0
16
+ fi
17
+
18
+ echo "Building Rust backend"
19
+ echo ""
20
+ echo "${PODS_TARGET_SRCROOT}"
21
+ echo "platform name"
22
+ echo $PLATFORM_NAME
23
+ if [ $PLATFORM_NAME = "iphonesimulator" ]; then
24
+ ZCASH_ACTIVE_ARCHITECTURE="aarch64-apple-ios-sim x86_64-apple-ios"
25
+ RUSTUP_TOOLCHAIN="nightly-2021-09-24"
26
+ else
27
+ ZCASH_ACTIVE_ARCHITECTURE="aarch64-apple-ios"
28
+ RUSTUP_TOOLCHAIN="stable"
29
+ fi
30
+
31
+ echo "fix 'permission denied issue'"
32
+ chmod -R +w ${PODS_TARGET_SRCROOT}
33
+
34
+ echo "RUSTUP_TOOLCHAIN=${RUSTUP_TOOLCHAIN} cargo build --manifest-path ${PODS_TARGET_SRCROOT}/Cargo.toml --target $ZCASH_ACTIVE_ARCHITECTURE --release"
35
+ if [[ -n "${DEVELOPER_SDK_DIR:-}" ]]; then
36
+ # Assume we're in Xcode, which means we're probably cross-compiling.
37
+ # In this case, we need to add an extra library search path for build scripts and proc-macros,
38
+ # which run on the host instead of the target.
39
+ # (macOS Big Sur does not have linkable libraries in /usr/lib/.)
40
+ echo "export LIBRARY_PATH=\"${DEVELOPER_SDK_DIR}/MacOSX.sdk/usr/lib:${LIBRARY_PATH:-}\""
41
+ export LIBRARY_PATH="${DEVELOPER_SDK_DIR}/MacOSX.sdk/usr/lib:${LIBRARY_PATH:-}"
42
+ fi
43
+ if [ ! -f ${ZCASH_LIB_RUST_BUILD_PATH}/universal/release/${ZCASH_LIB_RUST_NAME} ]; then
44
+ RUSTUP_TOOLCHAIN=${RUSTUP_TOOLCHAIN} cargo lipo --manifest-path ${PODS_TARGET_SRCROOT}/Cargo.toml --targets $ZCASH_ACTIVE_ARCHITECTURE --release
45
+ persist_environment
46
+ fi
47
+
48
+
49
+
50
+ if [ ! -d "${RUST_LIB_PATH}" ]; then
51
+ mkdir -p "${RUST_LIB_PATH}"
52
+ fi
53
+
54
+ echo "clean up existing artifacts: rm -f ${ZCASH_SDK_RUST_LIB_PATH}/${ZCASH_LIB_RUST_NAME}"
55
+ rm -f "${ZCASH_SDK_RUST_LIB_PATH}/${ZCASH_LIB_RUST_NAME}"
56
+ echo "clean up sdk lib path: rm -f ${RUST_LIB_PATH}/${ZCASH_LIB_RUST_NAME}"
57
+
58
+ rm -f "${RUST_LIB_PATH}/${ZCASH_LIB_RUST_NAME}"
59
+ echo "copying artifacts: cp -f ${ZCASH_LIB_RUST_BUILD_PATH}/universal/release/${ZCASH_LIB_RUST_NAME} ${ZCASH_SDK_RUST_LIB_PATH}/${ZCASH_LIB_RUST_NAME}"
60
+ # ALWAYS SHIP RELEASE NO MATTER WHAT YOUR BUILD IS (FOR NOW AT LEAST)
61
+ cp -f "${ZCASH_LIB_RUST_BUILD_PATH}/universal/release/${ZCASH_LIB_RUST_NAME}" "${ZCASH_SDK_RUST_LIB_PATH}/${ZCASH_LIB_RUST_NAME}"
62
+ echo "copying artifacts: cp -f ${ZCASH_LIB_RUST_BUILD_PATH}/universal/release/${ZCASH_LIB_RUST_NAME} ${RUST_LIB_PATH}/${ZCASH_LIB_RUST_NAME}"
63
+ cp -f "${ZCASH_LIB_RUST_BUILD_PATH}/universal/release/${ZCASH_LIB_RUST_NAME}" "${RUST_LIB_PATH}/${ZCASH_LIB_RUST_NAME}"
64
+
@@ -0,0 +1,16 @@
1
+ #!/bin/sh
2
+ #check if env-vars.sh exists
3
+ ENV_VARS_PATH=${PODS_TARGET_SRCROOT}/env-vars.sh
4
+ if [ -f $ENV_VARS_PATH ]; then
5
+ source $ENV_VARS_PATH
6
+ echo "importing $ENV_VARS_PATH"
7
+ fi
8
+
9
+ export ZCASH_TEST_SRC_PATH="${PODS_TARGET_SRCROOT}/ZcashLightClientKitTests"
10
+ if [ ! ${LIGHTWALLETD_ADDRESS} ]; then
11
+ echo "LIGHTWALLETD_ADDRESS VARIABLE NOT DEFINED"
12
+ exit 1
13
+ fi
14
+ echo "export ZCASH_TEST_SRC_PATH=$ZCASH_TEST_SRC_PATH"
15
+ #no `else` case needed if the CI works as expected
16
+ sourcery --templates "${ZCASH_TEST_SRC_PATH}/Stencil" --sources ${ZCASH_TEST_SRC_PATH} --output ${ZCASH_TEST_SRC_PATH} --args addr=$LIGHTWALLETD_ADDRESS
@@ -0,0 +1,31 @@
1
+ #!/bin/sh
2
+
3
+ cargo install cargo-lipo
4
+ rustup target add aarch64-apple-ios x86_64-apple-ios
5
+
6
+ echo "PWD: ${PWD}"
7
+
8
+ echo "*********************************************"
9
+ echo "* create fake .a so pod install picks it up *"
10
+ echo "*********************************************"
11
+ RUST_LIB_PATH="${PWD}"/lib
12
+ mkdir -p -v $RUST_LIB_PATH
13
+ echo "******************************************************************************"
14
+ echo " touch $RUST_LIB_PATH/libzcashlc.a "
15
+ echo "******************************************************************************"
16
+ touch $RUST_LIB_PATH/libzcashlc.a
17
+
18
+
19
+ ZCASH_POD_ROOT="${PWD%/*/*}"
20
+ ZCASH_POD_SRCROOT="${ZCASH_POD_ROOT}/ios/Pods/ZcashLightClientKit/ZcashLightClientKit"
21
+ ZCASH_SDK_GENERATED_SOURCES_FOLDER="${ZCASH_POD_SRCROOT}/Generated"
22
+
23
+ echo "***************************************************************************"
24
+ echo " touch ${ZCASH_POD_ROOT}/zcashlc/libzcashlc.a"
25
+ echo "***************************************************************************"
26
+ touch ${ZCASH_POD_SRCROOT}/zcashlc/libzcashlc.a
27
+
28
+ echo "***************************************************************************"
29
+ echo " touch ${ZCASH_POD_ROOT}/zcashlc/zcashlc.h"
30
+ echo "***************************************************************************"
31
+ touch ${ZCASH_POD_SRCROOT}/zcashlc/zcashlc.h
@@ -0,0 +1,23 @@
1
+ #!/bin/sh
2
+
3
+ export PATH="$HOME/.cargo/bin:$PATH"
4
+ export RUST_LIB_PATH="${PODS_TARGET_SRCROOT}/lib"
5
+ export ZCASH_POD_SCRIPTS="${PODS_TARGET_SRCROOT}/Scripts"
6
+ export ZCASH_LIB_RUST_BUILD_PATH="${PODS_TARGET_SRCROOT%/*/*/*/*}/ZcashLightClientKit/target"
7
+
8
+ export ZCASH_LIB_RUST_NAME="libzcashlc.a"
9
+
10
+ export ZCASH_SRC_PATH="${PODS_TARGET_SRCROOT%/*/*/*/*}/ZcashLightClientKit/ZcashLightClientKit"
11
+ export ZCASH_SDK_RUST_LIB_PATH="${ZCASH_SRC_PATH}/zcashlc"
12
+
13
+
14
+ function clean {
15
+ echo "CLEAN DETECTED"
16
+ cargo clean
17
+ if [ -d "${RUST_LIB_PATH}" ]; then
18
+ rm -rf "${RUST_LIB_PATH}"
19
+ fi
20
+ if [ -d "${ZCASH_LIB_RUST_BUILD_PATH}" ]; then
21
+ rm -rf "${ZCASH_LIB_RUST_BUILD_PATH}"
22
+ fi
23
+ }
@@ -0,0 +1,8 @@
1
+ #!/bin/bash
2
+
3
+ set -x
4
+
5
+ APP_DIR=${TRAVIS_BUILD_DIR}/Example/ZcashLightClientSample
6
+ cd ${APP_DIR}
7
+
8
+ pod install
@@ -0,0 +1,13 @@
1
+ #!/bin/bash
2
+
3
+ set -x
4
+
5
+ rustup-init --verbose -y
6
+
7
+ source $HOME/.cargo/env
8
+
9
+ rustup target add aarch64-apple-ios x86_64-apple-ios
10
+ rustup toolchain add nightly-2021-09-24
11
+ rustup +nightly-2021-09-24 target add aarch64-apple-ios-sim x86_64-apple-ios
12
+
13
+ cargo install cargo-lipo
@@ -77,8 +77,6 @@ class RNZcashModule(private val reactContext: ReactApplicationContext) :
77
77
  wallet.synchronizer.processorInfo.collectWith(scope, { update ->
78
78
  sendEvent("UpdateEvent") { args ->
79
79
  args.putString("alias", alias)
80
- args.putBoolean("isDownloading", update.isDownloading)
81
- args.putBoolean("isScanning", update.isScanning)
82
80
  args.putInt("lastDownloadedHeight", update.lastDownloadedHeight)
83
81
  args.putInt("lastScannedHeight", update.lastScannedHeight)
84
82
  args.putInt("scanProgress", update.scanProgress)
@@ -152,12 +150,6 @@ class RNZcashModule(private val reactContext: ReactApplicationContext) :
152
150
  }
153
151
  }
154
152
 
155
- @ReactMethod
156
- fun getBlockCount(
157
- promise: Promise
158
- ) = promise.wrap {
159
- }
160
-
161
153
  @ReactMethod
162
154
  fun deriveViewingKey(seedBytesHex: String, network: String = "mainnet", promise: Promise) {
163
155
  var keys = DerivationTool.deriveUnifiedViewingKeys(seedBytesHex.fromHex(), networks.getOrDefault(network, ZcashNetwork.Mainnet))[0]
@@ -183,24 +175,6 @@ class RNZcashModule(private val reactContext: ReactApplicationContext) :
183
175
  wallet.synchronizer.latestHeight
184
176
  }
185
177
 
186
- @ReactMethod
187
- fun getLatestScannedHeight(promise: Promise) = promise.wrap {
188
- // TODO: implement this after switching to StateFlow objects
189
- throw NotImplementedError()
190
- }
191
-
192
- @ReactMethod
193
- fun getProgress(promise: Promise) = promise.wrap {
194
- // TODO: implement this after switching to StateFlow objects
195
- throw NotImplementedError()
196
- }
197
-
198
- @ReactMethod
199
- fun getStatus(promise: Promise) = promise.wrap {
200
- // TODO: implement this after switching to StateFlow objects
201
- throw NotImplementedError()
202
- }
203
-
204
178
  @ReactMethod
205
179
  fun getShieldedBalance(alias: String, promise: Promise) = promise.wrap {
206
180
  val wallet = getWallet(alias)
@@ -247,9 +221,6 @@ class RNZcashModule(private val reactContext: ReactApplicationContext) :
247
221
  if (tx.errorCode != null) map.putString("errorCode", tx.errorCode.toString())
248
222
  promise.resolve(false)
249
223
  }
250
- sendEvent("PendingTransactionUpdated") { args ->
251
- args.putPendingTransaction(tx)
252
- }
253
224
  }
254
225
  } catch (t: Throwable) {
255
226
  promise.reject("Err", t)
@@ -268,56 +239,39 @@ class RNZcashModule(private val reactContext: ReactApplicationContext) :
268
239
  }
269
240
 
270
241
  @ReactMethod
271
- fun deriveTransparentAddress(seed: String, network: String = "mainnet", promise: Promise) = promise.wrap {
272
- DerivationTool.deriveTransparentAddress(seed.fromHex(), networks.getOrDefault(network, ZcashNetwork.Mainnet))
273
- }
274
-
275
- @ReactMethod
276
- fun isValidShieldedAddress(address: String, promise: Promise) {
242
+ fun isValidShieldedAddress(address: String, network: String, promise: Promise) {
277
243
  moduleScope.launch {
278
244
  promise.wrap {
279
- val wallet = getAnyWallet()
280
- wallet.synchronizer.isValidShieldedAddr(address)
245
+ var isValid = false
246
+ val wallets = synchronizerMap.asIterable()
247
+ for (wallet in wallets) {
248
+ if (wallet.value.synchronizer.network.networkName == network) {
249
+ isValid = wallet.value.synchronizer.isValidShieldedAddr(address)
250
+ break
251
+ }
252
+ }
253
+ isValid
281
254
  }
282
255
  }
283
256
  }
284
257
 
285
258
  @ReactMethod
286
- fun isValidTransparentAddress(address: String, promise: Promise) {
259
+ fun isValidTransparentAddress(address: String, network: String, promise: Promise) {
287
260
  moduleScope.launch {
288
261
  promise.wrap {
289
- val wallet = getAnyWallet()
290
- wallet.synchronizer.isValidTransparentAddr(address)
291
- }
292
- }
293
- }
294
-
295
- override fun onCatalystInstanceDestroy() {
296
- super.onCatalystInstanceDestroy()
297
- try {
298
- // cancelling the parent scope will also stop the synchronizer, through structured concurrency
299
- // so calling synchronizer.stop() here is possible but redundant
300
- moduleScope.cancel()
301
- } catch (t: Throwable) {
302
- // ignore
303
- }
304
- }
305
-
306
-
307
- //
308
- // Test functions (remove these, later)
309
- //
310
-
311
- @ReactMethod
312
- fun readyToSend(alias: String, promise: Promise) = promise.wrap {
313
- val wallet = getWallet(alias)
314
- // for testing purposes, one is enough--we just want to make sure we're not downloading
315
- wallet.synchronizer.status.filter { it == SYNCED }.onFirstWith(wallet.synchronizer.coroutineScope) {
316
- true
262
+ var isValid = false
263
+ val wallets = synchronizerMap.asIterable()
264
+ for (wallet in wallets) {
265
+ if (wallet.value.synchronizer.network.networkName == network) {
266
+ isValid = wallet.value.synchronizer.isValidTransparentAddr(address)
267
+ break
268
+ }
269
+ }
270
+ isValid
271
+ }
317
272
  }
318
273
  }
319
274
 
320
-
321
275
  //
322
276
  // Utilities
323
277
  //
@@ -331,15 +285,6 @@ class RNZcashModule(private val reactContext: ReactApplicationContext) :
331
285
  return wallet
332
286
  }
333
287
 
334
-
335
- /**
336
- * Retrieve any wallet object for tasks that need simple synchronizer
337
- * functions like address validation
338
- */
339
- private fun getAnyWallet(): WalletSynchronizer {
340
- val wallet = synchronizerMap.firstNotNullOf { it.takeIf { it != null } }
341
- return wallet.value
342
- }
343
288
 
344
289
  /**
345
290
  * Wrap the given block of logic in a promise, rejecting for any error.
@@ -352,21 +297,6 @@ class RNZcashModule(private val reactContext: ReactApplicationContext) :
352
297
  }
353
298
  }
354
299
 
355
- /**
356
- * Serialize a pending tranaction to a map as an event
357
- */
358
- private fun WritableMap.putPendingTransaction(tx: PendingTransaction) {
359
- sendEvent("PendingTransactionUpdated") { args ->
360
- tx.let { info ->
361
- if (tx.accountIndex != null ) putInt("accountIndex", tx.accountIndex)
362
- if (tx.expiryHeight != null ) putInt("expiryHeight", tx.expiryHeight)
363
- if (tx.submitAttempts != null ) putInt("submitAttempts", tx.submitAttempts)
364
- if (tx.errorMessage != null ) putString("errorMessage", tx.errorMessage)
365
- if (tx.createTime != null ) putString("PendingTransactionUpdated", tx.createTime.toString())
366
- }
367
- }
368
- }
369
-
370
300
  private fun sendEvent(eventName: String, putArgs: (WritableMap) -> Unit) {
371
301
  val args = Arguments.createMap()
372
302
  putArgs(args)
@@ -0,0 +1,6 @@
1
+ //
2
+ // Use this file to import your target's public headers that you would like to expose to Swift.
3
+ //
4
+
5
+ #import <React/RCTBridgeModule.h>
6
+ #import <React/RCTEventEmitter.h>
package/ios/RNZcash.m CHANGED
@@ -1,45 +1,91 @@
1
- // Formatted using clang-format with default settings.
2
-
3
- #import "RNZcash.h"
4
-
5
- @implementation RNZcash
6
-
7
- RCT_EXPORT_MODULE()
8
-
9
- // - (id)init {
10
- // self = [super init];
11
- // return self;
12
- // }
13
-
14
- + (BOOL)requiresMainQueueSetup {
15
- return NO;
16
- }
17
-
18
- RCT_REMAP_METHOD(getNumTransactions, getNumTransactions:(float) N
19
- resolver:(RCTPromiseResolveBlock)resolve
20
- rejecter:(RCTPromiseRejectBlock)reject)
21
- {
22
- // NSUInteger const onehundred = 100;
23
- // NSNumber *val = [NSNumber numberWithInteger:(N+42)];
24
- NSNumber *myNum = [NSNumber numberWithFloat:(N+123)];
25
- resolve(myNum);
26
- }
27
-
28
- RCT_REMAP_METHOD(deriveViewKey, deriveViewKey:(NSString *) seedBytesHex
29
- resolver:(RCTPromiseResolveBlock)resolve
30
- rejecter:(RCTPromiseRejectBlock)reject)
31
- {
32
- NSString *out = [seedBytesHex stringByAppendingString:@"-viewKey"];
33
- resolve(out);
34
- }
35
-
36
-
37
- RCT_REMAP_METHOD(getShieldedBalance,
38
- resolver:(RCTPromiseResolveBlock)resolve
39
- rejecter:(RCTPromiseRejectBlock)reject)
40
- {
41
- NSDictionary *dict = @{@"availableBalance":@"123",@"totalBalance": @"1234"};
42
- resolve(dict);
43
- }
1
+ #import <React/RCTBridgeModule.h>
2
+ #import <React/RCTEventEmitter.h>
3
+
4
+
5
+ @interface RCT_EXTERN_MODULE(RNZcash, RCTEventEmitter<RCTBridgeModule>)
6
+
7
+ // Synchronizer
8
+ RCT_EXTERN_METHOD(initialize:(NSString *)extfvk
9
+ :(NSString *)extpub
10
+ :(NSInteger *)birthdayHeight
11
+ :(NSString *)alias
12
+ :(NSString *)networkName
13
+ :(NSString *)defaultHost
14
+ :(NSInteger *)defaultPort
15
+ resolver:(RCTPromiseResolveBlock)resolve
16
+ rejecter:(RCTPromiseRejectBlock)reject
17
+ )
18
+
19
+ RCT_EXTERN_METHOD(start:(NSString *)alias
20
+ resolver:(RCTPromiseResolveBlock)resolve
21
+ rejecter:(RCTPromiseRejectBlock)reject
22
+ )
23
+
24
+ RCT_EXTERN_METHOD(stop:(NSString *)alias
25
+ resolver:(RCTPromiseResolveBlock)resolve
26
+ rejecter:(RCTPromiseRejectBlock)reject
27
+ )
28
+
29
+ RCT_EXTERN_METHOD(spendToAddress:(NSString *)alias
30
+ :(NSString *)zatoshi
31
+ :(NSString *)toAddress
32
+ :(NSString *)memo
33
+ :(NSInteger *)fromAccountIndex
34
+ :(NSString *)spendingKey
35
+ resolver:(RCTPromiseResolveBlock)resolve
36
+ rejecter:(RCTPromiseRejectBlock)reject
37
+ )
38
+
39
+ RCT_EXTERN_METHOD(getTransactions:(NSString *)alias
40
+ :(NSInteger *)first
41
+ :(NSInteger *)last
42
+ resolver:(RCTPromiseResolveBlock)resolve
43
+ rejecter:(RCTPromiseRejectBlock)reject
44
+ )
45
+
46
+ RCT_EXTERN_METHOD(getShieldedBalance:(NSString *)alias
47
+ resolver:(RCTPromiseResolveBlock)resolve
48
+ rejecter:(RCTPromiseRejectBlock)reject
49
+ )
50
+
51
+ RCT_EXTERN_METHOD(rescan:(NSString *)alias
52
+ :(NSInteger *)height
53
+ resolver:(RCTPromiseResolveBlock)resolve
54
+ rejecter:(RCTPromiseRejectBlock)reject
55
+ )
56
+
57
+ // Derivation tool
58
+ RCT_EXTERN_METHOD(deriveViewingKey:(NSString *)seed
59
+ :(NSString *)network
60
+ resolver:(RCTPromiseResolveBlock)resolve
61
+ rejecter:(RCTPromiseRejectBlock)reject
62
+ )
63
+
64
+ RCT_EXTERN_METHOD(deriveSpendingKey:(NSString *)seed
65
+ :(NSString *)network
66
+ resolver:(RCTPromiseResolveBlock)resolve
67
+ rejecter:(RCTPromiseRejectBlock)reject
68
+ )
69
+
70
+ RCT_EXTERN_METHOD(deriveShieldedAddress:(NSString *)viewingKey
71
+ :(NSString *)network
72
+ resolver:(RCTPromiseResolveBlock)resolve
73
+ rejecter:(RCTPromiseRejectBlock)reject
74
+ )
75
+
76
+ RCT_EXTERN_METHOD(isValidTransparentAddress:(NSString *)address
77
+ :(NSString *)network
78
+ resolver:(RCTPromiseResolveBlock)resolve
79
+ rejecter:(RCTPromiseRejectBlock)reject
80
+ )
81
+
82
+ RCT_EXTERN_METHOD(isValidShieldedAddress:(NSString *)address
83
+ :(NSString *)network
84
+ resolver:(RCTPromiseResolveBlock)resolve
85
+ rejecter:(RCTPromiseRejectBlock)reject
86
+ )
87
+
88
+ // Events
89
+ RCT_EXTERN_METHOD(supportedEvents)
44
90
 
45
91
  @end