Zip32AccountIndex UInt32 refactor

- Zip32Account(Int32) has been refactored to Zip32AccountIndex(UIn32)
This commit is contained in:
Lukas Korba 2024-11-25 11:32:55 +01:00
parent b31e1c91d7
commit 97137510b2
34 changed files with 485 additions and 520 deletions

View File

@ -21,6 +21,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
private var wallet: Initializer?
private var synchronizer: SDKSynchronizer?
let accountIndex = Zip32AccountIndex(0)
var sharedSynchronizer: SDKSynchronizer {
if let sync = synchronizer {
return sync
@ -34,7 +36,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var sharedViewingKey: UnifiedFullViewingKey {
let derivationTool = DerivationTool(networkType: kZcashNetwork.networkType)
let spendingKey = try! derivationTool
.deriveUnifiedSpendingKey(seed: DemoAppConfig.defaultSeed, accountIndex: 0)
.deriveUnifiedSpendingKey(seed: DemoAppConfig.defaultSeed, accountIndex: accountIndex)
return try! derivationTool.deriveUnifiedFullViewingKey(from: spendingKey)
}

View File

@ -19,7 +19,7 @@ class GetAddressViewController: UIViewController {
let synchronizer = SDKSynchronizer.shared
Task { @MainActor in
guard let uAddress = try? await synchronizer.getUnifiedAddress(account: Zip32Account(0)) else {
guard let uAddress = try? await synchronizer.getUnifiedAddress(accountIndex: Zip32AccountIndex(0)) else {
unifiedAddressLabel.text = "could not derive UA"
tAddressLabel.text = "could not derive tAddress"
saplingAddress.text = "could not derive zAddress"

View File

@ -19,13 +19,15 @@ class GetBalanceViewController: UIViewController {
var accountBalance: AccountBalance?
var rate: FiatCurrencyResult?
let accountIndex = Zip32AccountIndex(0)
override func viewDidLoad() {
super.viewDidLoad()
let synchronizer = AppDelegate.shared.sharedSynchronizer
self.title = "Account 0 Balance"
Task { @MainActor [weak self] in
self?.accountBalance = try? await synchronizer.getAccountBalance()
self?.accountBalance = try? await synchronizer.getAccountBalance(accountIndex: accountIndex)
self?.updateLabels()
}

View File

@ -15,7 +15,9 @@ class GetUTXOsViewController: UIViewController {
@IBOutlet weak var totalBalanceLabel: UILabel!
@IBOutlet weak var messageLabel: UILabel!
@IBOutlet weak var shieldFundsButton: UIButton!
let accountIndex = Zip32AccountIndex(0)
override func viewDidLoad() {
super.viewDidLoad()
@ -26,13 +28,12 @@ class GetUTXOsViewController: UIViewController {
let synchronizer = SDKSynchronizer.shared
Task { @MainActor in
let account = Zip32Account(0)
let tAddress = (try? await synchronizer.getTransparentAddress(account: account))?.stringEncoded ?? "no t-address found"
let tAddress = (try? await synchronizer.getTransparentAddress(accountIndex: accountIndex))?.stringEncoded ?? "no t-address found"
self.transparentAddressLabel.text = tAddress
// swiftlint:disable:next force_try
let balance = try! await AppDelegate.shared.sharedSynchronizer.getAccountBalance(account: account)?.unshielded ?? .zero
let balance = try! await AppDelegate.shared.sharedSynchronizer.getAccountBalance(accountIndex: accountIndex)?.unshielded ?? .zero
self.totalBalanceLabel.text = NumberFormatter.zcashNumberFormatter.string(from: NSNumber(value: balance.amount))
self.verifiedBalanceLabel.text = NumberFormatter.zcashNumberFormatter.string(from: NSNumber(value: balance.amount))
@ -43,7 +44,7 @@ class GetUTXOsViewController: UIViewController {
do {
let derivationTool = DerivationTool(networkType: kZcashNetwork.networkType)
let usk = try derivationTool.deriveUnifiedSpendingKey(seed: DemoAppConfig.defaultSeed, accountIndex: 0)
let usk = try derivationTool.deriveUnifiedSpendingKey(seed: DemoAppConfig.defaultSeed, accountIndex: accountIndex)
KRProgressHUD.showMessage("🛡 Shielding 🛡")

View File

@ -25,6 +25,7 @@ class SendViewController: UIViewController {
@IBOutlet weak var charactersLeftLabel: UILabel!
let characterLimit: Int = 512
let accountIndex = Zip32AccountIndex(0)
var wallet = Initializer.shared
@ -103,13 +104,11 @@ class SendViewController: UIViewController {
}
func updateBalance() async {
let account = Zip32Account(0)
balanceLabel.text = format(
balance: (try? await synchronizer.getAccountBalance(account: account))?.saplingBalance.total() ?? .zero
balance: (try? await synchronizer.getAccountBalance(accountIndex: accountIndex))?.saplingBalance.total() ?? .zero
)
verifiedBalanceLabel.text = format(
balance: (try? await synchronizer.getAccountBalance(account: account))?.saplingBalance.spendableValue ?? .zero
balance: (try? await synchronizer.getAccountBalance(accountIndex: accountIndex))?.saplingBalance.spendableValue ?? .zero
)
}
@ -124,7 +123,7 @@ class SendViewController: UIViewController {
func maxFundsOn() {
Task { @MainActor in
let fee = Zatoshi(10000)
let max: Zatoshi = ((try? await synchronizer.getAccountBalance(account: Zip32Account(0)))?.saplingBalance.spendableValue ?? .zero) - fee
let max: Zatoshi = ((try? await synchronizer.getAccountBalance(accountIndex: accountIndex))?.saplingBalance.spendableValue ?? .zero) - fee
amountTextField.text = format(balance: max)
amountTextField.isEnabled = false
}
@ -146,12 +145,12 @@ class SendViewController: UIViewController {
}
func isBalanceValid() async -> Bool {
let balance = (try? await synchronizer.getAccountBalance(account: Zip32Account(0)))?.saplingBalance.spendableValue ?? .zero
let balance = (try? await synchronizer.getAccountBalance(accountIndex: accountIndex))?.saplingBalance.spendableValue ?? .zero
return balance > .zero
}
func isAmountValid() async -> Bool {
let balance = (try? await synchronizer.getAccountBalance(account: Zip32Account(0)))?.saplingBalance.spendableValue ?? .zero
let balance = (try? await synchronizer.getAccountBalance(accountIndex: accountIndex))?.saplingBalance.spendableValue ?? .zero
guard
let value = amountTextField.text,
let amount = NumberFormatter.zcashNumberFormatter.number(from: value).flatMap({ Zatoshi($0.int64Value) }),
@ -230,7 +229,7 @@ class SendViewController: UIViewController {
}
let derivationTool = DerivationTool(networkType: kZcashNetwork.networkType)
guard let spendingKey = try? derivationTool.deriveUnifiedSpendingKey(seed: DemoAppConfig.defaultSeed, accountIndex: 0) else {
guard let spendingKey = try? derivationTool.deriveUnifiedSpendingKey(seed: DemoAppConfig.defaultSeed, accountIndex: accountIndex) else {
loggerProxy.error("NO SPENDING KEY")
return
}

View File

@ -6,12 +6,16 @@
//
/// A [ZIP 32](https://zips.z.cash/zip-0032) account index.
public struct Zip32Account: Equatable, Codable, Hashable {
public let index: Int32
///
/// This index must be paired with a seed, or other context that determines a seed,
/// in order to identify a ZIP 32 *account*.
public struct Zip32AccountIndex: Equatable, Codable, Hashable {
public let index: UInt32
public init(_ index: Int32) {
guard index >= 0 else {
fatalError("Account index must be >= 0. Input value is \(index).")
/// - Parameter index: the ZIP 32 account index, which must be less than ``1<<31``.
public init(_ index: UInt32) {
guard index < (1<<31) else {
fatalError("Account index must be less than 1<<31. Input value is \(index).")
}
self.index = index
@ -19,13 +23,14 @@ public struct Zip32Account: Equatable, Codable, Hashable {
}
public struct AccountId: Equatable, Codable, Hashable {
public let index: Int
public init(_ index: Int) {
guard index >= 0 else {
fatalError("Account index must be >= 0. Input value is \(index).")
public let id: Int
/// - Parameter id: the local account id, which must be nonnegative.
public init(_ id: Int) {
guard id >= 0 else {
fatalError("Account id must be >= 0. Input value is \(id).")
}
self.index = index
self.id = id
}
}

View File

@ -22,8 +22,9 @@ extension SaplingParamsAction: Action {
func run(with context: ActionContext, didUpdate: @escaping (CompactBlockProcessor.Event) async -> Void) async throws -> ActionContext {
logger.debug("Fetching sapling parameters")
// TODO: This is hardcoded Zip32Account for index 0, must be updated
try await saplingParametersHandler.handleIfNeeded(account: Zip32Account(0))
// TODO: [#1512] This is hardcoded Zip32AccountIndex for index 0, must be updated
// https://github.com/Electric-Coin-Company/zcash-swift-wallet-sdk/issues/1512
try await saplingParametersHandler.handleIfNeeded(accountIndex: Zip32AccountIndex(0))
await context.update(state: .updateSubtreeRoots)

View File

@ -837,16 +837,16 @@ extension CompactBlockProcessor {
}
extension CompactBlockProcessor {
func getUnifiedAddress(account: Zip32Account) async throws -> UnifiedAddress {
try await rustBackend.getCurrentAddress(account: account)
func getUnifiedAddress(accountIndex: Zip32AccountIndex) async throws -> UnifiedAddress {
try await rustBackend.getCurrentAddress(accountIndex: accountIndex)
}
func getSaplingAddress(account: Zip32Account) async throws -> SaplingAddress {
try await getUnifiedAddress(account: account).saplingReceiver()
func getSaplingAddress(accountIndex: Zip32AccountIndex) async throws -> SaplingAddress {
try await getUnifiedAddress(accountIndex: accountIndex).saplingReceiver()
}
func getTransparentAddress(account: Zip32Account) async throws -> TransparentAddress {
try await getUnifiedAddress(account: account).transparentReceiver()
func getTransparentAddress(accountIndex: Zip32AccountIndex) async throws -> TransparentAddress {
try await getUnifiedAddress(accountIndex: accountIndex).transparentReceiver()
}
}

View File

@ -39,8 +39,8 @@ extension UTXOFetcherImpl: UTXOFetcher {
let accounts = try await rustBackend.listAccounts()
var tAddresses: [TransparentAddress] = []
for account in accounts {
tAddresses += try await rustBackend.listTransparentReceivers(account: account)
for accountIndex in accounts {
tAddresses += try await rustBackend.listTransparentReceivers(accountIndex: accountIndex)
}
var utxos: [UnspentTransactionOutputEntity] = []

View File

@ -14,7 +14,7 @@ struct SaplingParametersHandlerConfig {
}
protocol SaplingParametersHandler {
func handleIfNeeded(account: Zip32Account) async throws
func handleIfNeeded(accountIndex: Zip32AccountIndex) async throws
}
struct SaplingParametersHandlerImpl {
@ -24,14 +24,14 @@ struct SaplingParametersHandlerImpl {
}
extension SaplingParametersHandlerImpl: SaplingParametersHandler {
func handleIfNeeded(account: Zip32Account) async throws {
func handleIfNeeded(accountIndex: Zip32AccountIndex) async throws {
try Task.checkCancellation()
do {
let totalSaplingBalance =
try await rustBackend.getWalletSummary()?.accountBalances[0]?.saplingBalance.total().amount
?? 0
let totalTransparentBalance = try await rustBackend.getTransparentBalance(account: account)
let totalTransparentBalance = try await rustBackend.getTransparentBalance(accountIndex: accountIndex)
// Download Sapling parameters only if sapling funds are detected.
guard totalSaplingBalance > 0 || totalTransparentBalance > 0 else { return }

View File

@ -32,13 +32,13 @@ public protocol ClosureSynchronizer {
func start(retry: Bool, completion: @escaping (Error?) -> Void)
func stop()
func getSaplingAddress(account: Zip32Account, completion: @escaping (Result<SaplingAddress, Error>) -> Void)
func getUnifiedAddress(account: Zip32Account, completion: @escaping (Result<UnifiedAddress, Error>) -> Void)
func getTransparentAddress(account: Zip32Account, completion: @escaping (Result<TransparentAddress, Error>) -> Void)
func getSaplingAddress(accountIndex: Zip32AccountIndex, completion: @escaping (Result<SaplingAddress, Error>) -> Void)
func getUnifiedAddress(accountIndex: Zip32AccountIndex, completion: @escaping (Result<UnifiedAddress, Error>) -> Void)
func getTransparentAddress(accountIndex: Zip32AccountIndex, completion: @escaping (Result<TransparentAddress, Error>) -> Void)
/// Creates a proposal for transferring funds to the given recipient.
///
/// - Parameter account: the account from which to transfer funds.
/// - Parameter accountIndex: the ZIP 32 index of the account from which to transfer funds.
/// - Parameter recipient: the recipient's address.
/// - Parameter amount: the amount to send in Zatoshi.
/// - Parameter memo: an optional memo to include as part of the proposal's transactions. Use `nil` when sending to transparent receivers otherwise the function will throw an error.
@ -46,7 +46,7 @@ public protocol ClosureSynchronizer {
/// If `prepare()` hasn't already been called since creation of the synchronizer instance or since the last wipe then this method throws
/// `SynchronizerErrors.notPrepared`.
func proposeTransfer(
account: Zip32Account,
accountIndex: Zip32AccountIndex,
recipient: Recipient,
amount: Zatoshi,
memo: Memo?,
@ -55,7 +55,7 @@ public protocol ClosureSynchronizer {
/// Creates a proposal for shielding any transparent funds received by the given account.
///
/// - Parameter account: the account for which to shield funds.
/// - Parameter accountIndex: the ZIP 32 index of the account from which to shield funds.
/// - Parameter shieldingThreshold: the minimum transparent balance required before a proposal will be created.
/// - Parameter memo: an optional memo to include as part of the proposal's transactions.
/// - Parameter transparentReceiver: a specific transparent receiver within the account
@ -69,7 +69,7 @@ public protocol ClosureSynchronizer {
/// If `prepare()` hasn't already been called since creation of the synchronizer instance or since the last wipe then this method throws
/// `SynchronizerErrors.notPrepared`.
func proposeShielding(
account: Zip32Account,
accountIndex: Zip32AccountIndex,
shieldingThreshold: Zatoshi,
memo: Memo,
transparentReceiver: TransparentAddress?,
@ -127,7 +127,7 @@ public protocol ClosureSynchronizer {
func refreshUTXOs(address: TransparentAddress, from height: BlockHeight, completion: @escaping (Result<RefreshedUTXOs, Error>) -> Void)
func getAccountBalance(account: Zip32Account, completion: @escaping (Result<AccountBalance?, Error>) -> Void)
func getAccountBalance(accountIndex: Zip32AccountIndex, completion: @escaping (Result<AccountBalance?, Error>) -> Void)
func refreshExchangeRateUSD()

View File

@ -31,13 +31,13 @@ public protocol CombineSynchronizer {
func start(retry: Bool) -> CompletablePublisher<Error>
func stop()
func getSaplingAddress(account: Zip32Account) -> SinglePublisher<SaplingAddress, Error>
func getUnifiedAddress(account: Zip32Account) -> SinglePublisher<UnifiedAddress, Error>
func getTransparentAddress(account: Zip32Account) -> SinglePublisher<TransparentAddress, Error>
func getSaplingAddress(accountIndex: Zip32AccountIndex) -> SinglePublisher<SaplingAddress, Error>
func getUnifiedAddress(accountIndex: Zip32AccountIndex) -> SinglePublisher<UnifiedAddress, Error>
func getTransparentAddress(accountIndex: Zip32AccountIndex) -> SinglePublisher<TransparentAddress, Error>
/// Creates a proposal for transferring funds to the given recipient.
///
/// - Parameter account: the account from which to transfer funds.
/// - Parameter accountIndex: the ZIP 32 index of the account from which to transfer funds.
/// - Parameter recipient: the recipient's address.
/// - Parameter amount: the amount to send in Zatoshi.
/// - Parameter memo: an optional memo to include as part of the proposal's transactions. Use `nil` when sending to transparent receivers otherwise the function will throw an error.
@ -45,7 +45,7 @@ public protocol CombineSynchronizer {
/// If `prepare()` hasn't already been called since creation of the synchronizer instance or since the last wipe then this method throws
/// `SynchronizerErrors.notPrepared`.
func proposeTransfer(
account: Zip32Account,
accountIndex: Zip32AccountIndex,
recipient: Recipient,
amount: Zatoshi,
memo: Memo?
@ -53,7 +53,7 @@ public protocol CombineSynchronizer {
/// Creates a proposal for shielding any transparent funds received by the given account.
///
/// - Parameter account: the account for which to shield funds.
/// - Parameter accountIndex: the ZIP 32 index of the account from which to shield funds.
/// - Parameter shieldingThreshold: the minimum transparent balance required before a proposal will be created.
/// - Parameter memo: an optional memo to include as part of the proposal's transactions.
/// - Parameter transparentReceiver: a specific transparent receiver within the account
@ -67,7 +67,7 @@ public protocol CombineSynchronizer {
/// If `prepare()` hasn't already been called since creation of the synchronizer instance or since the last wipe then this method throws
/// `SynchronizerErrors.notPrepared`.
func proposeShielding(
account: Zip32Account,
accountIndex: Zip32AccountIndex,
shieldingThreshold: Zatoshi,
memo: Memo,
transparentReceiver: TransparentAddress?
@ -110,7 +110,7 @@ public protocol CombineSynchronizer {
func proposefulfillingPaymentURI(
_ uri: String,
account: Zip32Account
accountIndex: Zip32AccountIndex
) -> SinglePublisher<Proposal, Error>
var allTransactions: SinglePublisher<[ZcashTransaction.Overview], Never> { get }

View File

@ -9,24 +9,24 @@ import Foundation
import SQLite
protocol AccountEntity {
var account: Zip32Account { get }
var accountIndex: Zip32AccountIndex { get }
var ufvk: String { get }
}
struct DbAccount: AccountEntity, Encodable, Decodable {
let account: Zip32Account
let accountIndex: Zip32AccountIndex
let ufvk: String
}
extension DbAccount: Hashable {
func hash(into hasher: inout Hasher) {
hasher.combine(account.index)
hasher.combine(accountIndex.index)
hasher.combine(ufvk)
}
static func == (lhs: Self, rhs: Self) -> Bool {
guard
lhs.account == rhs.account,
lhs.accountIndex == rhs.accountIndex,
lhs.ufvk == rhs.ufvk
else { return false }

View File

@ -147,10 +147,6 @@ public enum ZcashError: Equatable, Error {
/// Unified address generated by rust layer is invalid when calling ZcashRustBackend.getNextAvailableAddress
/// ZRUST0009
case rustGetNextAvailableAddressInvalidAddress
/// account parameter is lower than 0 when calling ZcashRustBackend.getTransparentBalance
/// - `account` is account passed to ZcashRustBackend.getTransparentBalance.
/// ZRUST0010
case rustGetTransparentBalanceNegativeAccount(_ account: Int)
/// Error from rust layer when calling ZcashRustBackend.getTransparentBalance
/// - `account` is account passed to ZcashRustBackend.getTransparentBalance.
/// - `rustError` contains error generated by the rust layer.
@ -487,9 +483,6 @@ public enum ZcashError: Equatable, Error {
/// Failed to decode `Checkpoint` object.
/// ZCHKP0002
case checkpointDecode(_ error: Error)
/// Invalid account when trying to derive a key
/// ZDRVT0001
case derivationToolInvalidAccount
/// Creation of the table for unspent transaction output failed.
/// - `sqliteError` is error produced by SQLite library.
/// ZUTOD0001
@ -684,7 +677,6 @@ public enum ZcashError: Equatable, Error {
case .rustGetNearestRewindHeight: return "Error from rust layer when calling ZcashRustBackend.getNearestRewindHeight"
case .rustGetNextAvailableAddress: return "Error from rust layer 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 .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"
@ -778,7 +770,6 @@ public enum ZcashError: Equatable, Error {
case .memoBytesInvalidUTF8: return "Invalid UTF-8 Bytes where detected when attempting to convert MemoBytes to Memo."
case .checkpointCantLoadFromDisk: return "Failed to load JSON with checkpoint from disk."
case .checkpointDecode: return "Failed to decode `Checkpoint` object."
case .derivationToolInvalidAccount: return "Invalid account when trying to derive a key"
case .unspentTransactionOutputDAOCreateTable: return "Creation of the table for unspent transaction output failed."
case .unspentTransactionOutputDAOStore: return "SQLite query failed when storing unspent transaction output."
case .unspentTransactionOutputDAOClearAll: return "SQLite query failed when removing all the unspent transation outputs."
@ -871,7 +862,6 @@ public enum ZcashError: Equatable, Error {
case .rustGetNearestRewindHeight: return .rustGetNearestRewindHeight
case .rustGetNextAvailableAddress: return .rustGetNextAvailableAddress
case .rustGetNextAvailableAddressInvalidAddress: return .rustGetNextAvailableAddressInvalidAddress
case .rustGetTransparentBalanceNegativeAccount: return .rustGetTransparentBalanceNegativeAccount
case .rustGetTransparentBalance: return .rustGetTransparentBalance
case .rustGetVerifiedBalance: return .rustGetVerifiedBalance
case .rustGetVerifiedTransparentBalanceNegativeAccount: return .rustGetVerifiedTransparentBalanceNegativeAccount
@ -965,7 +955,6 @@ public enum ZcashError: Equatable, Error {
case .memoBytesInvalidUTF8: return .memoBytesInvalidUTF8
case .checkpointCantLoadFromDisk: return .checkpointCantLoadFromDisk
case .checkpointDecode: return .checkpointDecode
case .derivationToolInvalidAccount: return .derivationToolInvalidAccount
case .unspentTransactionOutputDAOCreateTable: return .unspentTransactionOutputDAOCreateTable
case .unspentTransactionOutputDAOStore: return .unspentTransactionOutputDAOStore
case .unspentTransactionOutputDAOClearAll: return .unspentTransactionOutputDAOClearAll

View File

@ -85,8 +85,6 @@ public enum ZcashErrorCode: String {
case rustGetNextAvailableAddress = "ZRUST0008"
/// Unified address generated by rust layer is invalid when calling ZcashRustBackend.getNextAvailableAddress
case rustGetNextAvailableAddressInvalidAddress = "ZRUST0009"
/// account parameter is lower than 0 when calling ZcashRustBackend.getTransparentBalance
case rustGetTransparentBalanceNegativeAccount = "ZRUST0010"
/// Error from rust layer when calling ZcashRustBackend.getTransparentBalance
case rustGetTransparentBalance = "ZRUST0011"
/// Error from rust layer when calling ZcashRustBackend.getVerifiedBalance
@ -273,8 +271,6 @@ public enum ZcashErrorCode: String {
case checkpointCantLoadFromDisk = "ZCHKP0001"
/// Failed to decode `Checkpoint` object.
case checkpointDecode = "ZCHKP0002"
/// Invalid account when trying to derive a key
case derivationToolInvalidAccount = "ZDRVT0001"
/// Creation of the table for unspent transaction output failed.
case unspentTransactionOutputDAOCreateTable = "ZUTOD0001"
/// SQLite query failed when storing unspent transaction output.

View File

@ -178,10 +178,6 @@ enum ZcashErrorDefinition {
/// Unified address generated by rust layer is invalid when calling ZcashRustBackend.getNextAvailableAddress
// sourcery: code="ZRUST0009"
case rustGetNextAvailableAddressInvalidAddress
/// account parameter is lower than 0 when calling ZcashRustBackend.getTransparentBalance
/// - `account` is account passed to ZcashRustBackend.getTransparentBalance.
// sourcery: code="ZRUST0010"
case rustGetTransparentBalanceNegativeAccount(_ account: Int)
/// Error from rust layer when calling ZcashRustBackend.getTransparentBalance
/// - `account` is account passed to ZcashRustBackend.getTransparentBalance.
/// - `rustError` contains error generated by the rust layer.
@ -538,12 +534,6 @@ enum ZcashErrorDefinition {
// sourcery: code="ZCHKP0002"
case checkpointDecode(_ error: Error)
// MARK: - DerivationTool
/// Invalid account when trying to derive a key
// sourcery: code="ZDRVT0001"
case derivationToolInvalidAccount
// MARK: - UnspentTransactionOutputDAO
/// Creation of the table for unspent transaction output failed.

View File

@ -13,7 +13,7 @@ public protocol StringEncoded {
public struct UnifiedSpendingKey: Equatable, Undescribable {
let network: NetworkType
let bytes: [UInt8]
public let account: UInt32
public let accountIndex: Zip32AccountIndex
}
/// Sapling Extended Spending Key
@ -45,23 +45,23 @@ public struct TransparentAccountPrivKey: Equatable, Undescribable {
/// A ZIP 316 Unified Full Viewing Key.
public struct UnifiedFullViewingKey: Equatable, StringEncoded, Undescribable {
let encoding: String
public let account: UInt32
public let accountIndex: Zip32AccountIndex
public var stringEncoded: String { encoding }
/// Initializes a new UnifiedFullViewingKey (UFVK) from the provided string encoding
/// - Parameters:
/// - parameter encoding: String encoding of unified full viewing key
/// - parameter account: account number of the given UFVK
/// - parameter accountIndex: the ZIP32 account Index of the given UFVK
/// - parameter network: `NetworkType` corresponding to the encoding (Mainnet or Testnet)
/// - Throws: `unifiedFullViewingKeyInvalidInput`when the provided encoding is found to be invalid
public init(encoding: String, account: UInt32, network: NetworkType) throws {
public init(encoding: String, accountIndex: Zip32AccountIndex, network: NetworkType) throws {
guard DerivationTool(networkType: network).isValidUnifiedFullViewingKey(encoding) else {
throw ZcashError.unifiedFullViewingKeyInvalidInput
}
self.encoding = encoding
self.account = account
self.accountIndex = accountIndex
}
}

View File

@ -95,13 +95,13 @@ struct ZcashKeyDerivationBackend: ZcashKeyDerivationBackendWelding {
func deriveUnifiedSpendingKey(
from seed: [UInt8],
accountIndex: Int32
accountIndex: Zip32AccountIndex
) throws -> UnifiedSpendingKey {
let binaryKeyPtr = seed.withUnsafeBufferPointer { seedBufferPtr in
return zcashlc_derive_spending_key(
seedBufferPtr.baseAddress,
UInt(seed.count),
accountIndex,
Int32(accountIndex.index),
networkType.networkId
)
}
@ -137,7 +137,7 @@ struct ZcashKeyDerivationBackend: ZcashKeyDerivationBackendWelding {
throw ZcashError.rustDeriveUnifiedFullViewingKeyInvalidDerivedKey
}
return UnifiedFullViewingKey(validatedEncoding: derived, account: spendingKey.account)
return UnifiedFullViewingKey(validatedEncoding: derived, accountIndex: spendingKey.accountIndex)
}
func getSaplingReceiver(for uAddr: UnifiedAddress) throws -> SaplingAddress {
@ -202,7 +202,7 @@ struct ZcashKeyDerivationBackend: ZcashKeyDerivationBackendWelding {
func deriveArbitraryAccountKey(
contextString: [UInt8],
from seed: [UInt8],
accountIndex: Int32
accountIndex: Zip32AccountIndex
) throws -> [UInt8] {
let boxedSlicePtr = contextString.withUnsafeBufferPointer { contextStringBufferPtr in
seed.withUnsafeBufferPointer { seedBufferPtr in
@ -211,7 +211,7 @@ struct ZcashKeyDerivationBackend: ZcashKeyDerivationBackendWelding {
UInt(contextString.count),
seedBufferPtr.baseAddress,
UInt(seed.count),
accountIndex,
Int32(accountIndex.index),
networkType.networkId
)
}

View File

@ -40,12 +40,12 @@ protocol ZcashKeyDerivationBackendWelding {
/// - Returns: true when the encoded string is a valid UFVK. false in any other case
func isValidUnifiedFullViewingKey(_ ufvk: String) -> Bool
/// Derives and returns a unified spending key from the given seed for the given account ID.
/// Derives and returns a unified spending key from the given seed and ZIP 32 account index.
/// Returns the binary encoding of the spending key. The caller should manage the memory of (and store, if necessary) the returned spending key in a secure fashion.
/// - Parameter seed: a Byte Array with the seed
/// - Parameter accountIndex:account that the key can spend from
/// - Parameter accountIndex: the ZIP 32 index of the account from which the key can spend
/// - Throws: `rustDeriveUnifiedSpendingKey` if rust layer returns error.
func deriveUnifiedSpendingKey(from seed: [UInt8], accountIndex: Int32) throws -> UnifiedSpendingKey
func deriveUnifiedSpendingKey(from seed: [UInt8], accountIndex: Zip32AccountIndex) throws -> UnifiedSpendingKey
/// Derives a `UnifiedFullViewingKey` from a `UnifiedSpendingKey`
/// - Parameter spendingKey: the `UnifiedSpendingKey` to derive from
@ -81,7 +81,6 @@ protocol ZcashKeyDerivationBackendWelding {
/// - Parameter contextString: a globally-unique non-empty sequence of at most 252 bytes that identifies the desired context.
/// - Parameter seed: `[Uint8]` seed bytes
/// - Throws:
/// - `derivationToolInvalidAccount` if the `account.index` is invalid.
/// - some `ZcashError.rust*` error if the derivation fails.
/// - Returns a `[Uint8]`
static func deriveArbitraryWalletKey(
@ -93,14 +92,13 @@ protocol ZcashKeyDerivationBackendWelding {
///
/// - Parameter contextString: a globally-unique non-empty sequence of at most 252 bytes that identifies the desired context.
/// - Parameter seed: `[Uint8]` seed bytes
/// - Parameter accountIndex: `Int32` with the account number
/// - Parameter accountIndex: the ZIP 32 index of the account
/// - Throws:
/// - `derivationToolInvalidAccount` if the `account.index` is invalid.
/// - some `ZcashError.rust*` error if the derivation fails.
/// - Returns a `[Uint8]`
func deriveArbitraryAccountKey(
contextString: [UInt8],
from seed: [UInt8],
accountIndex: Int32
accountIndex: Zip32AccountIndex
) throws -> [UInt8]
}

View File

@ -9,6 +9,8 @@
import Foundation
import libzcashlc
typealias LCZip32Index = Int32
enum RustLogging: String {
/// The logs are completely disabled.
case off
@ -72,7 +74,7 @@ struct ZcashRustBackend: ZcashRustBackendWelding {
}
@DBActor
func listAccounts() async throws -> [Zip32Account] {
func listAccounts() async throws -> [Zip32AccountIndex] {
let accountsPtr = zcashlc_list_accounts(
dbData.0,
dbData.1,
@ -85,11 +87,11 @@ struct ZcashRustBackend: ZcashRustBackendWelding {
defer { zcashlc_free_accounts(accountsPtr) }
var accounts: [Zip32Account] = []
var accounts: [Zip32AccountIndex] = []
for i in (0 ..< Int(accountsPtr.pointee.len)) {
let account = accountsPtr.pointee.ptr.advanced(by: i).pointee
accounts.append(Zip32Account(Int32(account.account_index)))
accounts.append(Zip32AccountIndex(account.account_index))
}
return accounts
@ -148,7 +150,7 @@ struct ZcashRustBackend: ZcashRustBackendWelding {
@DBActor
func proposeTransfer(
account: Zip32Account,
accountIndex: Zip32AccountIndex,
to address: String,
value: Int64,
memo: MemoBytes?
@ -156,7 +158,7 @@ struct ZcashRustBackend: ZcashRustBackendWelding {
let proposal = zcashlc_propose_transfer(
dbData.0,
dbData.1,
account.index,
LCZip32Index(accountIndex.index),
[CChar](address.utf8CString),
value,
memo?.bytes,
@ -179,12 +181,12 @@ struct ZcashRustBackend: ZcashRustBackendWelding {
@DBActor
func proposeTransferFromURI(
_ uri: String,
account: Zip32Account
accountIndex: Zip32AccountIndex
) async throws -> FfiProposal {
let proposal = zcashlc_propose_transfer_from_uri(
dbData.0,
dbData.1,
account.index,
LCZip32Index(accountIndex.index),
[CChar](uri.utf8CString),
networkType.networkId,
minimumConfirmations
@ -219,11 +221,11 @@ struct ZcashRustBackend: ZcashRustBackendWelding {
}
@DBActor
func getCurrentAddress(account: Zip32Account) async throws -> UnifiedAddress {
func getCurrentAddress(accountIndex: Zip32AccountIndex) async throws -> UnifiedAddress {
let addressCStr = zcashlc_get_current_address(
dbData.0,
dbData.1,
account.index,
LCZip32Index(accountIndex.index),
networkType.networkId
)
@ -241,11 +243,11 @@ struct ZcashRustBackend: ZcashRustBackendWelding {
}
@DBActor
func getNextAvailableAddress(account: Zip32Account) async throws -> UnifiedAddress {
func getNextAvailableAddress(accountIndex: Zip32AccountIndex) async throws -> UnifiedAddress {
let addressCStr = zcashlc_get_next_available_address(
dbData.0,
dbData.1,
account.index,
LCZip32Index(accountIndex.index),
networkType.networkId
)
@ -281,22 +283,18 @@ struct ZcashRustBackend: ZcashRustBackendWelding {
}
@DBActor
func getTransparentBalance(account: Zip32Account) async throws -> Int64 {
guard account.index >= 0 else {
throw ZcashError.rustGetTransparentBalanceNegativeAccount(Int(account.index))
}
func getTransparentBalance(accountIndex: Zip32AccountIndex) async throws -> Int64 {
let balance = zcashlc_get_total_transparent_balance_for_account(
dbData.0,
dbData.1,
networkType.networkId,
account.index
LCZip32Index(accountIndex.index)
)
guard balance >= 0 else {
throw ZcashError.rustGetTransparentBalance(
Int(account.index),
lastErrorMessage(fallback: "Error getting Total Transparent balance from account \(account.index)")
Int(accountIndex.index),
lastErrorMessage(fallback: "Error getting Total Transparent balance from accountIndex \(accountIndex.index)")
)
}
@ -304,23 +302,19 @@ struct ZcashRustBackend: ZcashRustBackendWelding {
}
@DBActor
func getVerifiedTransparentBalance(account: Zip32Account) async throws -> Int64 {
guard account.index >= 0 else {
throw ZcashError.rustGetVerifiedTransparentBalanceNegativeAccount(Int(account.index))
}
func getVerifiedTransparentBalance(accountIndex: Zip32AccountIndex) async throws -> Int64 {
let balance = zcashlc_get_verified_transparent_balance_for_account(
dbData.0,
dbData.1,
networkType.networkId,
account.index,
LCZip32Index(accountIndex.index),
minimumShieldingConfirmations
)
guard balance >= 0 else {
throw ZcashError.rustGetVerifiedTransparentBalance(
Int(account.index),
lastErrorMessage(fallback: "Error getting verified transparent balance from account \(account.index)")
Int(accountIndex.index),
lastErrorMessage(fallback: "Error getting verified transparent balance from accountIndex \(accountIndex.index)")
)
}
@ -424,11 +418,11 @@ struct ZcashRustBackend: ZcashRustBackendWelding {
}
@DBActor
func listTransparentReceivers(account: Zip32Account) async throws -> [TransparentAddress] {
func listTransparentReceivers(accountIndex: Zip32AccountIndex) async throws -> [TransparentAddress] {
let encodedKeysPtr = zcashlc_list_transparent_receivers(
dbData.0,
dbData.1,
account.index,
LCZip32Index(accountIndex.index),
networkType.networkId
)
@ -747,7 +741,7 @@ struct ZcashRustBackend: ZcashRustBackendWelding {
@DBActor
func proposeShielding(
account: Zip32Account,
accountIndex: Zip32AccountIndex,
memo: MemoBytes?,
shieldingThreshold: Zatoshi,
transparentReceiver: String?
@ -755,7 +749,7 @@ struct ZcashRustBackend: ZcashRustBackendWelding {
let proposal = zcashlc_propose_shielding(
dbData.0,
dbData.1,
account.index,
LCZip32Index(accountIndex.index),
memo?.bytes,
UInt64(shieldingThreshold.amount),
transparentReceiver.map { [CChar]($0.utf8CString) },
@ -963,7 +957,7 @@ extension FFIBinaryKey {
bytes: self.encoding.toByteArray(
length: Int(self.encoding_len)
),
account: self.account_id
accountIndex: Zip32AccountIndex(self.account_id)
)
}
}

View File

@ -33,8 +33,8 @@ public enum RewindResult {
}
protocol ZcashRustBackendWelding {
/// Returns a list of the accounts in the wallet.
func listAccounts() async throws -> [Zip32Account]
/// Returns a list of the ZIP 32 indices of accounts in the wallet.
func listAccounts() async throws -> [Zip32AccountIndex]
/// Adds the next available account-level spend authority, given the current set of [ZIP 316]
/// account identifiers known, to the wallet database.
@ -73,14 +73,14 @@ protocol ZcashRustBackendWelding {
/// - Throws:
/// - `rustGetCurrentAddress` if rust layer returns error.
/// - `rustGetCurrentAddressInvalidAddress` if generated unified address isn't valid.
func getCurrentAddress(account: Zip32Account) async throws -> UnifiedAddress
func getCurrentAddress(accountIndex: Zip32AccountIndex) async throws -> UnifiedAddress
/// Returns a newly-generated unified payment address for the specified account, with the next available diversifier.
/// - parameter account: index of the given account
/// - Throws:
/// - `rustGetNextAvailableAddress` if rust layer returns error.
/// - `rustGetNextAvailableAddressInvalidAddress` if generated unified address isn't valid.
func getNextAvailableAddress(account: Zip32Account) async throws -> UnifiedAddress
func getNextAvailableAddress(accountIndex: Zip32AccountIndex) async throws -> UnifiedAddress
/// Get memo from note.
/// - parameter txId: ID of transaction containing the note
@ -93,7 +93,7 @@ protocol ZcashRustBackendWelding {
/// - Throws:
/// - `rustGetTransparentBalanceNegativeAccount` if `account` is < 0.
/// - `rustGetTransparentBalance` if rust layer returns error.
func getTransparentBalance(account: Zip32Account) async throws -> Int64
func getTransparentBalance(accountIndex: Zip32AccountIndex) async throws -> Int64
/// Initializes the data db. This will performs any migrations needed on the sqlite file
/// provided. Some migrations might need that callers provide the seed bytes.
@ -110,14 +110,14 @@ protocol ZcashRustBackendWelding {
/// - Throws:
/// - `rustListTransparentReceivers` if rust layer returns error.
/// - `rustListTransparentReceiversInvalidAddress` if transarent received generated by rust is invalid.
func listTransparentReceivers(account: Zip32Account) async throws -> [TransparentAddress]
func listTransparentReceivers(accountIndex: Zip32AccountIndex) async throws -> [TransparentAddress]
/// Get the verified cached transparent balance for the given account
/// - parameter account: account index to query the balance for.
/// - Throws:
/// - `rustGetVerifiedTransparentBalanceNegativeAccount` if `account` is < 0.
/// - `rustGetVerifiedTransparentBalance` if rust layer returns error.
func getVerifiedTransparentBalance(account: Zip32Account) async throws -> Int64
func getVerifiedTransparentBalance(accountIndex: Zip32AccountIndex) async throws -> Int64
/// Resets the state of the database to only contain block and transaction information up to the given height. clears up all derived data as well
/// - parameter height: height to rewind to.
@ -215,7 +215,7 @@ protocol ZcashRustBackendWelding {
/// - Parameter memo: the `MemoBytes` for this transaction. pass `nil` when sending to transparent receivers
/// - Throws: `rustCreateToAddress`.
func proposeTransfer(
account: Zip32Account,
accountIndex: Zip32AccountIndex,
to address: String,
value: Int64,
memo: MemoBytes?
@ -233,7 +233,7 @@ protocol ZcashRustBackendWelding {
/// - Throws: `rustCreateToAddress`.
func proposeTransferFromURI(
_ uri: String,
account: Zip32Account
accountIndex: Zip32AccountIndex
) async throws -> FfiProposal
/// Constructs a transaction proposal to shield all found UTXOs in data db for the given account,
@ -251,7 +251,7 @@ protocol ZcashRustBackendWelding {
/// to shield.
/// - Throws: `rustShieldFunds` if rust layer returns error.
func proposeShielding(
account: Zip32Account,
accountIndex: Zip32AccountIndex,
memo: MemoBytes?,
shieldingThreshold: Zatoshi,
transparentReceiver: String?

View File

@ -144,23 +144,23 @@ public protocol Synchronizer: AnyObject {
func stop()
/// Gets the sapling shielded address for the given account.
/// - Parameter account: the account whose address is of interest. By default, the first account is used.
/// - Parameter accountIndex: the ZIP 32 index of the account whose address is of interest.
/// - Returns the address or nil if account index is incorrect
func getSaplingAddress(account: Zip32Account) async throws -> SaplingAddress
func getSaplingAddress(accountIndex: Zip32AccountIndex) async throws -> SaplingAddress
/// Gets the unified address for the given account.
/// - Parameter account: the account whose address is of interest. By default, the first account is used.
/// - Parameter accountIndex: the ZIP 32 index of the account whose address is of interest.
/// - Returns the address or nil if account index is incorrect
func getUnifiedAddress(account: Zip32Account) async throws -> UnifiedAddress
func getUnifiedAddress(accountIndex: Zip32AccountIndex) async throws -> UnifiedAddress
/// Gets the transparent address for the given account.
/// - Parameter account: the account whose address is of interest. By default, the first account is used.
/// - Parameter accountIndex: the ZIP 32 index of the account whose address is of interest. By default, the first account is used.
/// - Returns the address or nil if account index is incorrect
func getTransparentAddress(account: Zip32Account) async throws -> TransparentAddress
func getTransparentAddress(accountIndex: Zip32AccountIndex) async throws -> TransparentAddress
/// Creates a proposal for transferring funds to the given recipient.
///
/// - Parameter account: the account from which to transfer funds.
/// - Parameter accountIndex: the ZIP 32 index of the account from which to transfer funds.
/// - Parameter recipient: the recipient's address.
/// - Parameter amount: the amount to send in Zatoshi.
/// - Parameter memo: an optional memo to include as part of the proposal's transactions. Use `nil` when sending to transparent receivers otherwise the function will throw an error.
@ -168,7 +168,7 @@ public protocol Synchronizer: AnyObject {
/// If `prepare()` hasn't already been called since creation of the synchronizer instance or since the last wipe then this method throws
/// `SynchronizerErrors.notPrepared`.
func proposeTransfer(
account: Zip32Account,
accountIndex: Zip32AccountIndex,
recipient: Recipient,
amount: Zatoshi,
memo: Memo?
@ -176,7 +176,7 @@ public protocol Synchronizer: AnyObject {
/// Creates a proposal for shielding any transparent funds received by the given account.
///
/// - Parameter account: the account for which to shield funds.
/// - Parameter accountIndex: the ZIP 32 index of the account for which to shield funds.
/// - Parameter shieldingThreshold: the minimum transparent balance required before a proposal will be created.
/// - Parameter memo: an optional memo to include as part of the proposal's transactions.
/// - Parameter transparentReceiver: a specific transparent receiver within the account
@ -190,7 +190,7 @@ public protocol Synchronizer: AnyObject {
/// If `prepare()` hasn't already been called since creation of the synchronizer instance or since the last wipe then this method throws
/// `SynchronizerErrors.notPrepared`.
func proposeShielding(
account: Zip32Account,
accountIndex: Zip32AccountIndex,
shieldingThreshold: Zatoshi,
memo: Memo,
transparentReceiver: TransparentAddress?
@ -228,15 +228,15 @@ public protocol Synchronizer: AnyObject {
memo: Memo?
) async throws -> ZcashTransaction.Overview
/// Attempts to propose fulfilling a [ZIP-321](https://zips.z.cash/zip-0321) payment URI using the given `account.index`
/// Attempts to propose fulfilling a [ZIP-321](https://zips.z.cash/zip-0321) payment URI by spending from the ZIP 32 account with the given index.
/// - Parameter uri: a valid ZIP-321 payment URI
/// - Parameter account: the account index that allows spends to occur.
/// - Parameter accountIndex: the ZIP 32 index of the account providing spend authority.
///
/// - NOTE: If `prepare()` hasn't already been called since creating of synchronizer instance or since the last wipe then this method throws
/// `SynchronizerErrors.notPrepared`.
func proposefulfillingPaymentURI(
_ uri: String,
account: Zip32Account
accountIndex: Zip32AccountIndex
) async throws -> Proposal
/// Shields transparent funds from the given private key into the best shielded pool of the account associated to the given `UnifiedSpendingKey`.
@ -310,7 +310,7 @@ public protocol Synchronizer: AnyObject {
/// Account balances from the given account index
/// - Parameter account: the index of the account
/// - Returns: `AccountBalance`, struct that holds sapling and unshielded balances or `nil` when no account is associated with `account.index`
func getAccountBalance(account: Zip32Account) async throws -> AccountBalance?
func getAccountBalance(accountIndex: Zip32AccountIndex) async throws -> AccountBalance?
/// Fetches the latest ZEC-USD exchange rate and updates `exchangeRateUSDSubject`.
func refreshExchangeRateUSD()

View File

@ -52,38 +52,38 @@ extension ClosureSDKSynchronizer: ClosureSynchronizer {
synchronizer.stop()
}
public func getSaplingAddress(account: Zip32Account, completion: @escaping (Result<SaplingAddress, Error>) -> Void) {
public func getSaplingAddress(accountIndex: Zip32AccountIndex, completion: @escaping (Result<SaplingAddress, Error>) -> Void) {
AsyncToClosureGateway.executeThrowingAction(completion) {
try await self.synchronizer.getSaplingAddress(account: account)
try await self.synchronizer.getSaplingAddress(accountIndex: accountIndex)
}
}
public func getUnifiedAddress(account: Zip32Account, completion: @escaping (Result<UnifiedAddress, Error>) -> Void) {
public func getUnifiedAddress(accountIndex: Zip32AccountIndex, completion: @escaping (Result<UnifiedAddress, Error>) -> Void) {
AsyncToClosureGateway.executeThrowingAction(completion) {
try await self.synchronizer.getUnifiedAddress(account: account)
try await self.synchronizer.getUnifiedAddress(accountIndex: accountIndex)
}
}
public func getTransparentAddress(account: Zip32Account, completion: @escaping (Result<TransparentAddress, Error>) -> Void) {
public func getTransparentAddress(accountIndex: Zip32AccountIndex, completion: @escaping (Result<TransparentAddress, Error>) -> Void) {
AsyncToClosureGateway.executeThrowingAction(completion) {
try await self.synchronizer.getTransparentAddress(account: account)
try await self.synchronizer.getTransparentAddress(accountIndex: accountIndex)
}
}
public func proposeTransfer(
account: Zip32Account,
accountIndex: Zip32AccountIndex,
recipient: Recipient,
amount: Zatoshi,
memo: Memo?,
completion: @escaping (Result<Proposal, Error>) -> Void
) {
AsyncToClosureGateway.executeThrowingAction(completion) {
try await self.synchronizer.proposeTransfer(account: account, recipient: recipient, amount: amount, memo: memo)
try await self.synchronizer.proposeTransfer(accountIndex: accountIndex, recipient: recipient, amount: amount, memo: memo)
}
}
public func proposeShielding(
account: Zip32Account,
accountIndex: Zip32AccountIndex,
shieldingThreshold: Zatoshi,
memo: Memo,
transparentReceiver: TransparentAddress? = nil,
@ -91,7 +91,7 @@ extension ClosureSDKSynchronizer: ClosureSynchronizer {
) {
AsyncToClosureGateway.executeThrowingAction(completion) {
try await self.synchronizer.proposeShielding(
account: account,
accountIndex: accountIndex,
shieldingThreshold: shieldingThreshold,
memo: memo,
transparentReceiver: transparentReceiver
@ -188,9 +188,9 @@ extension ClosureSDKSynchronizer: ClosureSynchronizer {
}
}
public func getAccountBalance(account: Zip32Account, completion: @escaping (Result<AccountBalance?, Error>) -> Void) {
public func getAccountBalance(accountIndex: Zip32AccountIndex, completion: @escaping (Result<AccountBalance?, Error>) -> Void) {
AsyncToClosureGateway.executeThrowingAction(completion) {
try await self.synchronizer.getAccountBalance(account: account)
try await self.synchronizer.getAccountBalance(accountIndex: accountIndex)
}
}

View File

@ -51,56 +51,56 @@ extension CombineSDKSynchronizer: CombineSynchronizer {
synchronizer.stop()
}
public func getSaplingAddress(account: Zip32Account) -> SinglePublisher<SaplingAddress, Error> {
public func getSaplingAddress(accountIndex: Zip32AccountIndex) -> SinglePublisher<SaplingAddress, Error> {
AsyncToCombineGateway.executeThrowingAction() {
try await self.synchronizer.getSaplingAddress(account: account)
try await self.synchronizer.getSaplingAddress(accountIndex: accountIndex)
}
}
public func getUnifiedAddress(account: Zip32Account) -> SinglePublisher<UnifiedAddress, Error> {
public func getUnifiedAddress(accountIndex: Zip32AccountIndex) -> SinglePublisher<UnifiedAddress, Error> {
AsyncToCombineGateway.executeThrowingAction() {
try await self.synchronizer.getUnifiedAddress(account: account)
try await self.synchronizer.getUnifiedAddress(accountIndex: accountIndex)
}
}
public func getTransparentAddress(account: Zip32Account) -> SinglePublisher<TransparentAddress, Error> {
public func getTransparentAddress(accountIndex: Zip32AccountIndex) -> SinglePublisher<TransparentAddress, Error> {
AsyncToCombineGateway.executeThrowingAction() {
try await self.synchronizer.getTransparentAddress(account: account)
try await self.synchronizer.getTransparentAddress(accountIndex: accountIndex)
}
}
public func proposeTransfer(
account: Zip32Account,
accountIndex: Zip32AccountIndex,
recipient: Recipient,
amount: Zatoshi,
memo: Memo?
) -> SinglePublisher<Proposal, Error> {
AsyncToCombineGateway.executeThrowingAction() {
try await self.synchronizer.proposeTransfer(account: account, recipient: recipient, amount: amount, memo: memo)
try await self.synchronizer.proposeTransfer(accountIndex: accountIndex, recipient: recipient, amount: amount, memo: memo)
}
}
public func proposefulfillingPaymentURI(
_ uri: String,
account: Zip32Account
accountIndex: Zip32AccountIndex
) -> SinglePublisher<Proposal, Error> {
AsyncToCombineGateway.executeThrowingAction() {
try await self.synchronizer.proposefulfillingPaymentURI(
uri,
account: account
accountIndex: accountIndex
)
}
}
public func proposeShielding(
account: Zip32Account,
accountIndex: Zip32AccountIndex,
shieldingThreshold: Zatoshi,
memo: Memo,
transparentReceiver: TransparentAddress? = nil
) -> SinglePublisher<Proposal?, Error> {
AsyncToCombineGateway.executeThrowingAction() {
try await self.synchronizer.proposeShielding(
account: account,
accountIndex: accountIndex,
shieldingThreshold: shieldingThreshold,
memo: memo,
transparentReceiver: transparentReceiver
@ -190,9 +190,9 @@ extension CombineSDKSynchronizer: CombineSynchronizer {
}
}
public func getAccountBalance(account: Zip32Account) -> SinglePublisher<AccountBalance?, Error> {
public func getAccountBalance(accountIndex: Zip32AccountIndex) -> SinglePublisher<AccountBalance?, Error> {
AsyncToCombineGateway.executeThrowingAction() {
try await self.synchronizer.getAccountBalance(account: account)
try await self.synchronizer.getAccountBalance(accountIndex: accountIndex)
}
}

View File

@ -28,6 +28,9 @@ public class SDKSynchronizer: Synchronizer {
let metrics: SDKMetrics
public let logger: Logger
var tor: TorClient?
// TODO: [#1512] Only one instance of hardcoded account index has been removed in deeper levels and moved here, needs to be resolved i 1512
// https://github.com/Electric-Coin-Company/zcash-swift-wallet-sdk/issues/1512
private var accountIndex = Zip32AccountIndex(0)
// Don't read this variable directly. Use `status` instead. And don't update this variable directly use `updateStatus()` methods instead.
private var underlyingStatus: GenericActor<InternalSyncStatus>
@ -265,7 +268,7 @@ public class SDKSynchronizer: Synchronizer {
// MARK: Synchronizer methods
public func proposeTransfer(account: Zip32Account, recipient: Recipient, amount: Zatoshi, memo: Memo?) async throws -> Proposal {
public func proposeTransfer(accountIndex: Zip32AccountIndex, recipient: Recipient, amount: Zatoshi, memo: Memo?) async throws -> Proposal {
try throwIfUnprepared()
if case Recipient.transparent = recipient, memo != nil {
@ -273,7 +276,7 @@ public class SDKSynchronizer: Synchronizer {
}
let proposal = try await transactionEncoder.proposeTransfer(
account: account,
accountIndex: accountIndex,
recipient: recipient.stringEncoded,
amount: amount,
memoBytes: memo?.asMemoBytes()
@ -283,7 +286,7 @@ public class SDKSynchronizer: Synchronizer {
}
public func proposeShielding(
account: Zip32Account,
accountIndex: Zip32AccountIndex,
shieldingThreshold: Zatoshi,
memo: Memo,
transparentReceiver: TransparentAddress? = nil
@ -291,7 +294,7 @@ public class SDKSynchronizer: Synchronizer {
try throwIfUnprepared()
return try await transactionEncoder.proposeShielding(
account: account,
accountIndex: accountIndex,
shieldingThreshold: shieldingThreshold,
memoBytes: memo.asMemoBytes(),
transparentReceiver: transparentReceiver?.stringEncoded
@ -300,13 +303,13 @@ public class SDKSynchronizer: Synchronizer {
public func proposefulfillingPaymentURI(
_ uri: String,
account: Zip32Account
accountIndex: Zip32AccountIndex
) async throws -> Proposal {
do {
try throwIfUnprepared()
return try await transactionEncoder.proposeFulfillingPaymentFromURI(
uri,
account: account
accountIndex: accountIndex
)
} catch ZcashError.rustCreateToAddress(let error) {
throw ZcashError.rustProposeTransferFromURI(error)
@ -394,9 +397,7 @@ public class SDKSynchronizer: Synchronizer {
try throwIfUnprepared()
// let's see if there are funds to shield
let account = Zip32Account(Int32(spendingKey.account))
guard let tBalance = try await self.getAccountBalance(account: account)?.unshielded else {
guard let tBalance = try await self.getAccountBalance(accountIndex: spendingKey.accountIndex)?.unshielded else {
throw ZcashError.synchronizerSpendingKeyDoesNotBelongToTheWallet
}
@ -406,7 +407,7 @@ public class SDKSynchronizer: Synchronizer {
}
guard let proposal = try await transactionEncoder.proposeShielding(
account: account,
accountIndex: spendingKey.accountIndex,
shieldingThreshold: shieldingThreshold,
memoBytes: memo.asMemoBytes(),
transparentReceiver: nil
@ -441,7 +442,7 @@ public class SDKSynchronizer: Synchronizer {
}
let proposal = try await transactionEncoder.proposeTransfer(
account: Zip32Account(Int32(spendingKey.account)),
accountIndex: spendingKey.accountIndex,
recipient: recipient.stringEncoded,
amount: zatoshi,
memoBytes: memo?.asMemoBytes()
@ -510,9 +511,8 @@ public class SDKSynchronizer: Synchronizer {
return try await blockProcessor.refreshUTXOs(tAddress: address, startHeight: height)
}
// TODO: This is hardcoded Zip32Account for index 0, must be updated
public func getAccountBalance(account: Zip32Account = Zip32Account(0)) async throws -> AccountBalance? {
try await initializer.rustBackend.getWalletSummary()?.accountBalances[UInt32(account.index)]
public func getAccountBalance(accountIndex: Zip32AccountIndex) async throws -> AccountBalance? {
try await initializer.rustBackend.getWalletSummary()?.accountBalances[accountIndex.index]
}
/// Fetches the latest ZEC-USD exchange rate.
@ -550,16 +550,16 @@ public class SDKSynchronizer: Synchronizer {
}
}
public func getUnifiedAddress(account: Zip32Account) async throws -> UnifiedAddress {
try await blockProcessor.getUnifiedAddress(account: account)
public func getUnifiedAddress(accountIndex: Zip32AccountIndex) async throws -> UnifiedAddress {
try await blockProcessor.getUnifiedAddress(accountIndex: accountIndex)
}
public func getSaplingAddress(account: Zip32Account) async throws -> SaplingAddress {
try await blockProcessor.getSaplingAddress(account: account)
public func getSaplingAddress(accountIndex: Zip32AccountIndex) async throws -> SaplingAddress {
try await blockProcessor.getSaplingAddress(accountIndex: accountIndex)
}
public func getTransparentAddress(account: Zip32Account) async throws -> TransparentAddress {
try await blockProcessor.getTransparentAddress(account: account)
public func getTransparentAddress(accountIndex: Zip32AccountIndex) async throws -> TransparentAddress {
try await blockProcessor.getTransparentAddress(accountIndex: accountIndex)
}
// MARK: Rewind
@ -923,10 +923,10 @@ public class SDKSynchronizer: Synchronizer {
// MARK: notify state
private func snapshotState(status: InternalSyncStatus) async -> SynchronizerState {
private func snapshotState(status: InternalSyncStatus, accountIndex: Zip32AccountIndex) async -> SynchronizerState {
await SynchronizerState(
syncSessionID: syncSession.value,
accountBalance: try? await getAccountBalance(),
accountBalance: try? await getAccountBalance(accountIndex: accountIndex),
internalSyncStatus: status,
latestBlockHeight: latestBlocksDataProvider.latestBlockHeight
)
@ -951,7 +951,7 @@ public class SDKSynchronizer: Synchronizer {
if SessionTicker.live.isNewSyncSession(oldStatus, newStatus) {
await self.syncSession.newSession(with: self.syncSessionIDGenerator)
}
newState = await snapshotState(status: newStatus)
newState = await snapshotState(status: newStatus, accountIndex: accountIndex)
}
latestState = newState

View File

@ -17,14 +17,13 @@ public protocol KeyValidation {
}
public protocol KeyDeriving {
/// Given the seed bytes tand the account index, return the UnifiedSpendingKey
/// Given the seed bytes and ZIP 32 account index, return the corresponding UnifiedSpendingKey.
/// - Parameter seed: `[Uint8]` seed bytes
/// - Parameter accountIndex: `Int32` with the account number
/// - Parameter accountIndex: the ZIP 32 index of the account
/// - Throws:
/// - `derivationToolInvalidAccount` if the `accountIndex` is invalid.
/// - some `ZcashError.rust*` error if the derivation fails.
/// - Returns a `UnifiedSpendingKey`
func deriveUnifiedSpendingKey(seed: [UInt8], accountIndex: Int32) throws -> UnifiedSpendingKey
func deriveUnifiedSpendingKey(seed: [UInt8], accountIndex: Zip32AccountIndex) throws -> UnifiedSpendingKey
/// Given a spending key, return the associated viewing key.
/// - Parameter spendingKey: the `UnifiedSpendingKey` from which to derive the `UnifiedFullViewingKey` from.
@ -59,7 +58,6 @@ public protocol KeyDeriving {
/// - Parameter contextString: a globally-unique non-empty sequence of at most 252 bytes that identifies the desired context.
/// - Parameter seed: `[Uint8]` seed bytes
/// - Throws:
/// - `derivationToolInvalidAccount` if the `accountIndex` is invalid.
/// - some `ZcashError.rust*` error if the derivation fails.
/// - Returns a `[Uint8]`
static func deriveArbitraryWalletKey(contextString: [UInt8], seed: [UInt8]) throws -> [UInt8]
@ -68,12 +66,11 @@ public protocol KeyDeriving {
///
/// - Parameter contextString: a globally-unique non-empty sequence of at most 252 bytes that identifies the desired context.
/// - Parameter seed: `[Uint8]` seed bytes
/// - Parameter accountIndex: `Int32` with the account number
/// - Parameter accountIndex: the ZIP 32 index of the account
/// - Throws:
/// - `derivationToolInvalidAccount` if the `accountIndex` is invalid.
/// - some `ZcashError.rust*` error if the derivation fails.
/// - Returns a `[Uint8]`
func deriveArbitraryAccountKey(contextString: [UInt8], seed: [UInt8], accountIndex: Int32) throws -> [UInt8]
func deriveArbitraryAccountKey(contextString: [UInt8], seed: [UInt8], accountIndex: Zip32AccountIndex) throws -> [UInt8]
}
public class DerivationTool: KeyDeriving {
@ -104,19 +101,14 @@ public class DerivationTool: KeyDeriving {
/// Given a seed and a number of accounts, return the associated spending keys.
/// - Parameter seed: the seed from which to derive spending keys.
/// - Parameter numberOfAccounts: the number of accounts to use. Multiple accounts are not fully
/// supported so the default value of 1 is recommended.
/// - Parameter accountIndex: the ZIP 32 index of the account
/// - Returns: the spending keys that correspond to the seed, formatted as Strings.
public func deriveUnifiedSpendingKey(seed: [UInt8], accountIndex: Int32) throws -> UnifiedSpendingKey {
guard accountIndex >= 0 else {
throw ZcashError.derivationToolInvalidAccount
}
return try backend.deriveUnifiedSpendingKey(from: seed, accountIndex: accountIndex)
public func deriveUnifiedSpendingKey(seed: [UInt8], accountIndex: Zip32AccountIndex) throws -> UnifiedSpendingKey {
try backend.deriveUnifiedSpendingKey(from: seed, accountIndex: accountIndex)
}
public func receiverTypecodesFromUnifiedAddress(_ address: UnifiedAddress) throws -> [UnifiedAddress.ReceiverTypecodes] {
return try backend.receiverTypecodesOnUnifiedAddress(address.stringEncoded)
try backend.receiverTypecodesOnUnifiedAddress(address.stringEncoded)
.map { UnifiedAddress.ReceiverTypecodes(typecode: $0) }
}
@ -130,28 +122,22 @@ public class DerivationTool: KeyDeriving {
/// - Parameter contextString: a globally-unique non-empty sequence of at most 252 bytes that identifies the desired context.
/// - Parameter seed: `[Uint8]` seed bytes
/// - Throws:
/// - `derivationToolInvalidAccount` if the `account` is invalid.
/// - some `ZcashError.rust*` error if the derivation fails.
/// - Returns a `[Uint8]`
public static func deriveArbitraryWalletKey(contextString: [UInt8], seed: [UInt8]) throws -> [UInt8] {
return try ZcashKeyDerivationBackend.deriveArbitraryWalletKey(contextString: contextString, from: seed)
try ZcashKeyDerivationBackend.deriveArbitraryWalletKey(contextString: contextString, from: seed)
}
/// Derives and returns a ZIP 32 Arbitrary Key from the given seed at the account level.
///
/// - Parameter contextString: a globally-unique non-empty sequence of at most 252 bytes that identifies the desired context.
/// - Parameter seed: `[Uint8]` seed bytes
/// - Parameter accountIndex: `Int32` with the account number
/// - Parameter accountIndex: the ZIP 32 index of the account
/// - Throws:
/// - `derivationToolInvalidAccount` if the `account` is invalid.
/// - some `ZcashError.rust*` error if the derivation fails.
/// - Returns a `[Uint8]`
public func deriveArbitraryAccountKey(contextString: [UInt8], seed: [UInt8], accountIndex: Int32) throws -> [UInt8] {
guard accountIndex >= 0 else {
throw ZcashError.derivationToolInvalidAccount
}
return try backend.deriveArbitraryAccountKey(contextString: contextString, from: seed, accountIndex: accountIndex)
public func deriveArbitraryAccountKey(contextString: [UInt8], seed: [UInt8], accountIndex: Zip32AccountIndex) throws -> [UInt8] {
try backend.deriveArbitraryAccountKey(contextString: contextString, from: seed, accountIndex: accountIndex)
}
}
@ -247,9 +233,9 @@ extension UnifiedFullViewingKey {
/// already validated by another function. only for internal use. Unless you are
/// constructing an address from a primitive function of the FFI, you probably
/// shouldn't be using this.
init(validatedEncoding: String, account: UInt32) {
init(validatedEncoding: String, accountIndex: Zip32AccountIndex) {
self.encoding = validatedEncoding
self.account = account
self.accountIndex = accountIndex
}
}

View File

@ -21,7 +21,7 @@ public enum TransactionEncoderError: Error {
protocol TransactionEncoder {
/// Creates a proposal for transferring funds to the given recipient.
///
/// - Parameter account: the account from which to transfer funds.
/// - Parameter accountIndex: the ZIP 32 index of the account from which to transfer funds.
/// - Parameter recipient: string containing the recipient's address.
/// - Parameter amount: the amount to send in Zatoshi.
/// - Parameter memoBytes: an optional memo to include as part of the proposal's transactions. Use `nil` when sending to transparent receivers otherwise the function will throw an error.
@ -29,7 +29,7 @@ protocol TransactionEncoder {
/// If `prepare()` hasn't already been called since creation of the synchronizer instance or since the last wipe then this method throws
/// `SynchronizerErrors.notPrepared`.
func proposeTransfer(
account: Zip32Account,
accountIndex: Zip32AccountIndex,
recipient: String,
amount: Zatoshi,
memoBytes: MemoBytes?
@ -37,7 +37,7 @@ protocol TransactionEncoder {
/// Creates a proposal for shielding any transparent funds received by the given account.
///
/// - Parameter account: the account for which to shield funds.
/// - Parameter accountIndex: the ZIP 32 index of the account from which to shield funds.
/// - Parameter shieldingThreshold: the minimum transparent balance required before a proposal will be created.
/// - Parameter memoBytes: an optional memo to include as part of the proposal's transactions.
/// - Parameter transparentReceiver: a specific transparent receiver within the account
@ -51,7 +51,7 @@ protocol TransactionEncoder {
/// If `prepare()` hasn't already been called since creation of the synchronizer instance or since the last wipe then this method throws
/// `SynchronizerErrors.notPrepared`.
func proposeShielding(
account: Zip32Account,
accountIndex: Zip32AccountIndex,
shieldingThreshold: Zatoshi,
memoBytes: MemoBytes?,
transparentReceiver: String?
@ -84,7 +84,7 @@ protocol TransactionEncoder {
/// - Some `ZcashError.rust*` if the creation of transaction fails.
func proposeFulfillingPaymentFromURI(
_ uri: String,
account: Zip32Account
accountIndex: Zip32AccountIndex
) async throws -> Proposal
/// submits a transaction to the Zcash peer-to-peer network.

View File

@ -56,13 +56,13 @@ class WalletTransactionEncoder: TransactionEncoder {
}
func proposeTransfer(
account: Zip32Account,
accountIndex: Zip32AccountIndex,
recipient: String,
amount: Zatoshi,
memoBytes: MemoBytes?
) async throws -> Proposal {
let proposal = try await rustBackend.proposeTransfer(
account: account,
accountIndex: accountIndex,
to: recipient,
value: amount.amount,
memo: memoBytes
@ -72,13 +72,13 @@ class WalletTransactionEncoder: TransactionEncoder {
}
func proposeShielding(
account: Zip32Account,
accountIndex: Zip32AccountIndex,
shieldingThreshold: Zatoshi,
memoBytes: MemoBytes?,
transparentReceiver: String? = nil
) async throws -> Proposal? {
guard let proposal = try await rustBackend.proposeShielding(
account: account,
accountIndex: accountIndex,
memo: memoBytes,
shieldingThreshold: shieldingThreshold,
transparentReceiver: transparentReceiver
@ -89,11 +89,11 @@ class WalletTransactionEncoder: TransactionEncoder {
func proposeFulfillingPaymentFromURI(
_ uri: String,
account: Zip32Account
accountIndex: Zip32AccountIndex
) async throws -> Proposal {
let proposal = try await rustBackend.proposeTransferFromURI(
uri,
account: account
accountIndex: accountIndex
)
return Proposal(inner: proposal)
}

View File

@ -113,7 +113,7 @@ class PaymentURIFulfillmentTests: ZcashTestCase {
do {
let proposal = try await coordinator.synchronizer.proposefulfillingPaymentURI(
paymentURI,
account: Account(0)
accountIndex: Zip32AccountIndex(0)
)
let transactions = try await coordinator.synchronizer.createProposedTransactions(
@ -320,7 +320,7 @@ class PaymentURIFulfillmentTests: ZcashTestCase {
do {
_ = try await coordinator.synchronizer.proposefulfillingPaymentURI(
paymentURI,
account: Account(0)
accountIndex: Zip32AccountIndex(0)
)
XCTFail("`fulfillPaymentURI` should have failed")

View File

@ -86,7 +86,7 @@ class ShieldFundsTests: ZcashTestCase {
/// verify that the shielded transactions are confirmed
///
func testShieldFunds() async throws {
let account = Account(0)
let accountIndex = Zip32AccountIndex(0)
// 1. load the dataset
try coordinator.service.useDataset(from: "https://raw.githubusercontent.com/zcash-hackworks/darksidewalletd-test-data/master/shield-funds/1631000.txt")
@ -101,7 +101,7 @@ class ShieldFundsTests: ZcashTestCase {
var initialTotalBalance = Zatoshi(-1)
var initialVerifiedBalance = Zatoshi(-1)
var initialTransparentBalance: Zatoshi = try await coordinator.synchronizer.getAccountBalance(account: account)?.unshielded ?? .zero
var initialTransparentBalance: Zatoshi = try await coordinator.synchronizer.getAccountBalance(accountIndex: accountIndex)?.unshielded ?? .zero
let utxo = try GetAddressUtxosReply(jsonString:
"""
@ -123,8 +123,8 @@ class ShieldFundsTests: ZcashTestCase {
do {
try await coordinator.sync(
completion: { synchronizer in
initialVerifiedBalance = try await synchronizer.getAccountBalance(account: account)?.saplingBalance.spendableValue ?? .zero
initialTotalBalance = try await synchronizer.getAccountBalance(account: account)?.saplingBalance.total() ?? .zero
initialVerifiedBalance = try await synchronizer.getAccountBalance(accountIndex: accountIndex)?.saplingBalance.spendableValue ?? .zero
initialTotalBalance = try await synchronizer.getAccountBalance(accountIndex: accountIndex)?.saplingBalance.total() ?? .zero
preTxExpectation.fulfill()
shouldContinue = true
},
@ -144,7 +144,7 @@ class ShieldFundsTests: ZcashTestCase {
// at this point the balance should be all zeroes for transparent and shielded funds
XCTAssertEqual(initialTotalBalance, Zatoshi.zero)
XCTAssertEqual(initialVerifiedBalance, Zatoshi.zero)
initialTransparentBalance = (try? await coordinator.synchronizer.getAccountBalance(account: account))?.unshielded ?? .zero
initialTransparentBalance = (try? await coordinator.synchronizer.getAccountBalance(accountIndex: accountIndex))?.unshielded ?? .zero
XCTAssertEqual(initialTransparentBalance, .zero)
@ -177,7 +177,7 @@ class ShieldFundsTests: ZcashTestCase {
// at this point the balance should be zero for shielded, then zero verified transparent funds
// and 10000 zatoshi of total (not verified) transparent funds.
let tFundsDetectedBalance = try await coordinator.synchronizer.getAccountBalance(account: account)?.unshielded ?? .zero
let tFundsDetectedBalance = try await coordinator.synchronizer.getAccountBalance(accountIndex: accountIndex)?.unshielded ?? .zero
XCTAssertEqual(tFundsDetectedBalance, Zatoshi(10000))
@ -206,7 +206,7 @@ class ShieldFundsTests: ZcashTestCase {
await fulfillment(of: [tFundsConfirmationSyncExpectation], timeout: 5)
// the transparent funds should be 10000 zatoshis both total and verified
let confirmedTFundsBalance = try await coordinator.synchronizer.getAccountBalance(account: account)?.unshielded ?? .zero
let confirmedTFundsBalance = try await coordinator.synchronizer.getAccountBalance(accountIndex: accountIndex)?.unshielded ?? .zero
XCTAssertEqual(confirmedTFundsBalance, Zatoshi(10000))
@ -237,13 +237,13 @@ class ShieldFundsTests: ZcashTestCase {
guard shouldContinue else { return }
let postShieldingBalance = try await coordinator.synchronizer.getAccountBalance(account: account)?.unshielded ?? .zero
let postShieldingBalance = try await coordinator.synchronizer.getAccountBalance(accountIndex: accountIndex)?.unshielded ?? .zero
// when funds are shielded the UTXOs should be marked as spend and not shown on the balance.
// now balance should be zero shielded, zero transaparent.
// verify that the balance has been marked as spent regardless of confirmation
// FIXME: [#720] this should be zero, https://github.com/zcash/ZcashLightClientKit/issues/720
XCTAssertEqual(postShieldingBalance, Zatoshi(10000))
var expectedBalance = try await coordinator.synchronizer.getAccountBalance()?.saplingBalance.total() ?? .zero
var expectedBalance = try await coordinator.synchronizer.getAccountBalance(accountIndex: accountIndex)?.saplingBalance.total() ?? .zero
XCTAssertEqual(expectedBalance, .zero)
// 10. clear the UTXO from darksidewalletd's cache
@ -290,11 +290,11 @@ class ShieldFundsTests: ZcashTestCase {
// Now it should verify that the balance has been shielded. The resulting balance should be zero
// transparent funds and `10000 - fee` total shielded funds, zero verified shielded funds.
let postShieldingShieldedBalance = try await coordinator.synchronizer.getAccountBalance(account: account)?.unshielded ?? .zero
let postShieldingShieldedBalance = try await coordinator.synchronizer.getAccountBalance(accountIndex: accountIndex)?.unshielded ?? .zero
XCTAssertEqual(postShieldingShieldedBalance, .zero)
expectedBalance = try await coordinator.synchronizer.getAccountBalance()?.saplingBalance.total() ?? .zero
expectedBalance = try await coordinator.synchronizer.getAccountBalance(accountIndex: accountIndex)?.saplingBalance.total() ?? .zero
XCTAssertEqual(expectedBalance, Zatoshi(9000))
// 14. proceed confirm the shielded funds by staging ten more blocks
@ -330,9 +330,9 @@ class ShieldFundsTests: ZcashTestCase {
XCTAssertNotNil(clearedTransaction)
expectedBalance = try await coordinator.synchronizer.getAccountBalance()?.saplingBalance.total() ?? .zero
expectedBalance = try await coordinator.synchronizer.getAccountBalance(accountIndex: accountIndex)?.saplingBalance.total() ?? .zero
XCTAssertEqual(expectedBalance, Zatoshi(9000))
let postShieldingConfirmationShieldedBalance = try await coordinator.synchronizer.getAccountBalance(account: account)?.unshielded ?? .zero
let postShieldingConfirmationShieldedBalance = try await coordinator.synchronizer.getAccountBalance(accountIndex: accountIndex)?.unshielded ?? .zero
XCTAssertEqual(postShieldingConfirmationShieldedBalance, .zero)
}

View File

@ -184,14 +184,14 @@ class ClosureSynchronizerOfflineTests: XCTestCase {
}
func testGetSaplingAddressSucceed() {
synchronizerMock.getSaplingAddressAccountClosure = { account in
XCTAssertEqual(account, Account(3))
synchronizerMock.getSaplingAddressAccountIndexClosure = { accountIndex in
XCTAssertEqual(accountIndex, Zip32AccountIndex(3))
return self.data.saplingAddress
}
let expectation = XCTestExpectation()
synchronizer.getSaplingAddress(account: Account(3)) { result in
synchronizer.getSaplingAddress(accountIndex: Zip32AccountIndex(3)) { accountIndex in
switch result {
case let .success(address):
XCTAssertEqual(address, self.data.saplingAddress)
@ -205,13 +205,13 @@ class ClosureSynchronizerOfflineTests: XCTestCase {
}
func testGetSaplingAddressThrowsError() {
synchronizerMock.getSaplingAddressAccountClosure = { _ in
synchronizerMock.getSaplingAddressAccountIndexClosure = { _ in
throw "Some error"
}
let expectation = XCTestExpectation()
synchronizer.getSaplingAddress(account: Account(3)) { result in
synchronizer.getSaplingAddress(accountIndex: Zip32AccountIndex(3)) { result in
switch result {
case .success:
XCTFail("Error should be thrown.")
@ -224,14 +224,14 @@ class ClosureSynchronizerOfflineTests: XCTestCase {
}
func testGetUnifiedAddressSucceed() {
synchronizerMock.getUnifiedAddressAccountClosure = { account in
XCTAssertEqual(account, Account(3))
synchronizerMock.getUnifiedAddressAccountIndexClosure = { accountIndex in
XCTAssertEqual(accountIndex, Zip32AccountIndex(3))
return self.data.unifiedAddress
}
let expectation = XCTestExpectation()
synchronizer.getUnifiedAddress(account: Account(3)) { result in
synchronizer.getUnifiedAddress(accountIndex: Zip32AccountIndex(3)) { result in
switch result {
case let .success(address):
XCTAssertEqual(address, self.data.unifiedAddress)
@ -245,13 +245,13 @@ class ClosureSynchronizerOfflineTests: XCTestCase {
}
func testGetUnifiedAddressThrowsError() {
synchronizerMock.getUnifiedAddressAccountClosure = { _ in
synchronizerMock.getUnifiedAddressAccountIndexClosure = { _ in
throw "Some error"
}
let expectation = XCTestExpectation()
synchronizer.getUnifiedAddress(account: Account(3)) { result in
synchronizer.getUnifiedAddress(accountIndex: Zip32AccountIndex(3)) { result in
switch result {
case .success:
XCTFail("Error should be thrown.")
@ -264,14 +264,14 @@ class ClosureSynchronizerOfflineTests: XCTestCase {
}
func testGetTransparentAddressSucceed() {
synchronizerMock.getTransparentAddressAccountClosure = { account in
XCTAssertEqual(account, Account(3))
synchronizerMock.getTransparentAddressAccountIndexClosure = { accountIndex in
XCTAssertEqual(accountIndex, Zip32AccountIndex(3))
return self.data.transparentAddress
}
let expectation = XCTestExpectation()
synchronizer.getTransparentAddress(account: Account(3)) { result in
synchronizer.getTransparentAddress(accountIndex: Zip32AccountIndex(3)) { result in
switch result {
case let .success(address):
XCTAssertEqual(address, self.data.transparentAddress)
@ -285,13 +285,13 @@ class ClosureSynchronizerOfflineTests: XCTestCase {
}
func testGetTransparentAddressThrowsError() {
synchronizerMock.getTransparentAddressAccountClosure = { _ in
synchronizerMock.getTransparentAddressAccountIndexClosure = { _ in
throw "Some error"
}
let expectation = XCTestExpectation()
synchronizer.getTransparentAddress(account: Account(3)) { result in
synchronizer.getTransparentAddress(accountIndex: Zip32AccountIndex(3)) { result in
switch result {
case .success:
XCTFail("Error should be thrown.")
@ -640,14 +640,14 @@ class ClosureSynchronizerOfflineTests: XCTestCase {
func testGetTransparentBalanceSucceed() {
let expectedBalance = AccountBalance(saplingBalance: .zero, orchardBalance: .zero, unshielded: Zatoshi(200))
synchronizerMock.getAccountBalanceAccountClosure = { receivedAccount in
XCTAssertEqual(receivedAccount, Account(3))
synchronizerMock.getAccountBalanceAccountIndexClosure = { receivedAccountIndex in
XCTAssertEqual(receivedAccountIndex, Zip32AccountIndex(3))
return expectedBalance
}
let expectation = XCTestExpectation()
synchronizer.getAccountBalance(account: Account(3)) { result in
synchronizer.getAccountBalance(accountIndex: Zip32AccountIndex(3)) { result in
switch result {
case let .success(receivedBalance):
XCTAssertEqual(receivedBalance, expectedBalance)
@ -661,13 +661,13 @@ class ClosureSynchronizerOfflineTests: XCTestCase {
}
func testGetTransparentBalanceThrowsError() {
synchronizerMock.getAccountBalanceAccountClosure = { _ in
synchronizerMock.getAccountBalanceAccountIndexClosure = { _ in
throw "Some error"
}
let expectation = XCTestExpectation()
synchronizer.getAccountBalance(account: Account(3)) { result in
synchronizer.getAccountBalance(accountIndex: Zip32AccountIndex(3)) { result in
switch result {
case .success:
XCTFail("Error should be thrown.")
@ -696,14 +696,14 @@ class ClosureSynchronizerOfflineTests: XCTestCase {
unshielded: .zero
)
synchronizerMock.getAccountBalanceAccountClosure = { receivedAccount in
XCTAssertEqual(receivedAccount, Account(3))
synchronizerMock.getAccountBalanceAccountIndexClosure = { receivedAccountIndex in
XCTAssertEqual(receivedAccountIndex, Zip32AccountIndex(3))
return expectedBalance
}
let expectation = XCTestExpectation()
synchronizer.getAccountBalance(account: Account(3)) { result in
synchronizer.getAccountBalance(accountIndex: Zip32AccountIndex(3)) { result in
switch result {
case let .success(receivedBalance):
XCTAssertEqual(receivedBalance, expectedBalance)
@ -717,13 +717,13 @@ class ClosureSynchronizerOfflineTests: XCTestCase {
}
func testGetShieldedBalanceThrowsError() {
synchronizerMock.getAccountBalanceAccountClosure = { _ in
synchronizerMock.getAccountBalanceAccountIndexClosure = { _ in
throw "Some error"
}
let expectation = XCTestExpectation()
synchronizer.getAccountBalance(account: Account(3)) { result in
synchronizer.getAccountBalance(accountIndex: Zip32AccountIndex(3)) { result in
switch result {
case .success:
XCTFail("Error should be thrown.")
@ -752,14 +752,14 @@ class ClosureSynchronizerOfflineTests: XCTestCase {
unshielded: .zero
)
synchronizerMock.getAccountBalanceAccountClosure = { receivedAccount in
XCTAssertEqual(receivedAccount, Account(3))
synchronizerMock.getAccountBalanceAccountIndexClosure = { receivedAccountIndex in
XCTAssertEqual(receivedAccountIndex, Zip32AccountIndex(3))
return expectedBalance
}
let expectation = XCTestExpectation()
synchronizer.getAccountBalance(account: Account(3)) { result in
synchronizer.getAccountBalance(accountIndex: Zip32AccountIndex(3)) { result in
switch result {
case let .success(receivedBalance):
XCTAssertEqual(receivedBalance, expectedBalance)
@ -773,13 +773,13 @@ class ClosureSynchronizerOfflineTests: XCTestCase {
}
func testGetShieldedVerifiedBalanceThrowsError() {
synchronizerMock.getAccountBalanceAccountClosure = { _ in
synchronizerMock.getAccountBalanceAccountIndexClosure = { _ in
throw "Some error"
}
let expectation = XCTestExpectation()
synchronizer.getAccountBalance(account: Account(3)) { result in
synchronizer.getAccountBalance(accountIndex: Zip32AccountIndex(3)) { result in
switch result {
case .success:
XCTFail("Error should be thrown.")

View File

@ -67,16 +67,16 @@ class DerivationToolMainnetTests: XCTestCase {
func testDeriveSpendingKeysFromSeed() throws {
let seedBytes = [UInt8](seedData)
let spendingKey = try derivationTool.deriveUnifiedSpendingKey(seed: seedBytes, account: Account(0))
let spendingKey = try derivationTool.deriveUnifiedSpendingKey(seed: seedBytes, accountIndex: Zip32AccountIndex(0))
XCTAssertEqual(expectedSpendingKey, spendingKey)
}
func testDeriveUnifiedSpendingKeyFromSeed() throws {
let account = Account(0)
let accountIndex = Zip32AccountIndex(0)
let seedBytes = [UInt8](seedData)
_ = try derivationTool.deriveUnifiedSpendingKey(seed: seedBytes, account: account)
_ = try derivationTool.deriveUnifiedSpendingKey(seed: seedBytes, accountIndex: accountIndex)
}
func testGetTransparentAddressFromUA() throws {
@ -108,7 +108,7 @@ class DerivationToolMainnetTests: XCTestCase {
let numberOfAccounts: Int = 10
var ufvks: [UnifiedFullViewingKey] = []
for i in 0..<numberOfAccounts {
let spendingKey = try derivationTool.deriveUnifiedSpendingKey(seed: [UInt8](seedData), account: Account(i))
let spendingKey = try derivationTool.deriveUnifiedSpendingKey(seed: [UInt8](seedData), accountIndex: Zip32AccountIndex(UInt32(i)))
let viewingKey = try derivationTool.deriveUnifiedFullViewingKey(from: spendingKey)
ufvks.append(viewingKey)
}
@ -151,7 +151,7 @@ class DerivationToolMainnetTests: XCTestCase {
let contextString = [UInt8]("Zcash test vectors".utf8)
let seed = Data(fromHexEncodedString: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")!.bytes
let expectedKey = Data(fromHexEncodedString: "bf60078362a09234fcbc6bf6c8a87bde9fc73776bf93f37adbcc439a85574a9a")!.bytes
let key = try DerivationTool(networkType: .mainnet).deriveArbitraryAccountKey(contextString: contextString, seed: seed, account: Account(0))
let key = try DerivationTool(networkType: .mainnet).deriveArbitraryAccountKey(contextString: contextString, seed: seed, accountIndex: Zip32AccountIndex(0))
XCTAssertEqual(key, expectedKey)
}
}

View File

@ -1289,19 +1289,21 @@ class SaplingParametersHandlerMock: SaplingParametersHandler {
// MARK: - handleIfNeeded
var handleIfNeededThrowableError: Error?
var handleIfNeededCallsCount = 0
var handleIfNeededCalled: Bool {
return handleIfNeededCallsCount > 0
var handleIfNeededAccountIndexThrowableError: Error?
var handleIfNeededAccountIndexCallsCount = 0
var handleIfNeededAccountIndexCalled: Bool {
return handleIfNeededAccountIndexCallsCount > 0
}
var handleIfNeededClosure: (() async throws -> Void)?
var handleIfNeededAccountIndexReceivedAccountIndex: Zip32AccountIndex?
var handleIfNeededAccountIndexClosure: ((Zip32AccountIndex) async throws -> Void)?
func handleIfNeeded() async throws {
if let error = handleIfNeededThrowableError {
func handleIfNeeded(accountIndex: Zip32AccountIndex) async throws {
if let error = handleIfNeededAccountIndexThrowableError {
throw error
}
handleIfNeededCallsCount += 1
try await handleIfNeededClosure!()
handleIfNeededAccountIndexCallsCount += 1
handleIfNeededAccountIndexReceivedAccountIndex = accountIndex
try await handleIfNeededAccountIndexClosure!(accountIndex)
}
}
@ -1406,121 +1408,121 @@ class SynchronizerMock: Synchronizer {
// MARK: - getSaplingAddress
var getSaplingAddressAccountThrowableError: Error?
var getSaplingAddressAccountCallsCount = 0
var getSaplingAddressAccountCalled: Bool {
return getSaplingAddressAccountCallsCount > 0
var getSaplingAddressAccountIndexThrowableError: Error?
var getSaplingAddressAccountIndexCallsCount = 0
var getSaplingAddressAccountIndexCalled: Bool {
return getSaplingAddressAccountIndexCallsCount > 0
}
var getSaplingAddressAccountReceivedAccount: Account?
var getSaplingAddressAccountReturnValue: SaplingAddress!
var getSaplingAddressAccountClosure: ((Account) async throws -> SaplingAddress)?
var getSaplingAddressAccountIndexReceivedAccountIndex: Zip32AccountIndex?
var getSaplingAddressAccountIndexReturnValue: SaplingAddress!
var getSaplingAddressAccountIndexClosure: ((Zip32AccountIndex) async throws -> SaplingAddress)?
func getSaplingAddress(account: Account) async throws -> SaplingAddress {
if let error = getSaplingAddressAccountThrowableError {
func getSaplingAddress(accountIndex: Zip32AccountIndex) async throws -> SaplingAddress {
if let error = getSaplingAddressAccountIndexThrowableError {
throw error
}
getSaplingAddressAccountCallsCount += 1
getSaplingAddressAccountReceivedAccount = account
if let closure = getSaplingAddressAccountClosure {
return try await closure(account)
getSaplingAddressAccountIndexCallsCount += 1
getSaplingAddressAccountIndexReceivedAccountIndex = accountIndex
if let closure = getSaplingAddressAccountIndexClosure {
return try await closure(accountIndex)
} else {
return getSaplingAddressAccountReturnValue
return getSaplingAddressAccountIndexReturnValue
}
}
// MARK: - getUnifiedAddress
var getUnifiedAddressAccountThrowableError: Error?
var getUnifiedAddressAccountCallsCount = 0
var getUnifiedAddressAccountCalled: Bool {
return getUnifiedAddressAccountCallsCount > 0
var getUnifiedAddressAccountIndexThrowableError: Error?
var getUnifiedAddressAccountIndexCallsCount = 0
var getUnifiedAddressAccountIndexCalled: Bool {
return getUnifiedAddressAccountIndexCallsCount > 0
}
var getUnifiedAddressAccountReceivedAccount: Account?
var getUnifiedAddressAccountReturnValue: UnifiedAddress!
var getUnifiedAddressAccountClosure: ((Account) async throws -> UnifiedAddress)?
var getUnifiedAddressAccountIndexReceivedAccountIndex: Zip32AccountIndex?
var getUnifiedAddressAccountIndexReturnValue: UnifiedAddress!
var getUnifiedAddressAccountIndexClosure: ((Zip32AccountIndex) async throws -> UnifiedAddress)?
func getUnifiedAddress(account: Account) async throws -> UnifiedAddress {
if let error = getUnifiedAddressAccountThrowableError {
func getUnifiedAddress(accountIndex: Zip32AccountIndex) async throws -> UnifiedAddress {
if let error = getUnifiedAddressAccountIndexThrowableError {
throw error
}
getUnifiedAddressAccountCallsCount += 1
getUnifiedAddressAccountReceivedAccount = account
if let closure = getUnifiedAddressAccountClosure {
return try await closure(account)
getUnifiedAddressAccountIndexCallsCount += 1
getUnifiedAddressAccountIndexReceivedAccountIndex = accountIndex
if let closure = getUnifiedAddressAccountIndexClosure {
return try await closure(accountIndex)
} else {
return getUnifiedAddressAccountReturnValue
return getUnifiedAddressAccountIndexReturnValue
}
}
// MARK: - getTransparentAddress
var getTransparentAddressAccountThrowableError: Error?
var getTransparentAddressAccountCallsCount = 0
var getTransparentAddressAccountCalled: Bool {
return getTransparentAddressAccountCallsCount > 0
var getTransparentAddressAccountIndexThrowableError: Error?
var getTransparentAddressAccountIndexCallsCount = 0
var getTransparentAddressAccountIndexCalled: Bool {
return getTransparentAddressAccountIndexCallsCount > 0
}
var getTransparentAddressAccountReceivedAccount: Account?
var getTransparentAddressAccountReturnValue: TransparentAddress!
var getTransparentAddressAccountClosure: ((Account) async throws -> TransparentAddress)?
var getTransparentAddressAccountIndexReceivedAccountIndex: Zip32AccountIndex?
var getTransparentAddressAccountIndexReturnValue: TransparentAddress!
var getTransparentAddressAccountIndexClosure: ((Zip32AccountIndex) async throws -> TransparentAddress)?
func getTransparentAddress(account: Account) async throws -> TransparentAddress {
if let error = getTransparentAddressAccountThrowableError {
func getTransparentAddress(accountIndex: Zip32AccountIndex) async throws -> TransparentAddress {
if let error = getTransparentAddressAccountIndexThrowableError {
throw error
}
getTransparentAddressAccountCallsCount += 1
getTransparentAddressAccountReceivedAccount = account
if let closure = getTransparentAddressAccountClosure {
return try await closure(account)
getTransparentAddressAccountIndexCallsCount += 1
getTransparentAddressAccountIndexReceivedAccountIndex = accountIndex
if let closure = getTransparentAddressAccountIndexClosure {
return try await closure(accountIndex)
} else {
return getTransparentAddressAccountReturnValue
return getTransparentAddressAccountIndexReturnValue
}
}
// MARK: - proposeTransfer
var proposeTransferAccountRecipientAmountMemoThrowableError: Error?
var proposeTransferAccountRecipientAmountMemoCallsCount = 0
var proposeTransferAccountRecipientAmountMemoCalled: Bool {
return proposeTransferAccountRecipientAmountMemoCallsCount > 0
var proposeTransferAccountIndexRecipientAmountMemoThrowableError: Error?
var proposeTransferAccountIndexRecipientAmountMemoCallsCount = 0
var proposeTransferAccountIndexRecipientAmountMemoCalled: Bool {
return proposeTransferAccountIndexRecipientAmountMemoCallsCount > 0
}
var proposeTransferAccountRecipientAmountMemoReceivedArguments: (account: Account, recipient: Recipient, amount: Zatoshi, memo: Memo?)?
var proposeTransferAccountRecipientAmountMemoReturnValue: Proposal!
var proposeTransferAccountRecipientAmountMemoClosure: ((Account, Recipient, Zatoshi, Memo?) async throws -> Proposal)?
var proposeTransferAccountIndexRecipientAmountMemoReceivedArguments: (accountIndex: Zip32AccountIndex, recipient: Recipient, amount: Zatoshi, memo: Memo?)?
var proposeTransferAccountIndexRecipientAmountMemoReturnValue: Proposal!
var proposeTransferAccountIndexRecipientAmountMemoClosure: ((Zip32AccountIndex, Recipient, Zatoshi, Memo?) async throws -> Proposal)?
func proposeTransfer(account: Account, recipient: Recipient, amount: Zatoshi, memo: Memo?) async throws -> Proposal {
if let error = proposeTransferAccountRecipientAmountMemoThrowableError {
func proposeTransfer(accountIndex: Zip32AccountIndex, recipient: Recipient, amount: Zatoshi, memo: Memo?) async throws -> Proposal {
if let error = proposeTransferAccountIndexRecipientAmountMemoThrowableError {
throw error
}
proposeTransferAccountRecipientAmountMemoCallsCount += 1
proposeTransferAccountRecipientAmountMemoReceivedArguments = (account: account, recipient: recipient, amount: amount, memo: memo)
if let closure = proposeTransferAccountRecipientAmountMemoClosure {
return try await closure(account, recipient, amount, memo)
proposeTransferAccountIndexRecipientAmountMemoCallsCount += 1
proposeTransferAccountIndexRecipientAmountMemoReceivedArguments = (accountIndex: accountIndex, recipient: recipient, amount: amount, memo: memo)
if let closure = proposeTransferAccountIndexRecipientAmountMemoClosure {
return try await closure(accountIndex, recipient, amount, memo)
} else {
return proposeTransferAccountRecipientAmountMemoReturnValue
return proposeTransferAccountIndexRecipientAmountMemoReturnValue
}
}
// MARK: - proposeShielding
var proposeShieldingAccountShieldingThresholdMemoTransparentReceiverThrowableError: Error?
var proposeShieldingAccountShieldingThresholdMemoTransparentReceiverCallsCount = 0
var proposeShieldingAccountShieldingThresholdMemoTransparentReceiverCalled: Bool {
return proposeShieldingAccountShieldingThresholdMemoTransparentReceiverCallsCount > 0
var proposeShieldingAccountIndexShieldingThresholdMemoTransparentReceiverThrowableError: Error?
var proposeShieldingAccountIndexShieldingThresholdMemoTransparentReceiverCallsCount = 0
var proposeShieldingAccountIndexShieldingThresholdMemoTransparentReceiverCalled: Bool {
return proposeShieldingAccountIndexShieldingThresholdMemoTransparentReceiverCallsCount > 0
}
var proposeShieldingAccountShieldingThresholdMemoTransparentReceiverReceivedArguments: (account: Account, shieldingThreshold: Zatoshi, memo: Memo, transparentReceiver: TransparentAddress?)?
var proposeShieldingAccountShieldingThresholdMemoTransparentReceiverReturnValue: Proposal?
var proposeShieldingAccountShieldingThresholdMemoTransparentReceiverClosure: ((Account, Zatoshi, Memo, TransparentAddress?) async throws -> Proposal?)?
var proposeShieldingAccountIndexShieldingThresholdMemoTransparentReceiverReceivedArguments: (accountIndex: Zip32AccountIndex, shieldingThreshold: Zatoshi, memo: Memo, transparentReceiver: TransparentAddress?)?
var proposeShieldingAccountIndexShieldingThresholdMemoTransparentReceiverReturnValue: Proposal?
var proposeShieldingAccountIndexShieldingThresholdMemoTransparentReceiverClosure: ((Zip32AccountIndex, Zatoshi, Memo, TransparentAddress?) async throws -> Proposal?)?
func proposeShielding(account: Account, shieldingThreshold: Zatoshi, memo: Memo, transparentReceiver: TransparentAddress?) async throws -> Proposal? {
if let error = proposeShieldingAccountShieldingThresholdMemoTransparentReceiverThrowableError {
func proposeShielding(accountIndex: Zip32AccountIndex, shieldingThreshold: Zatoshi, memo: Memo, transparentReceiver: TransparentAddress?) async throws -> Proposal? {
if let error = proposeShieldingAccountIndexShieldingThresholdMemoTransparentReceiverThrowableError {
throw error
}
proposeShieldingAccountShieldingThresholdMemoTransparentReceiverCallsCount += 1
proposeShieldingAccountShieldingThresholdMemoTransparentReceiverReceivedArguments = (account: account, shieldingThreshold: shieldingThreshold, memo: memo, transparentReceiver: transparentReceiver)
if let closure = proposeShieldingAccountShieldingThresholdMemoTransparentReceiverClosure {
return try await closure(account, shieldingThreshold, memo, transparentReceiver)
proposeShieldingAccountIndexShieldingThresholdMemoTransparentReceiverCallsCount += 1
proposeShieldingAccountIndexShieldingThresholdMemoTransparentReceiverReceivedArguments = (accountIndex: accountIndex, shieldingThreshold: shieldingThreshold, memo: memo, transparentReceiver: transparentReceiver)
if let closure = proposeShieldingAccountIndexShieldingThresholdMemoTransparentReceiverClosure {
return try await closure(accountIndex, shieldingThreshold, memo, transparentReceiver)
} else {
return proposeShieldingAccountShieldingThresholdMemoTransparentReceiverReturnValue
return proposeShieldingAccountIndexShieldingThresholdMemoTransparentReceiverReturnValue
}
}
@ -1574,25 +1576,25 @@ class SynchronizerMock: Synchronizer {
// MARK: - proposefulfillingPaymentURI
var proposefulfillingPaymentURIAccountThrowableError: Error?
var proposefulfillingPaymentURIAccountCallsCount = 0
var proposefulfillingPaymentURIAccountCalled: Bool {
return proposefulfillingPaymentURIAccountCallsCount > 0
var proposefulfillingPaymentURIAccountIndexThrowableError: Error?
var proposefulfillingPaymentURIAccountIndexCallsCount = 0
var proposefulfillingPaymentURIAccountIndexCalled: Bool {
return proposefulfillingPaymentURIAccountIndexCallsCount > 0
}
var proposefulfillingPaymentURIAccountReceivedArguments: (uri: String, account: Account)?
var proposefulfillingPaymentURIAccountReturnValue: Proposal!
var proposefulfillingPaymentURIAccountClosure: ((String, Account) async throws -> Proposal)?
var proposefulfillingPaymentURIAccountIndexReceivedArguments: (uri: String, accountIndex: Zip32AccountIndex)?
var proposefulfillingPaymentURIAccountIndexReturnValue: Proposal!
var proposefulfillingPaymentURIAccountIndexClosure: ((String, Zip32AccountIndex) async throws -> Proposal)?
func proposefulfillingPaymentURI(_ uri: String, account: Account) async throws -> Proposal {
if let error = proposefulfillingPaymentURIAccountThrowableError {
func proposefulfillingPaymentURI(_ uri: String, accountIndex: Zip32AccountIndex) async throws -> Proposal {
if let error = proposefulfillingPaymentURIAccountIndexThrowableError {
throw error
}
proposefulfillingPaymentURIAccountCallsCount += 1
proposefulfillingPaymentURIAccountReceivedArguments = (uri: uri, account: account)
if let closure = proposefulfillingPaymentURIAccountClosure {
return try await closure(uri, account)
proposefulfillingPaymentURIAccountIndexCallsCount += 1
proposefulfillingPaymentURIAccountIndexReceivedArguments = (uri: uri, accountIndex: accountIndex)
if let closure = proposefulfillingPaymentURIAccountIndexClosure {
return try await closure(uri, accountIndex)
} else {
return proposefulfillingPaymentURIAccountReturnValue
return proposefulfillingPaymentURIAccountIndexReturnValue
}
}
@ -1800,25 +1802,25 @@ class SynchronizerMock: Synchronizer {
// MARK: - getAccountBalance
var getAccountBalanceAccountThrowableError: Error?
var getAccountBalanceAccountCallsCount = 0
var getAccountBalanceAccountCalled: Bool {
return getAccountBalanceAccountCallsCount > 0
var getAccountBalanceAccountIndexThrowableError: Error?
var getAccountBalanceAccountIndexCallsCount = 0
var getAccountBalanceAccountIndexCalled: Bool {
return getAccountBalanceAccountIndexCallsCount > 0
}
var getAccountBalanceAccountReceivedAccount: Account?
var getAccountBalanceAccountReturnValue: AccountBalance?
var getAccountBalanceAccountClosure: ((Account) async throws -> AccountBalance?)?
var getAccountBalanceAccountIndexReceivedAccountIndex: Zip32AccountIndex?
var getAccountBalanceAccountIndexReturnValue: AccountBalance?
var getAccountBalanceAccountIndexClosure: ((Zip32AccountIndex) async throws -> AccountBalance?)?
func getAccountBalance(account: Account) async throws -> AccountBalance? {
if let error = getAccountBalanceAccountThrowableError {
func getAccountBalance(accountIndex: Zip32AccountIndex) async throws -> AccountBalance? {
if let error = getAccountBalanceAccountIndexThrowableError {
throw error
}
getAccountBalanceAccountCallsCount += 1
getAccountBalanceAccountReceivedAccount = account
if let closure = getAccountBalanceAccountClosure {
return try await closure(account)
getAccountBalanceAccountIndexCallsCount += 1
getAccountBalanceAccountIndexReceivedAccountIndex = accountIndex
if let closure = getAccountBalanceAccountIndexClosure {
return try await closure(accountIndex)
} else {
return getAccountBalanceAccountReturnValue
return getAccountBalanceAccountIndexReturnValue
}
}
@ -2425,10 +2427,10 @@ class ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
var listAccountsCalled: Bool {
return listAccountsCallsCount > 0
}
var listAccountsReturnValue: [Account]!
var listAccountsClosure: (() async throws -> [Account])?
var listAccountsReturnValue: [Zip32AccountIndex]!
var listAccountsClosure: (() async throws -> [Zip32AccountIndex])?
func listAccounts() async throws -> [Account] {
func listAccounts() async throws -> [Zip32AccountIndex] {
if let error = listAccountsThrowableError {
throw error
}
@ -2509,49 +2511,49 @@ class ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
// MARK: - getCurrentAddress
var getCurrentAddressAccountThrowableError: Error?
var getCurrentAddressAccountCallsCount = 0
var getCurrentAddressAccountCalled: Bool {
return getCurrentAddressAccountCallsCount > 0
var getCurrentAddressAccountIndexThrowableError: Error?
var getCurrentAddressAccountIndexCallsCount = 0
var getCurrentAddressAccountIndexCalled: Bool {
return getCurrentAddressAccountIndexCallsCount > 0
}
var getCurrentAddressAccountReceivedAccount: Account?
var getCurrentAddressAccountReturnValue: UnifiedAddress!
var getCurrentAddressAccountClosure: ((Account) async throws -> UnifiedAddress)?
var getCurrentAddressAccountIndexReceivedAccountIndex: Zip32AccountIndex?
var getCurrentAddressAccountIndexReturnValue: UnifiedAddress!
var getCurrentAddressAccountIndexClosure: ((Zip32AccountIndex) async throws -> UnifiedAddress)?
func getCurrentAddress(account: Account) async throws -> UnifiedAddress {
if let error = getCurrentAddressAccountThrowableError {
func getCurrentAddress(accountIndex: Zip32AccountIndex) async throws -> UnifiedAddress {
if let error = getCurrentAddressAccountIndexThrowableError {
throw error
}
getCurrentAddressAccountCallsCount += 1
getCurrentAddressAccountReceivedAccount = account
if let closure = getCurrentAddressAccountClosure {
return try await closure(account)
getCurrentAddressAccountIndexCallsCount += 1
getCurrentAddressAccountIndexReceivedAccountIndex = accountIndex
if let closure = getCurrentAddressAccountIndexClosure {
return try await closure(accountIndex)
} else {
return getCurrentAddressAccountReturnValue
return getCurrentAddressAccountIndexReturnValue
}
}
// MARK: - getNextAvailableAddress
var getNextAvailableAddressAccountThrowableError: Error?
var getNextAvailableAddressAccountCallsCount = 0
var getNextAvailableAddressAccountCalled: Bool {
return getNextAvailableAddressAccountCallsCount > 0
var getNextAvailableAddressAccountIndexThrowableError: Error?
var getNextAvailableAddressAccountIndexCallsCount = 0
var getNextAvailableAddressAccountIndexCalled: Bool {
return getNextAvailableAddressAccountIndexCallsCount > 0
}
var getNextAvailableAddressAccountReceivedAccount: Account?
var getNextAvailableAddressAccountReturnValue: UnifiedAddress!
var getNextAvailableAddressAccountClosure: ((Account) async throws -> UnifiedAddress)?
var getNextAvailableAddressAccountIndexReceivedAccountIndex: Zip32AccountIndex?
var getNextAvailableAddressAccountIndexReturnValue: UnifiedAddress!
var getNextAvailableAddressAccountIndexClosure: ((Zip32AccountIndex) async throws -> UnifiedAddress)?
func getNextAvailableAddress(account: Account) async throws -> UnifiedAddress {
if let error = getNextAvailableAddressAccountThrowableError {
func getNextAvailableAddress(accountIndex: Zip32AccountIndex) async throws -> UnifiedAddress {
if let error = getNextAvailableAddressAccountIndexThrowableError {
throw error
}
getNextAvailableAddressAccountCallsCount += 1
getNextAvailableAddressAccountReceivedAccount = account
if let closure = getNextAvailableAddressAccountClosure {
return try await closure(account)
getNextAvailableAddressAccountIndexCallsCount += 1
getNextAvailableAddressAccountIndexReceivedAccountIndex = accountIndex
if let closure = getNextAvailableAddressAccountIndexClosure {
return try await closure(accountIndex)
} else {
return getNextAvailableAddressAccountReturnValue
return getNextAvailableAddressAccountIndexReturnValue
}
}
@ -2581,25 +2583,25 @@ class ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
// MARK: - getTransparentBalance
var getTransparentBalanceAccountThrowableError: Error?
var getTransparentBalanceAccountCallsCount = 0
var getTransparentBalanceAccountCalled: Bool {
return getTransparentBalanceAccountCallsCount > 0
var getTransparentBalanceAccountIndexThrowableError: Error?
var getTransparentBalanceAccountIndexCallsCount = 0
var getTransparentBalanceAccountIndexCalled: Bool {
return getTransparentBalanceAccountIndexCallsCount > 0
}
var getTransparentBalanceAccountReceivedAccount: Account?
var getTransparentBalanceAccountReturnValue: Int64!
var getTransparentBalanceAccountClosure: ((Account) async throws -> Int64)?
var getTransparentBalanceAccountIndexReceivedAccountIndex: Zip32AccountIndex?
var getTransparentBalanceAccountIndexReturnValue: Int64!
var getTransparentBalanceAccountIndexClosure: ((Zip32AccountIndex) async throws -> Int64)?
func getTransparentBalance(account: Account) async throws -> Int64 {
if let error = getTransparentBalanceAccountThrowableError {
func getTransparentBalance(accountIndex: Zip32AccountIndex) async throws -> Int64 {
if let error = getTransparentBalanceAccountIndexThrowableError {
throw error
}
getTransparentBalanceAccountCallsCount += 1
getTransparentBalanceAccountReceivedAccount = account
if let closure = getTransparentBalanceAccountClosure {
return try await closure(account)
getTransparentBalanceAccountIndexCallsCount += 1
getTransparentBalanceAccountIndexReceivedAccountIndex = accountIndex
if let closure = getTransparentBalanceAccountIndexClosure {
return try await closure(accountIndex)
} else {
return getTransparentBalanceAccountReturnValue
return getTransparentBalanceAccountIndexReturnValue
}
}
@ -2629,49 +2631,49 @@ class ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
// MARK: - listTransparentReceivers
var listTransparentReceiversAccountThrowableError: Error?
var listTransparentReceiversAccountCallsCount = 0
var listTransparentReceiversAccountCalled: Bool {
return listTransparentReceiversAccountCallsCount > 0
var listTransparentReceiversAccountIndexThrowableError: Error?
var listTransparentReceiversAccountIndexCallsCount = 0
var listTransparentReceiversAccountIndexCalled: Bool {
return listTransparentReceiversAccountIndexCallsCount > 0
}
var listTransparentReceiversAccountReceivedAccount: Account?
var listTransparentReceiversAccountReturnValue: [TransparentAddress]!
var listTransparentReceiversAccountClosure: ((Account) async throws -> [TransparentAddress])?
var listTransparentReceiversAccountIndexReceivedAccountIndex: Zip32AccountIndex?
var listTransparentReceiversAccountIndexReturnValue: [TransparentAddress]!
var listTransparentReceiversAccountIndexClosure: ((Zip32AccountIndex) async throws -> [TransparentAddress])?
func listTransparentReceivers(account: Account) async throws -> [TransparentAddress] {
if let error = listTransparentReceiversAccountThrowableError {
func listTransparentReceivers(accountIndex: Zip32AccountIndex) async throws -> [TransparentAddress] {
if let error = listTransparentReceiversAccountIndexThrowableError {
throw error
}
listTransparentReceiversAccountCallsCount += 1
listTransparentReceiversAccountReceivedAccount = account
if let closure = listTransparentReceiversAccountClosure {
return try await closure(account)
listTransparentReceiversAccountIndexCallsCount += 1
listTransparentReceiversAccountIndexReceivedAccountIndex = accountIndex
if let closure = listTransparentReceiversAccountIndexClosure {
return try await closure(accountIndex)
} else {
return listTransparentReceiversAccountReturnValue
return listTransparentReceiversAccountIndexReturnValue
}
}
// MARK: - getVerifiedTransparentBalance
var getVerifiedTransparentBalanceAccountThrowableError: Error?
var getVerifiedTransparentBalanceAccountCallsCount = 0
var getVerifiedTransparentBalanceAccountCalled: Bool {
return getVerifiedTransparentBalanceAccountCallsCount > 0
var getVerifiedTransparentBalanceAccountIndexThrowableError: Error?
var getVerifiedTransparentBalanceAccountIndexCallsCount = 0
var getVerifiedTransparentBalanceAccountIndexCalled: Bool {
return getVerifiedTransparentBalanceAccountIndexCallsCount > 0
}
var getVerifiedTransparentBalanceAccountReceivedAccount: Account?
var getVerifiedTransparentBalanceAccountReturnValue: Int64!
var getVerifiedTransparentBalanceAccountClosure: ((Account) async throws -> Int64)?
var getVerifiedTransparentBalanceAccountIndexReceivedAccountIndex: Zip32AccountIndex?
var getVerifiedTransparentBalanceAccountIndexReturnValue: Int64!
var getVerifiedTransparentBalanceAccountIndexClosure: ((Zip32AccountIndex) async throws -> Int64)?
func getVerifiedTransparentBalance(account: Account) async throws -> Int64 {
if let error = getVerifiedTransparentBalanceAccountThrowableError {
func getVerifiedTransparentBalance(accountIndex: Zip32AccountIndex) async throws -> Int64 {
if let error = getVerifiedTransparentBalanceAccountIndexThrowableError {
throw error
}
getVerifiedTransparentBalanceAccountCallsCount += 1
getVerifiedTransparentBalanceAccountReceivedAccount = account
if let closure = getVerifiedTransparentBalanceAccountClosure {
return try await closure(account)
getVerifiedTransparentBalanceAccountIndexCallsCount += 1
getVerifiedTransparentBalanceAccountIndexReceivedAccountIndex = accountIndex
if let closure = getVerifiedTransparentBalanceAccountIndexClosure {
return try await closure(accountIndex)
} else {
return getVerifiedTransparentBalanceAccountReturnValue
return getVerifiedTransparentBalanceAccountIndexReturnValue
}
}
@ -2908,73 +2910,73 @@ class ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
// MARK: - proposeTransfer
var proposeTransferAccountToValueMemoThrowableError: Error?
var proposeTransferAccountToValueMemoCallsCount = 0
var proposeTransferAccountToValueMemoCalled: Bool {
return proposeTransferAccountToValueMemoCallsCount > 0
var proposeTransferAccountIndexToValueMemoThrowableError: Error?
var proposeTransferAccountIndexToValueMemoCallsCount = 0
var proposeTransferAccountIndexToValueMemoCalled: Bool {
return proposeTransferAccountIndexToValueMemoCallsCount > 0
}
var proposeTransferAccountToValueMemoReceivedArguments: (account: Account, address: String, value: Int64, memo: MemoBytes?)?
var proposeTransferAccountToValueMemoReturnValue: FfiProposal!
var proposeTransferAccountToValueMemoClosure: ((Account, String, Int64, MemoBytes?) async throws -> FfiProposal)?
var proposeTransferAccountIndexToValueMemoReceivedArguments: (accountIndex: Zip32AccountIndex, address: String, value: Int64, memo: MemoBytes?)?
var proposeTransferAccountIndexToValueMemoReturnValue: FfiProposal!
var proposeTransferAccountIndexToValueMemoClosure: ((Zip32AccountIndex, String, Int64, MemoBytes?) async throws -> FfiProposal)?
func proposeTransfer(account: Account, to address: String, value: Int64, memo: MemoBytes?) async throws -> FfiProposal {
if let error = proposeTransferAccountToValueMemoThrowableError {
func proposeTransfer(accountIndex: Zip32AccountIndex, to address: String, value: Int64, memo: MemoBytes?) async throws -> FfiProposal {
if let error = proposeTransferAccountIndexToValueMemoThrowableError {
throw error
}
proposeTransferAccountToValueMemoCallsCount += 1
proposeTransferAccountToValueMemoReceivedArguments = (account: account, address: address, value: value, memo: memo)
if let closure = proposeTransferAccountToValueMemoClosure {
return try await closure(account, address, value, memo)
proposeTransferAccountIndexToValueMemoCallsCount += 1
proposeTransferAccountIndexToValueMemoReceivedArguments = (accountIndex: accountIndex, address: address, value: value, memo: memo)
if let closure = proposeTransferAccountIndexToValueMemoClosure {
return try await closure(accountIndex, address, value, memo)
} else {
return proposeTransferAccountToValueMemoReturnValue
return proposeTransferAccountIndexToValueMemoReturnValue
}
}
// MARK: - proposeTransferFromURI
var proposeTransferFromURIAccountThrowableError: Error?
var proposeTransferFromURIAccountCallsCount = 0
var proposeTransferFromURIAccountCalled: Bool {
return proposeTransferFromURIAccountCallsCount > 0
var proposeTransferFromURIAccountIndexThrowableError: Error?
var proposeTransferFromURIAccountIndexCallsCount = 0
var proposeTransferFromURIAccountIndexCalled: Bool {
return proposeTransferFromURIAccountIndexCallsCount > 0
}
var proposeTransferFromURIAccountReceivedArguments: (uri: String, account: Account)?
var proposeTransferFromURIAccountReturnValue: FfiProposal!
var proposeTransferFromURIAccountClosure: ((String, Account) async throws -> FfiProposal)?
var proposeTransferFromURIAccountIndexReceivedArguments: (uri: String, accountIndex: Zip32AccountIndex)?
var proposeTransferFromURIAccountIndexReturnValue: FfiProposal!
var proposeTransferFromURIAccountIndexClosure: ((String, Zip32AccountIndex) async throws -> FfiProposal)?
func proposeTransferFromURI(_ uri: String, account: Account) async throws -> FfiProposal {
if let error = proposeTransferFromURIAccountThrowableError {
func proposeTransferFromURI(_ uri: String, accountIndex: Zip32AccountIndex) async throws -> FfiProposal {
if let error = proposeTransferFromURIAccountIndexThrowableError {
throw error
}
proposeTransferFromURIAccountCallsCount += 1
proposeTransferFromURIAccountReceivedArguments = (uri: uri, account: account)
if let closure = proposeTransferFromURIAccountClosure {
return try await closure(uri, account)
proposeTransferFromURIAccountIndexCallsCount += 1
proposeTransferFromURIAccountIndexReceivedArguments = (uri: uri, accountIndex: accountIndex)
if let closure = proposeTransferFromURIAccountIndexClosure {
return try await closure(uri, accountIndex)
} else {
return proposeTransferFromURIAccountReturnValue
return proposeTransferFromURIAccountIndexReturnValue
}
}
// MARK: - proposeShielding
var proposeShieldingAccountMemoShieldingThresholdTransparentReceiverThrowableError: Error?
var proposeShieldingAccountMemoShieldingThresholdTransparentReceiverCallsCount = 0
var proposeShieldingAccountMemoShieldingThresholdTransparentReceiverCalled: Bool {
return proposeShieldingAccountMemoShieldingThresholdTransparentReceiverCallsCount > 0
var proposeShieldingAccountIndexMemoShieldingThresholdTransparentReceiverThrowableError: Error?
var proposeShieldingAccountIndexMemoShieldingThresholdTransparentReceiverCallsCount = 0
var proposeShieldingAccountIndexMemoShieldingThresholdTransparentReceiverCalled: Bool {
return proposeShieldingAccountIndexMemoShieldingThresholdTransparentReceiverCallsCount > 0
}
var proposeShieldingAccountMemoShieldingThresholdTransparentReceiverReceivedArguments: (account: Account, memo: MemoBytes?, shieldingThreshold: Zatoshi, transparentReceiver: String?)?
var proposeShieldingAccountMemoShieldingThresholdTransparentReceiverReturnValue: FfiProposal?
var proposeShieldingAccountMemoShieldingThresholdTransparentReceiverClosure: ((Account, MemoBytes?, Zatoshi, String?) async throws -> FfiProposal?)?
var proposeShieldingAccountIndexMemoShieldingThresholdTransparentReceiverReceivedArguments: (accountIndex: Zip32AccountIndex, memo: MemoBytes?, shieldingThreshold: Zatoshi, transparentReceiver: String?)?
var proposeShieldingAccountIndexMemoShieldingThresholdTransparentReceiverReturnValue: FfiProposal?
var proposeShieldingAccountIndexMemoShieldingThresholdTransparentReceiverClosure: ((Zip32AccountIndex, MemoBytes?, Zatoshi, String?) async throws -> FfiProposal?)?
func proposeShielding(account: Account, memo: MemoBytes?, shieldingThreshold: Zatoshi, transparentReceiver: String?) async throws -> FfiProposal? {
if let error = proposeShieldingAccountMemoShieldingThresholdTransparentReceiverThrowableError {
func proposeShielding(accountIndex: Zip32AccountIndex, memo: MemoBytes?, shieldingThreshold: Zatoshi, transparentReceiver: String?) async throws -> FfiProposal? {
if let error = proposeShieldingAccountIndexMemoShieldingThresholdTransparentReceiverThrowableError {
throw error
}
proposeShieldingAccountMemoShieldingThresholdTransparentReceiverCallsCount += 1
proposeShieldingAccountMemoShieldingThresholdTransparentReceiverReceivedArguments = (account: account, memo: memo, shieldingThreshold: shieldingThreshold, transparentReceiver: transparentReceiver)
if let closure = proposeShieldingAccountMemoShieldingThresholdTransparentReceiverClosure {
return try await closure(account, memo, shieldingThreshold, transparentReceiver)
proposeShieldingAccountIndexMemoShieldingThresholdTransparentReceiverCallsCount += 1
proposeShieldingAccountIndexMemoShieldingThresholdTransparentReceiverReceivedArguments = (accountIndex: accountIndex, memo: memo, shieldingThreshold: shieldingThreshold, transparentReceiver: transparentReceiver)
if let closure = proposeShieldingAccountIndexMemoShieldingThresholdTransparentReceiverClosure {
return try await closure(accountIndex, memo, shieldingThreshold, transparentReceiver)
} else {
return proposeShieldingAccountMemoShieldingThresholdTransparentReceiverReturnValue
return proposeShieldingAccountIndexMemoShieldingThresholdTransparentReceiverReturnValue
}
}

View File

@ -86,7 +86,7 @@ class TestCoordinator {
self.spendingKey = try derivationTool.deriveUnifiedSpendingKey(
seed: Environment.seedBytes,
account: Account(0)
accountIndex: Zip32AccountIndex(0)
)
self.viewingKey = try derivationTool.deriveUnifiedFullViewingKey(from: spendingKey)