react-native-zcash 0.9.13 → 0.10.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 +4 -0
- package/android/build.gradle +6 -6
- package/android/src/main/assets/co.electriccoin.zcash/checkpoint/mainnet/3130000.json +8 -0
- package/android/src/main/java/app/edge/rnzcash/RNZcashModule.kt +126 -69
- package/ios/RNZcash.m +0 -5
- package/ios/RNZcash.swift +153 -104
- package/ios/ZCashLightClientKit/Account/Account.swift +48 -0
- package/ios/ZCashLightClientKit/Account/AccountMetadataKey.swift +96 -0
- package/ios/ZCashLightClientKit/Block/Actions/ScanAction.swift +23 -4
- package/ios/ZCashLightClientKit/Block/Actions/UpdateChainTipAction.swift +6 -2
- package/ios/ZCashLightClientKit/Block/Actions/UpdateSubtreeRootsAction.swift +4 -2
- package/ios/ZCashLightClientKit/Block/Actions/ValidateServerAction.swift +4 -1
- package/ios/ZCashLightClientKit/Block/CompactBlockProcessor.swift +83 -16
- package/ios/ZCashLightClientKit/Block/Download/BlockDownloader.swift +4 -2
- package/ios/ZCashLightClientKit/Block/Download/BlockDownloaderService.swift +22 -19
- package/ios/ZCashLightClientKit/Block/Enhance/BlockEnhancer.swift +50 -19
- package/ios/ZCashLightClientKit/Block/FetchUnspentTxOutputs/UTXOFetcher.swift +5 -3
- package/ios/ZCashLightClientKit/Block/SaplingParameters/SaplingParametersHandler.swift +22 -5
- package/ios/ZCashLightClientKit/Block/Scan/BlockScanner.swift +2 -1
- package/ios/ZCashLightClientKit/Block/Utils/CompactBlockProgress.swift +5 -3
- package/ios/ZCashLightClientKit/Checkpoint/BundleCheckpointSource.swift +88 -0
- package/ios/ZCashLightClientKit/Checkpoint/CheckpointSource.swift +4 -0
- package/ios/ZCashLightClientKit/ClosureSynchronizer.swift +52 -21
- package/ios/ZCashLightClientKit/CombineSynchronizer.swift +49 -27
- package/ios/ZCashLightClientKit/Constants/ZcashSDK.swift +8 -2
- package/ios/ZCashLightClientKit/DAO/BlockDao.swift +65 -0
- package/ios/ZCashLightClientKit/DAO/TransactionDao.swift +86 -1
- package/ios/ZCashLightClientKit/Entity/AccountEntity.swift +4 -4
- package/ios/ZCashLightClientKit/Entity/Pczt.swift +10 -0
- package/ios/ZCashLightClientKit/Entity/SentNoteEntity.swift +2 -2
- package/ios/ZCashLightClientKit/Entity/TransactionEntity.swift +40 -16
- package/ios/ZCashLightClientKit/Error/Sourcery/generateErrorCode.sh +1 -1
- package/ios/ZCashLightClientKit/Error/ZcashError.swift +182 -14
- package/ios/ZCashLightClientKit/Error/ZcashErrorCode.swift +63 -5
- package/ios/ZCashLightClientKit/Error/ZcashErrorCodeDefinition.swift +122 -12
- package/ios/ZCashLightClientKit/Initializer.swift +49 -14
- package/ios/ZCashLightClientKit/Metrics/SDKMetrics.swift +15 -6
- package/ios/ZCashLightClientKit/Model/SingleUseTransparentAddress.swift +29 -0
- package/ios/ZCashLightClientKit/Model/TransactionDataRequest.swift +83 -2
- package/ios/ZCashLightClientKit/Model/WalletSummary.swift +21 -4
- package/ios/ZCashLightClientKit/Model/WalletTypes.swift +38 -8
- package/ios/ZCashLightClientKit/Modules/Service/GRPC/LightWalletGRPCService.swift +177 -45
- package/ios/ZCashLightClientKit/Modules/Service/LightWalletService.swift +63 -16
- package/ios/ZCashLightClientKit/Modules/Service/Tor/LightWalletGRPCServiceOverTor.swift +273 -0
- package/ios/ZCashLightClientKit/Providers/LatestBlocksDataProvider.swift +5 -2
- package/ios/ZCashLightClientKit/Repository/TransactionRepository.swift +2 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2675000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2677500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2682500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2685000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2687500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2692500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2695000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2697500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2702500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2705000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2707500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2712500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2715000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2717500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2722500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2725000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2727500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2732500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2735000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2737500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2742500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2745000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2747500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2752500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2755000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2757500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2762500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2765000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2767500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2772500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2775000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2777500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2782500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2785000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2787500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2792500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2795000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2797500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2802500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2805000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2807500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2812500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2815000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2817500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2822500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2825000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2827500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2832500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2835000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2837500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2842500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2845000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2847500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2852500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2855000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2857500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2862500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2865000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2867500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2872500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2875000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2877500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2882500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2885000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2887500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2892500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2895000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2897500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2902500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2905000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2907500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2912500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2915000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2917500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2922500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2925000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2927500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2932500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2935000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2937500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2942500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2945000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2947500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2952500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2955000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2957500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2962500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2965000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2967500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2972500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2975000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2977500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2982500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2985000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2987500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2992500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2995000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2997500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3002500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3005000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3007500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3012500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3015000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3017500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3022500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3025000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3027500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3032500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3035000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3037500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3042500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3045000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3047500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3052500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3055000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3057500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3062500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3065000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3067500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3072500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3075000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3077500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3082500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3085000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3087500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3092500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3095000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3097500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3102500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3105000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3107500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3112500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3115000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3117500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3122500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3125000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3127500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/3130000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3010000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3020000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3030000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3040000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3050000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3060000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3070000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3080000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3090000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3100000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3110000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3120000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3130000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3140000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3150000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3160000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3170000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3180000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3190000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3200000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3210000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3220000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3230000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3240000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3250000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3260000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3270000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3280000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3290000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3300000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3310000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3320000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3330000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3340000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3350000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3360000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3370000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3380000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3390000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3400000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3410000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3420000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3430000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3440000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3450000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3460000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3470000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3480000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3490000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3500000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3510000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3520000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3530000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3540000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3550000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3560000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3570000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3580000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3590000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3600000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3610000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3620000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3630000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3640000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3650000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3660000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/3670000.json +8 -0
- package/ios/ZCashLightClientKit/Rust/ZcashKeyDerivationBackend.swift +89 -10
- package/ios/ZCashLightClientKit/Rust/ZcashKeyDerivationBackendWelding.swift +39 -3
- package/ios/ZCashLightClientKit/Rust/ZcashRustBackend.swift +532 -74
- package/ios/ZCashLightClientKit/Rust/ZcashRustBackendWelding.swift +97 -14
- package/ios/ZCashLightClientKit/Synchronizer/ClosureSDKSynchronizer.swift +104 -28
- package/ios/ZCashLightClientKit/Synchronizer/CombineSDKSynchronizer.swift +105 -31
- package/ios/ZCashLightClientKit/Synchronizer/Dependencies.swift +36 -9
- package/ios/ZCashLightClientKit/Synchronizer/SDKSynchronizer.swift +401 -175
- package/ios/ZCashLightClientKit/Synchronizer.swift +192 -69
- package/ios/ZCashLightClientKit/Tool/DerivationTool.swift +69 -12
- package/ios/ZCashLightClientKit/Tor/TorClient.swift +502 -11
- package/ios/ZCashLightClientKit/Transaction/TransactionEncoder.swift +10 -6
- package/ios/ZCashLightClientKit/Transaction/WalletTransactionEncoder.swift +24 -9
- package/ios/ZCashLightClientKit/Utils/SDKFlags.swift +71 -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 +1640 -378
- package/lib/rnzcash.rn.js.map +1 -1
- package/lib/src/react-native.d.ts +2 -2
- package/lib/src/types.d.ts +2 -0
- package/package.json +1 -1
- package/src/react-native.ts +2 -3
- package/src/types.ts +2 -0
package/ios/RNZcash.swift
CHANGED
|
@@ -4,7 +4,24 @@ import MnemonicSwift
|
|
|
4
4
|
import SwiftProtobuf
|
|
5
5
|
import os
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
actor SynchronizerStore {
|
|
8
|
+
private var map: [String: WalletSynchronizer] = [:]
|
|
9
|
+
|
|
10
|
+
func get(_ alias: String) -> WalletSynchronizer? {
|
|
11
|
+
map[alias]
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
func set(_ wallet: WalletSynchronizer, for alias: String) {
|
|
15
|
+
map[alias] = wallet
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
func remove(_ alias: String) {
|
|
19
|
+
map.removeValue(forKey: alias)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
let synchronizerStore = SynchronizerStore()
|
|
8
25
|
|
|
9
26
|
struct ConfirmedTx {
|
|
10
27
|
var minedHeight: Int
|
|
@@ -14,6 +31,8 @@ struct ConfirmedTx {
|
|
|
14
31
|
var blockTimeInSeconds: Int
|
|
15
32
|
var value: String
|
|
16
33
|
var fee: String?
|
|
34
|
+
var isShielding: Bool
|
|
35
|
+
var isExpired: Bool
|
|
17
36
|
var memos: [String]?
|
|
18
37
|
var dictionary: [String: Any?] {
|
|
19
38
|
return [
|
|
@@ -25,28 +44,8 @@ struct ConfirmedTx {
|
|
|
25
44
|
"value": value,
|
|
26
45
|
"fee": fee,
|
|
27
46
|
"memos": memos ?? [],
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
var nsDictionary: NSDictionary {
|
|
31
|
-
return dictionary as NSDictionary
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
struct TotalBalances {
|
|
36
|
-
var transparentAvailableZatoshi: Zatoshi
|
|
37
|
-
var transparentTotalZatoshi: Zatoshi
|
|
38
|
-
var saplingAvailableZatoshi: Zatoshi
|
|
39
|
-
var saplingTotalZatoshi: Zatoshi
|
|
40
|
-
var orchardAvailableZatoshi: Zatoshi
|
|
41
|
-
var orchardTotalZatoshi: Zatoshi
|
|
42
|
-
var dictionary: [String: Any] {
|
|
43
|
-
return [
|
|
44
|
-
"transparentAvailableZatoshi": String(transparentAvailableZatoshi.amount),
|
|
45
|
-
"transparentTotalZatoshi": String(transparentTotalZatoshi.amount),
|
|
46
|
-
"saplingAvailableZatoshi": String(saplingAvailableZatoshi.amount),
|
|
47
|
-
"saplingTotalZatoshi": String(saplingTotalZatoshi.amount),
|
|
48
|
-
"orchardAvailableZatoshi": String(orchardAvailableZatoshi.amount),
|
|
49
|
-
"orchardTotalZatoshi": String(orchardTotalZatoshi.amount),
|
|
47
|
+
"isShielding": isShielding,
|
|
48
|
+
"isExpired": isExpired,
|
|
50
49
|
]
|
|
51
50
|
}
|
|
52
51
|
var nsDictionary: NSDictionary {
|
|
@@ -109,9 +108,11 @@ class RNZcash: RCTEventEmitter {
|
|
|
109
108
|
spendParamsURL: try! spendParamsURLHelper(alias),
|
|
110
109
|
outputParamsURL: try! outputParamsURLHelper(alias),
|
|
111
110
|
saplingParamsSourceURL: SaplingParamsSourceURL.default,
|
|
112
|
-
alias: ZcashSynchronizerAlias.custom(alias)
|
|
111
|
+
alias: ZcashSynchronizerAlias.custom(alias),
|
|
112
|
+
isTorEnabled: false,
|
|
113
|
+
isExchangeRateEnabled: false
|
|
113
114
|
)
|
|
114
|
-
if
|
|
115
|
+
if await synchronizerStore.get(alias) == nil {
|
|
115
116
|
do {
|
|
116
117
|
let wallet = try WalletSynchronizer(
|
|
117
118
|
alias: alias, initializer: initializer, emitter: sendToJs)
|
|
@@ -121,11 +122,16 @@ class RNZcash: RCTEventEmitter {
|
|
|
121
122
|
_ = try await wallet.synchronizer.prepare(
|
|
122
123
|
with: seedBytes,
|
|
123
124
|
walletBirthday: birthdayHeight,
|
|
124
|
-
for: initMode
|
|
125
|
+
for: initMode,
|
|
126
|
+
name: alias,
|
|
127
|
+
keySource: nil
|
|
125
128
|
)
|
|
129
|
+
let accounts = try await wallet.synchronizer.listAccounts()
|
|
130
|
+
let accountUUID = accounts.first(where: { $0.name == alias })?.id
|
|
131
|
+
wallet.accountUUID = accountUUID
|
|
126
132
|
try await wallet.synchronizer.start()
|
|
127
133
|
wallet.subscribe()
|
|
128
|
-
|
|
134
|
+
await synchronizerStore.set(wallet, for: alias)
|
|
129
135
|
resolve(nil)
|
|
130
136
|
} catch {
|
|
131
137
|
reject("InitializeError", "Synchronizer failed to initialize", error)
|
|
@@ -137,45 +143,28 @@ class RNZcash: RCTEventEmitter {
|
|
|
137
143
|
}
|
|
138
144
|
}
|
|
139
145
|
|
|
140
|
-
@objc func
|
|
146
|
+
@objc func stop(
|
|
141
147
|
_ alias: String, resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
142
148
|
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
143
149
|
) {
|
|
144
150
|
Task {
|
|
145
|
-
if let wallet =
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
} catch {
|
|
150
|
-
reject("StartError", "Synchronizer failed to start", error)
|
|
151
|
-
}
|
|
151
|
+
if let wallet = await synchronizerStore.get(alias) {
|
|
152
|
+
wallet.synchronizer.stop()
|
|
153
|
+
wallet.cancellables.forEach { $0.cancel() }
|
|
154
|
+
await synchronizerStore.remove(alias)
|
|
152
155
|
resolve(nil)
|
|
153
156
|
} else {
|
|
154
|
-
reject("
|
|
157
|
+
reject("StopError", "Wallet does not exist", genericError)
|
|
155
158
|
}
|
|
156
159
|
}
|
|
157
160
|
}
|
|
158
161
|
|
|
159
|
-
@objc func stop(
|
|
160
|
-
_ alias: String, resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
161
|
-
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
162
|
-
) {
|
|
163
|
-
if let wallet = SynchronizerMap[alias] {
|
|
164
|
-
wallet.synchronizer.stop()
|
|
165
|
-
wallet.cancellables.forEach { $0.cancel() }
|
|
166
|
-
SynchronizerMap[alias] = nil
|
|
167
|
-
resolve(nil)
|
|
168
|
-
} else {
|
|
169
|
-
reject("StopError", "Wallet does not exist", genericError)
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
162
|
@objc func getLatestNetworkHeight(
|
|
174
163
|
_ alias: String, resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
175
164
|
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
176
165
|
) {
|
|
177
166
|
Task {
|
|
178
|
-
if let wallet =
|
|
167
|
+
if let wallet = await synchronizerStore.get(alias) {
|
|
179
168
|
do {
|
|
180
169
|
let height = try await wallet.synchronizer.latestHeight()
|
|
181
170
|
resolve(height)
|
|
@@ -197,8 +186,8 @@ class RNZcash: RCTEventEmitter {
|
|
|
197
186
|
do {
|
|
198
187
|
let endpoint = LightWalletEndpoint(address: host, port: port, secure: true)
|
|
199
188
|
let lightwalletd: LightWalletService = LightWalletGRPCService(endpoint: endpoint)
|
|
200
|
-
let height = try await lightwalletd.latestBlockHeight()
|
|
201
|
-
lightwalletd.
|
|
189
|
+
let height = try await lightwalletd.latestBlockHeight(mode: ServiceMode.direct)
|
|
190
|
+
await lightwalletd.closeConnections()
|
|
202
191
|
resolve(height)
|
|
203
192
|
} catch {
|
|
204
193
|
reject("getLatestNetworkHeightGrpc", "Failed to query blockheight", error)
|
|
@@ -212,7 +201,7 @@ class RNZcash: RCTEventEmitter {
|
|
|
212
201
|
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
213
202
|
) {
|
|
214
203
|
Task {
|
|
215
|
-
if let wallet =
|
|
204
|
+
if let wallet = await synchronizerStore.get(alias) {
|
|
216
205
|
let amount = Int64(zatoshi)
|
|
217
206
|
if amount == nil {
|
|
218
207
|
reject("ProposeTransferError", "Amount is invalid", genericError)
|
|
@@ -224,8 +213,12 @@ class RNZcash: RCTEventEmitter {
|
|
|
224
213
|
if memo != "" {
|
|
225
214
|
sdkMemo = try Memo(string: memo)
|
|
226
215
|
}
|
|
216
|
+
guard let accountUUID = wallet.accountUUID else {
|
|
217
|
+
reject("ProposeTransferError", "Account UUID not found", genericError)
|
|
218
|
+
return
|
|
219
|
+
}
|
|
227
220
|
let proposal = try await wallet.synchronizer.proposeTransfer(
|
|
228
|
-
|
|
221
|
+
accountUUID: accountUUID,
|
|
229
222
|
recipient: Recipient(toAddress, network: wallet.synchronizer.network.networkType),
|
|
230
223
|
amount: Zatoshi(amount!),
|
|
231
224
|
memo: sdkMemo
|
|
@@ -259,7 +252,7 @@ class RNZcash: RCTEventEmitter {
|
|
|
259
252
|
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
260
253
|
) {
|
|
261
254
|
Task {
|
|
262
|
-
if let wallet =
|
|
255
|
+
if let wallet = await synchronizerStore.get(alias) {
|
|
263
256
|
do {
|
|
264
257
|
let spendingKey = try deriveUnifiedSpendingKey(seed, wallet.synchronizer.network)
|
|
265
258
|
let data = Data.init(base64Encoded: proposalBase64)!
|
|
@@ -278,7 +271,7 @@ class RNZcash: RCTEventEmitter {
|
|
|
278
271
|
case .success(let txId):
|
|
279
272
|
lastTxid = txId.toHexStringTxId()
|
|
280
273
|
continue
|
|
281
|
-
case
|
|
274
|
+
case .submitFailure(txId: _, let code, let description):
|
|
282
275
|
throw NSError(
|
|
283
276
|
domain:
|
|
284
277
|
"transaction failed to submit with code: \(code) - description: \(description)",
|
|
@@ -304,7 +297,7 @@ class RNZcash: RCTEventEmitter {
|
|
|
304
297
|
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
305
298
|
) {
|
|
306
299
|
Task {
|
|
307
|
-
if let wallet =
|
|
300
|
+
if let wallet = await synchronizerStore.get(alias) {
|
|
308
301
|
if !wallet.fullySynced {
|
|
309
302
|
reject("shieldFunds", "Wallet is not synced", genericError)
|
|
310
303
|
return
|
|
@@ -315,17 +308,52 @@ class RNZcash: RCTEventEmitter {
|
|
|
315
308
|
let sdkMemo = try Memo(string: memo)
|
|
316
309
|
let shieldingThreshold = Int64(threshold) ?? 10000
|
|
317
310
|
|
|
318
|
-
let
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
311
|
+
guard let accountUUID = wallet.accountUUID else {
|
|
312
|
+
reject("shieldFunds", "Account UUID not found", genericError)
|
|
313
|
+
return
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
guard
|
|
317
|
+
let proposal = try await wallet.synchronizer.proposeShielding(
|
|
318
|
+
accountUUID: accountUUID,
|
|
319
|
+
shieldingThreshold: Zatoshi(shieldingThreshold),
|
|
320
|
+
memo: sdkMemo
|
|
321
|
+
)
|
|
322
|
+
else {
|
|
323
|
+
throw NSError(
|
|
324
|
+
domain: "shieldFunds",
|
|
325
|
+
code: -1,
|
|
326
|
+
userInfo: [NSLocalizedDescriptionKey: "Proposal was nil"]
|
|
327
|
+
)
|
|
328
|
+
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
let stream = try await wallet.synchronizer.createProposedTransactions(
|
|
332
|
+
proposal: proposal,
|
|
333
|
+
spendingKey: spendingKey
|
|
322
334
|
)
|
|
323
335
|
|
|
324
|
-
|
|
336
|
+
if let result = try await stream.first(where: { _ in true }) {
|
|
337
|
+
switch result {
|
|
338
|
+
case .success(let txId):
|
|
339
|
+
resolve(txId.toHexStringTxId())
|
|
340
|
+
return
|
|
325
341
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
342
|
+
default:
|
|
343
|
+
throw NSError(
|
|
344
|
+
domain: "shieldFunds",
|
|
345
|
+
code: -1,
|
|
346
|
+
userInfo: [NSLocalizedDescriptionKey: "Failed: \(result)"]
|
|
347
|
+
)
|
|
348
|
+
}
|
|
349
|
+
} else {
|
|
350
|
+
// Stream ended without producing any result
|
|
351
|
+
throw NSError(
|
|
352
|
+
domain: "shieldFunds",
|
|
353
|
+
code: -1,
|
|
354
|
+
userInfo: [NSLocalizedDescriptionKey: "No result returned"]
|
|
355
|
+
)
|
|
356
|
+
}
|
|
329
357
|
} catch {
|
|
330
358
|
reject("shieldFunds", "Failed to shield funds", genericError)
|
|
331
359
|
}
|
|
@@ -340,7 +368,7 @@ class RNZcash: RCTEventEmitter {
|
|
|
340
368
|
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
341
369
|
) {
|
|
342
370
|
Task {
|
|
343
|
-
if let wallet =
|
|
371
|
+
if let wallet = await synchronizerStore.get(alias) {
|
|
344
372
|
wallet.synchronizer.rewind(.birthday).sink(
|
|
345
373
|
receiveCompletion: { completion in
|
|
346
374
|
Task {
|
|
@@ -353,6 +381,8 @@ class RNZcash: RCTEventEmitter {
|
|
|
353
381
|
wallet.cancellables.forEach { $0.cancel() }
|
|
354
382
|
try await wallet.synchronizer.start()
|
|
355
383
|
wallet.subscribe()
|
|
384
|
+
let txs = try await wallet.synchronizer.allTransactions()
|
|
385
|
+
wallet.emitTxs(transactions: txs)
|
|
356
386
|
resolve(nil)
|
|
357
387
|
case .failure:
|
|
358
388
|
reject("RescanError", "Failed to rescan wallet", genericError)
|
|
@@ -381,7 +411,8 @@ class RNZcash: RCTEventEmitter {
|
|
|
381
411
|
{
|
|
382
412
|
let derivationTool = DerivationTool(networkType: network.networkType)
|
|
383
413
|
let seedBytes = try Mnemonic.deterministicSeedBytes(from: seed)
|
|
384
|
-
let spendingKey = try derivationTool.deriveUnifiedSpendingKey(
|
|
414
|
+
let spendingKey = try derivationTool.deriveUnifiedSpendingKey(
|
|
415
|
+
seed: seedBytes, accountIndex: Zip32AccountIndex(0))
|
|
385
416
|
return spendingKey
|
|
386
417
|
}
|
|
387
418
|
|
|
@@ -412,12 +443,18 @@ class RNZcash: RCTEventEmitter {
|
|
|
412
443
|
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
413
444
|
) {
|
|
414
445
|
Task {
|
|
415
|
-
if let wallet =
|
|
446
|
+
if let wallet = await synchronizerStore.get(alias) {
|
|
416
447
|
do {
|
|
417
|
-
let
|
|
418
|
-
|
|
448
|
+
guard let accountUUID = wallet.accountUUID else {
|
|
449
|
+
reject("deriveUnifiedAddress", "Account UUID not found", genericError)
|
|
450
|
+
return
|
|
451
|
+
}
|
|
452
|
+
let unifiedAddress = try await wallet.synchronizer.getUnifiedAddress(
|
|
453
|
+
accountUUID: accountUUID)
|
|
454
|
+
let saplingAddress = try await wallet.synchronizer.getSaplingAddress(
|
|
455
|
+
accountUUID: accountUUID)
|
|
419
456
|
let transparentAddress = try await wallet.synchronizer.getTransparentAddress(
|
|
420
|
-
|
|
457
|
+
accountUUID: accountUUID)
|
|
421
458
|
let addresses: NSDictionary = [
|
|
422
459
|
"unifiedAddress": unifiedAddress.stringEncoded,
|
|
423
460
|
"saplingAddress": saplingAddress.stringEncoded,
|
|
@@ -472,6 +509,7 @@ class RNZcash: RCTEventEmitter {
|
|
|
472
509
|
|
|
473
510
|
class WalletSynchronizer: NSObject {
|
|
474
511
|
public var alias: String
|
|
512
|
+
public var accountUUID: AccountUUID?
|
|
475
513
|
public var synchronizer: SDKSynchronizer
|
|
476
514
|
var status: String
|
|
477
515
|
var emit: (String, Any) -> Void
|
|
@@ -479,7 +517,6 @@ class WalletSynchronizer: NSObject {
|
|
|
479
517
|
var restart: Bool
|
|
480
518
|
var processorState: ProcessorState
|
|
481
519
|
var cancellables: [AnyCancellable] = []
|
|
482
|
-
var balances: TotalBalances
|
|
483
520
|
|
|
484
521
|
init(alias: String, initializer: Initializer, emitter: @escaping (String, Any) -> Void) throws {
|
|
485
522
|
self.alias = alias
|
|
@@ -492,13 +529,6 @@ class WalletSynchronizer: NSObject {
|
|
|
492
529
|
scanProgress: 0,
|
|
493
530
|
networkBlockHeight: 0
|
|
494
531
|
)
|
|
495
|
-
self.balances = TotalBalances(
|
|
496
|
-
transparentAvailableZatoshi: Zatoshi(0),
|
|
497
|
-
transparentTotalZatoshi: Zatoshi(0),
|
|
498
|
-
saplingAvailableZatoshi: Zatoshi(0),
|
|
499
|
-
saplingTotalZatoshi: Zatoshi(0),
|
|
500
|
-
orchardAvailableZatoshi: Zatoshi(0),
|
|
501
|
-
orchardTotalZatoshi: Zatoshi(0))
|
|
502
532
|
}
|
|
503
533
|
|
|
504
534
|
public func subscribe() {
|
|
@@ -567,7 +597,7 @@ class WalletSynchronizer: NSObject {
|
|
|
567
597
|
var scanProgress = 0
|
|
568
598
|
|
|
569
599
|
switch event.internalSyncStatus {
|
|
570
|
-
case .syncing(let progress):
|
|
600
|
+
case .syncing(let progress, _):
|
|
571
601
|
scanProgress = Int(floor(progress * 100))
|
|
572
602
|
case .synced:
|
|
573
603
|
scanProgress = 100
|
|
@@ -598,19 +628,22 @@ class WalletSynchronizer: NSObject {
|
|
|
598
628
|
scanProgress: 0,
|
|
599
629
|
networkBlockHeight: 0
|
|
600
630
|
)
|
|
601
|
-
self.balances = TotalBalances(
|
|
602
|
-
transparentAvailableZatoshi: Zatoshi(0),
|
|
603
|
-
transparentTotalZatoshi: Zatoshi(0),
|
|
604
|
-
saplingAvailableZatoshi: Zatoshi(0),
|
|
605
|
-
saplingTotalZatoshi: Zatoshi(0),
|
|
606
|
-
orchardAvailableZatoshi: Zatoshi(0),
|
|
607
|
-
orchardTotalZatoshi: Zatoshi(0))
|
|
608
631
|
}
|
|
609
632
|
|
|
610
633
|
func updateBalanceState(event: SynchronizerState) {
|
|
611
|
-
let
|
|
612
|
-
|
|
613
|
-
|
|
634
|
+
guard let accountUUID = self.accountUUID else {
|
|
635
|
+
return
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
// Safely check if the account exists in the balances dictionary
|
|
639
|
+
guard let accountBalance = event.accountsBalances[accountUUID] else {
|
|
640
|
+
return
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
// Account exists, safely access the balance properties
|
|
644
|
+
let transparentBalance = accountBalance.unshielded
|
|
645
|
+
let shieldedBalance = accountBalance.saplingBalance
|
|
646
|
+
let orchardBalance = accountBalance.orchardBalance
|
|
614
647
|
|
|
615
648
|
let transparentAvailableZatoshi = transparentBalance
|
|
616
649
|
let transparentTotalZatoshi = transparentBalance
|
|
@@ -621,16 +654,15 @@ class WalletSynchronizer: NSObject {
|
|
|
621
654
|
let orchardAvailableZatoshi = orchardBalance.spendableValue
|
|
622
655
|
let orchardTotalZatoshi = orchardBalance.total()
|
|
623
656
|
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
data["alias"] = self.alias
|
|
657
|
+
let data: NSDictionary = [
|
|
658
|
+
"alias": self.alias,
|
|
659
|
+
"transparentAvailableZatoshi": String(transparentAvailableZatoshi.amount),
|
|
660
|
+
"transparentTotalZatoshi": String(transparentTotalZatoshi.amount),
|
|
661
|
+
"saplingAvailableZatoshi": String(saplingAvailableZatoshi.amount),
|
|
662
|
+
"saplingTotalZatoshi": String(saplingTotalZatoshi.amount),
|
|
663
|
+
"orchardAvailableZatoshi": String(orchardAvailableZatoshi.amount),
|
|
664
|
+
"orchardTotalZatoshi": String(orchardTotalZatoshi.amount),
|
|
665
|
+
]
|
|
634
666
|
emit("BalanceEvent", data)
|
|
635
667
|
}
|
|
636
668
|
|
|
@@ -639,7 +671,9 @@ class WalletSynchronizer: NSObject {
|
|
|
639
671
|
minedHeight: tx.minedHeight ?? 0,
|
|
640
672
|
rawTransactionId: (tx.rawID.toHexStringTxId()),
|
|
641
673
|
blockTimeInSeconds: Int(tx.blockTime ?? 0),
|
|
642
|
-
value: String(describing: abs(tx.value.amount))
|
|
674
|
+
value: String(describing: abs(tx.value.amount)),
|
|
675
|
+
isShielding: tx.isShielding,
|
|
676
|
+
isExpired: tx.isExpiredUmined ?? false
|
|
643
677
|
)
|
|
644
678
|
if tx.raw != nil {
|
|
645
679
|
confTx.raw = tx.raw!.hexEncodedString()
|
|
@@ -651,7 +685,7 @@ class WalletSynchronizer: NSObject {
|
|
|
651
685
|
let recipients = await self.synchronizer.getRecipients(for: tx)
|
|
652
686
|
if recipients.count > 0 {
|
|
653
687
|
let addresses = recipients.compactMap {
|
|
654
|
-
if case
|
|
688
|
+
if case .address(let address) = $0 {
|
|
655
689
|
return address
|
|
656
690
|
} else {
|
|
657
691
|
return nil
|
|
@@ -676,7 +710,6 @@ class WalletSynchronizer: NSObject {
|
|
|
676
710
|
Task {
|
|
677
711
|
var out: [NSDictionary] = []
|
|
678
712
|
for tx in transactions {
|
|
679
|
-
if tx.isExpiredUmined ?? false { continue }
|
|
680
713
|
let confTx = await parseTx(tx: tx)
|
|
681
714
|
out.append(confTx.nsDictionary)
|
|
682
715
|
}
|
|
@@ -687,6 +720,22 @@ class WalletSynchronizer: NSObject {
|
|
|
687
720
|
}
|
|
688
721
|
}
|
|
689
722
|
|
|
723
|
+
extension AccountUUID {
|
|
724
|
+
static func fromAlias(_ alias: String) -> AccountUUID {
|
|
725
|
+
let bytes = Array(alias.utf8)
|
|
726
|
+
let folded = foldTo16Bytes(bytes)
|
|
727
|
+
return AccountUUID(id: folded)
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
func foldTo16Bytes(_ bytes: [UInt8]) -> [UInt8] {
|
|
732
|
+
var out = [UInt8](repeating: 0, count: 16)
|
|
733
|
+
for (i, b) in bytes.enumerated() {
|
|
734
|
+
out[i % 16] ^= b
|
|
735
|
+
}
|
|
736
|
+
return out
|
|
737
|
+
}
|
|
738
|
+
|
|
690
739
|
// Local file helper funcs
|
|
691
740
|
func documentsDirectoryHelper() throws -> URL {
|
|
692
741
|
try FileManager.default.url(
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Account.swift
|
|
3
|
+
// ZcashLightClientKit
|
|
4
|
+
//
|
|
5
|
+
// Created by Lukáš Korba on 2024-11-19.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
/// A [ZIP 32](https://zips.z.cash/zip-0032) account index.
|
|
9
|
+
///
|
|
10
|
+
/// This index must be paired with a seed, or other context that determines a seed,
|
|
11
|
+
/// in order to identify a ZIP 32 *account*.
|
|
12
|
+
public struct Zip32AccountIndex: Equatable, Codable, Hashable {
|
|
13
|
+
public let index: UInt32
|
|
14
|
+
|
|
15
|
+
/// - Parameter index: the ZIP 32 account index, which must be less than ``1<<31``.
|
|
16
|
+
public init(_ index: UInt32) {
|
|
17
|
+
guard index < (1 << 31) else {
|
|
18
|
+
fatalError("Account index must be less than 1<<31. Input value is \(index).")
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
self.index = index
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public struct AccountId: Equatable, Codable, Hashable {
|
|
26
|
+
public let id: Int
|
|
27
|
+
|
|
28
|
+
/// - Parameter id: the local account id, which must be nonnegative.
|
|
29
|
+
public init(_ id: Int) {
|
|
30
|
+
guard id >= 0 else {
|
|
31
|
+
fatalError("Account id must be >= 0. Input value is \(id).")
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
self.id = id
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public struct AccountUUID: Equatable, Codable, Hashable, Identifiable {
|
|
39
|
+
public let id: [UInt8]
|
|
40
|
+
|
|
41
|
+
init(id: [UInt8]) {
|
|
42
|
+
guard id.count == 16 else {
|
|
43
|
+
fatalError("Account UUID must be 16 bytes long. Input value is \(id).")
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
self.id = id
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
//
|
|
2
|
+
// AccountMetadataKey.swift
|
|
3
|
+
// ZcashLightClientKit
|
|
4
|
+
//
|
|
5
|
+
// Created by Jack Grigg on 25/02/2025.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
/// A ZIP 325 Account Metadata Key.
|
|
12
|
+
public class AccountMetadataKey {
|
|
13
|
+
private let accountMetadataKeyPtr: OpaquePointer
|
|
14
|
+
private let networkType: NetworkType
|
|
15
|
+
|
|
16
|
+
/// Derives a ZIP 325 Account Metadata Key from the given seed.
|
|
17
|
+
public init(
|
|
18
|
+
from seed: [UInt8],
|
|
19
|
+
accountIndex: Zip32AccountIndex,
|
|
20
|
+
networkType: NetworkType
|
|
21
|
+
) throws {
|
|
22
|
+
let accountMetadataKeyPtr = seed.withUnsafeBufferPointer { seedBufferPtr in
|
|
23
|
+
return zcashlc_derive_account_metadata_key(
|
|
24
|
+
seedBufferPtr.baseAddress,
|
|
25
|
+
UInt(seed.count),
|
|
26
|
+
LCZip32Index(accountIndex.index),
|
|
27
|
+
networkType.networkId
|
|
28
|
+
)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
guard let accountMetadataKeyPtr else {
|
|
32
|
+
throw ZcashError.rustDeriveAccountMetadataKey(lastErrorMessage(fallback: "`deriveAccountMetadataKey` failed with unknown error"))
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
self.accountMetadataKeyPtr = accountMetadataKeyPtr
|
|
36
|
+
self.networkType = networkType
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
deinit {
|
|
40
|
+
zcashlc_free_account_metadata_key(accountMetadataKeyPtr)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/// Derives a metadata key for private use from this ZIP 325 Account Metadata Key.
|
|
44
|
+
///
|
|
45
|
+
/// - Parameter ufvk: the external UFVK for which a metadata key is required, or `null` if the
|
|
46
|
+
/// metadata key is "inherent" (for the same account as the Account Metadata Key).
|
|
47
|
+
/// - Parameter privateUseSubject: a globally unique non-empty sequence of at most 252 bytes
|
|
48
|
+
/// that identifies the desired private-use context.
|
|
49
|
+
///
|
|
50
|
+
/// If `ufvk` is null, this function will return a single 32-byte metadata key.
|
|
51
|
+
///
|
|
52
|
+
/// If `ufvk` is non-null, this function will return one metadata key for every FVK item
|
|
53
|
+
/// contained within the UFVK, in preference order. As UFVKs may in general change over
|
|
54
|
+
/// time (due to the inclusion of new higher-preference FVK items, or removal of older
|
|
55
|
+
/// deprecated FVK items), private usage of these keys should always follow preference
|
|
56
|
+
/// order:
|
|
57
|
+
/// - For encryption-like private usage, the first key in the array should always be
|
|
58
|
+
/// used, and all other keys ignored.
|
|
59
|
+
/// - For decryption-like private usage, each key in the array should be tried in turn
|
|
60
|
+
/// until metadata can be recovered, and then the metadata should be re-encrypted
|
|
61
|
+
/// under the first key.
|
|
62
|
+
public func derivePrivateUseMetadataKey(
|
|
63
|
+
ufvk: UnifiedFullViewingKey?,
|
|
64
|
+
privateUseSubject: [UInt8]
|
|
65
|
+
) throws -> [Data] {
|
|
66
|
+
var kSource: [CChar]?
|
|
67
|
+
if let ufvk {
|
|
68
|
+
kSource = [CChar](ufvk.stringEncoded.utf8CString)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
let keysPtr = privateUseSubject.withUnsafeBufferPointer { privateUseSubjectBufferPtr in
|
|
72
|
+
return zcashlc_derive_private_use_metadata_key(
|
|
73
|
+
accountMetadataKeyPtr,
|
|
74
|
+
kSource,
|
|
75
|
+
privateUseSubjectBufferPtr.baseAddress,
|
|
76
|
+
UInt(privateUseSubject.count),
|
|
77
|
+
networkType.networkId
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
guard let keysPtr else {
|
|
82
|
+
throw ZcashError.rustDerivePrivateUseMetadataKey(lastErrorMessage(fallback: "`derivePrivateUseMetadataKey` failed with unknown error"))
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
defer { zcashlc_free_txids(keysPtr) }
|
|
86
|
+
|
|
87
|
+
var keys: [Data] = []
|
|
88
|
+
|
|
89
|
+
for i in (0 ..< Int(keysPtr.pointee.len)) {
|
|
90
|
+
let txId = FfiTxId(tuple: keysPtr.pointee.ptr.advanced(by: i).pointee)
|
|
91
|
+
keys.append(Data(txId.array))
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return keys
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -73,13 +73,32 @@ extension ScanAction: Action {
|
|
|
73
73
|
// Proper solution is handled in
|
|
74
74
|
// TODO: [#1353] Advanced progress reporting, https://github.com/Electric-Coin-Company/zcash-swift-wallet-sdk/issues/1353
|
|
75
75
|
if progressReportReducer == 0 {
|
|
76
|
+
let walletSummary = try? await rustBackend.getWalletSummary()
|
|
77
|
+
let recoveryProgress = walletSummary?.recoveryProgress
|
|
78
|
+
|
|
76
79
|
// report scan progress only if it's available
|
|
77
|
-
if let scanProgress =
|
|
78
|
-
|
|
79
|
-
let
|
|
80
|
+
if let scanProgress = walletSummary?.scanProgress {
|
|
81
|
+
let composedNumerator = Float(scanProgress.numerator) + Float(recoveryProgress?.numerator ?? 0)
|
|
82
|
+
let composedDenominator = Float(scanProgress.denominator) + Float(recoveryProgress?.denominator ?? 0)
|
|
83
|
+
|
|
84
|
+
logger.debug("progress ratio: \(composedNumerator)/\(composedDenominator)")
|
|
85
|
+
|
|
86
|
+
let progress: Float
|
|
87
|
+
if composedDenominator == 0 {
|
|
88
|
+
progress = 1.0
|
|
89
|
+
} else {
|
|
90
|
+
progress = composedNumerator / composedDenominator
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// this shouldn't happen but if it does, we need to get notified by clients and work on a fix
|
|
94
|
+
if progress > 1.0 {
|
|
95
|
+
throw ZcashError.rustScanProgressOutOfRange("\(progress)")
|
|
96
|
+
}
|
|
97
|
+
|
|
80
98
|
logger.debug("progress float: \(progress)")
|
|
81
|
-
await didUpdate(.syncProgress(progress))
|
|
99
|
+
await didUpdate(.syncProgress(progress, scanProgress.isComplete))
|
|
82
100
|
}
|
|
101
|
+
|
|
83
102
|
progressReportReducer = Constants.reportDelay
|
|
84
103
|
} else {
|
|
85
104
|
progressReportReducer -= 1
|
|
@@ -13,6 +13,7 @@ final class UpdateChainTipAction {
|
|
|
13
13
|
var service: LightWalletService
|
|
14
14
|
var latestBlocksDataProvider: LatestBlocksDataProvider
|
|
15
15
|
let logger: Logger
|
|
16
|
+
let sdkFlags: SDKFlags
|
|
16
17
|
|
|
17
18
|
init(container: DIContainer) {
|
|
18
19
|
service = container.resolve(LightWalletService.self)
|
|
@@ -20,11 +21,13 @@ final class UpdateChainTipAction {
|
|
|
20
21
|
rustBackend = container.resolve(ZcashRustBackendWelding.self)
|
|
21
22
|
latestBlocksDataProvider = container.resolve(LatestBlocksDataProvider.self)
|
|
22
23
|
logger = container.resolve(Logger.self)
|
|
24
|
+
sdkFlags = container.resolve(SDKFlags.self)
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
func updateChainTip(_ context: ActionContext, time: TimeInterval) async throws {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
+
// called each sync, right after getInfo in ValidateServerAction
|
|
29
|
+
let latestBlockHeight = try await service.latestBlockHeight(mode: await sdkFlags.ifTor(.defaultTor))
|
|
30
|
+
|
|
28
31
|
logger.debug("Latest block height is \(latestBlockHeight)")
|
|
29
32
|
try await rustBackend.updateChainTip(height: Int32(latestBlockHeight))
|
|
30
33
|
await context.update(lastChainTipUpdateTime: time)
|
|
@@ -43,6 +46,7 @@ extension UpdateChainTipAction: Action {
|
|
|
43
46
|
if await context.prevState == .updateSubtreeRoots || now - lastChainTipUpdateTime > 600 {
|
|
44
47
|
await downloader.stopDownload()
|
|
45
48
|
try await updateChainTip(context, time: now)
|
|
49
|
+
await sdkFlags.markChainTipAsUpdated()
|
|
46
50
|
await context.update(state: .clearCache)
|
|
47
51
|
} else if await context.prevState == .txResubmission {
|
|
48
52
|
await context.update(state: .download)
|