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.
- package/CHANGELOG.md +10 -0
- package/android/build.gradle +3 -3
- package/android/src/main/assets/co.electriccoin.zcash/checkpoint/mainnet/2650000.json +8 -0
- package/android/src/main/assets/co.electriccoin.zcash/checkpoint/mainnet/2660000.json +8 -0
- package/android/src/main/java/app/edge/rnzcash/RNZcashModule.kt +15 -25
- package/ios/RNZcash.m +3 -5
- package/ios/RNZcash.swift +42 -23
- package/ios/RNZcash.xcodeproj/xcuserdata/samholmes.xcuserdatad/xcschemes/xcschememanagement.plist +14 -0
- package/ios/RNZcash.xcworkspace/xcuserdata/samholmes.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/ios/ZCashLightClientKit/Block/Actions/Action.swift +1 -0
- package/ios/ZCashLightClientKit/Block/Actions/EnhanceAction.swift +1 -1
- package/ios/ZCashLightClientKit/Block/Actions/ProcessSuggestedScanRangesAction.swift +1 -1
- package/ios/ZCashLightClientKit/Block/Actions/ScanAction.swift +1 -1
- package/ios/ZCashLightClientKit/Block/Actions/TxResubmissionAction.swift +75 -0
- package/ios/ZCashLightClientKit/Block/Actions/UpdateChainTipAction.swift +1 -1
- package/ios/ZCashLightClientKit/Block/Actions/UpdateSubtreeRootsAction.swift +3 -1
- package/ios/ZCashLightClientKit/Block/CompactBlockProcessor.swift +14 -0
- package/ios/ZCashLightClientKit/Block/Download/BlockDownloaderService.swift +2 -2
- package/ios/ZCashLightClientKit/Block/Enhance/BlockEnhancer.swift +54 -49
- package/ios/ZCashLightClientKit/Checkpoint/BundleCheckpointSource.swift +1 -6
- package/ios/ZCashLightClientKit/Checkpoint/CheckpointSourceFactory.swift +1 -1
- package/ios/ZCashLightClientKit/ClosureSynchronizer.swift +3 -1
- package/ios/ZCashLightClientKit/CombineSynchronizer.swift +6 -2
- package/ios/ZCashLightClientKit/Constants/ZcashSDK.swift +15 -0
- package/ios/ZCashLightClientKit/DAO/TransactionDao.swift +20 -4
- package/ios/ZCashLightClientKit/Entity/TransactionEntity.swift +27 -24
- package/ios/ZCashLightClientKit/Error/Sourcery/generateErrorCode.sh +2 -2
- package/ios/ZCashLightClientKit/Error/ZcashError.swift +32 -1
- package/ios/ZCashLightClientKit/Error/ZcashErrorCode.swift +11 -1
- package/ios/ZCashLightClientKit/Error/ZcashErrorCodeDefinition.swift +18 -0
- package/ios/ZCashLightClientKit/Initializer.swift +22 -14
- package/ios/ZCashLightClientKit/Metrics/SDKMetrics.swift +0 -1
- package/ios/ZCashLightClientKit/Model/FiatCurrencyResult.swift +25 -0
- package/ios/ZCashLightClientKit/Model/Proposal.swift +1 -1
- package/ios/ZCashLightClientKit/Model/TransactionDataRequest.swift +26 -0
- package/ios/ZCashLightClientKit/Model/WalletTypes.swift +39 -1
- package/ios/ZCashLightClientKit/Model/Zatoshi.swift +1 -1
- package/ios/ZCashLightClientKit/Modules/Service/GRPC/LightWalletGRPCService.swift +39 -2
- package/ios/ZCashLightClientKit/Modules/Service/GRPC/ProtoBuf/proto/service.proto +5 -4
- package/ios/ZCashLightClientKit/Modules/Service/GRPC/ProtoBuf/service.grpc.swift +819 -3
- package/ios/ZCashLightClientKit/Modules/Service/GRPC/ProtoBuf/service.pb.swift +2 -2
- package/ios/ZCashLightClientKit/Modules/Service/LightWalletService.swift +3 -1
- package/ios/ZCashLightClientKit/Providers/ResourceProvider.swift +10 -0
- package/ios/ZCashLightClientKit/Repository/TransactionRepository.swift +4 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2475000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2477500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2482500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2485000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2487500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2492500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2495000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2497500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2502500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2505000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2507500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2512500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2515000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2517500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2522500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2525000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2527500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2532500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2535000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2537500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2542500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2545000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2547500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2552500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2555000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2557500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2562500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2565000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2567500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2572500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2575000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2577500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2582500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2585000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2587500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2592500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2595000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2597500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2602500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2605000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2607500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2612500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2615000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2617500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2622500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2625000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2627500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2632500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2635000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2637500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2642500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2645000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2647500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2650000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2660000.json +8 -0
- package/ios/ZCashLightClientKit/Rust/ZcashKeyDerivationBackend.swift +4 -24
- package/ios/ZCashLightClientKit/Rust/ZcashKeyDerivationBackendWelding.swift +0 -15
- package/ios/ZCashLightClientKit/Rust/ZcashRustBackend.swift +133 -32
- package/ios/ZCashLightClientKit/Rust/ZcashRustBackendWelding.swift +18 -1
- package/ios/ZCashLightClientKit/Synchronizer/ClosureSDKSynchronizer.swift +4 -0
- package/ios/ZCashLightClientKit/Synchronizer/CombineSDKSynchronizer.swift +5 -1
- package/ios/ZCashLightClientKit/Synchronizer/Dependencies.swift +53 -3
- package/ios/ZCashLightClientKit/Synchronizer/SDKSynchronizer.swift +236 -7
- package/ios/ZCashLightClientKit/Synchronizer.swift +28 -0
- package/ios/ZCashLightClientKit/Tool/DerivationTool.swift +29 -5
- package/ios/ZCashLightClientKit/Tor/TorClient.swift +57 -0
- package/ios/ZCashLightClientKit/Utils/LoggingProxy.swift +4 -0
- package/ios/ZCashLightClientKit/Utils/OSLogger.swift +4 -0
- package/ios/lib/libzcashlc.a +0 -0
- package/ios/libzcashlc.xcframework/Info.plist +5 -5
- package/ios/libzcashlc.xcframework/ios-arm64/libzcashlc.a +0 -0
- package/ios/libzcashlc.xcframework/ios-arm64_x86_64-simulator/libzcashlc.a +0 -0
- package/ios/zcashlc.h +287 -42
- package/lib/rnzcash.rn.js +8 -8
- package/lib/rnzcash.rn.js.map +1 -1
- package/lib/src/react-native.d.ts +3 -3
- package/lib/src/types.d.ts +4 -2
- package/package.json +1 -1
- package/src/react-native.ts +13 -18
- package/src/types.ts +5 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.9.1 (2024-10-01)
|
|
6
|
+
|
|
7
|
+
- changed: Updated checkpoints
|
|
8
|
+
|
|
9
|
+
## 0.9.0 (2024-09-25)
|
|
10
|
+
|
|
11
|
+
- added: Support sending to ZIP-320 TEX addresses
|
|
12
|
+
- changed: Replace `sendToAddress` with `createTransfer`
|
|
13
|
+
- changed: Updated checkpoints
|
|
14
|
+
|
|
5
15
|
## 0.8.1 (2024-09-16)
|
|
6
16
|
|
|
7
17
|
- changed: Updated checkpoints
|
package/android/build.gradle
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
buildscript {
|
|
2
2
|
def kotlinVersion = rootProject.ext.has('kotlinVersion')
|
|
3
3
|
? rootProject.ext.get('kotlinVersion')
|
|
4
|
-
: '1.
|
|
4
|
+
: '1.9.23'
|
|
5
5
|
|
|
6
6
|
repositories {
|
|
7
7
|
mavenCentral()
|
|
@@ -49,8 +49,8 @@ dependencies {
|
|
|
49
49
|
|
|
50
50
|
implementation 'androidx.appcompat:appcompat:1.6.1'
|
|
51
51
|
implementation 'androidx.paging:paging-runtime-ktx:2.1.2'
|
|
52
|
-
implementation 'cash.z.ecc.android:zcash-android-sdk:2.
|
|
53
|
-
implementation 'cash.z.ecc.android:zcash-android-sdk-incubator:2.
|
|
52
|
+
implementation 'cash.z.ecc.android:zcash-android-sdk:2.2.4'
|
|
53
|
+
implementation 'cash.z.ecc.android:zcash-android-sdk-incubator:2.2.4'
|
|
54
54
|
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3"
|
|
55
55
|
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3"
|
|
56
56
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
{
|
|
2
|
+
"network": "main",
|
|
3
|
+
"height": "2650000",
|
|
4
|
+
"hash": "0000000000b32debcdb364e5fc7988044a4eb29e4f86ed6c97a95f0836e3c37f",
|
|
5
|
+
"time": 1726602492,
|
|
6
|
+
"saplingTree": "01e09fe8115a458f1802d1d95ad1cbc4d6737d31ebf4a63f936b62011034dabd31010855462f487eaa137ee9950887b40953765357aff4a9eda4d85d4eccf274c42a1f000001488261fba3b34b7f78d50bc11ce1830c2339813606bb17570d7293128769577101216344eb0f3b3b8bddd4d2b51a36f6bb4fa368125d29dc02cf776797152bd95a00011f360200bebb9acb23f27fd0cb18a95b746d3a07c4df8cf7a843147bd0f9042d0000000001b5c2bb61f0ea5b18cfdeddac25f36c98988ce0705eae6824a3121158a6f6f824010d143acd831f6da07b124b16f4c4e58102caa7517722bb550946c5fa2a245371000000019a730d9d524de40f3fa2a76a8072ff66ef8ce0af24a68a080ef683a9d45aab7301b254e3cfba937bcd40621e1d623a943440b083892546f081aab37058fd1b763f000000013e2598f743726006b8de42476ed56a55a75629a7b82e430c4e7c101a69e9b02a011619f99023a69bb647eab2d2aa1a73c3673c74bb033c3c4930eacda19e6fd93b0000000160272b134ca494b602137d89e528c751c06d3ef4a87a45f33af343c15060cc1e0000000000",
|
|
7
|
+
"orchardTree": "016c37f7adb67b940b91f05b0d60e1d98c2d4f67c0a766ae367d42a56302ea0416001f015126bbb64a18d6e518922654683434e6aa3c488e1a4e2b35d5ff4bb4d32c310501e8131c28e898b1247a2e28d1691b0854445aecf30e7bd601117fdd36967c893e01c454a4fac32e3c68f16a55476d7e992d7cec2e4af24bc34d7d9c459f58fbe22100000102b7afec099b149198431e309cec4b3f95531b53fa350ff453c0a648276bc1140001cc846293d335bbb212a6c0f54fd45d92f995724d58b9b5fed397dbc55e3bb8030001f783a7a186e453c6d11e88542ed866790b00d4102899da05c57eb0d71fffbc2500000000010c104faa2b1148b1b627090aa939e321b82edcb0ce70aa4eee298997556b4f35000112278dfeae9949f887b70ae81e084f8897a5054627acef3efd01c8b29793d522000160040850b766b126a2b4843fcdfdffa5d5cab3f53bc860a3bef68958b5f066170001cc2dcaa338b312112db04b435a706d63244dd435238f0aa1e9e1598d35470810012dcc4273c8a0ed2337ecf7879380a07e7d427c7f9d82e538002bd1442978402c01daf63debf5b40df902dae98dadc029f281474d190cddecef1b10653248a234150001e2bca6a8d987d668defba89dc082196a922634ed88e065c669e526bb8815ee1b000000000000"
|
|
8
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
{
|
|
2
|
+
"network": "main",
|
|
3
|
+
"height": "2660000",
|
|
4
|
+
"hash": "00000000005baeb43a5acf3d5a0260a7031b64cf3e93bdfd9fda65681ad6ac65",
|
|
5
|
+
"time": 1727357043,
|
|
6
|
+
"saplingTree": "0182e472c765ae0592c2db984f967f0b48357f23b4d98320a3e00b882a270f113301cda356ef2098fa6bcaa1920f0c8ac7804e090cfb29d9fcb77c02a6118f12ce5e1f01147ad91a9145bf5c3de4f733c7217f86ba93a98c2fea782a899b3ae59fa33d030172ad5772ba974db80f29278d183449aea8febde0f700fd90fe9f2a97857a235b000001000ca48e6490054cf88ec2d2d3ffd02c4d0179099a3e593282b160b9e57eda0e0000000001cd773536cc74a4d9954981c31e07f4099cc0d55e3f2ee672776e1fc275319a0a01e07e58633fa5b35ec018b9309edc4827b2e3ca25c1b4f1d0dc1e7122c9afa93400010c2d67aaab29f19fee9179914c48f29b116ad43ef6b94a7200be67d740f7a51301aa31e734a8b2f54db91099896f41868a43a19992ac1358531c567e0042e85a5600019a730d9d524de40f3fa2a76a8072ff66ef8ce0af24a68a080ef683a9d45aab7301b254e3cfba937bcd40621e1d623a943440b083892546f081aab37058fd1b763f000000013e2598f743726006b8de42476ed56a55a75629a7b82e430c4e7c101a69e9b02a011619f99023a69bb647eab2d2aa1a73c3673c74bb033c3c4930eacda19e6fd93b0000000160272b134ca494b602137d89e528c751c06d3ef4a87a45f33af343c15060cc1e0000000000",
|
|
7
|
+
"orchardTree": "01a56006df9c2cea376340e9c4151357aa4e5cc6df1450a5cbcc7d2d40331c8b2801d0d52fceb31b3d9426567fe46e230349296d9f82429dd578e1ad555f85bb6b3c1f01114610a2dd861669b0711647b63596255cf3490ed17553b84d3f0022ec653b1801516ffaa1aaff108712065c456e635c917fe7e5c94e307e40f302d9007ed1d429016d2bd0ae12cbc2001ae60146ff02af15246450edb3e32d74af21828152f0970e000001da3f3fafc421317061f2c62fc0e044a9c65f3ec18e5066cbbfeb652c4138660c0000010113d5a7bccf7b402da04b40b55c966ff762cb9cfa433df7bd8b4abce604f2110000014791455ec71b72a30f5f94215492c9836a5486f4b7ffae9887bfb0a419dacb340000010c104faa2b1148b1b627090aa939e321b82edcb0ce70aa4eee298997556b4f35000112278dfeae9949f887b70ae81e084f8897a5054627acef3efd01c8b29793d522000160040850b766b126a2b4843fcdfdffa5d5cab3f53bc860a3bef68958b5f066170001cc2dcaa338b312112db04b435a706d63244dd435238f0aa1e9e1598d35470810012dcc4273c8a0ed2337ecf7879380a07e7d427c7f9d82e538002bd1442978402c01daf63debf5b40df902dae98dadc029f281474d190cddecef1b10653248a234150001e2bca6a8d987d668defba89dc082196a922634ed88e065c669e526bb8815ee1b000000000000"
|
|
8
|
+
}
|
|
@@ -20,6 +20,7 @@ import kotlinx.coroutines.Dispatchers
|
|
|
20
20
|
import kotlinx.coroutines.async
|
|
21
21
|
import kotlinx.coroutines.flow.*
|
|
22
22
|
import kotlinx.coroutines.launch
|
|
23
|
+
import java.util.Base64
|
|
23
24
|
|
|
24
25
|
class RNZcashModule(private val reactContext: ReactApplicationContext) :
|
|
25
26
|
ReactContextBaseJavaModule(reactContext) {
|
|
@@ -203,7 +204,7 @@ class RNZcashModule(private val reactContext: ReactApplicationContext) :
|
|
|
203
204
|
}
|
|
204
205
|
map.putInt("minedHeight", tx.minedHeight?.value?.toInt() ?: 0)
|
|
205
206
|
map.putInt("blockTimeInSeconds", tx.blockTimeEpochSeconds?.toInt() ?: 0)
|
|
206
|
-
map.putString("rawTransactionId", tx.
|
|
207
|
+
map.putString("rawTransactionId", tx.txIdString())
|
|
207
208
|
if (tx.raw != null) {
|
|
208
209
|
map.putString("raw", tx.raw!!.byteArray.toHex())
|
|
209
210
|
}
|
|
@@ -323,6 +324,7 @@ class RNZcashModule(private val reactContext: ReactApplicationContext) :
|
|
|
323
324
|
val map = Arguments.createMap()
|
|
324
325
|
map.putInt("transactionCount", proposal.transactionCount())
|
|
325
326
|
map.putString("totalFee", proposal.totalFeeRequired().value.toString())
|
|
327
|
+
map.putString("proposalBase64", Base64.getEncoder().encodeToString(proposal.toByteArray()))
|
|
326
328
|
promise.resolve(map)
|
|
327
329
|
} catch (t: Throwable) {
|
|
328
330
|
promise.reject("Err", t)
|
|
@@ -330,12 +332,11 @@ class RNZcashModule(private val reactContext: ReactApplicationContext) :
|
|
|
330
332
|
}
|
|
331
333
|
}
|
|
332
334
|
|
|
335
|
+
@kotlin.ExperimentalStdlibApi
|
|
333
336
|
@ReactMethod
|
|
334
|
-
fun
|
|
337
|
+
fun createTransfer(
|
|
335
338
|
alias: String,
|
|
336
|
-
|
|
337
|
-
toAddress: String,
|
|
338
|
-
memo: String = "",
|
|
339
|
+
proposalBase64: String,
|
|
339
340
|
seed: String,
|
|
340
341
|
promise: Promise,
|
|
341
342
|
) {
|
|
@@ -344,18 +345,15 @@ class RNZcashModule(private val reactContext: ReactApplicationContext) :
|
|
|
344
345
|
try {
|
|
345
346
|
val seedPhrase = SeedPhrase.new(seed)
|
|
346
347
|
val usk = DerivationTool.getInstance().deriveUnifiedSpendingKey(seedPhrase.toByteArray(), wallet.network, Account.DEFAULT)
|
|
347
|
-
val
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
)
|
|
354
|
-
val
|
|
355
|
-
|
|
356
|
-
map.putString("txId", tx.rawId.byteArray.toHexReversed())
|
|
357
|
-
if (tx.raw != null) map.putString("raw", tx.raw?.byteArray?.toHex())
|
|
358
|
-
promise.resolve(map)
|
|
348
|
+
val proposalByteArray = Base64.getDecoder().decode(proposalBase64)
|
|
349
|
+
val proposal = Proposal.fromByteArray(proposalByteArray)
|
|
350
|
+
|
|
351
|
+
val txs =
|
|
352
|
+
wallet.coroutineScope.async {
|
|
353
|
+
wallet.createProposedTransactions(proposal, usk).take(proposal.transactionCount()).toList()
|
|
354
|
+
}.await()
|
|
355
|
+
val txid = txs[txs.lastIndex].txIdString() // The last transfer is the most relevant to the user
|
|
356
|
+
promise.resolve(txid)
|
|
359
357
|
} catch (t: Throwable) {
|
|
360
358
|
promise.reject("Err", t)
|
|
361
359
|
}
|
|
@@ -473,14 +471,6 @@ class RNZcashModule(private val reactContext: ReactApplicationContext) :
|
|
|
473
471
|
.emit(eventName, args)
|
|
474
472
|
}
|
|
475
473
|
|
|
476
|
-
private fun ByteArray.toHexReversed(): String {
|
|
477
|
-
val sb = StringBuilder(size * 2)
|
|
478
|
-
var i = size - 1
|
|
479
|
-
while (i >= 0)
|
|
480
|
-
sb.append(String.format("%02x", this[i--]))
|
|
481
|
-
return sb.toString()
|
|
482
|
-
}
|
|
483
|
-
|
|
484
474
|
data class Balances(
|
|
485
475
|
val transparentBalance: Zatoshi?,
|
|
486
476
|
val saplingBalances: WalletBalance?,
|
package/ios/RNZcash.m
CHANGED
|
@@ -44,11 +44,9 @@ resolver:(RCTPromiseResolveBlock)resolve
|
|
|
44
44
|
rejecter:(RCTPromiseRejectBlock)reject
|
|
45
45
|
)
|
|
46
46
|
|
|
47
|
-
RCT_EXTERN_METHOD(
|
|
48
|
-
:(NSString *)
|
|
49
|
-
:(NSString *)
|
|
50
|
-
:(NSString *)memo
|
|
51
|
-
:(NSString *)spendingKey
|
|
47
|
+
RCT_EXTERN_METHOD(createTransfer:(NSString *)alias
|
|
48
|
+
:(NSString *)proposalBase64
|
|
49
|
+
:(NSString *)seed
|
|
52
50
|
resolver:(RCTPromiseResolveBlock)resolve
|
|
53
51
|
rejecter:(RCTPromiseRejectBlock)reject
|
|
54
52
|
)
|
package/ios/RNZcash.swift
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import Combine
|
|
2
2
|
import Foundation
|
|
3
3
|
import MnemonicSwift
|
|
4
|
+
import SwiftProtobuf
|
|
4
5
|
import os
|
|
5
6
|
|
|
6
7
|
var SynchronizerMap = [String: WalletSynchronizer]()
|
|
@@ -102,6 +103,7 @@ class RNZcash: RCTEventEmitter {
|
|
|
102
103
|
fsBlockDbRoot: try! fsBlockDbRootURLHelper(alias, network),
|
|
103
104
|
generalStorageURL: try! generalStorageURLHelper(alias, network),
|
|
104
105
|
dataDbURL: try! dataDbURLHelper(alias, network),
|
|
106
|
+
torDirURL: try! torDirURLHelper(alias, network),
|
|
105
107
|
endpoint: endpoint,
|
|
106
108
|
network: network,
|
|
107
109
|
spendParamsURL: try! spendParamsURLHelper(alias),
|
|
@@ -229,7 +231,10 @@ class RNZcash: RCTEventEmitter {
|
|
|
229
231
|
memo: sdkMemo
|
|
230
232
|
)
|
|
231
233
|
|
|
234
|
+
let proposalBase64 = try proposal.inner.serializedData().base64EncodedString()
|
|
235
|
+
|
|
232
236
|
let out: NSMutableDictionary = [
|
|
237
|
+
"proposalBase64": proposalBase64,
|
|
233
238
|
"transactionCount": proposal.transactionCount(),
|
|
234
239
|
"totalFee": String(proposal.totalFeeRequired().amount),
|
|
235
240
|
]
|
|
@@ -248,42 +253,47 @@ class RNZcash: RCTEventEmitter {
|
|
|
248
253
|
}
|
|
249
254
|
}
|
|
250
255
|
|
|
251
|
-
@objc func
|
|
252
|
-
_ alias: String, _
|
|
256
|
+
@objc func createTransfer(
|
|
257
|
+
_ alias: String, _ proposalBase64: String, _ seed: String,
|
|
253
258
|
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
254
259
|
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
255
260
|
) {
|
|
256
261
|
Task {
|
|
257
262
|
if let wallet = SynchronizerMap[alias] {
|
|
258
|
-
let amount = Int64(zatoshi)
|
|
259
|
-
if amount == nil {
|
|
260
|
-
reject("SpendToAddressError", "Amount is invalid", genericError)
|
|
261
|
-
return
|
|
262
|
-
}
|
|
263
|
-
|
|
264
263
|
do {
|
|
265
264
|
let spendingKey = try deriveUnifiedSpendingKey(seed, wallet.synchronizer.network)
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
let
|
|
271
|
-
spendingKey: spendingKey
|
|
272
|
-
zatoshi: Zatoshi(amount!),
|
|
273
|
-
toAddress: Recipient(toAddress, network: wallet.synchronizer.network.networkType),
|
|
274
|
-
memo: sdkMemo
|
|
265
|
+
let data = Data.init(base64Encoded: proposalBase64)!
|
|
266
|
+
let ffiProposal = try FfiProposal(serializedData: data)
|
|
267
|
+
let proposal = Proposal(inner: ffiProposal)
|
|
268
|
+
|
|
269
|
+
let transactions = try await wallet.synchronizer.createProposedTransactions(
|
|
270
|
+
proposal: proposal, spendingKey: spendingKey
|
|
275
271
|
)
|
|
276
272
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
tx
|
|
273
|
+
var lastTxid = "" // The last transfer is the most relevant to the user
|
|
274
|
+
for try await tx in transactions {
|
|
275
|
+
switch tx {
|
|
276
|
+
case .grpcFailure(_, let error):
|
|
277
|
+
throw error
|
|
278
|
+
case .success(let txId):
|
|
279
|
+
lastTxid = txId.toHexStringTxId()
|
|
280
|
+
continue
|
|
281
|
+
case let .submitFailure(txId: _, code: code, description: description):
|
|
282
|
+
throw NSError(
|
|
283
|
+
domain:
|
|
284
|
+
"transaction failed to submit with code: \(code) - description: \(description)",
|
|
285
|
+
code: 0)
|
|
286
|
+
case .notAttempted(_):
|
|
287
|
+
throw NSError(domain: "transaction not attempted", code: 0)
|
|
288
|
+
}
|
|
280
289
|
}
|
|
281
|
-
|
|
290
|
+
|
|
291
|
+
resolve(lastTxid)
|
|
282
292
|
} catch {
|
|
283
|
-
reject("
|
|
293
|
+
reject("createTransfer", "Failed to spend", error)
|
|
284
294
|
}
|
|
285
295
|
} else {
|
|
286
|
-
reject("
|
|
296
|
+
reject("createTransfer", "Wallet does not exist", genericError)
|
|
287
297
|
}
|
|
288
298
|
}
|
|
289
299
|
}
|
|
@@ -432,6 +442,7 @@ class RNZcash: RCTEventEmitter {
|
|
|
432
442
|
if derivationTool.isValidUnifiedAddress(address)
|
|
433
443
|
|| derivationTool.isValidSaplingAddress(address)
|
|
434
444
|
|| derivationTool.isValidTransparentAddress(address)
|
|
445
|
+
|| derivationTool.isValidTexAddress(address)
|
|
435
446
|
{
|
|
436
447
|
resolve(true)
|
|
437
448
|
} else {
|
|
@@ -698,6 +709,14 @@ func dataDbURLHelper(_ alias: String, _ network: ZcashNetwork) throws -> URL {
|
|
|
698
709
|
)
|
|
699
710
|
}
|
|
700
711
|
|
|
712
|
+
func torDirURLHelper(_ alias: String, _ network: ZcashNetwork) throws -> URL {
|
|
713
|
+
try documentsDirectoryHelper()
|
|
714
|
+
.appendingPathComponent(
|
|
715
|
+
network.constants.defaultDbNamePrefix + alias + ZcashSDK.defaultTorDirName,
|
|
716
|
+
isDirectory: true
|
|
717
|
+
)
|
|
718
|
+
}
|
|
719
|
+
|
|
701
720
|
func spendParamsURLHelper(_ alias: String) throws -> URL {
|
|
702
721
|
try documentsDirectoryHelper().appendingPathComponent(alias + "sapling-spend.params")
|
|
703
722
|
}
|
package/ios/RNZcash.xcodeproj/xcuserdata/samholmes.xcuserdatad/xcschemes/xcschememanagement.plist
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
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>0</integer>
|
|
11
|
+
</dict>
|
|
12
|
+
</dict>
|
|
13
|
+
</dict>
|
|
14
|
+
</plist>
|
package/ios/RNZcash.xcworkspace/xcuserdata/samholmes.xcuserdatad/UserInterfaceState.xcuserstate
ADDED
|
Binary file
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
//
|
|
2
|
+
// TxResubmissionAction.swift
|
|
3
|
+
//
|
|
4
|
+
//
|
|
5
|
+
// Created by Lukas Korba on 06-17-2024.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
|
|
10
|
+
final class TxResubmissionAction {
|
|
11
|
+
private enum Constants {
|
|
12
|
+
static let thresholdToTrigger = TimeInterval(300.0)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
var latestResolvedTime: TimeInterval = 0
|
|
16
|
+
let transactionRepository: TransactionRepository
|
|
17
|
+
let transactionEncoder: TransactionEncoder
|
|
18
|
+
let logger: Logger
|
|
19
|
+
|
|
20
|
+
init(container: DIContainer) {
|
|
21
|
+
transactionRepository = container.resolve(TransactionRepository.self)
|
|
22
|
+
transactionEncoder = container.resolve(TransactionEncoder.self)
|
|
23
|
+
logger = container.resolve(Logger.self)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
extension TxResubmissionAction: Action {
|
|
28
|
+
var removeBlocksCacheWhenFailed: Bool { true }
|
|
29
|
+
|
|
30
|
+
func run(with context: ActionContext, didUpdate: @escaping (CompactBlockProcessor.Event) async -> Void) async throws -> ActionContext {
|
|
31
|
+
let latestBlockHeight = await context.syncControlData.latestBlockHeight
|
|
32
|
+
|
|
33
|
+
// find all candidates for the resubmission
|
|
34
|
+
do {
|
|
35
|
+
logger.info("TxResubmissionAction check started at \(latestBlockHeight) height.")
|
|
36
|
+
let transactions = try await transactionRepository.findForResubmission(upTo: latestBlockHeight)
|
|
37
|
+
|
|
38
|
+
// no candidates, update the time and continue with the next action
|
|
39
|
+
if transactions.isEmpty {
|
|
40
|
+
latestResolvedTime = Date().timeIntervalSince1970
|
|
41
|
+
} else {
|
|
42
|
+
let now = Date().timeIntervalSince1970
|
|
43
|
+
let diff = now - latestResolvedTime
|
|
44
|
+
|
|
45
|
+
// the last time resubmission was triggered is more than 5 minutes ago so try again
|
|
46
|
+
if diff > Constants.thresholdToTrigger {
|
|
47
|
+
// resubmission
|
|
48
|
+
do {
|
|
49
|
+
for transaction in transactions {
|
|
50
|
+
logger.info("TxResubmissionAction trying to resubmit transaction \(transaction.rawID.toHexStringTxId()).")
|
|
51
|
+
let encodedTransaction = try transaction.encodedTransaction()
|
|
52
|
+
|
|
53
|
+
try await transactionEncoder.submit(transaction: encodedTransaction)
|
|
54
|
+
}
|
|
55
|
+
} catch {
|
|
56
|
+
logger.error("TxResubmissionAction failed to resubmit candidates.")
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
latestResolvedTime = Date().timeIntervalSince1970
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
} catch {
|
|
63
|
+
logger.error("TxResubmissionAction failed to find candidates.")
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if await context.prevState == .enhance {
|
|
67
|
+
await context.update(state: .updateChainTip)
|
|
68
|
+
} else {
|
|
69
|
+
await context.update(state: .finished)
|
|
70
|
+
}
|
|
71
|
+
return context
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
func stop() async { }
|
|
75
|
+
}
|
|
@@ -44,7 +44,7 @@ extension UpdateChainTipAction: Action {
|
|
|
44
44
|
await downloader.stopDownload()
|
|
45
45
|
try await updateChainTip(context, time: now)
|
|
46
46
|
await context.update(state: .clearCache)
|
|
47
|
-
} else if await context.prevState == .
|
|
47
|
+
} else if await context.prevState == .txResubmission {
|
|
48
48
|
await context.update(state: .download)
|
|
49
49
|
}
|
|
50
50
|
|
|
@@ -30,7 +30,7 @@ extension UpdateSubtreeRootsAction: Action {
|
|
|
30
30
|
|
|
31
31
|
logger.debug("Attempt to get subtree roots, this may fail because lightwalletd may not support Spend before Sync.")
|
|
32
32
|
let stream = service.getSubtreeRoots(request)
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
var saplingRoots: [SubtreeRoot] = []
|
|
35
35
|
|
|
36
36
|
do {
|
|
@@ -39,6 +39,8 @@ extension UpdateSubtreeRootsAction: Action {
|
|
|
39
39
|
}
|
|
40
40
|
} catch ZcashError.serviceSubtreeRootsStreamFailed(LightWalletServiceError.timeOut) {
|
|
41
41
|
throw ZcashError.serviceSubtreeRootsStreamFailed(LightWalletServiceError.timeOut)
|
|
42
|
+
} catch {
|
|
43
|
+
await context.update(state: .updateChainTip)
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
logger.debug("Sapling tree has \(saplingRoots.count) subtrees")
|
|
@@ -56,6 +56,7 @@ actor CompactBlockProcessor {
|
|
|
56
56
|
let saplingParamsSourceURL: SaplingParamsSourceURL
|
|
57
57
|
let fsBlockCacheRoot: URL
|
|
58
58
|
let dataDb: URL
|
|
59
|
+
let torDir: URL
|
|
59
60
|
let spendParamsURL: URL
|
|
60
61
|
let outputParamsURL: URL
|
|
61
62
|
let enhanceBatchSize: Int
|
|
@@ -79,6 +80,7 @@ actor CompactBlockProcessor {
|
|
|
79
80
|
cacheDbURL: URL? = nil,
|
|
80
81
|
fsBlockCacheRoot: URL,
|
|
81
82
|
dataDb: URL,
|
|
83
|
+
torDir: URL,
|
|
82
84
|
spendParamsURL: URL,
|
|
83
85
|
outputParamsURL: URL,
|
|
84
86
|
saplingParamsSourceURL: SaplingParamsSourceURL,
|
|
@@ -94,6 +96,7 @@ actor CompactBlockProcessor {
|
|
|
94
96
|
self.alias = alias
|
|
95
97
|
self.fsBlockCacheRoot = fsBlockCacheRoot
|
|
96
98
|
self.dataDb = dataDb
|
|
99
|
+
self.torDir = torDir
|
|
97
100
|
self.spendParamsURL = spendParamsURL
|
|
98
101
|
self.outputParamsURL = outputParamsURL
|
|
99
102
|
self.saplingParamsSourceURL = saplingParamsSourceURL
|
|
@@ -112,6 +115,7 @@ actor CompactBlockProcessor {
|
|
|
112
115
|
alias: ZcashSynchronizerAlias,
|
|
113
116
|
fsBlockCacheRoot: URL,
|
|
114
117
|
dataDb: URL,
|
|
118
|
+
torDir: URL,
|
|
115
119
|
spendParamsURL: URL,
|
|
116
120
|
outputParamsURL: URL,
|
|
117
121
|
saplingParamsSourceURL: SaplingParamsSourceURL,
|
|
@@ -126,6 +130,7 @@ actor CompactBlockProcessor {
|
|
|
126
130
|
self.alias = alias
|
|
127
131
|
self.fsBlockCacheRoot = fsBlockCacheRoot
|
|
128
132
|
self.dataDb = dataDb
|
|
133
|
+
self.torDir = torDir
|
|
129
134
|
self.spendParamsURL = spendParamsURL
|
|
130
135
|
self.outputParamsURL = outputParamsURL
|
|
131
136
|
self.saplingParamsSourceURL = saplingParamsSourceURL
|
|
@@ -151,6 +156,7 @@ actor CompactBlockProcessor {
|
|
|
151
156
|
alias: initializer.alias,
|
|
152
157
|
fsBlockCacheRoot: initializer.fsBlockDbRoot,
|
|
153
158
|
dataDb: initializer.dataDbURL,
|
|
159
|
+
torDir: initializer.torDirURL,
|
|
154
160
|
spendParamsURL: initializer.spendParamsURL,
|
|
155
161
|
outputParamsURL: initializer.outputParamsURL,
|
|
156
162
|
saplingParamsSourceURL: initializer.saplingParamsSourceURL,
|
|
@@ -228,6 +234,8 @@ actor CompactBlockProcessor {
|
|
|
228
234
|
action = SaplingParamsAction(container: container)
|
|
229
235
|
case .clearCache:
|
|
230
236
|
action = ClearCacheAction(container: container)
|
|
237
|
+
case .txResubmission:
|
|
238
|
+
action = TxResubmissionAction(container: container)
|
|
231
239
|
case .finished, .failed, .stopped, .idle:
|
|
232
240
|
return nil
|
|
233
241
|
}
|
|
@@ -284,6 +292,10 @@ extension CompactBlockProcessor {
|
|
|
284
292
|
func latestHeight() async throws -> BlockHeight {
|
|
285
293
|
try await blockDownloaderService.latestBlockHeight()
|
|
286
294
|
}
|
|
295
|
+
|
|
296
|
+
func consensusBranchIdFor(_ height: Int32) -> Int32? {
|
|
297
|
+
try? rustBackend.consensusBranchIdFor(height: height)
|
|
298
|
+
}
|
|
287
299
|
}
|
|
288
300
|
|
|
289
301
|
// MARK: - Rewind
|
|
@@ -667,6 +679,8 @@ extension CompactBlockProcessor {
|
|
|
667
679
|
break
|
|
668
680
|
case .stopped:
|
|
669
681
|
break
|
|
682
|
+
case .txResubmission:
|
|
683
|
+
break
|
|
670
684
|
}
|
|
671
685
|
}
|
|
672
686
|
|
|
@@ -43,7 +43,7 @@ protocol BlockDownloaderService {
|
|
|
43
43
|
Gets the transaction for the Id given
|
|
44
44
|
- Parameter txId: Data representing the transaction Id
|
|
45
45
|
*/
|
|
46
|
-
func fetchTransaction(txId: Data) async throws -> ZcashTransaction.Fetched
|
|
46
|
+
func fetchTransaction(txId: Data) async throws -> (tx: ZcashTransaction.Fetched?, status: TransactionStatus)
|
|
47
47
|
|
|
48
48
|
func fetchUnspentTransactionOutputs(tAddress: String, startHeight: BlockHeight) -> AsyncThrowingStream<UnspentTransactionOutputEntity, Error>
|
|
49
49
|
|
|
@@ -111,7 +111,7 @@ extension BlockDownloaderServiceImpl: BlockDownloaderService {
|
|
|
111
111
|
try await self.storage.latestHeight()
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
func fetchTransaction(txId: Data) async throws -> ZcashTransaction.Fetched {
|
|
114
|
+
func fetchTransaction(txId: Data) async throws -> (tx: ZcashTransaction.Fetched?, status: TransactionStatus) {
|
|
115
115
|
try await lightwalletService.fetchTransaction(txId: txId)
|
|
116
116
|
}
|
|
117
117
|
}
|