Migrate to in-progress version of FFI backend 0.5.0
Includes: - Exposed `WalletSummary`. - Exposed transaction proposals. - `ScanSummary` returned from `ZcashRustBackend.scanBlocks`. Closes Electric-Coin-Company/zcash-swift-wallet-sdk#1259. Closes Electric-Coin-Company/zcash-swift-wallet-sdk#1299.
This commit is contained in:
parent
06d2b6986f
commit
ded20fe7b0
|
@ -158,8 +158,7 @@
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/zcash-hackworks/zcash-light-client-ffi",
|
"location" : "https://github.com/zcash-hackworks/zcash-light-client-ffi",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "514dcd7e6fbfa252bf36d9f00d6b98f465a70704",
|
"revision" : "5f58e32ffae1b285cae1c01bbf350eaae31ffeb5"
|
||||||
"version" : "0.4.1"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
@ -104,8 +104,7 @@
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/zcash-hackworks/zcash-light-client-ffi",
|
"location" : "https://github.com/zcash-hackworks/zcash-light-client-ffi",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "9bc5877ef6302e877922f79ebead52e50bce94fd",
|
"revision" : "5f58e32ffae1b285cae1c01bbf350eaae31ffeb5"
|
||||||
"version" : "0.4.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
@ -16,7 +16,8 @@ let package = Package(
|
||||||
dependencies: [
|
dependencies: [
|
||||||
.package(url: "https://github.com/grpc/grpc-swift.git", from: "1.19.1"),
|
.package(url: "https://github.com/grpc/grpc-swift.git", from: "1.19.1"),
|
||||||
.package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.14.1"),
|
.package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.14.1"),
|
||||||
.package(url: "https://github.com/zcash-hackworks/zcash-light-client-ffi", from: "0.4.1")
|
// Compiled from revision `d5bd88138610b15f9585fcba696bd1023e716fd8`.
|
||||||
|
.package(url: "https://github.com/zcash-hackworks/zcash-light-client-ffi", revision: "5f58e32ffae1b285cae1c01bbf350eaae31ffeb5")
|
||||||
],
|
],
|
||||||
targets: [
|
targets: [
|
||||||
.target(
|
.target(
|
||||||
|
@ -28,6 +29,7 @@ let package = Package(
|
||||||
],
|
],
|
||||||
exclude: [
|
exclude: [
|
||||||
"Modules/Service/GRPC/ProtoBuf/proto/compact_formats.proto",
|
"Modules/Service/GRPC/ProtoBuf/proto/compact_formats.proto",
|
||||||
|
"Modules/Service/GRPC/ProtoBuf/proto/proposal.proto",
|
||||||
"Modules/Service/GRPC/ProtoBuf/proto/service.proto",
|
"Modules/Service/GRPC/ProtoBuf/proto/service.proto",
|
||||||
"Error/Sourcery/"
|
"Error/Sourcery/"
|
||||||
],
|
],
|
||||||
|
|
|
@ -63,7 +63,7 @@ extension ScanAction: Action {
|
||||||
let incrementedProcessedHeight = processedHeight + BlockHeight(increment)
|
let incrementedProcessedHeight = processedHeight + BlockHeight(increment)
|
||||||
await context.update(processedHeight: incrementedProcessedHeight)
|
await context.update(processedHeight: incrementedProcessedHeight)
|
||||||
await self?.latestBlocksDataProvider.updateScannedData()
|
await self?.latestBlocksDataProvider.updateScannedData()
|
||||||
|
|
||||||
// ScanAction is controlled locally so it must report back the updated scanned height
|
// ScanAction is controlled locally so it must report back the updated scanned height
|
||||||
await context.update(lastScannedHeight: lastScannedHeight)
|
await context.update(lastScannedHeight: lastScannedHeight)
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ extension ScanAction: Action {
|
||||||
// TODO: [#1353] Advanced progress reporting, https://github.com/Electric-Coin-Company/zcash-swift-wallet-sdk/issues/1353
|
// TODO: [#1353] Advanced progress reporting, https://github.com/Electric-Coin-Company/zcash-swift-wallet-sdk/issues/1353
|
||||||
if progressReportReducer == 0 {
|
if progressReportReducer == 0 {
|
||||||
// report scan progress only if it's available
|
// report scan progress only if it's available
|
||||||
if let scanProgress = try? await rustBackend.getScanProgress() {
|
if let scanProgress = try? await rustBackend.getWalletSummary()?.scanProgress {
|
||||||
let progress = try scanProgress.progress()
|
let progress = try scanProgress.progress()
|
||||||
logger.debug("progress: \(progress)")
|
logger.debug("progress: \(progress)")
|
||||||
await didUpdate(.syncProgress(progress))
|
await didUpdate(.syncProgress(progress))
|
||||||
|
|
|
@ -658,13 +658,8 @@ extension CompactBlockProcessor {
|
||||||
await send(event: .finished(lastScannedHeight))
|
await send(event: .finished(lastScannedHeight))
|
||||||
await context.update(state: .finished)
|
await context.update(state: .finished)
|
||||||
|
|
||||||
let verifiedBalance = Zatoshi((try? await rustBackend.getVerifiedBalance(account: 0)) ?? 0)
|
let walletSummary = try? await rustBackend.getWalletSummary()
|
||||||
let totalBalance = Zatoshi((try? await rustBackend.getBalance(account: 0)) ?? 0)
|
await metrics.logCBPOverviewReport(logger, walletSummary: walletSummary)
|
||||||
let shieldedBalance = WalletBalance(
|
|
||||||
verified: verifiedBalance,
|
|
||||||
total: totalBalance
|
|
||||||
)
|
|
||||||
await metrics.logCBPOverviewReport(logger, shieldedBalance: shieldedBalance)
|
|
||||||
|
|
||||||
// If new blocks were mined during previous sync run the sync process again
|
// If new blocks were mined during previous sync run the sync process again
|
||||||
if newerBlocksWereMinedDuringSync {
|
if newerBlocksWereMinedDuringSync {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// HandleSaplingParametersIfNeeded.swift
|
// SaplingParametersHandler.swift
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Created by Lukáš Korba on 23.11.2022.
|
// Created by Lukáš Korba on 23.11.2022.
|
||||||
//
|
//
|
||||||
|
@ -28,11 +28,13 @@ extension SaplingParametersHandlerImpl: SaplingParametersHandler {
|
||||||
try Task.checkCancellation()
|
try Task.checkCancellation()
|
||||||
|
|
||||||
do {
|
do {
|
||||||
let totalShieldedBalance = try await rustBackend.getBalance(account: Int32(0))
|
let totalSaplingBalance =
|
||||||
|
try await rustBackend.getWalletSummary()?.accountBalances[0]?.saplingBalance.total().amount
|
||||||
|
?? 0
|
||||||
let totalTransparentBalance = try await rustBackend.getTransparentBalance(account: Int32(0))
|
let totalTransparentBalance = try await rustBackend.getTransparentBalance(account: Int32(0))
|
||||||
|
|
||||||
// Download Sapling parameters only if sapling funds are detected.
|
// Download Sapling parameters only if sapling funds are detected.
|
||||||
guard totalShieldedBalance > 0 || totalTransparentBalance > 0 else { return }
|
guard totalSaplingBalance > 0 || totalTransparentBalance > 0 else { return }
|
||||||
} catch {
|
} catch {
|
||||||
// if sapling balance can't be detected of we fail to obtain the balance
|
// if sapling balance can't be detected of we fail to obtain the balance
|
||||||
// for some reason we shall not proceed to download the parameters and
|
// for some reason we shall not proceed to download the parameters and
|
||||||
|
|
|
@ -51,9 +51,12 @@ extension BlockScannerImpl: BlockScanner {
|
||||||
|
|
||||||
let batchSize = UInt32(config.scanningBatchSize)
|
let batchSize = UInt32(config.scanningBatchSize)
|
||||||
|
|
||||||
|
// TODO: [#1355] Do more with ScanSummary
|
||||||
|
// https://github.com/Electric-Coin-Company/zcash-swift-wallet-sdk/issues/1355
|
||||||
|
let scanSummary: ScanSummary
|
||||||
let scanStartTime = Date()
|
let scanStartTime = Date()
|
||||||
do {
|
do {
|
||||||
try await self.rustBackend.scanBlocks(fromHeight: Int32(startHeight), limit: batchSize)
|
scanSummary = try await self.rustBackend.scanBlocks(fromHeight: Int32(startHeight), limit: batchSize)
|
||||||
} catch {
|
} catch {
|
||||||
logger.debug("block scanning failed with error: \(String(describing: error))")
|
logger.debug("block scanning failed with error: \(String(describing: error))")
|
||||||
throw error
|
throw error
|
||||||
|
@ -61,10 +64,8 @@ extension BlockScannerImpl: BlockScanner {
|
||||||
|
|
||||||
let scanFinishTime = Date()
|
let scanFinishTime = Date()
|
||||||
|
|
||||||
// TODO: [#1259] potential bug when rustBackend.scanBlocks scan less blocks than batchSize,
|
lastScannedHeight = scanSummary.scannedRange.upperBound - 1
|
||||||
// https://github.com/zcash/ZcashLightClientKit/issues/1259
|
|
||||||
lastScannedHeight = startHeight + Int(batchSize) - 1
|
|
||||||
|
|
||||||
scannedNewBlocks = previousScannedHeight != lastScannedHeight
|
scannedNewBlocks = previousScannedHeight != lastScannedHeight
|
||||||
if scannedNewBlocks {
|
if scannedNewBlocks {
|
||||||
try await didScan(lastScannedHeight, batchSize)
|
try await didScan(lastScannedHeight, batchSize)
|
||||||
|
|
|
@ -121,11 +121,6 @@ public enum ZcashError: Equatable, Error {
|
||||||
/// - `rustError` contains error generated by the rust layer.
|
/// - `rustError` contains error generated by the rust layer.
|
||||||
/// ZRUST0003
|
/// ZRUST0003
|
||||||
case rustDecryptAndStoreTransaction(_ rustError: String)
|
case rustDecryptAndStoreTransaction(_ rustError: String)
|
||||||
/// Error from rust layer when calling ZcashRustBackend.getBalance
|
|
||||||
/// - `account` is account passed to ZcashRustBackend.getBalance.
|
|
||||||
/// - `rustError` contains error generated by the rust layer.
|
|
||||||
/// ZRUST0004
|
|
||||||
case rustGetBalance(_ account: Int, _ rustError: String)
|
|
||||||
/// Error from rust layer when calling ZcashRustBackend.getCurrentAddress
|
/// Error from rust layer when calling ZcashRustBackend.getCurrentAddress
|
||||||
/// - `rustError` contains error generated by the rust layer.
|
/// - `rustError` contains error generated by the rust layer.
|
||||||
/// ZRUST0005
|
/// ZRUST0005
|
||||||
|
@ -153,11 +148,6 @@ public enum ZcashError: Equatable, Error {
|
||||||
/// - `rustError` contains error generated by the rust layer.
|
/// - `rustError` contains error generated by the rust layer.
|
||||||
/// ZRUST0011
|
/// ZRUST0011
|
||||||
case rustGetTransparentBalance(_ account: Int, _ rustError: String)
|
case rustGetTransparentBalance(_ account: Int, _ rustError: String)
|
||||||
/// Error from rust layer when calling ZcashRustBackend.getVerifiedBalance
|
|
||||||
/// - `account` is account passed to ZcashRustBackend.getVerifiedBalance.
|
|
||||||
/// - `rustError` contains error generated by the rust layer.
|
|
||||||
/// ZRUST0012
|
|
||||||
case rustGetVerifiedBalance(_ account: Int, _ rustError: String)
|
|
||||||
/// account parameter is lower than 0 when calling ZcashRustBackend.getVerifiedTransparentBalance
|
/// account parameter is lower than 0 when calling ZcashRustBackend.getVerifiedTransparentBalance
|
||||||
/// - `account` is account passed to ZcashRustBackend.getVerifiedTransparentBalance.
|
/// - `account` is account passed to ZcashRustBackend.getVerifiedTransparentBalance.
|
||||||
/// ZRUST0013
|
/// ZRUST0013
|
||||||
|
@ -297,10 +287,6 @@ public enum ZcashError: Equatable, Error {
|
||||||
/// Invalid transaction ID length when calling ZcashRustBackend.getMemo. txId must be 32 bytes.
|
/// Invalid transaction ID length when calling ZcashRustBackend.getMemo. txId must be 32 bytes.
|
||||||
/// ZRUST0050
|
/// ZRUST0050
|
||||||
case rustGetMemoInvalidTxIdLength
|
case rustGetMemoInvalidTxIdLength
|
||||||
/// Error from rust layer when calling ZcashRustBackend.getScanProgress
|
|
||||||
/// - `rustError` contains error generated by the rust layer.
|
|
||||||
/// ZRUST0051
|
|
||||||
case rustGetScanProgress(_ rustError: String)
|
|
||||||
/// Error from rust layer when calling ZcashRustBackend.fullyScannedHeight
|
/// Error from rust layer when calling ZcashRustBackend.fullyScannedHeight
|
||||||
/// - `rustError` contains error generated by the rust layer.
|
/// - `rustError` contains error generated by the rust layer.
|
||||||
/// ZRUST0052
|
/// ZRUST0052
|
||||||
|
@ -317,6 +303,10 @@ public enum ZcashError: Equatable, Error {
|
||||||
/// - `progress` value reported
|
/// - `progress` value reported
|
||||||
/// ZRUST0055
|
/// ZRUST0055
|
||||||
case rustScanProgressOutOfRange(_ progress: String)
|
case rustScanProgressOutOfRange(_ progress: String)
|
||||||
|
/// Error from rust layer when calling ZcashRustBackend.getWalletSummary
|
||||||
|
/// - `rustError` contains error generated by the rust layer.
|
||||||
|
/// ZRUST0056
|
||||||
|
case rustGetWalletSummary(_ rustError: String)
|
||||||
/// SQLite query failed when fetching all accounts from the database.
|
/// SQLite query failed when fetching all accounts from the database.
|
||||||
/// - `sqliteError` is error produced by SQLite library.
|
/// - `sqliteError` is error produced by SQLite library.
|
||||||
/// ZADAO0001
|
/// ZADAO0001
|
||||||
|
@ -614,7 +604,6 @@ public enum ZcashError: Equatable, Error {
|
||||||
case .rustCreateAccount: return "Error from rust layer when calling ZcashRustBackend.createAccount"
|
case .rustCreateAccount: return "Error from rust layer when calling ZcashRustBackend.createAccount"
|
||||||
case .rustCreateToAddress: return "Error from rust layer when calling ZcashRustBackend.createToAddress"
|
case .rustCreateToAddress: return "Error from rust layer when calling ZcashRustBackend.createToAddress"
|
||||||
case .rustDecryptAndStoreTransaction: return "Error from rust layer when calling ZcashRustBackend.decryptAndStoreTransaction"
|
case .rustDecryptAndStoreTransaction: return "Error from rust layer when calling ZcashRustBackend.decryptAndStoreTransaction"
|
||||||
case .rustGetBalance: return "Error from rust layer when calling ZcashRustBackend.getBalance"
|
|
||||||
case .rustGetCurrentAddress: return "Error from rust layer when calling ZcashRustBackend.getCurrentAddress"
|
case .rustGetCurrentAddress: return "Error from rust layer when calling ZcashRustBackend.getCurrentAddress"
|
||||||
case .rustGetCurrentAddressInvalidAddress: return "Unified address generated by rust layer is invalid when calling ZcashRustBackend.getCurrentAddress"
|
case .rustGetCurrentAddressInvalidAddress: return "Unified address generated by rust layer is invalid when calling ZcashRustBackend.getCurrentAddress"
|
||||||
case .rustGetNearestRewindHeight: return "Error from rust layer when calling ZcashRustBackend.getNearestRewindHeight"
|
case .rustGetNearestRewindHeight: return "Error from rust layer when calling ZcashRustBackend.getNearestRewindHeight"
|
||||||
|
@ -622,7 +611,6 @@ public enum ZcashError: Equatable, Error {
|
||||||
case .rustGetNextAvailableAddressInvalidAddress: return "Unified address generated by rust layer is invalid when calling ZcashRustBackend.getNextAvailableAddress"
|
case .rustGetNextAvailableAddressInvalidAddress: return "Unified address generated by rust layer is invalid when calling ZcashRustBackend.getNextAvailableAddress"
|
||||||
case .rustGetTransparentBalanceNegativeAccount: return "account parameter is lower than 0 when calling ZcashRustBackend.getTransparentBalance"
|
case .rustGetTransparentBalanceNegativeAccount: return "account parameter is lower than 0 when calling ZcashRustBackend.getTransparentBalance"
|
||||||
case .rustGetTransparentBalance: return "Error from rust layer when calling ZcashRustBackend.getTransparentBalance"
|
case .rustGetTransparentBalance: return "Error from rust layer when calling ZcashRustBackend.getTransparentBalance"
|
||||||
case .rustGetVerifiedBalance: return "Error from rust layer when calling ZcashRustBackend.getVerifiedBalance"
|
|
||||||
case .rustGetVerifiedTransparentBalanceNegativeAccount: return "account parameter is lower than 0 when calling ZcashRustBackend.getVerifiedTransparentBalance"
|
case .rustGetVerifiedTransparentBalanceNegativeAccount: return "account parameter is lower than 0 when calling ZcashRustBackend.getVerifiedTransparentBalance"
|
||||||
case .rustGetVerifiedTransparentBalance: return "Error from rust layer when calling ZcashRustBackend.getVerifiedTransparentBalance"
|
case .rustGetVerifiedTransparentBalance: return "Error from rust layer when calling ZcashRustBackend.getVerifiedTransparentBalance"
|
||||||
case .rustInitDataDb: return "Error from rust layer when calling ZcashRustBackend.initDataDb"
|
case .rustInitDataDb: return "Error from rust layer when calling ZcashRustBackend.initDataDb"
|
||||||
|
@ -660,11 +648,11 @@ public enum ZcashError: Equatable, Error {
|
||||||
case .rustUpdateChainTip: return "Error from rust layer when calling ZcashRustBackend.updateChainTip"
|
case .rustUpdateChainTip: return "Error from rust layer when calling ZcashRustBackend.updateChainTip"
|
||||||
case .rustSuggestScanRanges: return "Error from rust layer when calling ZcashRustBackend.suggestScanRanges"
|
case .rustSuggestScanRanges: return "Error from rust layer when calling ZcashRustBackend.suggestScanRanges"
|
||||||
case .rustGetMemoInvalidTxIdLength: return "Invalid transaction ID length when calling ZcashRustBackend.getMemo. txId must be 32 bytes."
|
case .rustGetMemoInvalidTxIdLength: return "Invalid transaction ID length when calling ZcashRustBackend.getMemo. txId must be 32 bytes."
|
||||||
case .rustGetScanProgress: return "Error from rust layer when calling ZcashRustBackend.getScanProgress"
|
|
||||||
case .rustFullyScannedHeight: return "Error from rust layer when calling ZcashRustBackend.fullyScannedHeight"
|
case .rustFullyScannedHeight: return "Error from rust layer when calling ZcashRustBackend.fullyScannedHeight"
|
||||||
case .rustMaxScannedHeight: return "Error from rust layer when calling ZcashRustBackend.maxScannedHeight"
|
case .rustMaxScannedHeight: return "Error from rust layer when calling ZcashRustBackend.maxScannedHeight"
|
||||||
case .rustLatestCachedBlockHeight: return "Error from rust layer when calling ZcashRustBackend.latestCachedBlockHeight"
|
case .rustLatestCachedBlockHeight: return "Error from rust layer when calling ZcashRustBackend.latestCachedBlockHeight"
|
||||||
case .rustScanProgressOutOfRange: return "Rust layer's call ZcashRustBackend.getScanProgress returned values that after computation are outside of allowed range 0-100%."
|
case .rustScanProgressOutOfRange: return "Rust layer's call ZcashRustBackend.getScanProgress returned values that after computation are outside of allowed range 0-100%."
|
||||||
|
case .rustGetWalletSummary: return "Error from rust layer when calling ZcashRustBackend.getWalletSummary"
|
||||||
case .accountDAOGetAll: return "SQLite query failed when fetching all accounts from the database."
|
case .accountDAOGetAll: return "SQLite query failed when fetching all accounts from the database."
|
||||||
case .accountDAOGetAllCantDecode: return "Fetched accounts from SQLite but can't decode them."
|
case .accountDAOGetAllCantDecode: return "Fetched accounts from SQLite but can't decode them."
|
||||||
case .accountDAOFindBy: return "SQLite query failed when seaching for accounts in the database."
|
case .accountDAOFindBy: return "SQLite query failed when seaching for accounts in the database."
|
||||||
|
@ -785,7 +773,6 @@ public enum ZcashError: Equatable, Error {
|
||||||
case .rustCreateAccount: return .rustCreateAccount
|
case .rustCreateAccount: return .rustCreateAccount
|
||||||
case .rustCreateToAddress: return .rustCreateToAddress
|
case .rustCreateToAddress: return .rustCreateToAddress
|
||||||
case .rustDecryptAndStoreTransaction: return .rustDecryptAndStoreTransaction
|
case .rustDecryptAndStoreTransaction: return .rustDecryptAndStoreTransaction
|
||||||
case .rustGetBalance: return .rustGetBalance
|
|
||||||
case .rustGetCurrentAddress: return .rustGetCurrentAddress
|
case .rustGetCurrentAddress: return .rustGetCurrentAddress
|
||||||
case .rustGetCurrentAddressInvalidAddress: return .rustGetCurrentAddressInvalidAddress
|
case .rustGetCurrentAddressInvalidAddress: return .rustGetCurrentAddressInvalidAddress
|
||||||
case .rustGetNearestRewindHeight: return .rustGetNearestRewindHeight
|
case .rustGetNearestRewindHeight: return .rustGetNearestRewindHeight
|
||||||
|
@ -793,7 +780,6 @@ public enum ZcashError: Equatable, Error {
|
||||||
case .rustGetNextAvailableAddressInvalidAddress: return .rustGetNextAvailableAddressInvalidAddress
|
case .rustGetNextAvailableAddressInvalidAddress: return .rustGetNextAvailableAddressInvalidAddress
|
||||||
case .rustGetTransparentBalanceNegativeAccount: return .rustGetTransparentBalanceNegativeAccount
|
case .rustGetTransparentBalanceNegativeAccount: return .rustGetTransparentBalanceNegativeAccount
|
||||||
case .rustGetTransparentBalance: return .rustGetTransparentBalance
|
case .rustGetTransparentBalance: return .rustGetTransparentBalance
|
||||||
case .rustGetVerifiedBalance: return .rustGetVerifiedBalance
|
|
||||||
case .rustGetVerifiedTransparentBalanceNegativeAccount: return .rustGetVerifiedTransparentBalanceNegativeAccount
|
case .rustGetVerifiedTransparentBalanceNegativeAccount: return .rustGetVerifiedTransparentBalanceNegativeAccount
|
||||||
case .rustGetVerifiedTransparentBalance: return .rustGetVerifiedTransparentBalance
|
case .rustGetVerifiedTransparentBalance: return .rustGetVerifiedTransparentBalance
|
||||||
case .rustInitDataDb: return .rustInitDataDb
|
case .rustInitDataDb: return .rustInitDataDb
|
||||||
|
@ -831,11 +817,11 @@ public enum ZcashError: Equatable, Error {
|
||||||
case .rustUpdateChainTip: return .rustUpdateChainTip
|
case .rustUpdateChainTip: return .rustUpdateChainTip
|
||||||
case .rustSuggestScanRanges: return .rustSuggestScanRanges
|
case .rustSuggestScanRanges: return .rustSuggestScanRanges
|
||||||
case .rustGetMemoInvalidTxIdLength: return .rustGetMemoInvalidTxIdLength
|
case .rustGetMemoInvalidTxIdLength: return .rustGetMemoInvalidTxIdLength
|
||||||
case .rustGetScanProgress: return .rustGetScanProgress
|
|
||||||
case .rustFullyScannedHeight: return .rustFullyScannedHeight
|
case .rustFullyScannedHeight: return .rustFullyScannedHeight
|
||||||
case .rustMaxScannedHeight: return .rustMaxScannedHeight
|
case .rustMaxScannedHeight: return .rustMaxScannedHeight
|
||||||
case .rustLatestCachedBlockHeight: return .rustLatestCachedBlockHeight
|
case .rustLatestCachedBlockHeight: return .rustLatestCachedBlockHeight
|
||||||
case .rustScanProgressOutOfRange: return .rustScanProgressOutOfRange
|
case .rustScanProgressOutOfRange: return .rustScanProgressOutOfRange
|
||||||
|
case .rustGetWalletSummary: return .rustGetWalletSummary
|
||||||
case .accountDAOGetAll: return .accountDAOGetAll
|
case .accountDAOGetAll: return .accountDAOGetAll
|
||||||
case .accountDAOGetAllCantDecode: return .accountDAOGetAllCantDecode
|
case .accountDAOGetAllCantDecode: return .accountDAOGetAllCantDecode
|
||||||
case .accountDAOFindBy: return .accountDAOFindBy
|
case .accountDAOFindBy: return .accountDAOFindBy
|
||||||
|
|
|
@ -71,8 +71,6 @@ public enum ZcashErrorCode: String {
|
||||||
case rustCreateToAddress = "ZRUST0002"
|
case rustCreateToAddress = "ZRUST0002"
|
||||||
/// Error from rust layer when calling ZcashRustBackend.decryptAndStoreTransaction
|
/// Error from rust layer when calling ZcashRustBackend.decryptAndStoreTransaction
|
||||||
case rustDecryptAndStoreTransaction = "ZRUST0003"
|
case rustDecryptAndStoreTransaction = "ZRUST0003"
|
||||||
/// Error from rust layer when calling ZcashRustBackend.getBalance
|
|
||||||
case rustGetBalance = "ZRUST0004"
|
|
||||||
/// Error from rust layer when calling ZcashRustBackend.getCurrentAddress
|
/// Error from rust layer when calling ZcashRustBackend.getCurrentAddress
|
||||||
case rustGetCurrentAddress = "ZRUST0005"
|
case rustGetCurrentAddress = "ZRUST0005"
|
||||||
/// Unified address generated by rust layer is invalid when calling ZcashRustBackend.getCurrentAddress
|
/// Unified address generated by rust layer is invalid when calling ZcashRustBackend.getCurrentAddress
|
||||||
|
@ -87,8 +85,6 @@ public enum ZcashErrorCode: String {
|
||||||
case rustGetTransparentBalanceNegativeAccount = "ZRUST0010"
|
case rustGetTransparentBalanceNegativeAccount = "ZRUST0010"
|
||||||
/// Error from rust layer when calling ZcashRustBackend.getTransparentBalance
|
/// Error from rust layer when calling ZcashRustBackend.getTransparentBalance
|
||||||
case rustGetTransparentBalance = "ZRUST0011"
|
case rustGetTransparentBalance = "ZRUST0011"
|
||||||
/// Error from rust layer when calling ZcashRustBackend.getVerifiedBalance
|
|
||||||
case rustGetVerifiedBalance = "ZRUST0012"
|
|
||||||
/// account parameter is lower than 0 when calling ZcashRustBackend.getVerifiedTransparentBalance
|
/// account parameter is lower than 0 when calling ZcashRustBackend.getVerifiedTransparentBalance
|
||||||
case rustGetVerifiedTransparentBalanceNegativeAccount = "ZRUST0013"
|
case rustGetVerifiedTransparentBalanceNegativeAccount = "ZRUST0013"
|
||||||
/// Error from rust layer when calling ZcashRustBackend.getVerifiedTransparentBalance
|
/// Error from rust layer when calling ZcashRustBackend.getVerifiedTransparentBalance
|
||||||
|
@ -163,8 +159,6 @@ public enum ZcashErrorCode: String {
|
||||||
case rustSuggestScanRanges = "ZRUST0049"
|
case rustSuggestScanRanges = "ZRUST0049"
|
||||||
/// Invalid transaction ID length when calling ZcashRustBackend.getMemo. txId must be 32 bytes.
|
/// Invalid transaction ID length when calling ZcashRustBackend.getMemo. txId must be 32 bytes.
|
||||||
case rustGetMemoInvalidTxIdLength = "ZRUST0050"
|
case rustGetMemoInvalidTxIdLength = "ZRUST0050"
|
||||||
/// Error from rust layer when calling ZcashRustBackend.getScanProgress
|
|
||||||
case rustGetScanProgress = "ZRUST0051"
|
|
||||||
/// Error from rust layer when calling ZcashRustBackend.fullyScannedHeight
|
/// Error from rust layer when calling ZcashRustBackend.fullyScannedHeight
|
||||||
case rustFullyScannedHeight = "ZRUST0052"
|
case rustFullyScannedHeight = "ZRUST0052"
|
||||||
/// Error from rust layer when calling ZcashRustBackend.maxScannedHeight
|
/// Error from rust layer when calling ZcashRustBackend.maxScannedHeight
|
||||||
|
@ -173,6 +167,8 @@ public enum ZcashErrorCode: String {
|
||||||
case rustLatestCachedBlockHeight = "ZRUST0054"
|
case rustLatestCachedBlockHeight = "ZRUST0054"
|
||||||
/// Rust layer's call ZcashRustBackend.getScanProgress returned values that after computation are outside of allowed range 0-100%.
|
/// Rust layer's call ZcashRustBackend.getScanProgress returned values that after computation are outside of allowed range 0-100%.
|
||||||
case rustScanProgressOutOfRange = "ZRUST0055"
|
case rustScanProgressOutOfRange = "ZRUST0055"
|
||||||
|
/// Error from rust layer when calling ZcashRustBackend.getWalletSummary
|
||||||
|
case rustGetWalletSummary = "ZRUST0056"
|
||||||
/// SQLite query failed when fetching all accounts from the database.
|
/// SQLite query failed when fetching all accounts from the database.
|
||||||
case accountDAOGetAll = "ZADAO0001"
|
case accountDAOGetAll = "ZADAO0001"
|
||||||
/// Fetched accounts from SQLite but can't decode them.
|
/// Fetched accounts from SQLite but can't decode them.
|
||||||
|
|
|
@ -12,7 +12,7 @@ protocol SDKMetrics {
|
||||||
func actionStart(_ action: CBPState)
|
func actionStart(_ action: CBPState)
|
||||||
func actionDetail(_ detail: String, `for` action: CBPState)
|
func actionDetail(_ detail: String, `for` action: CBPState)
|
||||||
func actionStop()
|
func actionStop()
|
||||||
func logCBPOverviewReport(_ logger: Logger, shieldedBalance: WalletBalance) async
|
func logCBPOverviewReport(_ logger: Logger, walletSummary: WalletSummary?) async
|
||||||
}
|
}
|
||||||
|
|
||||||
final class SDKMetricsImpl: SDKMetrics {
|
final class SDKMetricsImpl: SDKMetrics {
|
||||||
|
@ -102,15 +102,16 @@ final class SDKMetricsImpl: SDKMetrics {
|
||||||
}
|
}
|
||||||
|
|
||||||
// swiftlint:disable string_concatenation
|
// swiftlint:disable string_concatenation
|
||||||
func logCBPOverviewReport(_ logger: Logger, shieldedBalance: WalletBalance) async {
|
func logCBPOverviewReport(_ logger: Logger, walletSummary: WalletSummary?) async {
|
||||||
actionStop()
|
actionStop()
|
||||||
|
|
||||||
|
let accountBalance = walletSummary?.accountBalances[0]
|
||||||
logger.sync(
|
logger.sync(
|
||||||
"""
|
"""
|
||||||
SYNC (\(syncs)) REPORT
|
SYNC (\(syncs)) REPORT
|
||||||
finished in: \(Date().timeIntervalSince1970 - cbpStartTime)
|
finished in: \(Date().timeIntervalSince1970 - cbpStartTime)
|
||||||
verified balance: \(shieldedBalance.verified.amount)
|
verified balance: \(accountBalance?.saplingBalance.spendableValue.amount ?? 0)
|
||||||
total balance: \(shieldedBalance.total.amount)
|
total balance: \(accountBalance?.saplingBalance.total().amount ?? 0)
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
//
|
||||||
|
// ScanSummary.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by Jack Grigg on 26/01/2024.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
struct ScanSummary: Equatable {
|
||||||
|
let scannedRange: Range<BlockHeight>
|
||||||
|
let spentSaplingNoteCount: UInt64
|
||||||
|
let receivedSaplingNoteCount: UInt64
|
||||||
|
}
|
|
@ -1,12 +1,27 @@
|
||||||
//
|
//
|
||||||
// ScanProgress.swift
|
// WalletSummary.swift
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Created by Jack Grigg on 06/09/2023.
|
// Created by Jack Grigg on 06/09/2023.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
struct PoolBalance: Equatable {
|
||||||
|
let spendableValue: Zatoshi
|
||||||
|
let changePendingConfirmation: Zatoshi
|
||||||
|
let valuePendingSpendability: Zatoshi
|
||||||
|
|
||||||
|
func total() -> Zatoshi {
|
||||||
|
self.spendableValue + self.changePendingConfirmation + self.valuePendingSpendability
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct AccountBalance: Equatable {
|
||||||
|
let saplingBalance: PoolBalance
|
||||||
|
let unshielded: Zatoshi
|
||||||
|
}
|
||||||
|
|
||||||
struct ScanProgress: Equatable {
|
struct ScanProgress: Equatable {
|
||||||
let numerator: UInt64
|
let numerator: UInt64
|
||||||
let denominator: UInt64
|
let denominator: UInt64
|
||||||
|
@ -27,3 +42,11 @@ struct ScanProgress: Equatable {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct WalletSummary: Equatable {
|
||||||
|
let accountBalances: [UInt32: AccountBalance]
|
||||||
|
let chainTipHeight: BlockHeight
|
||||||
|
let fullyScannedHeight: BlockHeight
|
||||||
|
let scanProgress: ScanProgress?
|
||||||
|
let nextSaplingSubtreeIndex: UInt32
|
||||||
|
}
|
|
@ -0,0 +1,548 @@
|
||||||
|
// DO NOT EDIT.
|
||||||
|
// swift-format-ignore-file
|
||||||
|
//
|
||||||
|
// Generated by the Swift generator plugin for the protocol buffer compiler.
|
||||||
|
// Source: proto/proposal.proto
|
||||||
|
//
|
||||||
|
// For information on using the generated types, please see the documentation:
|
||||||
|
// https://github.com/apple/swift-protobuf/
|
||||||
|
|
||||||
|
// Copyright (c) 2023 The Zcash developers
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import SwiftProtobuf
|
||||||
|
|
||||||
|
// If the compiler emits an error on this type, it is because this file
|
||||||
|
// was generated by a version of the `protoc` Swift plug-in that is
|
||||||
|
// incompatible with the version of SwiftProtobuf to which you are linking.
|
||||||
|
// Please ensure that you are building against the same version of the API
|
||||||
|
// that was used to generate this file.
|
||||||
|
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
|
||||||
|
struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
|
||||||
|
typealias Version = _2
|
||||||
|
}
|
||||||
|
|
||||||
|
enum FfiValuePool: SwiftProtobuf.Enum {
|
||||||
|
typealias RawValue = Int
|
||||||
|
|
||||||
|
/// Protobuf requires that enums have a zero discriminant as the default
|
||||||
|
/// value. However, we need to require that a known value pool is selected,
|
||||||
|
/// and we do not want to fall back to any default, so sending the
|
||||||
|
/// PoolNotSpecified value will be treated as an error.
|
||||||
|
case poolNotSpecified // = 0
|
||||||
|
|
||||||
|
/// The transparent value pool (P2SH is not distinguished from P2PKH)
|
||||||
|
case transparent // = 1
|
||||||
|
|
||||||
|
/// The Sapling value pool
|
||||||
|
case sapling // = 2
|
||||||
|
|
||||||
|
/// The Orchard value pool
|
||||||
|
case orchard // = 3
|
||||||
|
case UNRECOGNIZED(Int)
|
||||||
|
|
||||||
|
init() {
|
||||||
|
self = .poolNotSpecified
|
||||||
|
}
|
||||||
|
|
||||||
|
init?(rawValue: Int) {
|
||||||
|
switch rawValue {
|
||||||
|
case 0: self = .poolNotSpecified
|
||||||
|
case 1: self = .transparent
|
||||||
|
case 2: self = .sapling
|
||||||
|
case 3: self = .orchard
|
||||||
|
default: self = .UNRECOGNIZED(rawValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var rawValue: Int {
|
||||||
|
switch self {
|
||||||
|
case .poolNotSpecified: return 0
|
||||||
|
case .transparent: return 1
|
||||||
|
case .sapling: return 2
|
||||||
|
case .orchard: return 3
|
||||||
|
case .UNRECOGNIZED(let i): return i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#if swift(>=4.2)
|
||||||
|
|
||||||
|
extension FfiValuePool: CaseIterable {
|
||||||
|
// The compiler won't synthesize support with the UNRECOGNIZED case.
|
||||||
|
static let allCases: [FfiValuePool] = [
|
||||||
|
.poolNotSpecified,
|
||||||
|
.transparent,
|
||||||
|
.sapling,
|
||||||
|
.orchard,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // swift(>=4.2)
|
||||||
|
|
||||||
|
/// The fee rule used in constructing a Proposal
|
||||||
|
enum FfiFeeRule: SwiftProtobuf.Enum {
|
||||||
|
typealias RawValue = Int
|
||||||
|
|
||||||
|
/// Protobuf requires that enums have a zero discriminant as the default
|
||||||
|
/// value. However, we need to require that a known fee rule is selected,
|
||||||
|
/// and we do not want to fall back to any default, so sending the
|
||||||
|
/// FeeRuleNotSpecified value will be treated as an error.
|
||||||
|
case notSpecified // = 0
|
||||||
|
|
||||||
|
/// 10000 ZAT
|
||||||
|
case preZip313 // = 1
|
||||||
|
|
||||||
|
/// 1000 ZAT
|
||||||
|
case zip313 // = 2
|
||||||
|
|
||||||
|
/// MAX(10000, 5000 * logical_actions) ZAT
|
||||||
|
case zip317 // = 3
|
||||||
|
case UNRECOGNIZED(Int)
|
||||||
|
|
||||||
|
init() {
|
||||||
|
self = .notSpecified
|
||||||
|
}
|
||||||
|
|
||||||
|
init?(rawValue: Int) {
|
||||||
|
switch rawValue {
|
||||||
|
case 0: self = .notSpecified
|
||||||
|
case 1: self = .preZip313
|
||||||
|
case 2: self = .zip313
|
||||||
|
case 3: self = .zip317
|
||||||
|
default: self = .UNRECOGNIZED(rawValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var rawValue: Int {
|
||||||
|
switch self {
|
||||||
|
case .notSpecified: return 0
|
||||||
|
case .preZip313: return 1
|
||||||
|
case .zip313: return 2
|
||||||
|
case .zip317: return 3
|
||||||
|
case .UNRECOGNIZED(let i): return i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#if swift(>=4.2)
|
||||||
|
|
||||||
|
extension FfiFeeRule: CaseIterable {
|
||||||
|
// The compiler won't synthesize support with the UNRECOGNIZED case.
|
||||||
|
static let allCases: [FfiFeeRule] = [
|
||||||
|
.notSpecified,
|
||||||
|
.preZip313,
|
||||||
|
.zip313,
|
||||||
|
.zip317,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // swift(>=4.2)
|
||||||
|
|
||||||
|
/// A data structure that describes the inputs to be consumed and outputs to
|
||||||
|
/// be produced in a proposed transaction.
|
||||||
|
struct FfiProposal {
|
||||||
|
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
||||||
|
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||||
|
// methods supported on all messages.
|
||||||
|
|
||||||
|
var protoVersion: UInt32 = 0
|
||||||
|
|
||||||
|
/// ZIP 321 serialized transaction request
|
||||||
|
var transactionRequest: String = String()
|
||||||
|
|
||||||
|
/// The anchor height to be used in creating the transaction, if any.
|
||||||
|
/// Setting the anchor height to zero will disallow the use of any shielded
|
||||||
|
/// inputs.
|
||||||
|
var anchorHeight: UInt32 = 0
|
||||||
|
|
||||||
|
/// The inputs to be used in creating the transaction.
|
||||||
|
var inputs: [FfiProposedInput] = []
|
||||||
|
|
||||||
|
/// The total value, fee value, and change outputs of the proposed
|
||||||
|
/// transaction
|
||||||
|
var balance: FfiTransactionBalance {
|
||||||
|
get {return _balance ?? FfiTransactionBalance()}
|
||||||
|
set {_balance = newValue}
|
||||||
|
}
|
||||||
|
/// Returns true if `balance` has been explicitly set.
|
||||||
|
var hasBalance: Bool {return self._balance != nil}
|
||||||
|
/// Clears the value of `balance`. Subsequent reads from it will return its default value.
|
||||||
|
mutating func clearBalance() {self._balance = nil}
|
||||||
|
|
||||||
|
/// The fee rule used in constructing this proposal
|
||||||
|
var feeRule: FfiFeeRule = .notSpecified
|
||||||
|
|
||||||
|
/// The target height for which the proposal was constructed
|
||||||
|
///
|
||||||
|
/// The chain must contain at least this many blocks in order for the proposal to
|
||||||
|
/// be executed.
|
||||||
|
var minTargetHeight: UInt32 = 0
|
||||||
|
|
||||||
|
/// A flag indicating whether the proposal is for a shielding transaction,
|
||||||
|
/// used for determining which OVK to select for wallet-internal outputs.
|
||||||
|
var isShielding: Bool = false
|
||||||
|
|
||||||
|
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||||
|
|
||||||
|
init() {}
|
||||||
|
|
||||||
|
fileprivate var _balance: FfiTransactionBalance? = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The unique identifier and value for each proposed input.
|
||||||
|
struct FfiProposedInput {
|
||||||
|
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
||||||
|
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||||
|
// methods supported on all messages.
|
||||||
|
|
||||||
|
var txid: Data = Data()
|
||||||
|
|
||||||
|
var valuePool: FfiValuePool = .poolNotSpecified
|
||||||
|
|
||||||
|
var index: UInt32 = 0
|
||||||
|
|
||||||
|
var value: UInt64 = 0
|
||||||
|
|
||||||
|
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||||
|
|
||||||
|
init() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The proposed change outputs and fee value.
|
||||||
|
struct FfiTransactionBalance {
|
||||||
|
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
||||||
|
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||||
|
// methods supported on all messages.
|
||||||
|
|
||||||
|
var proposedChange: [FfiChangeValue] = []
|
||||||
|
|
||||||
|
var feeRequired: UInt64 = 0
|
||||||
|
|
||||||
|
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||||
|
|
||||||
|
init() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A proposed change output. If the transparent value pool is selected,
|
||||||
|
/// the `memo` field must be null.
|
||||||
|
struct FfiChangeValue {
|
||||||
|
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
||||||
|
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||||
|
// methods supported on all messages.
|
||||||
|
|
||||||
|
var value: UInt64 = 0
|
||||||
|
|
||||||
|
var valuePool: FfiValuePool = .poolNotSpecified
|
||||||
|
|
||||||
|
var memo: FfiMemoBytes {
|
||||||
|
get {return _memo ?? FfiMemoBytes()}
|
||||||
|
set {_memo = newValue}
|
||||||
|
}
|
||||||
|
/// Returns true if `memo` has been explicitly set.
|
||||||
|
var hasMemo: Bool {return self._memo != nil}
|
||||||
|
/// Clears the value of `memo`. Subsequent reads from it will return its default value.
|
||||||
|
mutating func clearMemo() {self._memo = nil}
|
||||||
|
|
||||||
|
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||||
|
|
||||||
|
init() {}
|
||||||
|
|
||||||
|
fileprivate var _memo: FfiMemoBytes? = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An object wrapper for memo bytes, to facilitate representing the
|
||||||
|
/// `change_memo == None` case.
|
||||||
|
struct FfiMemoBytes {
|
||||||
|
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
||||||
|
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||||
|
// methods supported on all messages.
|
||||||
|
|
||||||
|
var value: Data = Data()
|
||||||
|
|
||||||
|
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||||
|
|
||||||
|
init() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if swift(>=5.5) && canImport(_Concurrency)
|
||||||
|
extension FfiValuePool: @unchecked Sendable {}
|
||||||
|
extension FfiFeeRule: @unchecked Sendable {}
|
||||||
|
extension FfiProposal: @unchecked Sendable {}
|
||||||
|
extension FfiProposedInput: @unchecked Sendable {}
|
||||||
|
extension FfiTransactionBalance: @unchecked Sendable {}
|
||||||
|
extension FfiChangeValue: @unchecked Sendable {}
|
||||||
|
extension FfiMemoBytes: @unchecked Sendable {}
|
||||||
|
#endif // swift(>=5.5) && canImport(_Concurrency)
|
||||||
|
|
||||||
|
// MARK: - Code below here is support for the SwiftProtobuf runtime.
|
||||||
|
|
||||||
|
fileprivate let _protobuf_package = "cash.z.wallet.sdk.ffi"
|
||||||
|
|
||||||
|
extension FfiValuePool: SwiftProtobuf._ProtoNameProviding {
|
||||||
|
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||||
|
0: .same(proto: "PoolNotSpecified"),
|
||||||
|
1: .same(proto: "Transparent"),
|
||||||
|
2: .same(proto: "Sapling"),
|
||||||
|
3: .same(proto: "Orchard"),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
extension FfiFeeRule: SwiftProtobuf._ProtoNameProviding {
|
||||||
|
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||||
|
0: .same(proto: "FeeRuleNotSpecified"),
|
||||||
|
1: .same(proto: "PreZip313"),
|
||||||
|
2: .same(proto: "Zip313"),
|
||||||
|
3: .same(proto: "Zip317"),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
extension FfiProposal: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||||
|
static let protoMessageName: String = _protobuf_package + ".Proposal"
|
||||||
|
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||||
|
1: .same(proto: "protoVersion"),
|
||||||
|
2: .same(proto: "transactionRequest"),
|
||||||
|
3: .same(proto: "anchorHeight"),
|
||||||
|
4: .same(proto: "inputs"),
|
||||||
|
5: .same(proto: "balance"),
|
||||||
|
6: .same(proto: "feeRule"),
|
||||||
|
7: .same(proto: "minTargetHeight"),
|
||||||
|
8: .same(proto: "isShielding"),
|
||||||
|
]
|
||||||
|
|
||||||
|
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||||
|
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||||
|
// The use of inline closures is to circumvent an issue where the compiler
|
||||||
|
// allocates stack space for every case branch when no optimizations are
|
||||||
|
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||||
|
switch fieldNumber {
|
||||||
|
case 1: try { try decoder.decodeSingularUInt32Field(value: &self.protoVersion) }()
|
||||||
|
case 2: try { try decoder.decodeSingularStringField(value: &self.transactionRequest) }()
|
||||||
|
case 3: try { try decoder.decodeSingularUInt32Field(value: &self.anchorHeight) }()
|
||||||
|
case 4: try { try decoder.decodeRepeatedMessageField(value: &self.inputs) }()
|
||||||
|
case 5: try { try decoder.decodeSingularMessageField(value: &self._balance) }()
|
||||||
|
case 6: try { try decoder.decodeSingularEnumField(value: &self.feeRule) }()
|
||||||
|
case 7: try { try decoder.decodeSingularUInt32Field(value: &self.minTargetHeight) }()
|
||||||
|
case 8: try { try decoder.decodeSingularBoolField(value: &self.isShielding) }()
|
||||||
|
default: break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||||
|
// The use of inline closures is to circumvent an issue where the compiler
|
||||||
|
// allocates stack space for every if/case branch local when no optimizations
|
||||||
|
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||||
|
// https://github.com/apple/swift-protobuf/issues/1182
|
||||||
|
if self.protoVersion != 0 {
|
||||||
|
try visitor.visitSingularUInt32Field(value: self.protoVersion, fieldNumber: 1)
|
||||||
|
}
|
||||||
|
if !self.transactionRequest.isEmpty {
|
||||||
|
try visitor.visitSingularStringField(value: self.transactionRequest, fieldNumber: 2)
|
||||||
|
}
|
||||||
|
if self.anchorHeight != 0 {
|
||||||
|
try visitor.visitSingularUInt32Field(value: self.anchorHeight, fieldNumber: 3)
|
||||||
|
}
|
||||||
|
if !self.inputs.isEmpty {
|
||||||
|
try visitor.visitRepeatedMessageField(value: self.inputs, fieldNumber: 4)
|
||||||
|
}
|
||||||
|
try { if let v = self._balance {
|
||||||
|
try visitor.visitSingularMessageField(value: v, fieldNumber: 5)
|
||||||
|
} }()
|
||||||
|
if self.feeRule != .notSpecified {
|
||||||
|
try visitor.visitSingularEnumField(value: self.feeRule, fieldNumber: 6)
|
||||||
|
}
|
||||||
|
if self.minTargetHeight != 0 {
|
||||||
|
try visitor.visitSingularUInt32Field(value: self.minTargetHeight, fieldNumber: 7)
|
||||||
|
}
|
||||||
|
if self.isShielding != false {
|
||||||
|
try visitor.visitSingularBoolField(value: self.isShielding, fieldNumber: 8)
|
||||||
|
}
|
||||||
|
try unknownFields.traverse(visitor: &visitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func ==(lhs: FfiProposal, rhs: FfiProposal) -> Bool {
|
||||||
|
if lhs.protoVersion != rhs.protoVersion {return false}
|
||||||
|
if lhs.transactionRequest != rhs.transactionRequest {return false}
|
||||||
|
if lhs.anchorHeight != rhs.anchorHeight {return false}
|
||||||
|
if lhs.inputs != rhs.inputs {return false}
|
||||||
|
if lhs._balance != rhs._balance {return false}
|
||||||
|
if lhs.feeRule != rhs.feeRule {return false}
|
||||||
|
if lhs.minTargetHeight != rhs.minTargetHeight {return false}
|
||||||
|
if lhs.isShielding != rhs.isShielding {return false}
|
||||||
|
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension FfiProposedInput: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||||
|
static let protoMessageName: String = _protobuf_package + ".ProposedInput"
|
||||||
|
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||||
|
1: .same(proto: "txid"),
|
||||||
|
2: .same(proto: "valuePool"),
|
||||||
|
3: .same(proto: "index"),
|
||||||
|
4: .same(proto: "value"),
|
||||||
|
]
|
||||||
|
|
||||||
|
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||||
|
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||||
|
// The use of inline closures is to circumvent an issue where the compiler
|
||||||
|
// allocates stack space for every case branch when no optimizations are
|
||||||
|
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||||
|
switch fieldNumber {
|
||||||
|
case 1: try { try decoder.decodeSingularBytesField(value: &self.txid) }()
|
||||||
|
case 2: try { try decoder.decodeSingularEnumField(value: &self.valuePool) }()
|
||||||
|
case 3: try { try decoder.decodeSingularUInt32Field(value: &self.index) }()
|
||||||
|
case 4: try { try decoder.decodeSingularUInt64Field(value: &self.value) }()
|
||||||
|
default: break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||||
|
if !self.txid.isEmpty {
|
||||||
|
try visitor.visitSingularBytesField(value: self.txid, fieldNumber: 1)
|
||||||
|
}
|
||||||
|
if self.valuePool != .poolNotSpecified {
|
||||||
|
try visitor.visitSingularEnumField(value: self.valuePool, fieldNumber: 2)
|
||||||
|
}
|
||||||
|
if self.index != 0 {
|
||||||
|
try visitor.visitSingularUInt32Field(value: self.index, fieldNumber: 3)
|
||||||
|
}
|
||||||
|
if self.value != 0 {
|
||||||
|
try visitor.visitSingularUInt64Field(value: self.value, fieldNumber: 4)
|
||||||
|
}
|
||||||
|
try unknownFields.traverse(visitor: &visitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func ==(lhs: FfiProposedInput, rhs: FfiProposedInput) -> Bool {
|
||||||
|
if lhs.txid != rhs.txid {return false}
|
||||||
|
if lhs.valuePool != rhs.valuePool {return false}
|
||||||
|
if lhs.index != rhs.index {return false}
|
||||||
|
if lhs.value != rhs.value {return false}
|
||||||
|
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension FfiTransactionBalance: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||||
|
static let protoMessageName: String = _protobuf_package + ".TransactionBalance"
|
||||||
|
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||||
|
1: .same(proto: "proposedChange"),
|
||||||
|
2: .same(proto: "feeRequired"),
|
||||||
|
]
|
||||||
|
|
||||||
|
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||||
|
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||||
|
// The use of inline closures is to circumvent an issue where the compiler
|
||||||
|
// allocates stack space for every case branch when no optimizations are
|
||||||
|
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||||
|
switch fieldNumber {
|
||||||
|
case 1: try { try decoder.decodeRepeatedMessageField(value: &self.proposedChange) }()
|
||||||
|
case 2: try { try decoder.decodeSingularUInt64Field(value: &self.feeRequired) }()
|
||||||
|
default: break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||||
|
if !self.proposedChange.isEmpty {
|
||||||
|
try visitor.visitRepeatedMessageField(value: self.proposedChange, fieldNumber: 1)
|
||||||
|
}
|
||||||
|
if self.feeRequired != 0 {
|
||||||
|
try visitor.visitSingularUInt64Field(value: self.feeRequired, fieldNumber: 2)
|
||||||
|
}
|
||||||
|
try unknownFields.traverse(visitor: &visitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func ==(lhs: FfiTransactionBalance, rhs: FfiTransactionBalance) -> Bool {
|
||||||
|
if lhs.proposedChange != rhs.proposedChange {return false}
|
||||||
|
if lhs.feeRequired != rhs.feeRequired {return false}
|
||||||
|
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension FfiChangeValue: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||||
|
static let protoMessageName: String = _protobuf_package + ".ChangeValue"
|
||||||
|
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||||
|
1: .same(proto: "value"),
|
||||||
|
2: .same(proto: "valuePool"),
|
||||||
|
3: .same(proto: "memo"),
|
||||||
|
]
|
||||||
|
|
||||||
|
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||||
|
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||||
|
// The use of inline closures is to circumvent an issue where the compiler
|
||||||
|
// allocates stack space for every case branch when no optimizations are
|
||||||
|
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||||
|
switch fieldNumber {
|
||||||
|
case 1: try { try decoder.decodeSingularUInt64Field(value: &self.value) }()
|
||||||
|
case 2: try { try decoder.decodeSingularEnumField(value: &self.valuePool) }()
|
||||||
|
case 3: try { try decoder.decodeSingularMessageField(value: &self._memo) }()
|
||||||
|
default: break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||||
|
// The use of inline closures is to circumvent an issue where the compiler
|
||||||
|
// allocates stack space for every if/case branch local when no optimizations
|
||||||
|
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||||
|
// https://github.com/apple/swift-protobuf/issues/1182
|
||||||
|
if self.value != 0 {
|
||||||
|
try visitor.visitSingularUInt64Field(value: self.value, fieldNumber: 1)
|
||||||
|
}
|
||||||
|
if self.valuePool != .poolNotSpecified {
|
||||||
|
try visitor.visitSingularEnumField(value: self.valuePool, fieldNumber: 2)
|
||||||
|
}
|
||||||
|
try { if let v = self._memo {
|
||||||
|
try visitor.visitSingularMessageField(value: v, fieldNumber: 3)
|
||||||
|
} }()
|
||||||
|
try unknownFields.traverse(visitor: &visitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func ==(lhs: FfiChangeValue, rhs: FfiChangeValue) -> Bool {
|
||||||
|
if lhs.value != rhs.value {return false}
|
||||||
|
if lhs.valuePool != rhs.valuePool {return false}
|
||||||
|
if lhs._memo != rhs._memo {return false}
|
||||||
|
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension FfiMemoBytes: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||||
|
static let protoMessageName: String = _protobuf_package + ".MemoBytes"
|
||||||
|
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||||
|
1: .same(proto: "value"),
|
||||||
|
]
|
||||||
|
|
||||||
|
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||||
|
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||||
|
// The use of inline closures is to circumvent an issue where the compiler
|
||||||
|
// allocates stack space for every case branch when no optimizations are
|
||||||
|
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||||
|
switch fieldNumber {
|
||||||
|
case 1: try { try decoder.decodeSingularBytesField(value: &self.value) }()
|
||||||
|
default: break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||||
|
if !self.value.isEmpty {
|
||||||
|
try visitor.visitSingularBytesField(value: self.value, fieldNumber: 1)
|
||||||
|
}
|
||||||
|
try unknownFields.traverse(visitor: &visitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func ==(lhs: FfiMemoBytes, rhs: FfiMemoBytes) -> Bool {
|
||||||
|
if lhs.value != rhs.value {return false}
|
||||||
|
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
// Copyright (c) 2023 The Zcash developers
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
package cash.z.wallet.sdk.ffi;
|
||||||
|
option swift_prefix = "Ffi";
|
||||||
|
|
||||||
|
// A data structure that describes the inputs to be consumed and outputs to
|
||||||
|
// be produced in a proposed transaction.
|
||||||
|
message Proposal {
|
||||||
|
uint32 protoVersion = 1;
|
||||||
|
// ZIP 321 serialized transaction request
|
||||||
|
string transactionRequest = 2;
|
||||||
|
// The anchor height to be used in creating the transaction, if any.
|
||||||
|
// Setting the anchor height to zero will disallow the use of any shielded
|
||||||
|
// inputs.
|
||||||
|
uint32 anchorHeight = 3;
|
||||||
|
// The inputs to be used in creating the transaction.
|
||||||
|
repeated ProposedInput inputs = 4;
|
||||||
|
// The total value, fee value, and change outputs of the proposed
|
||||||
|
// transaction
|
||||||
|
TransactionBalance balance = 5;
|
||||||
|
// The fee rule used in constructing this proposal
|
||||||
|
FeeRule feeRule = 6;
|
||||||
|
// The target height for which the proposal was constructed
|
||||||
|
//
|
||||||
|
// The chain must contain at least this many blocks in order for the proposal to
|
||||||
|
// be executed.
|
||||||
|
uint32 minTargetHeight = 7;
|
||||||
|
// A flag indicating whether the proposal is for a shielding transaction,
|
||||||
|
// used for determining which OVK to select for wallet-internal outputs.
|
||||||
|
bool isShielding = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ValuePool {
|
||||||
|
// Protobuf requires that enums have a zero discriminant as the default
|
||||||
|
// value. However, we need to require that a known value pool is selected,
|
||||||
|
// and we do not want to fall back to any default, so sending the
|
||||||
|
// PoolNotSpecified value will be treated as an error.
|
||||||
|
PoolNotSpecified = 0;
|
||||||
|
// The transparent value pool (P2SH is not distinguished from P2PKH)
|
||||||
|
Transparent = 1;
|
||||||
|
// The Sapling value pool
|
||||||
|
Sapling = 2;
|
||||||
|
// The Orchard value pool
|
||||||
|
Orchard = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The unique identifier and value for each proposed input.
|
||||||
|
message ProposedInput {
|
||||||
|
bytes txid = 1;
|
||||||
|
ValuePool valuePool = 2;
|
||||||
|
uint32 index = 3;
|
||||||
|
uint64 value = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The fee rule used in constructing a Proposal
|
||||||
|
enum FeeRule {
|
||||||
|
// Protobuf requires that enums have a zero discriminant as the default
|
||||||
|
// value. However, we need to require that a known fee rule is selected,
|
||||||
|
// and we do not want to fall back to any default, so sending the
|
||||||
|
// FeeRuleNotSpecified value will be treated as an error.
|
||||||
|
FeeRuleNotSpecified = 0;
|
||||||
|
// 10000 ZAT
|
||||||
|
PreZip313 = 1;
|
||||||
|
// 1000 ZAT
|
||||||
|
Zip313 = 2;
|
||||||
|
// MAX(10000, 5000 * logical_actions) ZAT
|
||||||
|
Zip317 = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The proposed change outputs and fee value.
|
||||||
|
message TransactionBalance {
|
||||||
|
repeated ChangeValue proposedChange = 1;
|
||||||
|
uint64 feeRequired = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A proposed change output. If the transparent value pool is selected,
|
||||||
|
// the `memo` field must be null.
|
||||||
|
message ChangeValue {
|
||||||
|
uint64 value = 1;
|
||||||
|
ValuePool valuePool = 2;
|
||||||
|
MemoBytes memo = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// An object wrapper for memo bytes, to facilitate representing the
|
||||||
|
// `change_memo == None` case.
|
||||||
|
message MemoBytes {
|
||||||
|
bytes value = 1;
|
||||||
|
}
|
|
@ -80,45 +80,36 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
||||||
return ffiBinaryKeyPtr.pointee.unsafeToUnifiedSpendingKey(network: networkType)
|
return ffiBinaryKeyPtr.pointee.unsafeToUnifiedSpendingKey(network: networkType)
|
||||||
}
|
}
|
||||||
|
|
||||||
func createToAddress(
|
func proposeTransfer(
|
||||||
usk: UnifiedSpendingKey,
|
account: Int32,
|
||||||
to address: String,
|
to address: String,
|
||||||
value: Int64,
|
value: Int64,
|
||||||
memo: MemoBytes?
|
memo: MemoBytes?
|
||||||
) async throws -> Data {
|
) async throws -> FfiProposal {
|
||||||
var contiguousTxIdBytes = ContiguousArray<UInt8>([UInt8](repeating: 0x0, count: 32))
|
|
||||||
|
|
||||||
globalDBLock.lock()
|
globalDBLock.lock()
|
||||||
let success = contiguousTxIdBytes.withUnsafeMutableBufferPointer { txIdBytePtr in
|
let proposal = zcashlc_propose_transfer(
|
||||||
usk.bytes.withUnsafeBufferPointer { uskPtr in
|
dbData.0,
|
||||||
zcashlc_create_to_address(
|
dbData.1,
|
||||||
dbData.0,
|
account,
|
||||||
dbData.1,
|
[CChar](address.utf8CString),
|
||||||
uskPtr.baseAddress,
|
value,
|
||||||
UInt(usk.bytes.count),
|
memo?.bytes,
|
||||||
[CChar](address.utf8CString),
|
networkType.networkId,
|
||||||
value,
|
minimumConfirmations,
|
||||||
memo?.bytes,
|
useZIP317Fees
|
||||||
spendParamsPath.0,
|
)
|
||||||
spendParamsPath.1,
|
|
||||||
outputParamsPath.0,
|
|
||||||
outputParamsPath.1,
|
|
||||||
networkType.networkId,
|
|
||||||
minimumConfirmations,
|
|
||||||
useZIP317Fees,
|
|
||||||
txIdBytePtr.baseAddress
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
globalDBLock.unlock()
|
globalDBLock.unlock()
|
||||||
|
|
||||||
guard success else {
|
guard let proposal else {
|
||||||
throw ZcashError.rustCreateToAddress(lastErrorMessage(fallback: "`createToAddress` failed with unknown error"))
|
throw ZcashError.rustCreateToAddress(lastErrorMessage(fallback: "`proposeTransfer` failed with unknown error"))
|
||||||
}
|
}
|
||||||
|
|
||||||
return contiguousTxIdBytes.withUnsafeBufferPointer { txIdBytePtr in
|
defer { zcashlc_free_boxed_slice(proposal) }
|
||||||
Data(txIdBytePtr)
|
|
||||||
}
|
return try FfiProposal(contiguousBytes: Data(
|
||||||
|
bytes: proposal.pointee.ptr,
|
||||||
|
count: Int(proposal.pointee.len)
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
func decryptAndStoreTransaction(txBytes: [UInt8], minedHeight: Int32) async throws {
|
func decryptAndStoreTransaction(txBytes: [UInt8], minedHeight: Int32) async throws {
|
||||||
|
@ -138,18 +129,6 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getBalance(account: Int32) async throws -> Int64 {
|
|
||||||
globalDBLock.lock()
|
|
||||||
let balance = zcashlc_get_balance(dbData.0, dbData.1, account, networkType.networkId)
|
|
||||||
globalDBLock.unlock()
|
|
||||||
|
|
||||||
guard balance >= 0 else {
|
|
||||||
throw ZcashError.rustGetBalance(Int(account), lastErrorMessage(fallback: "Error getting total balance from account \(account)"))
|
|
||||||
}
|
|
||||||
|
|
||||||
return balance
|
|
||||||
}
|
|
||||||
|
|
||||||
func getCurrentAddress(account: Int32) async throws -> UnifiedAddress {
|
func getCurrentAddress(account: Int32) async throws -> UnifiedAddress {
|
||||||
globalDBLock.lock()
|
globalDBLock.lock()
|
||||||
let addressCStr = zcashlc_get_current_address(
|
let addressCStr = zcashlc_get_current_address(
|
||||||
|
@ -256,27 +235,6 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
||||||
return balance
|
return balance
|
||||||
}
|
}
|
||||||
|
|
||||||
func getVerifiedBalance(account: Int32) async throws -> Int64 {
|
|
||||||
globalDBLock.lock()
|
|
||||||
let balance = zcashlc_get_verified_balance(
|
|
||||||
dbData.0,
|
|
||||||
dbData.1,
|
|
||||||
account,
|
|
||||||
networkType.networkId,
|
|
||||||
minimumConfirmations
|
|
||||||
)
|
|
||||||
globalDBLock.unlock()
|
|
||||||
|
|
||||||
guard balance >= 0 else {
|
|
||||||
throw ZcashError.rustGetVerifiedBalance(
|
|
||||||
Int(account),
|
|
||||||
lastErrorMessage(fallback: "Error getting verified balance from account \(account)")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return balance
|
|
||||||
}
|
|
||||||
|
|
||||||
func getVerifiedTransparentBalance(account: Int32) async throws -> Int64 {
|
func getVerifiedTransparentBalance(account: Int32) async throws -> Int64 {
|
||||||
guard account >= 0 else {
|
guard account >= 0 else {
|
||||||
throw ZcashError.rustGetVerifiedTransparentBalanceNegativeAccount(Int(account))
|
throw ZcashError.rustGetVerifiedTransparentBalanceNegativeAccount(Int(account))
|
||||||
|
@ -576,21 +534,35 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getScanProgress() async throws -> ScanProgress? {
|
func getWalletSummary() async throws -> WalletSummary? {
|
||||||
globalDBLock.lock()
|
globalDBLock.lock()
|
||||||
let result = zcashlc_get_scan_progress(dbData.0, dbData.1, networkType.networkId)
|
let summaryPtr = zcashlc_get_wallet_summary(dbData.0, dbData.1, networkType.networkId, minimumConfirmations)
|
||||||
globalDBLock.unlock()
|
globalDBLock.unlock()
|
||||||
|
|
||||||
if result.denominator == 0 {
|
guard let summaryPtr else {
|
||||||
switch result.numerator {
|
throw ZcashError.rustGetWalletSummary(lastErrorMessage(fallback: "`getWalletSummary` failed with unknown error"))
|
||||||
case 0:
|
|
||||||
return nil
|
|
||||||
default:
|
|
||||||
throw ZcashError.rustGetScanProgress(lastErrorMessage(fallback: "`getScanProgress` failed with unknown error"))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return ScanProgress(numerator: result.numerator, denominator: result.denominator)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defer { zcashlc_free_wallet_summary(summaryPtr) }
|
||||||
|
|
||||||
|
if summaryPtr.pointee.fully_scanned_height < 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var accountBalances: [UInt32: AccountBalance] = [:]
|
||||||
|
|
||||||
|
for i in (0 ..< Int(summaryPtr.pointee.account_balances_len)) {
|
||||||
|
let accountBalance = summaryPtr.pointee.account_balances.advanced(by: i).pointee
|
||||||
|
accountBalances[accountBalance.account_id] = accountBalance.toAccountBalance()
|
||||||
|
}
|
||||||
|
|
||||||
|
return WalletSummary(
|
||||||
|
accountBalances: accountBalances,
|
||||||
|
chainTipHeight: BlockHeight(summaryPtr.pointee.chain_tip_height),
|
||||||
|
fullyScannedHeight: BlockHeight(summaryPtr.pointee.fully_scanned_height),
|
||||||
|
scanProgress: summaryPtr.pointee.scan_progress?.pointee.toScanProgress(),
|
||||||
|
nextSaplingSubtreeIndex: UInt32(summaryPtr.pointee.next_sapling_subtree_index)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func suggestScanRanges() async throws -> [ScanRange] {
|
func suggestScanRanges() async throws -> [ScanRange] {
|
||||||
|
@ -623,48 +595,90 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
||||||
return scanRanges
|
return scanRanges
|
||||||
}
|
}
|
||||||
|
|
||||||
func scanBlocks(fromHeight: Int32, limit: UInt32 = 0) async throws {
|
func scanBlocks(fromHeight: Int32, limit: UInt32 = 0) async throws -> ScanSummary {
|
||||||
globalDBLock.lock()
|
globalDBLock.lock()
|
||||||
let result = zcashlc_scan_blocks(fsBlockDbRoot.0, fsBlockDbRoot.1, dbData.0, dbData.1, fromHeight, limit, networkType.networkId)
|
let summaryPtr = zcashlc_scan_blocks(fsBlockDbRoot.0, fsBlockDbRoot.1, dbData.0, dbData.1, fromHeight, limit, networkType.networkId)
|
||||||
globalDBLock.unlock()
|
globalDBLock.unlock()
|
||||||
|
|
||||||
guard result != 0 else {
|
guard let summaryPtr else {
|
||||||
throw ZcashError.rustScanBlocks(lastErrorMessage(fallback: "`scanBlocks` failed with unknown error"))
|
throw ZcashError.rustScanBlocks(lastErrorMessage(fallback: "`scanBlocks` failed with unknown error"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defer { zcashlc_free_scan_summary(summaryPtr) }
|
||||||
|
|
||||||
|
return ScanSummary(
|
||||||
|
scannedRange: Range(uncheckedBounds: (
|
||||||
|
BlockHeight(summaryPtr.pointee.scanned_start),
|
||||||
|
BlockHeight(summaryPtr.pointee.scanned_end)
|
||||||
|
)),
|
||||||
|
spentSaplingNoteCount: summaryPtr.pointee.spent_sapling_note_count,
|
||||||
|
receivedSaplingNoteCount: summaryPtr.pointee.received_sapling_note_count
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func shieldFunds(
|
func proposeShielding(
|
||||||
usk: UnifiedSpendingKey,
|
account: Int32,
|
||||||
memo: MemoBytes?,
|
memo: MemoBytes?,
|
||||||
shieldingThreshold: Zatoshi
|
shieldingThreshold: Zatoshi
|
||||||
|
) async throws -> FfiProposal {
|
||||||
|
globalDBLock.lock()
|
||||||
|
let proposal = zcashlc_propose_shielding(
|
||||||
|
dbData.0,
|
||||||
|
dbData.1,
|
||||||
|
account,
|
||||||
|
memo?.bytes,
|
||||||
|
UInt64(shieldingThreshold.amount),
|
||||||
|
networkType.networkId,
|
||||||
|
minimumConfirmations,
|
||||||
|
useZIP317Fees
|
||||||
|
)
|
||||||
|
globalDBLock.unlock()
|
||||||
|
|
||||||
|
guard let proposal else {
|
||||||
|
throw ZcashError.rustShieldFunds(lastErrorMessage(fallback: "`proposeShielding` failed with unknown error"))
|
||||||
|
}
|
||||||
|
|
||||||
|
defer { zcashlc_free_boxed_slice(proposal) }
|
||||||
|
|
||||||
|
return try FfiProposal(contiguousBytes: Data(
|
||||||
|
bytes: proposal.pointee.ptr,
|
||||||
|
count: Int(proposal.pointee.len)
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
func createProposedTransaction(
|
||||||
|
proposal: FfiProposal,
|
||||||
|
usk: UnifiedSpendingKey
|
||||||
) async throws -> Data {
|
) async throws -> Data {
|
||||||
var contiguousTxIdBytes = ContiguousArray<UInt8>([UInt8](repeating: 0x0, count: 32))
|
var contiguousTxIdBytes = ContiguousArray<UInt8>([UInt8](repeating: 0x0, count: 32))
|
||||||
|
|
||||||
|
let proposalBytes = try proposal.serializedData(partial: false).bytes
|
||||||
|
|
||||||
globalDBLock.lock()
|
globalDBLock.lock()
|
||||||
let success = contiguousTxIdBytes.withUnsafeMutableBufferPointer { txIdBytePtr in
|
let success = contiguousTxIdBytes.withUnsafeMutableBufferPointer { txIdBytePtr in
|
||||||
usk.bytes.withUnsafeBufferPointer { uskBuffer in
|
proposalBytes.withUnsafeBufferPointer { proposalPtr in
|
||||||
zcashlc_shield_funds(
|
usk.bytes.withUnsafeBufferPointer { uskPtr in
|
||||||
dbData.0,
|
zcashlc_create_proposed_transaction(
|
||||||
dbData.1,
|
dbData.0,
|
||||||
uskBuffer.baseAddress,
|
dbData.1,
|
||||||
UInt(usk.bytes.count),
|
proposalPtr.baseAddress,
|
||||||
memo?.bytes,
|
UInt(proposalBytes.count),
|
||||||
UInt64(shieldingThreshold.amount),
|
uskPtr.baseAddress,
|
||||||
spendParamsPath.0,
|
UInt(usk.bytes.count),
|
||||||
spendParamsPath.1,
|
spendParamsPath.0,
|
||||||
outputParamsPath.0,
|
spendParamsPath.1,
|
||||||
outputParamsPath.1,
|
outputParamsPath.0,
|
||||||
networkType.networkId,
|
outputParamsPath.1,
|
||||||
minimumConfirmations,
|
networkType.networkId,
|
||||||
useZIP317Fees,
|
txIdBytePtr.baseAddress
|
||||||
txIdBytePtr.baseAddress
|
)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
globalDBLock.unlock()
|
globalDBLock.unlock()
|
||||||
|
|
||||||
guard success else {
|
guard success else {
|
||||||
throw ZcashError.rustShieldFunds(lastErrorMessage(fallback: "`shieldFunds` failed with unknown error"))
|
throw ZcashError.rustCreateToAddress(lastErrorMessage(fallback: "`createToAddress` failed with unknown error"))
|
||||||
}
|
}
|
||||||
|
|
||||||
return contiguousTxIdBytes.withUnsafeBufferPointer { txIdBytePtr in
|
return contiguousTxIdBytes.withUnsafeBufferPointer { txIdBytePtr in
|
||||||
|
@ -778,3 +792,34 @@ extension Array where Element == FfiSubtreeRoot {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension FfiBalance {
|
||||||
|
/// Converts an [`FfiBalance`] into a [`PoolBalance`].
|
||||||
|
func toPoolBalance() -> PoolBalance {
|
||||||
|
.init(
|
||||||
|
spendableValue: Zatoshi(self.spendable_value),
|
||||||
|
changePendingConfirmation: Zatoshi(self.change_pending_confirmation),
|
||||||
|
valuePendingSpendability: Zatoshi(self.value_pending_spendability)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension FfiAccountBalance {
|
||||||
|
/// Converts an [`FfiAccountBalance`] into a [`AccountBalance`].
|
||||||
|
func toAccountBalance() -> AccountBalance {
|
||||||
|
.init(
|
||||||
|
saplingBalance: self.sapling_balance.toPoolBalance(),
|
||||||
|
unshielded: Zatoshi(self.unshielded)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension FfiScanProgress {
|
||||||
|
/// Converts an [`FfiScanProgress`] into a [`ScanProgress`].
|
||||||
|
func toScanProgress() -> ScanProgress {
|
||||||
|
.init(
|
||||||
|
numerator: self.numerator,
|
||||||
|
denominator: self.denominator
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -41,30 +41,12 @@ protocol ZcashRustBackendWelding {
|
||||||
/// - Throws: `rustCreateAccount`.
|
/// - Throws: `rustCreateAccount`.
|
||||||
func createAccount(seed: [UInt8], treeState: TreeState, recoverUntil: UInt32?) async throws -> UnifiedSpendingKey
|
func createAccount(seed: [UInt8], treeState: TreeState, recoverUntil: UInt32?) async throws -> UnifiedSpendingKey
|
||||||
|
|
||||||
/// Creates a transaction to the given address from the given account
|
|
||||||
/// - Parameter usk: `UnifiedSpendingKey` for the account that controls the funds to be spent.
|
|
||||||
/// - Parameter to: recipient address
|
|
||||||
/// - Parameter value: transaction amount in Zatoshi
|
|
||||||
/// - Parameter memo: the `MemoBytes` for this transaction. pass `nil` when sending to transparent receivers
|
|
||||||
/// - Throws: `rustCreateToAddress`.
|
|
||||||
func createToAddress(
|
|
||||||
usk: UnifiedSpendingKey,
|
|
||||||
to address: String,
|
|
||||||
value: Int64,
|
|
||||||
memo: MemoBytes?
|
|
||||||
) async throws -> Data
|
|
||||||
|
|
||||||
/// Scans a transaction for any information that can be decrypted by the accounts in the wallet, and saves it to the wallet.
|
/// Scans a transaction for any information that can be decrypted by the accounts in the wallet, and saves it to the wallet.
|
||||||
/// - parameter tx: the transaction to decrypt
|
/// - parameter tx: the transaction to decrypt
|
||||||
/// - parameter minedHeight: height on which this transaction was mined. this is used to fetch the consensus branch ID.
|
/// - parameter minedHeight: height on which this transaction was mined. this is used to fetch the consensus branch ID.
|
||||||
/// - Throws: `rustDecryptAndStoreTransaction`.
|
/// - Throws: `rustDecryptAndStoreTransaction`.
|
||||||
func decryptAndStoreTransaction(txBytes: [UInt8], minedHeight: Int32) async throws
|
func decryptAndStoreTransaction(txBytes: [UInt8], minedHeight: Int32) async throws
|
||||||
|
|
||||||
/// Get the (unverified) balance from the given account.
|
|
||||||
/// - parameter account: index of the given account
|
|
||||||
/// - Throws: `rustGetBalance`.
|
|
||||||
func getBalance(account: Int32) async throws -> Int64
|
|
||||||
|
|
||||||
/// Returns the most-recently-generated unified payment address for the specified account.
|
/// Returns the most-recently-generated unified payment address for the specified account.
|
||||||
/// - parameter account: index of the given account
|
/// - parameter account: index of the given account
|
||||||
/// - Throws:
|
/// - Throws:
|
||||||
|
@ -120,11 +102,6 @@ protocol ZcashRustBackendWelding {
|
||||||
/// - `rustListTransparentReceiversInvalidAddress` if transarent received generated by rust is invalid.
|
/// - `rustListTransparentReceiversInvalidAddress` if transarent received generated by rust is invalid.
|
||||||
func listTransparentReceivers(account: Int32) async throws -> [TransparentAddress]
|
func listTransparentReceivers(account: Int32) async throws -> [TransparentAddress]
|
||||||
|
|
||||||
/// Get the verified balance from the given account
|
|
||||||
/// - parameter account: index of the given account
|
|
||||||
/// - Throws: `rustGetVerifiedBalance` when rust layer throws error.
|
|
||||||
func getVerifiedBalance(account: Int32) async throws -> Int64
|
|
||||||
|
|
||||||
/// Get the verified cached transparent balance for the given account
|
/// Get the verified cached transparent balance for the given account
|
||||||
/// - parameter account: account index to query the balance for.
|
/// - parameter account: account index to query the balance for.
|
||||||
/// - Throws:
|
/// - Throws:
|
||||||
|
@ -167,8 +144,8 @@ protocol ZcashRustBackendWelding {
|
||||||
/// height due to the fact that out-of-order scanning can leave gaps.
|
/// height due to the fact that out-of-order scanning can leave gaps.
|
||||||
func maxScannedHeight() async throws -> BlockHeight?
|
func maxScannedHeight() async throws -> BlockHeight?
|
||||||
|
|
||||||
/// Returns the scan progress derived from the current wallet state.
|
/// Returns the account balances and sync status of the wallet.
|
||||||
func getScanProgress() async throws -> ScanProgress?
|
func getWalletSummary() async throws -> WalletSummary?
|
||||||
|
|
||||||
/// Returns a list of suggested scan ranges based upon the current wallet state.
|
/// Returns a list of suggested scan ranges based upon the current wallet state.
|
||||||
///
|
///
|
||||||
|
@ -198,7 +175,7 @@ protocol ZcashRustBackendWelding {
|
||||||
/// - parameter fromHeight: scan starting from the given height.
|
/// - parameter fromHeight: scan starting from the given height.
|
||||||
/// - parameter limit: scan up to limit blocks.
|
/// - parameter limit: scan up to limit blocks.
|
||||||
/// - Throws: `rustScanBlocks` if rust layer returns error.
|
/// - Throws: `rustScanBlocks` if rust layer returns error.
|
||||||
func scanBlocks(fromHeight: Int32, limit: UInt32) async throws
|
func scanBlocks(fromHeight: Int32, limit: UInt32) async throws -> ScanSummary
|
||||||
|
|
||||||
/// Upserts a UTXO into the data db database
|
/// Upserts a UTXO into the data db database
|
||||||
/// - parameter txid: the txid bytes for the UTXO
|
/// - parameter txid: the txid bytes for the UTXO
|
||||||
|
@ -215,14 +192,42 @@ protocol ZcashRustBackendWelding {
|
||||||
height: BlockHeight
|
height: BlockHeight
|
||||||
) async throws
|
) async throws
|
||||||
|
|
||||||
/// Creates a transaction to shield all found UTXOs in data db for the account the provided `UnifiedSpendingKey` has spend authority for.
|
/// Select transaction inputs, compute fees, and construct a proposal for a transaction
|
||||||
/// - Parameter usk: `UnifiedSpendingKey` that spend transparent funds and where the funds will be shielded to.
|
/// that can then be authorized and made ready for submission to the network with
|
||||||
|
/// `createProposedTransaction`.
|
||||||
|
///
|
||||||
|
/// - parameter account: index of the given account
|
||||||
|
/// - Parameter to: recipient address
|
||||||
|
/// - Parameter value: transaction amount in Zatoshi
|
||||||
|
/// - Parameter memo: the `MemoBytes` for this transaction. pass `nil` when sending to transparent receivers
|
||||||
|
/// - Throws: `rustCreateToAddress`.
|
||||||
|
func proposeTransfer(
|
||||||
|
account: Int32,
|
||||||
|
to address: String,
|
||||||
|
value: Int64,
|
||||||
|
memo: MemoBytes?
|
||||||
|
) async throws -> FfiProposal
|
||||||
|
|
||||||
|
/// Constructs a transaction proposal to shield all found UTXOs in data db for the given account,
|
||||||
|
/// that can then be authorized and made ready for submission to the network with
|
||||||
|
/// `createProposedTransaction`.
|
||||||
|
///
|
||||||
|
/// - parameter account: index of the given account
|
||||||
/// - Parameter memo: the `Memo` for this transaction
|
/// - Parameter memo: the `Memo` for this transaction
|
||||||
/// - Throws: `rustShieldFunds` if rust layer returns error.
|
/// - Throws: `rustShieldFunds` if rust layer returns error.
|
||||||
func shieldFunds(
|
func proposeShielding(
|
||||||
usk: UnifiedSpendingKey,
|
account: Int32,
|
||||||
memo: MemoBytes?,
|
memo: MemoBytes?,
|
||||||
shieldingThreshold: Zatoshi
|
shieldingThreshold: Zatoshi
|
||||||
|
) async throws -> FfiProposal
|
||||||
|
|
||||||
|
/// Creates a transaction from the given proposal.
|
||||||
|
/// - Parameter proposal: the transaction proposal.
|
||||||
|
/// - Parameter usk: `UnifiedSpendingKey` for the account that controls the funds to be spent.
|
||||||
|
/// - Throws: `rustCreateToAddress`.
|
||||||
|
func createProposedTransaction(
|
||||||
|
proposal: FfiProposal,
|
||||||
|
usk: UnifiedSpendingKey
|
||||||
) async throws -> Data
|
) async throws -> Data
|
||||||
|
|
||||||
/// Gets the consensus branch id for the given height
|
/// Gets the consensus branch id for the given height
|
||||||
|
|
|
@ -414,15 +414,13 @@ public class SDKSynchronizer: Synchronizer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public func getShieldedBalance(accountIndex: Int = 0) async throws -> Zatoshi {
|
public func getShieldedBalance(accountIndex: Int = 0) async throws -> Zatoshi {
|
||||||
let balance = try await initializer.rustBackend.getBalance(account: Int32(accountIndex))
|
try await initializer.rustBackend.getWalletSummary()?.accountBalances[UInt32(accountIndex)]?
|
||||||
|
.saplingBalance.total() ?? Zatoshi.zero
|
||||||
return Zatoshi(balance)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public func getShieldedVerifiedBalance(accountIndex: Int = 0) async throws -> Zatoshi {
|
public func getShieldedVerifiedBalance(accountIndex: Int = 0) async throws -> Zatoshi {
|
||||||
let balance = try await initializer.rustBackend.getVerifiedBalance(account: Int32(accountIndex))
|
try await initializer.rustBackend.getWalletSummary()?.accountBalances[UInt32(accountIndex)]?
|
||||||
|
.saplingBalance.spendableValue ?? Zatoshi.zero
|
||||||
return Zatoshi(balance)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public func getUnifiedAddress(accountIndex: Int) async throws -> UnifiedAddress {
|
public func getUnifiedAddress(accountIndex: Int) async throws -> UnifiedAddress {
|
||||||
|
|
|
@ -85,13 +85,19 @@ class WalletTransactionEncoder: TransactionEncoder {
|
||||||
throw ZcashError.walletTransEncoderCreateTransactionMissingSaplingParams
|
throw ZcashError.walletTransEncoderCreateTransactionMissingSaplingParams
|
||||||
}
|
}
|
||||||
|
|
||||||
let txId = try await rustBackend.createToAddress(
|
// TODO: Expose the proposal in a way that enables querying its fee.
|
||||||
usk: spendingKey,
|
let proposal = try await rustBackend.proposeTransfer(
|
||||||
|
account: Int32(spendingKey.account),
|
||||||
to: address,
|
to: address,
|
||||||
value: zatoshi.amount,
|
value: zatoshi.amount,
|
||||||
memo: memoBytes
|
memo: memoBytes
|
||||||
)
|
)
|
||||||
|
|
||||||
|
let txId = try await rustBackend.createProposedTransaction(
|
||||||
|
proposal: proposal,
|
||||||
|
usk: spendingKey
|
||||||
|
)
|
||||||
|
|
||||||
return txId
|
return txId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,13 +127,19 @@ class WalletTransactionEncoder: TransactionEncoder {
|
||||||
guard ensureParams(spend: self.spendParamsURL, output: self.outputParamsURL) else {
|
guard ensureParams(spend: self.spendParamsURL, output: self.outputParamsURL) else {
|
||||||
throw ZcashError.walletTransEncoderShieldFundsMissingSaplingParams
|
throw ZcashError.walletTransEncoderShieldFundsMissingSaplingParams
|
||||||
}
|
}
|
||||||
|
|
||||||
let txId = try await rustBackend.shieldFunds(
|
// TODO: Expose the proposal in a way that enables querying its fee.
|
||||||
usk: spendingKey,
|
let proposal = try await rustBackend.proposeShielding(
|
||||||
|
account: Int32(spendingKey.account),
|
||||||
memo: memo,
|
memo: memo,
|
||||||
shieldingThreshold: shieldingThreshold
|
shieldingThreshold: shieldingThreshold
|
||||||
)
|
)
|
||||||
|
|
||||||
|
let txId = try await rustBackend.createProposedTransaction(
|
||||||
|
proposal: proposal,
|
||||||
|
usk: spendingKey
|
||||||
|
)
|
||||||
|
|
||||||
return txId
|
return txId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Generated using Sourcery 2.0.3 — https://github.com/krzysztofzablocki/Sourcery
|
// Generated using Sourcery 2.1.4 — https://github.com/krzysztofzablocki/Sourcery
|
||||||
// DO NOT EDIT
|
// DO NOT EDIT
|
||||||
import Combine
|
import Combine
|
||||||
@testable import ZcashLightClientKit
|
@testable import ZcashLightClientKit
|
||||||
|
@ -1191,17 +1191,17 @@ class SDKMetricsMock: SDKMetrics {
|
||||||
|
|
||||||
// MARK: - logCBPOverviewReport
|
// MARK: - logCBPOverviewReport
|
||||||
|
|
||||||
var logCBPOverviewReportShieldedBalanceCallsCount = 0
|
var logCBPOverviewReportWalletSummaryCallsCount = 0
|
||||||
var logCBPOverviewReportShieldedBalanceCalled: Bool {
|
var logCBPOverviewReportWalletSummaryCalled: Bool {
|
||||||
return logCBPOverviewReportShieldedBalanceCallsCount > 0
|
return logCBPOverviewReportWalletSummaryCallsCount > 0
|
||||||
}
|
}
|
||||||
var logCBPOverviewReportShieldedBalanceReceivedArguments: (logger: Logger, shieldedBalance: WalletBalance)?
|
var logCBPOverviewReportWalletSummaryReceivedArguments: (logger: Logger, walletSummary: WalletSummary?)?
|
||||||
var logCBPOverviewReportShieldedBalanceClosure: ((Logger, WalletBalance) async -> Void)?
|
var logCBPOverviewReportWalletSummaryClosure: ((Logger, WalletSummary?) async -> Void)?
|
||||||
|
|
||||||
func logCBPOverviewReport(_ logger: Logger, shieldedBalance: WalletBalance) async {
|
func logCBPOverviewReport(_ logger: Logger, walletSummary: WalletSummary?) async {
|
||||||
logCBPOverviewReportShieldedBalanceCallsCount += 1
|
logCBPOverviewReportWalletSummaryCallsCount += 1
|
||||||
logCBPOverviewReportShieldedBalanceReceivedArguments = (logger: logger, shieldedBalance: shieldedBalance)
|
logCBPOverviewReportWalletSummaryReceivedArguments = (logger: logger, walletSummary: walletSummary)
|
||||||
await logCBPOverviewReportShieldedBalanceClosure!(logger, shieldedBalance)
|
await logCBPOverviewReportWalletSummaryClosure!(logger, walletSummary)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2179,39 +2179,6 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - createToAddress
|
|
||||||
|
|
||||||
var createToAddressUskToValueMemoThrowableError: Error?
|
|
||||||
func setCreateToAddressUskToValueMemoThrowableError(_ param: Error?) async {
|
|
||||||
createToAddressUskToValueMemoThrowableError = param
|
|
||||||
}
|
|
||||||
var createToAddressUskToValueMemoCallsCount = 0
|
|
||||||
var createToAddressUskToValueMemoCalled: Bool {
|
|
||||||
return createToAddressUskToValueMemoCallsCount > 0
|
|
||||||
}
|
|
||||||
var createToAddressUskToValueMemoReceivedArguments: (usk: UnifiedSpendingKey, address: String, value: Int64, memo: MemoBytes?)?
|
|
||||||
var createToAddressUskToValueMemoReturnValue: Data!
|
|
||||||
func setCreateToAddressUskToValueMemoReturnValue(_ param: Data) async {
|
|
||||||
createToAddressUskToValueMemoReturnValue = param
|
|
||||||
}
|
|
||||||
var createToAddressUskToValueMemoClosure: ((UnifiedSpendingKey, String, Int64, MemoBytes?) async throws -> Data)?
|
|
||||||
func setCreateToAddressUskToValueMemoClosure(_ param: ((UnifiedSpendingKey, String, Int64, MemoBytes?) async throws -> Data)?) async {
|
|
||||||
createToAddressUskToValueMemoClosure = param
|
|
||||||
}
|
|
||||||
|
|
||||||
func createToAddress(usk: UnifiedSpendingKey, to address: String, value: Int64, memo: MemoBytes?) async throws -> Data {
|
|
||||||
if let error = createToAddressUskToValueMemoThrowableError {
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
createToAddressUskToValueMemoCallsCount += 1
|
|
||||||
createToAddressUskToValueMemoReceivedArguments = (usk: usk, address: address, value: value, memo: memo)
|
|
||||||
if let closure = createToAddressUskToValueMemoClosure {
|
|
||||||
return try await closure(usk, address, value, memo)
|
|
||||||
} else {
|
|
||||||
return createToAddressUskToValueMemoReturnValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - decryptAndStoreTransaction
|
// MARK: - decryptAndStoreTransaction
|
||||||
|
|
||||||
var decryptAndStoreTransactionTxBytesMinedHeightThrowableError: Error?
|
var decryptAndStoreTransactionTxBytesMinedHeightThrowableError: Error?
|
||||||
|
@ -2237,39 +2204,6 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
||||||
try await decryptAndStoreTransactionTxBytesMinedHeightClosure!(txBytes, minedHeight)
|
try await decryptAndStoreTransactionTxBytesMinedHeightClosure!(txBytes, minedHeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - getBalance
|
|
||||||
|
|
||||||
var getBalanceAccountThrowableError: Error?
|
|
||||||
func setGetBalanceAccountThrowableError(_ param: Error?) async {
|
|
||||||
getBalanceAccountThrowableError = param
|
|
||||||
}
|
|
||||||
var getBalanceAccountCallsCount = 0
|
|
||||||
var getBalanceAccountCalled: Bool {
|
|
||||||
return getBalanceAccountCallsCount > 0
|
|
||||||
}
|
|
||||||
var getBalanceAccountReceivedAccount: Int32?
|
|
||||||
var getBalanceAccountReturnValue: Int64!
|
|
||||||
func setGetBalanceAccountReturnValue(_ param: Int64) async {
|
|
||||||
getBalanceAccountReturnValue = param
|
|
||||||
}
|
|
||||||
var getBalanceAccountClosure: ((Int32) async throws -> Int64)?
|
|
||||||
func setGetBalanceAccountClosure(_ param: ((Int32) async throws -> Int64)?) async {
|
|
||||||
getBalanceAccountClosure = param
|
|
||||||
}
|
|
||||||
|
|
||||||
func getBalance(account: Int32) async throws -> Int64 {
|
|
||||||
if let error = getBalanceAccountThrowableError {
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
getBalanceAccountCallsCount += 1
|
|
||||||
getBalanceAccountReceivedAccount = account
|
|
||||||
if let closure = getBalanceAccountClosure {
|
|
||||||
return try await closure(account)
|
|
||||||
} else {
|
|
||||||
return getBalanceAccountReturnValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - getCurrentAddress
|
// MARK: - getCurrentAddress
|
||||||
|
|
||||||
var getCurrentAddressAccountThrowableError: Error?
|
var getCurrentAddressAccountThrowableError: Error?
|
||||||
|
@ -2501,39 +2435,6 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - getVerifiedBalance
|
|
||||||
|
|
||||||
var getVerifiedBalanceAccountThrowableError: Error?
|
|
||||||
func setGetVerifiedBalanceAccountThrowableError(_ param: Error?) async {
|
|
||||||
getVerifiedBalanceAccountThrowableError = param
|
|
||||||
}
|
|
||||||
var getVerifiedBalanceAccountCallsCount = 0
|
|
||||||
var getVerifiedBalanceAccountCalled: Bool {
|
|
||||||
return getVerifiedBalanceAccountCallsCount > 0
|
|
||||||
}
|
|
||||||
var getVerifiedBalanceAccountReceivedAccount: Int32?
|
|
||||||
var getVerifiedBalanceAccountReturnValue: Int64!
|
|
||||||
func setGetVerifiedBalanceAccountReturnValue(_ param: Int64) async {
|
|
||||||
getVerifiedBalanceAccountReturnValue = param
|
|
||||||
}
|
|
||||||
var getVerifiedBalanceAccountClosure: ((Int32) async throws -> Int64)?
|
|
||||||
func setGetVerifiedBalanceAccountClosure(_ param: ((Int32) async throws -> Int64)?) async {
|
|
||||||
getVerifiedBalanceAccountClosure = param
|
|
||||||
}
|
|
||||||
|
|
||||||
func getVerifiedBalance(account: Int32) async throws -> Int64 {
|
|
||||||
if let error = getVerifiedBalanceAccountThrowableError {
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
getVerifiedBalanceAccountCallsCount += 1
|
|
||||||
getVerifiedBalanceAccountReceivedAccount = account
|
|
||||||
if let closure = getVerifiedBalanceAccountClosure {
|
|
||||||
return try await closure(account)
|
|
||||||
} else {
|
|
||||||
return getVerifiedBalanceAccountReturnValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - getVerifiedTransparentBalance
|
// MARK: - getVerifiedTransparentBalance
|
||||||
|
|
||||||
var getVerifiedTransparentBalanceAccountThrowableError: Error?
|
var getVerifiedTransparentBalanceAccountThrowableError: Error?
|
||||||
|
@ -2729,34 +2630,34 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - getScanProgress
|
// MARK: - getWalletSummary
|
||||||
|
|
||||||
var getScanProgressThrowableError: Error?
|
var getWalletSummaryThrowableError: Error?
|
||||||
func setGetScanProgressThrowableError(_ param: Error?) async {
|
func setGetWalletSummaryThrowableError(_ param: Error?) async {
|
||||||
getScanProgressThrowableError = param
|
getWalletSummaryThrowableError = param
|
||||||
}
|
}
|
||||||
var getScanProgressCallsCount = 0
|
var getWalletSummaryCallsCount = 0
|
||||||
var getScanProgressCalled: Bool {
|
var getWalletSummaryCalled: Bool {
|
||||||
return getScanProgressCallsCount > 0
|
return getWalletSummaryCallsCount > 0
|
||||||
}
|
}
|
||||||
var getScanProgressReturnValue: ScanProgress?
|
var getWalletSummaryReturnValue: WalletSummary?
|
||||||
func setGetScanProgressReturnValue(_ param: ScanProgress?) async {
|
func setGetWalletSummaryReturnValue(_ param: WalletSummary?) async {
|
||||||
getScanProgressReturnValue = param
|
getWalletSummaryReturnValue = param
|
||||||
}
|
}
|
||||||
var getScanProgressClosure: (() async throws -> ScanProgress?)?
|
var getWalletSummaryClosure: (() async throws -> WalletSummary?)?
|
||||||
func setGetScanProgressClosure(_ param: (() async throws -> ScanProgress?)?) async {
|
func setGetWalletSummaryClosure(_ param: (() async throws -> WalletSummary?)?) async {
|
||||||
getScanProgressClosure = param
|
getWalletSummaryClosure = param
|
||||||
}
|
}
|
||||||
|
|
||||||
func getScanProgress() async throws -> ScanProgress? {
|
func getWalletSummary() async throws -> WalletSummary? {
|
||||||
if let error = getScanProgressThrowableError {
|
if let error = getWalletSummaryThrowableError {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
getScanProgressCallsCount += 1
|
getWalletSummaryCallsCount += 1
|
||||||
if let closure = getScanProgressClosure {
|
if let closure = getWalletSummaryClosure {
|
||||||
return try await closure()
|
return try await closure()
|
||||||
} else {
|
} else {
|
||||||
return getScanProgressReturnValue
|
return getWalletSummaryReturnValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2802,18 +2703,26 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
||||||
return scanBlocksFromHeightLimitCallsCount > 0
|
return scanBlocksFromHeightLimitCallsCount > 0
|
||||||
}
|
}
|
||||||
var scanBlocksFromHeightLimitReceivedArguments: (fromHeight: Int32, limit: UInt32)?
|
var scanBlocksFromHeightLimitReceivedArguments: (fromHeight: Int32, limit: UInt32)?
|
||||||
var scanBlocksFromHeightLimitClosure: ((Int32, UInt32) async throws -> Void)?
|
var scanBlocksFromHeightLimitReturnValue: ScanSummary!
|
||||||
func setScanBlocksFromHeightLimitClosure(_ param: ((Int32, UInt32) async throws -> Void)?) async {
|
func setScanBlocksFromHeightLimitReturnValue(_ param: ScanSummary) async {
|
||||||
|
scanBlocksFromHeightLimitReturnValue = param
|
||||||
|
}
|
||||||
|
var scanBlocksFromHeightLimitClosure: ((Int32, UInt32) async throws -> ScanSummary)?
|
||||||
|
func setScanBlocksFromHeightLimitClosure(_ param: ((Int32, UInt32) async throws -> ScanSummary)?) async {
|
||||||
scanBlocksFromHeightLimitClosure = param
|
scanBlocksFromHeightLimitClosure = param
|
||||||
}
|
}
|
||||||
|
|
||||||
func scanBlocks(fromHeight: Int32, limit: UInt32) async throws {
|
func scanBlocks(fromHeight: Int32, limit: UInt32) async throws -> ScanSummary {
|
||||||
if let error = scanBlocksFromHeightLimitThrowableError {
|
if let error = scanBlocksFromHeightLimitThrowableError {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
scanBlocksFromHeightLimitCallsCount += 1
|
scanBlocksFromHeightLimitCallsCount += 1
|
||||||
scanBlocksFromHeightLimitReceivedArguments = (fromHeight: fromHeight, limit: limit)
|
scanBlocksFromHeightLimitReceivedArguments = (fromHeight: fromHeight, limit: limit)
|
||||||
try await scanBlocksFromHeightLimitClosure!(fromHeight, limit)
|
if let closure = scanBlocksFromHeightLimitClosure {
|
||||||
|
return try await closure(fromHeight, limit)
|
||||||
|
} else {
|
||||||
|
return scanBlocksFromHeightLimitReturnValue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - putUnspentTransparentOutput
|
// MARK: - putUnspentTransparentOutput
|
||||||
|
@ -2841,36 +2750,102 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
||||||
try await putUnspentTransparentOutputTxidIndexScriptValueHeightClosure!(txid, index, script, value, height)
|
try await putUnspentTransparentOutputTxidIndexScriptValueHeightClosure!(txid, index, script, value, height)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - shieldFunds
|
// MARK: - proposeTransfer
|
||||||
|
|
||||||
var shieldFundsUskMemoShieldingThresholdThrowableError: Error?
|
var proposeTransferAccountToValueMemoThrowableError: Error?
|
||||||
func setShieldFundsUskMemoShieldingThresholdThrowableError(_ param: Error?) async {
|
func setProposeTransferAccountToValueMemoThrowableError(_ param: Error?) async {
|
||||||
shieldFundsUskMemoShieldingThresholdThrowableError = param
|
proposeTransferAccountToValueMemoThrowableError = param
|
||||||
}
|
}
|
||||||
var shieldFundsUskMemoShieldingThresholdCallsCount = 0
|
var proposeTransferAccountToValueMemoCallsCount = 0
|
||||||
var shieldFundsUskMemoShieldingThresholdCalled: Bool {
|
var proposeTransferAccountToValueMemoCalled: Bool {
|
||||||
return shieldFundsUskMemoShieldingThresholdCallsCount > 0
|
return proposeTransferAccountToValueMemoCallsCount > 0
|
||||||
}
|
}
|
||||||
var shieldFundsUskMemoShieldingThresholdReceivedArguments: (usk: UnifiedSpendingKey, memo: MemoBytes?, shieldingThreshold: Zatoshi)?
|
var proposeTransferAccountToValueMemoReceivedArguments: (account: Int32, address: String, value: Int64, memo: MemoBytes?)?
|
||||||
var shieldFundsUskMemoShieldingThresholdReturnValue: Data!
|
var proposeTransferAccountToValueMemoReturnValue: FfiProposal!
|
||||||
func setShieldFundsUskMemoShieldingThresholdReturnValue(_ param: Data) async {
|
func setProposeTransferAccountToValueMemoReturnValue(_ param: FfiProposal) async {
|
||||||
shieldFundsUskMemoShieldingThresholdReturnValue = param
|
proposeTransferAccountToValueMemoReturnValue = param
|
||||||
}
|
}
|
||||||
var shieldFundsUskMemoShieldingThresholdClosure: ((UnifiedSpendingKey, MemoBytes?, Zatoshi) async throws -> Data)?
|
var proposeTransferAccountToValueMemoClosure: ((Int32, String, Int64, MemoBytes?) async throws -> FfiProposal)?
|
||||||
func setShieldFundsUskMemoShieldingThresholdClosure(_ param: ((UnifiedSpendingKey, MemoBytes?, Zatoshi) async throws -> Data)?) async {
|
func setProposeTransferAccountToValueMemoClosure(_ param: ((Int32, String, Int64, MemoBytes?) async throws -> FfiProposal)?) async {
|
||||||
shieldFundsUskMemoShieldingThresholdClosure = param
|
proposeTransferAccountToValueMemoClosure = param
|
||||||
}
|
}
|
||||||
|
|
||||||
func shieldFunds(usk: UnifiedSpendingKey, memo: MemoBytes?, shieldingThreshold: Zatoshi) async throws -> Data {
|
func proposeTransfer(account: Int32, to address: String, value: Int64, memo: MemoBytes?) async throws -> FfiProposal {
|
||||||
if let error = shieldFundsUskMemoShieldingThresholdThrowableError {
|
if let error = proposeTransferAccountToValueMemoThrowableError {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
shieldFundsUskMemoShieldingThresholdCallsCount += 1
|
proposeTransferAccountToValueMemoCallsCount += 1
|
||||||
shieldFundsUskMemoShieldingThresholdReceivedArguments = (usk: usk, memo: memo, shieldingThreshold: shieldingThreshold)
|
proposeTransferAccountToValueMemoReceivedArguments = (account: account, address: address, value: value, memo: memo)
|
||||||
if let closure = shieldFundsUskMemoShieldingThresholdClosure {
|
if let closure = proposeTransferAccountToValueMemoClosure {
|
||||||
return try await closure(usk, memo, shieldingThreshold)
|
return try await closure(account, address, value, memo)
|
||||||
} else {
|
} else {
|
||||||
return shieldFundsUskMemoShieldingThresholdReturnValue
|
return proposeTransferAccountToValueMemoReturnValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - proposeShielding
|
||||||
|
|
||||||
|
var proposeShieldingAccountMemoShieldingThresholdThrowableError: Error?
|
||||||
|
func setProposeShieldingAccountMemoShieldingThresholdThrowableError(_ param: Error?) async {
|
||||||
|
proposeShieldingAccountMemoShieldingThresholdThrowableError = param
|
||||||
|
}
|
||||||
|
var proposeShieldingAccountMemoShieldingThresholdCallsCount = 0
|
||||||
|
var proposeShieldingAccountMemoShieldingThresholdCalled: Bool {
|
||||||
|
return proposeShieldingAccountMemoShieldingThresholdCallsCount > 0
|
||||||
|
}
|
||||||
|
var proposeShieldingAccountMemoShieldingThresholdReceivedArguments: (account: Int32, memo: MemoBytes?, shieldingThreshold: Zatoshi)?
|
||||||
|
var proposeShieldingAccountMemoShieldingThresholdReturnValue: FfiProposal!
|
||||||
|
func setProposeShieldingAccountMemoShieldingThresholdReturnValue(_ param: FfiProposal) async {
|
||||||
|
proposeShieldingAccountMemoShieldingThresholdReturnValue = param
|
||||||
|
}
|
||||||
|
var proposeShieldingAccountMemoShieldingThresholdClosure: ((Int32, MemoBytes?, Zatoshi) async throws -> FfiProposal)?
|
||||||
|
func setProposeShieldingAccountMemoShieldingThresholdClosure(_ param: ((Int32, MemoBytes?, Zatoshi) async throws -> FfiProposal)?) async {
|
||||||
|
proposeShieldingAccountMemoShieldingThresholdClosure = param
|
||||||
|
}
|
||||||
|
|
||||||
|
func proposeShielding(account: Int32, memo: MemoBytes?, shieldingThreshold: Zatoshi) async throws -> FfiProposal {
|
||||||
|
if let error = proposeShieldingAccountMemoShieldingThresholdThrowableError {
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
proposeShieldingAccountMemoShieldingThresholdCallsCount += 1
|
||||||
|
proposeShieldingAccountMemoShieldingThresholdReceivedArguments = (account: account, memo: memo, shieldingThreshold: shieldingThreshold)
|
||||||
|
if let closure = proposeShieldingAccountMemoShieldingThresholdClosure {
|
||||||
|
return try await closure(account, memo, shieldingThreshold)
|
||||||
|
} else {
|
||||||
|
return proposeShieldingAccountMemoShieldingThresholdReturnValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - createProposedTransaction
|
||||||
|
|
||||||
|
var createProposedTransactionProposalUskThrowableError: Error?
|
||||||
|
func setCreateProposedTransactionProposalUskThrowableError(_ param: Error?) async {
|
||||||
|
createProposedTransactionProposalUskThrowableError = param
|
||||||
|
}
|
||||||
|
var createProposedTransactionProposalUskCallsCount = 0
|
||||||
|
var createProposedTransactionProposalUskCalled: Bool {
|
||||||
|
return createProposedTransactionProposalUskCallsCount > 0
|
||||||
|
}
|
||||||
|
var createProposedTransactionProposalUskReceivedArguments: (proposal: FfiProposal, usk: UnifiedSpendingKey)?
|
||||||
|
var createProposedTransactionProposalUskReturnValue: Data!
|
||||||
|
func setCreateProposedTransactionProposalUskReturnValue(_ param: Data) async {
|
||||||
|
createProposedTransactionProposalUskReturnValue = param
|
||||||
|
}
|
||||||
|
var createProposedTransactionProposalUskClosure: ((FfiProposal, UnifiedSpendingKey) async throws -> Data)?
|
||||||
|
func setCreateProposedTransactionProposalUskClosure(_ param: ((FfiProposal, UnifiedSpendingKey) async throws -> Data)?) async {
|
||||||
|
createProposedTransactionProposalUskClosure = param
|
||||||
|
}
|
||||||
|
|
||||||
|
func createProposedTransaction(proposal: FfiProposal, usk: UnifiedSpendingKey) async throws -> Data {
|
||||||
|
if let error = createProposedTransactionProposalUskThrowableError {
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
createProposedTransactionProposalUskCallsCount += 1
|
||||||
|
createProposedTransactionProposalUskReceivedArguments = (proposal: proposal, usk: usk)
|
||||||
|
if let closure = createProposedTransactionProposalUskClosure {
|
||||||
|
return try await closure(proposal, usk)
|
||||||
|
} else {
|
||||||
|
return createProposedTransactionProposalUskReturnValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
scriptDir=${0:a:h}
|
scriptDir=${0:a:h}
|
||||||
cd "${scriptDir}"
|
cd "${scriptDir}"
|
||||||
|
|
||||||
sourcery_version=2.0.3
|
sourcery_version=2.1.4
|
||||||
|
|
||||||
if which sourcery >/dev/null; then
|
if which sourcery >/dev/null; then
|
||||||
if [[ $(sourcery --version) != $sourcery_version ]]; then
|
if [[ $(sourcery --version) != $sourcery_version ]]; then
|
||||||
|
|
|
@ -75,7 +75,6 @@ class RustBackendMockHelper {
|
||||||
await rustBackendMock.setInitBlockMetadataDbClosure() { }
|
await rustBackendMock.setInitBlockMetadataDbClosure() { }
|
||||||
await rustBackendMock.setWriteBlocksMetadataBlocksClosure() { _ in }
|
await rustBackendMock.setWriteBlocksMetadataBlocksClosure() { _ in }
|
||||||
await rustBackendMock.setGetTransparentBalanceAccountReturnValue(0)
|
await rustBackendMock.setGetTransparentBalanceAccountReturnValue(0)
|
||||||
await rustBackendMock.setGetVerifiedBalanceAccountReturnValue(0)
|
|
||||||
await rustBackendMock.setListTransparentReceiversAccountReturnValue([])
|
await rustBackendMock.setListTransparentReceiversAccountReturnValue([])
|
||||||
await rustBackendMock.setGetCurrentAddressAccountThrowableError(ZcashError.rustGetCurrentAddress("mocked error"))
|
await rustBackendMock.setGetCurrentAddressAccountThrowableError(ZcashError.rustGetCurrentAddress("mocked error"))
|
||||||
await rustBackendMock.setGetNextAvailableAddressAccountThrowableError(ZcashError.rustGetNextAvailableAddress("mocked error"))
|
await rustBackendMock.setGetNextAvailableAddressAccountThrowableError(ZcashError.rustGetNextAvailableAddress("mocked error"))
|
||||||
|
@ -84,22 +83,15 @@ class RustBackendMockHelper {
|
||||||
await rustBackendMock.setInitDataDbSeedReturnValue(.seedRequired)
|
await rustBackendMock.setInitDataDbSeedReturnValue(.seedRequired)
|
||||||
await rustBackendMock.setGetNearestRewindHeightHeightReturnValue(-1)
|
await rustBackendMock.setGetNearestRewindHeightHeightReturnValue(-1)
|
||||||
await rustBackendMock.setPutUnspentTransparentOutputTxidIndexScriptValueHeightClosure() { _, _, _, _, _ in }
|
await rustBackendMock.setPutUnspentTransparentOutputTxidIndexScriptValueHeightClosure() { _, _, _, _, _ in }
|
||||||
await rustBackendMock.setCreateToAddressUskToValueMemoThrowableError(ZcashError.rustCreateToAddress("mocked error"))
|
await rustBackendMock.setProposeTransferAccountToValueMemoThrowableError(ZcashError.rustCreateToAddress("mocked error"))
|
||||||
await rustBackendMock.setShieldFundsUskMemoShieldingThresholdThrowableError(ZcashError.rustShieldFunds("mocked error"))
|
await rustBackendMock.setProposeShieldingAccountMemoShieldingThresholdThrowableError(ZcashError.rustShieldFunds("mocked error"))
|
||||||
|
await rustBackendMock.setCreateProposedTransactionProposalUskThrowableError(ZcashError.rustCreateToAddress("mocked error"))
|
||||||
await rustBackendMock.setDecryptAndStoreTransactionTxBytesMinedHeightThrowableError(ZcashError.rustDecryptAndStoreTransaction("mock fail"))
|
await rustBackendMock.setDecryptAndStoreTransactionTxBytesMinedHeightThrowableError(ZcashError.rustDecryptAndStoreTransaction("mock fail"))
|
||||||
|
|
||||||
await rustBackendMock.setInitDataDbSeedClosure() { seed in
|
await rustBackendMock.setInitDataDbSeedClosure() { seed in
|
||||||
return try await rustBackend.initDataDb(seed: seed)
|
return try await rustBackend.initDataDb(seed: seed)
|
||||||
}
|
}
|
||||||
|
|
||||||
await rustBackendMock.setGetBalanceAccountClosure() { account in
|
|
||||||
return try await rustBackend.getBalance(account: account)
|
|
||||||
}
|
|
||||||
|
|
||||||
await rustBackendMock.setGetVerifiedBalanceAccountClosure() { account in
|
|
||||||
return try await rustBackend.getVerifiedBalance(account: account)
|
|
||||||
}
|
|
||||||
|
|
||||||
await rustBackendMock.setRewindToHeightHeightClosure() { height in
|
await rustBackendMock.setRewindToHeightHeightClosure() { height in
|
||||||
try await rustBackend.rewindToHeight(height: height)
|
try await rustBackend.rewindToHeight(height: height)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue