react-native-zcash 0.2.1 → 0.2.2
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 +8 -0
- package/android/build.gradle +8 -2
- package/android/src/main/java/app/edge/rnzcash/RNZcashModule.kt +41 -33
- package/ios/RNZcash.swift +34 -10
- package/ios/RNZcash.xcodeproj/xcuserdata/Matthew.xcuserdatad/xcschemes/xcschememanagement.plist +22 -0
- package/ios/RNZcash.xcworkspace/xcuserdata/Matthew.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/package.json +1 -2
- package/react-native-zcash.podspec +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# React Native Zcash
|
|
2
2
|
|
|
3
|
+
## 0.2.2 (2022-06-10)
|
|
4
|
+
|
|
5
|
+
- Upgrade SDKs to NU5 compatible versions
|
|
6
|
+
- Android: Upgrade zcash-android-sdk to v1.5.0-beta01
|
|
7
|
+
- iOS: Upgrade ZcashLightClientKit to v0.14.0-beta
|
|
8
|
+
- iOS: Fix memory leak after stopping synchronizer
|
|
9
|
+
- ANdroid: White space and import cleanups
|
|
10
|
+
|
|
3
11
|
## 0.2.1 (2022-03-16)
|
|
4
12
|
|
|
5
13
|
- Update the ZcashLightClientKit dependency
|
package/android/build.gradle
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
buildscript {
|
|
2
2
|
ext.versions = [
|
|
3
3
|
'kotlin': '1.5.0',
|
|
4
|
-
'zcash': '1.
|
|
4
|
+
'zcash': '1.5.0-beta01',
|
|
5
5
|
'room': '2.3.0'
|
|
6
6
|
]
|
|
7
7
|
repositories {
|
|
@@ -33,7 +33,7 @@ def safeExtGet(prop, fallback) {
|
|
|
33
33
|
|
|
34
34
|
def DEFAULT_COMPILE_SDK_VERSION = 28
|
|
35
35
|
def DEFAULT_BUILD_TOOLS_VERSION = "28.0.2"
|
|
36
|
-
def DEFAULT_MIN_SDK_VERSION =
|
|
36
|
+
def DEFAULT_MIN_SDK_VERSION = 19
|
|
37
37
|
def DEFAULT_TARGET_SDK_VERSION = 27
|
|
38
38
|
|
|
39
39
|
android {
|
|
@@ -80,4 +80,10 @@ dependencies {
|
|
|
80
80
|
implementation "androidx.paging:paging-runtime-ktx:2.1.2"
|
|
81
81
|
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.9"
|
|
82
82
|
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9"
|
|
83
|
+
|
|
84
|
+
implementation ("androidx.appcompat:appcompat:1.3.1") {
|
|
85
|
+
version {
|
|
86
|
+
strictly '1.3.1'
|
|
87
|
+
}
|
|
88
|
+
}
|
|
83
89
|
}
|
|
@@ -1,32 +1,29 @@
|
|
|
1
1
|
package app.edge.rnzcash;
|
|
2
2
|
|
|
3
|
-
import androidx.paging.PagedList
|
|
4
3
|
import cash.z.ecc.android.sdk.Initializer
|
|
5
4
|
import cash.z.ecc.android.sdk.SdkSynchronizer
|
|
6
5
|
import cash.z.ecc.android.sdk.Synchronizer
|
|
7
|
-
import cash.z.ecc.android.sdk.Synchronizer.Status.SYNCED
|
|
8
|
-
import cash.z.ecc.android.sdk.block.CompactBlockProcessor
|
|
9
6
|
import cash.z.ecc.android.sdk.db.entity.*
|
|
10
7
|
import cash.z.ecc.android.sdk.ext.*
|
|
11
|
-
import cash.z.ecc.android.sdk.transaction
|
|
8
|
+
import cash.z.ecc.android.sdk.internal.transaction.PagedTransactionRepository
|
|
9
|
+
import cash.z.ecc.android.sdk.internal.*
|
|
12
10
|
import cash.z.ecc.android.sdk.type.*
|
|
13
11
|
import cash.z.ecc.android.sdk.tool.DerivationTool
|
|
14
12
|
import com.facebook.react.bridge.*
|
|
15
13
|
import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter
|
|
16
14
|
import kotlinx.coroutines.CoroutineScope
|
|
17
|
-
import kotlinx.coroutines.cancel
|
|
18
15
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
|
19
|
-
import kotlinx.coroutines.flow.filter
|
|
20
16
|
import kotlinx.coroutines.launch
|
|
17
|
+
import kotlinx.coroutines.runBlocking
|
|
21
18
|
import java.nio.charset.StandardCharsets
|
|
22
19
|
import kotlin.coroutines.EmptyCoroutineContext
|
|
23
20
|
|
|
24
21
|
class WalletSynchronizer constructor(val initializer: Initializer) {
|
|
25
|
-
|
|
26
|
-
val synchronizer: SdkSynchronizer = Synchronizer(
|
|
22
|
+
|
|
23
|
+
val synchronizer: SdkSynchronizer = Synchronizer.newBlocking(
|
|
27
24
|
initializer
|
|
28
25
|
) as SdkSynchronizer
|
|
29
|
-
val repository = PagedTransactionRepository(initializer.context, 10, initializer.rustBackend, initializer.birthday, initializer.viewingKeys)
|
|
26
|
+
val repository = runBlocking { PagedTransactionRepository.new(initializer.context, 10, initializer.rustBackend, initializer.birthday, initializer.viewingKeys) }
|
|
30
27
|
var isStarted = false
|
|
31
28
|
}
|
|
32
29
|
|
|
@@ -50,28 +47,32 @@ class RNZcashModule(private val reactContext: ReactApplicationContext) :
|
|
|
50
47
|
@ReactMethod
|
|
51
48
|
fun initialize(extfvk: String, extpub: String, birthdayHeight: Int, alias: String, networkName: String = "mainnet", defaultHost: String = "mainnet.lightwalletd.com", defaultPort: Int = 9067, promise: Promise) =
|
|
52
49
|
promise.wrap {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
50
|
+
Twig.plant(TroubleshootingTwig())
|
|
51
|
+
var vk = UnifiedViewingKey(extfvk, extpub)
|
|
52
|
+
if (synchronizerMap[alias] == null) {
|
|
53
|
+
runBlocking {
|
|
54
|
+
Initializer.new(reactApplicationContext) {
|
|
55
|
+
it.importedWalletBirthday(birthdayHeight)
|
|
56
|
+
it.setViewingKeys(vk)
|
|
57
|
+
it.setNetwork(networks[networkName]
|
|
58
|
+
?: ZcashNetwork.Mainnet, defaultHost, defaultPort)
|
|
59
|
+
it.alias = alias
|
|
60
|
+
}
|
|
61
|
+
}.let { initializer ->
|
|
62
|
+
synchronizerMap[alias] = WalletSynchronizer(initializer)
|
|
64
63
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
}
|
|
65
|
+
val wallet = getWallet(alias)
|
|
66
|
+
wallet.synchronizer.hashCode().toString()
|
|
68
67
|
}
|
|
69
68
|
|
|
70
69
|
@ReactMethod
|
|
71
70
|
fun start(alias: String, promise: Promise) = promise.wrap {
|
|
72
71
|
val wallet = getWallet(alias)
|
|
73
72
|
if (!wallet.isStarted) {
|
|
74
|
-
|
|
73
|
+
runBlocking {
|
|
74
|
+
wallet.synchronizer.prepare()
|
|
75
|
+
}
|
|
75
76
|
wallet.synchronizer.start(moduleScope)
|
|
76
77
|
val scope = wallet.synchronizer.coroutineScope
|
|
77
78
|
wallet.synchronizer.processorInfo.collectWith(scope, { update ->
|
|
@@ -83,7 +84,7 @@ class RNZcashModule(private val reactContext: ReactApplicationContext) :
|
|
|
83
84
|
args.putInt("networkBlockHeight", update.networkBlockHeight)
|
|
84
85
|
}
|
|
85
86
|
})
|
|
86
|
-
wallet.synchronizer.status.collectWith(scope, { status ->
|
|
87
|
+
wallet.synchronizer.status.collectWith(scope, { status ->
|
|
87
88
|
sendEvent("StatusEvent") { args ->
|
|
88
89
|
args.putString("alias", alias)
|
|
89
90
|
args.putString("name", status.toString())
|
|
@@ -104,7 +105,6 @@ class RNZcashModule(private val reactContext: ReactApplicationContext) :
|
|
|
104
105
|
args.putInt("transactionCount", txList.count())
|
|
105
106
|
}
|
|
106
107
|
})
|
|
107
|
-
wallet.repository.prepare()
|
|
108
108
|
wallet.isStarted = true
|
|
109
109
|
}
|
|
110
110
|
"success"
|
|
@@ -152,7 +152,7 @@ class RNZcashModule(private val reactContext: ReactApplicationContext) :
|
|
|
152
152
|
|
|
153
153
|
@ReactMethod
|
|
154
154
|
fun deriveViewingKey(seedBytesHex: String, network: String = "mainnet", promise: Promise) {
|
|
155
|
-
var keys = DerivationTool.deriveUnifiedViewingKeys(seedBytesHex.fromHex(), networks.getOrDefault(network, ZcashNetwork.Mainnet))[0]
|
|
155
|
+
var keys = runBlocking { DerivationTool.deriveUnifiedViewingKeys(seedBytesHex.fromHex(), networks.getOrDefault(network, ZcashNetwork.Mainnet))[0] }
|
|
156
156
|
val map = Arguments.createMap()
|
|
157
157
|
map.putString("extfvk", keys.extfvk)
|
|
158
158
|
map.putString("extpub", keys.extpub)
|
|
@@ -161,7 +161,7 @@ class RNZcashModule(private val reactContext: ReactApplicationContext) :
|
|
|
161
161
|
|
|
162
162
|
@ReactMethod
|
|
163
163
|
fun deriveSpendingKey(seedBytesHex: String, network: String = "mainnet", promise: Promise) = promise.wrap {
|
|
164
|
-
DerivationTool.deriveSpendingKeys(seedBytesHex.fromHex(), networks.getOrDefault(network, ZcashNetwork.Mainnet))[0]
|
|
164
|
+
runBlocking { DerivationTool.deriveSpendingKeys(seedBytesHex.fromHex(), networks.getOrDefault(network, ZcashNetwork.Mainnet))[0] }
|
|
165
165
|
}
|
|
166
166
|
|
|
167
167
|
//
|
|
@@ -226,7 +226,7 @@ class RNZcashModule(private val reactContext: ReactApplicationContext) :
|
|
|
226
226
|
promise.reject("Err", t)
|
|
227
227
|
}
|
|
228
228
|
}
|
|
229
|
-
|
|
229
|
+
|
|
230
230
|
}
|
|
231
231
|
|
|
232
232
|
//
|
|
@@ -235,7 +235,7 @@ class RNZcashModule(private val reactContext: ReactApplicationContext) :
|
|
|
235
235
|
|
|
236
236
|
@ReactMethod
|
|
237
237
|
fun deriveShieldedAddress(viewingKey: String, network: String = "mainnet", promise: Promise) = promise.wrap {
|
|
238
|
-
DerivationTool.deriveShieldedAddress(viewingKey, networks.getOrDefault(network, ZcashNetwork.Mainnet))
|
|
238
|
+
runBlocking { DerivationTool.deriveShieldedAddress(viewingKey, networks.getOrDefault(network, ZcashNetwork.Mainnet)) }
|
|
239
239
|
}
|
|
240
240
|
|
|
241
241
|
@ReactMethod
|
|
@@ -256,7 +256,7 @@ class RNZcashModule(private val reactContext: ReactApplicationContext) :
|
|
|
256
256
|
}
|
|
257
257
|
|
|
258
258
|
@ReactMethod
|
|
259
|
-
fun isValidTransparentAddress(address: String, network: String, promise: Promise) {
|
|
259
|
+
fun isValidTransparentAddress(address: String, network: String, promise: Promise) {
|
|
260
260
|
moduleScope.launch {
|
|
261
261
|
promise.wrap {
|
|
262
262
|
var isValid = false
|
|
@@ -278,13 +278,13 @@ class RNZcashModule(private val reactContext: ReactApplicationContext) :
|
|
|
278
278
|
|
|
279
279
|
/**
|
|
280
280
|
* Retrieve wallet object from synchronizer map
|
|
281
|
-
*/
|
|
281
|
+
*/
|
|
282
282
|
private fun getWallet(alias: String): WalletSynchronizer {
|
|
283
283
|
val wallet = synchronizerMap.get(alias)
|
|
284
284
|
if (wallet == null) throw Exception("Wallet not found")
|
|
285
285
|
return wallet
|
|
286
286
|
}
|
|
287
|
-
|
|
287
|
+
|
|
288
288
|
|
|
289
289
|
/**
|
|
290
290
|
* Wrap the given block of logic in a promise, rejecting for any error.
|
|
@@ -314,4 +314,12 @@ class RNZcashModule(private val reactContext: ReactApplicationContext) :
|
|
|
314
314
|
"Unable to parse memo."
|
|
315
315
|
}
|
|
316
316
|
}
|
|
317
|
+
|
|
318
|
+
inline fun ByteArray.toHexReversed(): String {
|
|
319
|
+
val sb = StringBuilder(size * 2)
|
|
320
|
+
var i = size - 1
|
|
321
|
+
while (i >= 0)
|
|
322
|
+
sb.append(String.format("%02x", this[i--]))
|
|
323
|
+
return sb.toString()
|
|
324
|
+
}
|
|
317
325
|
}
|
package/ios/RNZcash.swift
CHANGED
|
@@ -135,6 +135,7 @@ class RNZcash : RCTEventEmitter {
|
|
|
135
135
|
@objc func stop(_ alias: String, resolver resolve: RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock) -> Void {
|
|
136
136
|
if let wallet = SynchronizerMap[alias] {
|
|
137
137
|
wallet.synchronizer.stop()
|
|
138
|
+
SynchronizerMap[alias] = nil
|
|
138
139
|
resolve(nil)
|
|
139
140
|
} else {
|
|
140
141
|
reject("StopError", "Wallet does not exist", genericError)
|
|
@@ -327,7 +328,7 @@ class WalletSynchronizer : NSObject {
|
|
|
327
328
|
|
|
328
329
|
public func subscribe() {
|
|
329
330
|
// Processor status
|
|
330
|
-
NotificationCenter.default.addObserver(self, selector: #selector(updateProcessorState(notification:)), name:
|
|
331
|
+
NotificationCenter.default.addObserver(self, selector: #selector(updateProcessorState(notification:)), name: nil, object: self.synchronizer.blockProcessor)
|
|
331
332
|
// Synchronizer Status
|
|
332
333
|
NotificationCenter.default.addObserver(self, selector: #selector(updateSyncStatus(notification:)), name: .synchronizerDisconnected, object: self.synchronizer)
|
|
333
334
|
NotificationCenter.default.addObserver(self, selector: #selector(updateSyncStatus(notification:)), name: .synchronizerStopped, object: self.synchronizer)
|
|
@@ -371,17 +372,40 @@ class WalletSynchronizer : NSObject {
|
|
|
371
372
|
}
|
|
372
373
|
|
|
373
374
|
@objc public func updateProcessorState(notification: NSNotification) {
|
|
374
|
-
let
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
375
|
+
let prevLastDownloadedHeight = self.processorState.lastDownloadedHeight
|
|
376
|
+
let prevScanProgress = self.processorState.scanProgress
|
|
377
|
+
let prevLastScannedHeight = self.synchronizer.latestScannedHeight
|
|
378
|
+
let prevNetworkBlockHeight = self.processorState.lastScannedHeight
|
|
379
|
+
|
|
380
|
+
if !self.fullySynced {
|
|
381
|
+
switch self.synchronizer.status {
|
|
382
|
+
case .downloading(let status):
|
|
383
|
+
// The SDK emits all zero values just before emitting a SYNCED status so we need to ignore these
|
|
384
|
+
if status.targetHeight == 0 {
|
|
385
|
+
return
|
|
386
|
+
}
|
|
387
|
+
self.processorState.lastDownloadedHeight = status.progressHeight
|
|
388
|
+
self.processorState.networkBlockHeight = status.targetHeight
|
|
389
|
+
break
|
|
390
|
+
case .scanning(let status):
|
|
391
|
+
self.processorState.scanProgress = Int(floor(status.progress * 100))
|
|
392
|
+
self.processorState.lastScannedHeight = status.progressHeight
|
|
393
|
+
self.processorState.networkBlockHeight = status.targetHeight
|
|
394
|
+
default:
|
|
395
|
+
return
|
|
396
|
+
}
|
|
380
397
|
} else {
|
|
381
|
-
|
|
398
|
+
self.processorState.lastDownloadedHeight = self.synchronizer.latestScannedHeight
|
|
399
|
+
self.processorState.scanProgress = 100
|
|
400
|
+
self.processorState.lastScannedHeight = self.synchronizer.latestScannedHeight
|
|
401
|
+
self.processorState.networkBlockHeight = try! self.synchronizer.latestHeight()
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
if self.processorState.lastDownloadedHeight != prevLastDownloadedHeight || self.processorState.scanProgress != prevScanProgress ||
|
|
405
|
+
self.processorState.lastScannedHeight != prevLastScannedHeight ||
|
|
406
|
+
self.processorState.networkBlockHeight != prevNetworkBlockHeight {
|
|
407
|
+
emit("UpdateEvent", self.processorState.nsDictionary)
|
|
382
408
|
}
|
|
383
|
-
self.processorState.networkBlockHeight = status.targetHeight!
|
|
384
|
-
emit("UpdateEvent", self.processorState.nsDictionary)
|
|
385
409
|
}
|
|
386
410
|
|
|
387
411
|
func initializeProcessorState() {
|
package/ios/RNZcash.xcodeproj/xcuserdata/Matthew.xcuserdatad/xcschemes/xcschememanagement.plist
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
+
<plist version="1.0">
|
|
4
|
+
<dict>
|
|
5
|
+
<key>SchemeUserState</key>
|
|
6
|
+
<dict>
|
|
7
|
+
<key>RNZcash.xcscheme_^#shared#^_</key>
|
|
8
|
+
<dict>
|
|
9
|
+
<key>orderHint</key>
|
|
10
|
+
<integer>28</integer>
|
|
11
|
+
</dict>
|
|
12
|
+
</dict>
|
|
13
|
+
<key>SuppressBuildableAutocreation</key>
|
|
14
|
+
<dict>
|
|
15
|
+
<key>58B511DA1A9E6C8500147676</key>
|
|
16
|
+
<dict>
|
|
17
|
+
<key>primary</key>
|
|
18
|
+
<true/>
|
|
19
|
+
</dict>
|
|
20
|
+
</dict>
|
|
21
|
+
</dict>
|
|
22
|
+
</plist>
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-zcash",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Zcash library for React Native",
|
|
5
5
|
"homepage": "https://github.com/EdgeApp/react-native-zcash",
|
|
6
6
|
"repository": {
|
|
@@ -28,7 +28,6 @@
|
|
|
28
28
|
"lib",
|
|
29
29
|
"package.json",
|
|
30
30
|
"README.md",
|
|
31
|
-
"Scripts",
|
|
32
31
|
"src"
|
|
33
32
|
],
|
|
34
33
|
"main": "lib/rnzcash.rn.js",
|