ZcashLightClientKit/Sources/ZcashLightClientKit/Rust/ZcashRustBackendWelding.swift

486 lines
22 KiB
Swift
Raw Normal View History

//
// ZcashRustBackendWelding.swift
// ZcashLightClientKit
//
// Created by Francisco Gindre on 12/09/2019.
// Copyright © 2019 Electric Coin Company. All rights reserved.
//
import Foundation
[#461] Adopt a Type-Safe Keys and Addresses API This PR creates data types for Addresses and Keys so that they are not represented by Strings anymore. This avoids mistakenly use the wrong keys because they are all alike for the type system. New Protocols: ============= StringEncoded -> Protocol that makes a type can be expressed in an string-encoded fashion either for UI or Interchange purposes. Undescribable -> A protocol that implements methods that override default decriptions used by debuggers, loggers and event trackers to avoid types conforming to it to be leaked to logs. Deleted Protocols: ================== UnifiedFullViewingKey --> turned into a struct. UnifiedAddress --> turned into a struct new Error Type: ================ ```` enum KeyEncodingError: Error { case invalidEncoding } ```` This error is thrown when an Address or Key type (addresses are public keys in the end) can be decoded from their String representation, typically upon initialization from a User input. New Types: ========= SaplingExtendedSpendingKey -> Type for Sapling Extended Full Viewing Keys this type will be replaced with Unified Spending Keys soon. SaplingExtendedFullViewingKey -> Extended Full Viewing Key for Sapling. Maintains existing funcionality. Will be probably deprecated in favor of UFVK. TransparentAccountPrivKey -> Private key for transparent account. Used only for shielding operations. Note: this will probably be deprecated soon. UnifiedFullViewingKey -> Replaces the protocol that had the same name. TransparentAddress -> Replaces a type alias with a struct SaplingAddress --> Represents a Sapling receiver address. Comonly called zAddress. This address corresponds to the Zcash Sapling shielded pool. Although this it is fully functional, we encourage developers to choose `UnifiedAddress` before Sapling or Transparent ones. UnifiedAddress -> Represents a UA. String-encodable and Equatable. Use of UAs must be favored instead of individual receivers for different pools. This type can't be decomposed into their Receiver types yet. Recipient -> This represents all valid receiver types to be used as inputs for outgoing transactions. ```` public enum Recipient: Equatable, StringEncoded { case transparent(TransparentAddress) case sapling(SaplingAddress) case unified(UnifiedAddress) ```` The wrapped concrete receiver is a valid receiver type. Deleted Type Aliases: ===================== The following aliases were deleted and turned into types ```` public typealias TransparentAddress = String public typealias SaplingShieldedAddress = String ```` Changes to Derivation Tool ========================== DerivationTool has been changed to accomodate this new types and remove Strings whenever possible. Changes to Synchronizer and CompactBlockProcessor ================================================= Accordingly these to components have been modified to accept the new types intead of strings when possible. Changes to Demo App =================== The demo App has been patch to compile and work with the new types. Developers must consider that the use (and abuse) of forced_try and forced unwrapping is a "license" that maintainers are using for the sake of brevity. We consider that clients of this SDK do know how to handle Errors and Optional and it is not the objective of the demo code to show good practices on those matters. Closes #461
2022-08-20 15:10:22 -07:00
enum RustWeldingError: Error {
case genericError(message: String)
case dataDbInitFailed(message: String)
case dataDbNotEmpty
case saplingSpendParametersNotFound
case malformedStringInput
case noConsensusBranchId(height: Int32)
2021-04-02 15:18:16 -07:00
case unableToDeriveKeys
case invalidInput(message: String)
case invalidRewind(suggestedHeight: Int32)
}
[#461] Adopt a Type-Safe Keys and Addresses API This PR creates data types for Addresses and Keys so that they are not represented by Strings anymore. This avoids mistakenly use the wrong keys because they are all alike for the type system. New Protocols: ============= StringEncoded -> Protocol that makes a type can be expressed in an string-encoded fashion either for UI or Interchange purposes. Undescribable -> A protocol that implements methods that override default decriptions used by debuggers, loggers and event trackers to avoid types conforming to it to be leaked to logs. Deleted Protocols: ================== UnifiedFullViewingKey --> turned into a struct. UnifiedAddress --> turned into a struct new Error Type: ================ ```` enum KeyEncodingError: Error { case invalidEncoding } ```` This error is thrown when an Address or Key type (addresses are public keys in the end) can be decoded from their String representation, typically upon initialization from a User input. New Types: ========= SaplingExtendedSpendingKey -> Type for Sapling Extended Full Viewing Keys this type will be replaced with Unified Spending Keys soon. SaplingExtendedFullViewingKey -> Extended Full Viewing Key for Sapling. Maintains existing funcionality. Will be probably deprecated in favor of UFVK. TransparentAccountPrivKey -> Private key for transparent account. Used only for shielding operations. Note: this will probably be deprecated soon. UnifiedFullViewingKey -> Replaces the protocol that had the same name. TransparentAddress -> Replaces a type alias with a struct SaplingAddress --> Represents a Sapling receiver address. Comonly called zAddress. This address corresponds to the Zcash Sapling shielded pool. Although this it is fully functional, we encourage developers to choose `UnifiedAddress` before Sapling or Transparent ones. UnifiedAddress -> Represents a UA. String-encodable and Equatable. Use of UAs must be favored instead of individual receivers for different pools. This type can't be decomposed into their Receiver types yet. Recipient -> This represents all valid receiver types to be used as inputs for outgoing transactions. ```` public enum Recipient: Equatable, StringEncoded { case transparent(TransparentAddress) case sapling(SaplingAddress) case unified(UnifiedAddress) ```` The wrapped concrete receiver is a valid receiver type. Deleted Type Aliases: ===================== The following aliases were deleted and turned into types ```` public typealias TransparentAddress = String public typealias SaplingShieldedAddress = String ```` Changes to Derivation Tool ========================== DerivationTool has been changed to accomodate this new types and remove Strings whenever possible. Changes to Synchronizer and CompactBlockProcessor ================================================= Accordingly these to components have been modified to accept the new types intead of strings when possible. Changes to Demo App =================== The demo App has been patch to compile and work with the new types. Developers must consider that the use (and abuse) of forced_try and forced unwrapping is a "license" that maintainers are using for the sake of brevity. We consider that clients of this SDK do know how to handle Errors and Optional and it is not the objective of the demo code to show good practices on those matters. Closes #461
2022-08-20 15:10:22 -07:00
enum ZcashRustBackendWeldingConstants {
static let validChain: Int32 = -1
}
/// Enumeration of potential return states for database initialization. If `seedRequired`
/// is returned, the caller must re-attempt initialization providing the seed
public enum DbInitResult {
case success
case seedRequired
}
[#461] Adopt a Type-Safe Keys and Addresses API This PR creates data types for Addresses and Keys so that they are not represented by Strings anymore. This avoids mistakenly use the wrong keys because they are all alike for the type system. New Protocols: ============= StringEncoded -> Protocol that makes a type can be expressed in an string-encoded fashion either for UI or Interchange purposes. Undescribable -> A protocol that implements methods that override default decriptions used by debuggers, loggers and event trackers to avoid types conforming to it to be leaked to logs. Deleted Protocols: ================== UnifiedFullViewingKey --> turned into a struct. UnifiedAddress --> turned into a struct new Error Type: ================ ```` enum KeyEncodingError: Error { case invalidEncoding } ```` This error is thrown when an Address or Key type (addresses are public keys in the end) can be decoded from their String representation, typically upon initialization from a User input. New Types: ========= SaplingExtendedSpendingKey -> Type for Sapling Extended Full Viewing Keys this type will be replaced with Unified Spending Keys soon. SaplingExtendedFullViewingKey -> Extended Full Viewing Key for Sapling. Maintains existing funcionality. Will be probably deprecated in favor of UFVK. TransparentAccountPrivKey -> Private key for transparent account. Used only for shielding operations. Note: this will probably be deprecated soon. UnifiedFullViewingKey -> Replaces the protocol that had the same name. TransparentAddress -> Replaces a type alias with a struct SaplingAddress --> Represents a Sapling receiver address. Comonly called zAddress. This address corresponds to the Zcash Sapling shielded pool. Although this it is fully functional, we encourage developers to choose `UnifiedAddress` before Sapling or Transparent ones. UnifiedAddress -> Represents a UA. String-encodable and Equatable. Use of UAs must be favored instead of individual receivers for different pools. This type can't be decomposed into their Receiver types yet. Recipient -> This represents all valid receiver types to be used as inputs for outgoing transactions. ```` public enum Recipient: Equatable, StringEncoded { case transparent(TransparentAddress) case sapling(SaplingAddress) case unified(UnifiedAddress) ```` The wrapped concrete receiver is a valid receiver type. Deleted Type Aliases: ===================== The following aliases were deleted and turned into types ```` public typealias TransparentAddress = String public typealias SaplingShieldedAddress = String ```` Changes to Derivation Tool ========================== DerivationTool has been changed to accomodate this new types and remove Strings whenever possible. Changes to Synchronizer and CompactBlockProcessor ================================================= Accordingly these to components have been modified to accept the new types intead of strings when possible. Changes to Demo App =================== The demo App has been patch to compile and work with the new types. Developers must consider that the use (and abuse) of forced_try and forced unwrapping is a "license" that maintainers are using for the sake of brevity. We consider that clients of this SDK do know how to handle Errors and Optional and it is not the objective of the demo code to show good practices on those matters. Closes #461
2022-08-20 15:10:22 -07:00
protocol ZcashRustBackendWelding {
/// Adds the next available account-level spend authority, given the current set of [ZIP 316]
/// account identifiers known, to the wallet database.
///
/// Returns the newly created [ZIP 316] account identifier, along with the binary encoding of the
/// [`UnifiedSpendingKey`] for the newly created account. The caller should manage the memory of
/// (and store) the returned spending keys in a secure fashion.
///
/// If `seed` was imported from a backup and this method is being used to restore a
/// previous wallet state, you should use this method to add all of the desired
/// accounts before scanning the chain from the seed's birthday height.
///
/// By convention, wallets should only allow a new account to be generated after funds
/// have been received by the currently-available account (in order to enable
/// automated account recovery).
/// - Parameters:
/// - dbData: location of the data db
/// - seed: byte array of the zip32 seed
/// - networkType: network type of this key
/// - Returns: The `UnifiedSpendingKey` structs for the number of accounts created
///
static func createAccount(
dbData: URL,
seed: [UInt8],
networkType: NetworkType
) throws -> UnifiedSpendingKey
/// Creates a transaction to the given address from the given account
/// - Parameter dbData: URL for the Data DB
/// - Parameter usk: `UnifiedSpendingKey` for the account that controls the funds to be spent.
/// - Parameter to: recipient address
/// - Parameter value: transaction amount in Zatoshi
/// - Parameter memo: the `MemoBytes` for this transaction. pass `nil` when sending to transparent receivers
/// - Parameter spendParamsPath: path escaped String for the filesystem locations where the spend parameters are located
/// - Parameter outputParamsPath: path escaped String for the filesystem locations where the output parameters are located
/// - Parameter networkType: network type of this key
static func createToAddress(
dbData: URL,
usk: UnifiedSpendingKey,
to address: String,
value: Int64,
memo: MemoBytes?,
spendParamsPath: String,
outputParamsPath: String,
networkType: NetworkType
) -> Int64 // swiftlint:disable function_parameter_count
/// Scans a transaction for any information that can be decrypted by the accounts in the
/// wallet, and saves it to the wallet.
///
/// - Parameters:
/// - dbData: location of the data db file
/// - tx: the transaction to decrypt
/// - minedHeight: height on which this transaction was mined. this is used to fetch the consensus branch ID.
/// - networkType: network type of this key
/// returns false if fails to decrypt.
static func decryptAndStoreTransaction(
dbData: URL,
txBytes: [UInt8],
minedHeight: Int32,
networkType: NetworkType
) -> Bool
/// Derives and returns a unified spending key from the given seed for the given account ID.
/// 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 index that the key can spend from
/// - Parameter networkType: network type of this key
/// - Throws `.unableToDerive` when there's an error
static func deriveUnifiedSpendingKey(
from seed: [UInt8],
accountIndex: Int32,
networkType: NetworkType
) throws -> UnifiedSpendingKey
/// get the (unverified) balance from the given account
/// - Parameters:
/// - dbData: location of the data db
/// - account: index of the given account
/// - networkType: network type of this key
static func getBalance(
dbData: URL,
account: Int32,
networkType: NetworkType
) -> Int64
/// Returns the most-recently-generated unified payment address for the specified account.
/// - Parameters:
/// - dbData: location of the data db
/// - account: index of the given account
/// - networkType: network type of this key
static func getCurrentAddress(
dbData: URL,
account: Int32,
networkType: NetworkType
) throws -> UnifiedAddress
/// Wallets might need to be rewound because of a reorg, or by user request.
/// There are times where the wallet could get out of sync for many reasons and
/// users might be asked to rescan their wallets in order to fix that. This function
/// returns the nearest height where a rewind is possible. Currently pruning gets rid
/// of sapling witnesses older than 100 blocks. So in order to reconstruct the witness
/// tree that allows to spend notes from the given wallet the rewind can't be more than
/// 100 blocks or back to the oldest unspent note that this wallet contains.
/// - Parameters:
/// - dbData: location of the data db file
/// - height: height you would like to rewind to.
/// - networkType: network type of this key]
/// - Returns: the blockheight of the nearest rewind height.
///
static func getNearestRewindHeight(
dbData: URL,
height: Int32,
networkType: NetworkType
) -> Int32
/// Returns a newly-generated unified payment address for the specified account, with the next available diversifier.
/// - Parameters:
/// - dbData: location of the data db
/// - account: index of the given account
/// - networkType: network type of this key
static func getNextAvailableAddress(
dbData: URL,
account: Int32,
networkType: NetworkType
) throws -> UnifiedAddress
/// get received memo from note
/// - Parameters:
/// - dbData: location of the data db file
/// - idNote: note_id of note where the memo is located
/// - networkType: network type of this key
@available(*, deprecated, message: "This function will be deprecated soon. Use `getReceivedMemo(dbData:idNote:networkType)` instead")
static func getReceivedMemoAsUTF8(
dbData: URL,
idNote: Int64,
networkType: NetworkType
) -> String?
/// get received memo from note
/// - Parameters:
/// - dbData: location of the data db file
/// - idNote: note_id of note where the memo is located
/// - networkType: network type of this key
static func getReceivedMemo(
dbData: URL,
idNote: Int64,
networkType: NetworkType
) -> Memo?
/// Returns the Sapling receiver within the given Unified Address, if any.
/// - Parameter uAddr: a `UnifiedAddress`
/// - Returns a `SaplingAddress` if any
/// - Throws `receiverNotFound` when the receiver is not found. `invalidUnifiedAddress` if the UA provided is not valid
static func getSaplingReceiver(for uAddr: UnifiedAddress) throws -> SaplingAddress?
/// get sent memo from note
/// - Parameters:
/// - dbData: location of the data db file
/// - idNote: note_id of note where the memo is located
/// - networkType: network type of this key
@available(*, deprecated, message: "This function will be deprecated soon. Use `getSentMemo(dbData:idNote:networkType)` instead")
static func getSentMemoAsUTF8(
dbData: URL,
idNote: Int64,
networkType: NetworkType
) -> String?
/// get sent memo from note
/// - Parameters:
/// - dbData: location of the data db file
/// - idNote: note_id of note where the memo is located
/// - networkType: network type of this key
/// - Returns: a `Memo` if any
static func getSentMemo(
dbData: URL,
idNote: Int64,
networkType: NetworkType
) -> Memo?
/// Get the verified cached transparent balance for the given address
/// - Parameters:
/// - dbData: location of the data db file
/// - account; the account index to query
/// - networkType: network type of this key
static func getTransparentBalance(
dbData: URL,
account: Int32,
networkType: NetworkType
) throws -> Int64
/// Returns the transparent receiver within the given Unified Address, if any.
// - Parameter uAddr: a `UnifiedAddress`
/// - Returns a `TransparentAddress` if any
/// - Throws `receiverNotFound` when the receiver is not found. `invalidUnifiedAddress` if the UA provided is not valid
static func getTransparentReceiver(for uAddr: UnifiedAddress) throws -> TransparentAddress?
/// gets the latest error if available. Clear the existing error
/// - Returns a `RustWeldingError` if exists
static func lastError() -> RustWeldingError?
2021-09-17 06:49:58 -07:00
/// gets the latest error message from librustzcash. Does not clear existing error
static func getLastError() -> String?
2021-09-17 06:49:58 -07:00
/// initialize the accounts table from a set of unified full viewing keys
/// - Note: this function should only be used when restoring an existing seed phrase.
/// when creating a new wallet, use `createAccount()` instead
/// - Parameter dbData: location of the data db
/// - Parameter ufvks: an array of UnifiedFullViewingKeys
/// - Parameter networkType: network type of this key
static func initAccountsTable(
dbData: URL,
ufvks: [UnifiedFullViewingKey],
networkType: NetworkType
) throws
[#461] Adopt a Type-Safe Keys and Addresses API This PR creates data types for Addresses and Keys so that they are not represented by Strings anymore. This avoids mistakenly use the wrong keys because they are all alike for the type system. New Protocols: ============= StringEncoded -> Protocol that makes a type can be expressed in an string-encoded fashion either for UI or Interchange purposes. Undescribable -> A protocol that implements methods that override default decriptions used by debuggers, loggers and event trackers to avoid types conforming to it to be leaked to logs. Deleted Protocols: ================== UnifiedFullViewingKey --> turned into a struct. UnifiedAddress --> turned into a struct new Error Type: ================ ```` enum KeyEncodingError: Error { case invalidEncoding } ```` This error is thrown when an Address or Key type (addresses are public keys in the end) can be decoded from their String representation, typically upon initialization from a User input. New Types: ========= SaplingExtendedSpendingKey -> Type for Sapling Extended Full Viewing Keys this type will be replaced with Unified Spending Keys soon. SaplingExtendedFullViewingKey -> Extended Full Viewing Key for Sapling. Maintains existing funcionality. Will be probably deprecated in favor of UFVK. TransparentAccountPrivKey -> Private key for transparent account. Used only for shielding operations. Note: this will probably be deprecated soon. UnifiedFullViewingKey -> Replaces the protocol that had the same name. TransparentAddress -> Replaces a type alias with a struct SaplingAddress --> Represents a Sapling receiver address. Comonly called zAddress. This address corresponds to the Zcash Sapling shielded pool. Although this it is fully functional, we encourage developers to choose `UnifiedAddress` before Sapling or Transparent ones. UnifiedAddress -> Represents a UA. String-encodable and Equatable. Use of UAs must be favored instead of individual receivers for different pools. This type can't be decomposed into their Receiver types yet. Recipient -> This represents all valid receiver types to be used as inputs for outgoing transactions. ```` public enum Recipient: Equatable, StringEncoded { case transparent(TransparentAddress) case sapling(SaplingAddress) case unified(UnifiedAddress) ```` The wrapped concrete receiver is a valid receiver type. Deleted Type Aliases: ===================== The following aliases were deleted and turned into types ```` public typealias TransparentAddress = String public typealias SaplingShieldedAddress = String ```` Changes to Derivation Tool ========================== DerivationTool has been changed to accomodate this new types and remove Strings whenever possible. Changes to Synchronizer and CompactBlockProcessor ================================================= Accordingly these to components have been modified to accept the new types intead of strings when possible. Changes to Demo App =================== The demo App has been patch to compile and work with the new types. Developers must consider that the use (and abuse) of forced_try and forced unwrapping is a "license" that maintainers are using for the sake of brevity. We consider that clients of this SDK do know how to handle Errors and Optional and it is not the objective of the demo code to show good practices on those matters. Closes #461
2022-08-20 15:10:22 -07:00
/// 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.
/// - Parameter dbData: location of the data db sql file
/// - Parameter seed: ZIP-32 compliant seed bytes for this wallet
/// - Parameter networkType: network type of this key
/// - Returns: `DbInitResult.success` if the dataDb was initialized successfully
/// or `DbInitResult.seedRequired` if the operation requires the seed to be passed
/// in order to be completed successfully.
static func initDataDb(
dbData: URL,
seed: [UInt8]?,
networkType: NetworkType
) throws -> DbInitResult
/// Returns the network and address type for the given Zcash address string,
/// if the string represents a valid Zcash address.
static func getAddressMetadata(_ address: String) -> AddressMetadata?
/// Validates the if the given string is a valid Sapling Address
/// - Parameter address: UTF-8 encoded String to validate
/// - Parameter networkType: network type of this key
/// - Returns: true when the address is valid. Returns false in any other case
[#461] Adopt a Type-Safe Keys and Addresses API This PR creates data types for Addresses and Keys so that they are not represented by Strings anymore. This avoids mistakenly use the wrong keys because they are all alike for the type system. New Protocols: ============= StringEncoded -> Protocol that makes a type can be expressed in an string-encoded fashion either for UI or Interchange purposes. Undescribable -> A protocol that implements methods that override default decriptions used by debuggers, loggers and event trackers to avoid types conforming to it to be leaked to logs. Deleted Protocols: ================== UnifiedFullViewingKey --> turned into a struct. UnifiedAddress --> turned into a struct new Error Type: ================ ```` enum KeyEncodingError: Error { case invalidEncoding } ```` This error is thrown when an Address or Key type (addresses are public keys in the end) can be decoded from their String representation, typically upon initialization from a User input. New Types: ========= SaplingExtendedSpendingKey -> Type for Sapling Extended Full Viewing Keys this type will be replaced with Unified Spending Keys soon. SaplingExtendedFullViewingKey -> Extended Full Viewing Key for Sapling. Maintains existing funcionality. Will be probably deprecated in favor of UFVK. TransparentAccountPrivKey -> Private key for transparent account. Used only for shielding operations. Note: this will probably be deprecated soon. UnifiedFullViewingKey -> Replaces the protocol that had the same name. TransparentAddress -> Replaces a type alias with a struct SaplingAddress --> Represents a Sapling receiver address. Comonly called zAddress. This address corresponds to the Zcash Sapling shielded pool. Although this it is fully functional, we encourage developers to choose `UnifiedAddress` before Sapling or Transparent ones. UnifiedAddress -> Represents a UA. String-encodable and Equatable. Use of UAs must be favored instead of individual receivers for different pools. This type can't be decomposed into their Receiver types yet. Recipient -> This represents all valid receiver types to be used as inputs for outgoing transactions. ```` public enum Recipient: Equatable, StringEncoded { case transparent(TransparentAddress) case sapling(SaplingAddress) case unified(UnifiedAddress) ```` The wrapped concrete receiver is a valid receiver type. Deleted Type Aliases: ===================== The following aliases were deleted and turned into types ```` public typealias TransparentAddress = String public typealias SaplingShieldedAddress = String ```` Changes to Derivation Tool ========================== DerivationTool has been changed to accomodate this new types and remove Strings whenever possible. Changes to Synchronizer and CompactBlockProcessor ================================================= Accordingly these to components have been modified to accept the new types intead of strings when possible. Changes to Demo App =================== The demo App has been patch to compile and work with the new types. Developers must consider that the use (and abuse) of forced_try and forced unwrapping is a "license" that maintainers are using for the sake of brevity. We consider that clients of this SDK do know how to handle Errors and Optional and it is not the objective of the demo code to show good practices on those matters. Closes #461
2022-08-20 15:10:22 -07:00
/// - Throws: Error when the provided address belongs to another network
static func isValidSaplingAddress(_ address: String, networkType: NetworkType) -> Bool
/// Validates the if the given string is a valid Sapling Extended Full Viewing Key
/// - Parameter key: UTF-8 encoded String to validate
/// - Parameter networkType: network type of this key
/// - Returns: `true` when the Sapling Extended Full Viewing Key is valid. `false` in any other case
/// - Throws: Error when there's another problem not related to validity of the string in question
static func isValidSaplingExtendedFullViewingKey(_ key: String, networkType: NetworkType) -> Bool
[#461] Adopt a Type-Safe Keys and Addresses API This PR creates data types for Addresses and Keys so that they are not represented by Strings anymore. This avoids mistakenly use the wrong keys because they are all alike for the type system. New Protocols: ============= StringEncoded -> Protocol that makes a type can be expressed in an string-encoded fashion either for UI or Interchange purposes. Undescribable -> A protocol that implements methods that override default decriptions used by debuggers, loggers and event trackers to avoid types conforming to it to be leaked to logs. Deleted Protocols: ================== UnifiedFullViewingKey --> turned into a struct. UnifiedAddress --> turned into a struct new Error Type: ================ ```` enum KeyEncodingError: Error { case invalidEncoding } ```` This error is thrown when an Address or Key type (addresses are public keys in the end) can be decoded from their String representation, typically upon initialization from a User input. New Types: ========= SaplingExtendedSpendingKey -> Type for Sapling Extended Full Viewing Keys this type will be replaced with Unified Spending Keys soon. SaplingExtendedFullViewingKey -> Extended Full Viewing Key for Sapling. Maintains existing funcionality. Will be probably deprecated in favor of UFVK. TransparentAccountPrivKey -> Private key for transparent account. Used only for shielding operations. Note: this will probably be deprecated soon. UnifiedFullViewingKey -> Replaces the protocol that had the same name. TransparentAddress -> Replaces a type alias with a struct SaplingAddress --> Represents a Sapling receiver address. Comonly called zAddress. This address corresponds to the Zcash Sapling shielded pool. Although this it is fully functional, we encourage developers to choose `UnifiedAddress` before Sapling or Transparent ones. UnifiedAddress -> Represents a UA. String-encodable and Equatable. Use of UAs must be favored instead of individual receivers for different pools. This type can't be decomposed into their Receiver types yet. Recipient -> This represents all valid receiver types to be used as inputs for outgoing transactions. ```` public enum Recipient: Equatable, StringEncoded { case transparent(TransparentAddress) case sapling(SaplingAddress) case unified(UnifiedAddress) ```` The wrapped concrete receiver is a valid receiver type. Deleted Type Aliases: ===================== The following aliases were deleted and turned into types ```` public typealias TransparentAddress = String public typealias SaplingShieldedAddress = String ```` Changes to Derivation Tool ========================== DerivationTool has been changed to accomodate this new types and remove Strings whenever possible. Changes to Synchronizer and CompactBlockProcessor ================================================= Accordingly these to components have been modified to accept the new types intead of strings when possible. Changes to Demo App =================== The demo App has been patch to compile and work with the new types. Developers must consider that the use (and abuse) of forced_try and forced unwrapping is a "license" that maintainers are using for the sake of brevity. We consider that clients of this SDK do know how to handle Errors and Optional and it is not the objective of the demo code to show good practices on those matters. Closes #461
2022-08-20 15:10:22 -07:00
/// Validates the if the given string is a valid Sapling Extended Spending Key
[#461] Adopt a Type-Safe Keys and Addresses API This PR creates data types for Addresses and Keys so that they are not represented by Strings anymore. This avoids mistakenly use the wrong keys because they are all alike for the type system. New Protocols: ============= StringEncoded -> Protocol that makes a type can be expressed in an string-encoded fashion either for UI or Interchange purposes. Undescribable -> A protocol that implements methods that override default decriptions used by debuggers, loggers and event trackers to avoid types conforming to it to be leaked to logs. Deleted Protocols: ================== UnifiedFullViewingKey --> turned into a struct. UnifiedAddress --> turned into a struct new Error Type: ================ ```` enum KeyEncodingError: Error { case invalidEncoding } ```` This error is thrown when an Address or Key type (addresses are public keys in the end) can be decoded from their String representation, typically upon initialization from a User input. New Types: ========= SaplingExtendedSpendingKey -> Type for Sapling Extended Full Viewing Keys this type will be replaced with Unified Spending Keys soon. SaplingExtendedFullViewingKey -> Extended Full Viewing Key for Sapling. Maintains existing funcionality. Will be probably deprecated in favor of UFVK. TransparentAccountPrivKey -> Private key for transparent account. Used only for shielding operations. Note: this will probably be deprecated soon. UnifiedFullViewingKey -> Replaces the protocol that had the same name. TransparentAddress -> Replaces a type alias with a struct SaplingAddress --> Represents a Sapling receiver address. Comonly called zAddress. This address corresponds to the Zcash Sapling shielded pool. Although this it is fully functional, we encourage developers to choose `UnifiedAddress` before Sapling or Transparent ones. UnifiedAddress -> Represents a UA. String-encodable and Equatable. Use of UAs must be favored instead of individual receivers for different pools. This type can't be decomposed into their Receiver types yet. Recipient -> This represents all valid receiver types to be used as inputs for outgoing transactions. ```` public enum Recipient: Equatable, StringEncoded { case transparent(TransparentAddress) case sapling(SaplingAddress) case unified(UnifiedAddress) ```` The wrapped concrete receiver is a valid receiver type. Deleted Type Aliases: ===================== The following aliases were deleted and turned into types ```` public typealias TransparentAddress = String public typealias SaplingShieldedAddress = String ```` Changes to Derivation Tool ========================== DerivationTool has been changed to accomodate this new types and remove Strings whenever possible. Changes to Synchronizer and CompactBlockProcessor ================================================= Accordingly these to components have been modified to accept the new types intead of strings when possible. Changes to Demo App =================== The demo App has been patch to compile and work with the new types. Developers must consider that the use (and abuse) of forced_try and forced unwrapping is a "license" that maintainers are using for the sake of brevity. We consider that clients of this SDK do know how to handle Errors and Optional and it is not the objective of the demo code to show good practices on those matters. Closes #461
2022-08-20 15:10:22 -07:00
/// - Returns: `true` when the Sapling Extended Spending Key is valid, false in any other case.
/// - Throws: Error when the key is semantically valid but it belongs to another network
/// - parameter key: String encoded Extendeed Spending Key
/// - parameter networkType: `NetworkType` signaling testnet or mainnet
static func isValidSaplingExtendedSpendingKey(_ key: String, networkType: NetworkType) -> Bool
/// Validates the if the given string is a valid Transparent Address
/// - Parameter address: UTF-8 encoded String to validate
/// - Parameter networkType: network type of this key
/// - Returns: true when the address is valid and transparent. false in any other case
/// - Throws: Error when the provided address belongs to another network
static func isValidTransparentAddress(_ address: String, networkType: NetworkType) -> Bool
/// validates whether a string encoded address is a valid Unified Address.
/// - Parameter address: UTF-8 encoded String to validate
/// - Parameter networkType: network type of this key
/// - Returns: true when the address is valid and transparent. false in any other case
/// - Throws: Error when the provided address belongs to another network
static func isValidUnifiedAddress(_ address: String, networkType: NetworkType) -> Bool
/// verifies that the given string-encoded `UnifiedFullViewingKey` is valid.
/// - Parameter ufvk: UTF-8 encoded String to validate
/// - Parameter networkType: network type of this key
/// - Returns: true when the encoded string is a valid UFVK. false in any other case
/// - Throws: Error when there's another problem not related to validity of the string in question
static func isValidUnifiedFullViewingKey(_ ufvk: String, networkType: NetworkType) -> Bool
/// initialize the blocks table from a given checkpoint (heigh, hash, time, saplingTree and networkType)
/// - Parameters:
/// - dbData: location of the data db
/// - height: represents the block height of the given checkpoint
/// - hash: hash of the merkle tree
/// - time: in milliseconds from reference
/// - saplingTree: hash of the sapling tree
/// - networkType: `NetworkType` signaling testnet or mainnet
2021-09-15 05:21:29 -07:00
static func initBlocksTable(
dbData: URL,
height: Int32,
hash: String,
time: UInt32,
saplingTree: String,
networkType: NetworkType
) throws // swiftlint:disable function_parameter_count
/// Returns a list of the transparent receivers for the diversified unified addresses that have
/// been allocated for the provided account.
/// - Parameters:
/// - dbData: location of the data db
/// - account: index of the given account
/// - networkType: the network type
static func listTransparentReceivers(
dbData: URL,
account: Int32,
networkType: NetworkType
) throws -> [TransparentAddress]
/// get the verified balance from the given account
/// - Parameters:
/// - dbData: location of the data db
/// - account: index of the given account
/// - networkType: the network type
static func getVerifiedBalance(
dbData: URL,
account: Int32,
networkType: NetworkType
) -> Int64
/// Get the verified cached transparent balance for the given account
/// - Parameters:
/// - dbData: location of the data db
/// - account: account index to query the balance for.
/// - networkType: the network type
static func getVerifiedTransparentBalance(
dbData: URL,
account: Int32,
networkType: NetworkType
) throws -> Int64
/// Checks that the scanned blocks in the data database, when combined with the recent
/// `CompactBlock`s in the cache database, form a valid chain.
/// This function is built on the core assumption that the information provided in the
/// cache database is more likely to be accurate than the previously-scanned information.
/// This follows from the design (and trust) assumption that the `lightwalletd` server
/// provides accurate block information as of the time it was requested.
/// - Parameters:
/// - dbCache: location of the cache db file
/// - dbData: location of the data db file
/// - networkType: the network type
/// - Returns:
/// - `-1` if the combined chain is valid.
/// - `upper_bound` if the combined chain is invalid.
/// - `upper_bound` is the height of the highest invalid block (on the assumption that the highest block in the cache database is correct).
/// - `0` if there was an error during validation unrelated to chain validity.
/// - Important: This function does not mutate either of the databases.
static func validateCombinedChain(
dbCache: URL,
dbData: URL,
networkType: NetworkType
) -> Int32
/// 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
/// - Parameters:
/// - dbData: location of the data db file
/// - height: height to rewind to. DON'T PASS ARBITRARY HEIGHT. Use getNearestRewindHeight when unsure
/// - networkType: the network type
static func rewindToHeight(
dbData: URL,
height: Int32,
networkType: NetworkType
) -> Bool
/// Scans new blocks added to the cache for any transactions received by the tracked
/// accounts.
/// This function pays attention only to cached blocks with heights greater than the
/// highest scanned block in `db_data`. Cached blocks with lower heights are not verified
/// against previously-scanned blocks. In particular, this function **assumes** that the
/// caller is handling rollbacks.
/// For brand-new light client databases, this function starts scanning from the Sapling
/// activation height. This height can be fast-forwarded to a more recent block by calling
/// [`initBlocksTable`] before this function.
/// Scanned blocks are required to be height-sequential. If a block is missing from the
/// cache, an error will be signalled.
///
/// - Parameters:
/// - dbCache: location of the compact block cache db
/// - dbData: location of the data db file
/// - limit: scan up to limit blocks. pass 0 to set no limit.
/// - networkType: the network type
/// returns false if fails to scan.
static func scanBlocks(
dbCache: URL,
dbData: URL,
limit: UInt32,
networkType: NetworkType
) -> Bool
/// puts a UTXO into the data db database
/// - Parameters:
/// - dbData: location of the data db file
/// - txid: the txid bytes for the UTXO
/// - index: the index of the UTXO
/// - script: the script of the UTXO
/// - value: the value of the UTXO
/// - height: the mined height for the UTXO
/// - networkType: the network type
/// - Returns: true if the operation succeded or false otherwise
2021-09-17 06:49:58 -07:00
static func putUnspentTransparentOutput(
dbData: URL,
txid: [UInt8],
index: Int,
script: [UInt8],
value: Int64,
height: BlockHeight,
networkType: NetworkType
) throws -> Bool
/// Creates a transaction to shield all found UTXOs in cache db for the account the provided `UnifiedSpendingKey` has spend authority for.
/// - Parameter dbCache: URL for the Cache DB
/// - Parameter dbData: URL for the Data DB
/// - Parameter usk: `UnifiedSpendingKey` that spend transparent funds and where the funds will be shielded to.
/// - Parameter memo: the `Memo` for this transaction
/// - Parameter spendParamsPath: path escaped String for the filesystem locations where the spend parameters are located
/// - Parameter outputParamsPath: path escaped String for the filesystem locations where the output parameters are located
/// - Parameter networkType: the network type
2021-09-15 05:21:29 -07:00
static func shieldFunds(
dbCache: URL,
dbData: URL,
usk: UnifiedSpendingKey,
memo: MemoBytes?,
2021-09-15 05:21:29 -07:00
spendParamsPath: String,
outputParamsPath: String,
networkType: NetworkType
) -> Int64 // swiftlint:disable function_parameter_count
/// Obtains the available receiver typecodes for the given String encoded Unified Address
/// - Parameter address: public key represented as a String
/// - Returns the `[UInt32]` that compose the given UA
/// - Throws `RustWeldingError.invalidInput(message: String)` when the UA is either invalid or malformed
static func receiverTypecodesOnUnifiedAddress(_ address: String) throws -> [UInt32]
/// Gets the consensus branch id for the given height
/// - Parameter height: the height you what to know the branch id for
/// - Parameter networkType: the network type
static func consensusBranchIdFor(
height: Int32,
networkType: NetworkType
) throws -> Int32
/// Derives a `UnifiedFullViewingKey` from a `UnifiedSpendingKey`
/// - Parameter spendingKey: the `UnifiedSpendingKey` to derive from
/// - Parameter networkType: the network type
/// - Throws: `RustWeldingError.unableToDeriveKeys` if the SDK couldn't derive the UFVK.
/// - Returns: the derived `UnifiedFullViewingKey`
static func deriveUnifiedFullViewingKey(
from spendingKey: UnifiedSpendingKey,
networkType: NetworkType
) throws -> UnifiedFullViewingKey
}