ZcashLightClientKit/MIGRATING.md

7.4 KiB

Migrating from previous versions to Unreleased

PendingDb is no longer used. Wallet developers should take care about deleting the database file since the SDK will no longer require it or any of the information stored.

Failed transactions will be treated as "Expired-Unmined" instead. The SDK won't track failures on its own. Wallet developers would have to account for those.

Migrating from previous versions to 0.20.0-beta

The SDKSynchronizer no longer uses NotificationCenter to send notifications. Notifications are replaced with Combine publishers.

stateStream publisher replaces notifications related to SyncStatus changes. These notifications are replaced by stateStream:

  • .synchronizerStarted
  • .synchronizerProgressUpdated
  • .synchronizerStatusWillUpdate
  • .synchronizerSynced
  • .synchronizerStopped
  • .synchronizerDisconnected
  • .synchronizerSyncing
  • .synchronizerEnhancing
  • .synchronizerFetching
  • .synchronizerFailed

eventStream publisher replaces notifications related to transactions and other stuff. These notifications are replaced by eventStream:

  • .synchronizerMinedTransaction
  • .synchronizerFoundTransactions
  • .synchronizerStoredUTXOs
  • .synchronizerConnectionStateChanged

latestState is also new property that can be used to get the latest SDK state in a synchronous way. SDKSynchronizer.status is no longer public. To get SyncStatus either subscribe to stateStream or use latestState.

Migrating from previous versions to 0.18.x

Compact block cache no longer uses a sqlite database. The existing database should be deleted. Initializer now takes an fsBlockDbRootURL which is a URL pointing to a RW directory in the filesystem that will be used to store the cached blocks and the companion database managed internally by the SDK.

Initializer provides a convenience initializer that takes the an optional URL to the cacheDb location to migrate the internal state of the CompactBlockProcessor and delete that database.

    convenience public init(
        cacheDbURL: URL?,
        fsBlockDbRoot: URL,
        dataDbURL: URL,
        pendingDbURL: URL,
        endpoint: LightWalletEndpoint,
        network: ZcashNetwork,
        spendParamsURL: URL,
        outputParamsURL: URL,
        viewingKeys: [UnifiedFullViewingKey],
        walletBirthday: BlockHeight,
        alias: String = "",
        loggerProxy: Logger? = nil
    )

We do not make any efforts to extract the cached blocks in the sqlite cacheDb and storing them on disk. Although this might be the logical step to do, we think such migration as little to gain since a migration function will be a "run once" function with many different scenarios to consider and possibly very error prone. On the other hand, we rather delete the cacheDb altogether and free up that space on the users' devices since we have surveyed that the cacheDb as been growing exponentially taking up many gigabyte of disk space. We forsee that many possible attempts to copy information from one cache to another, would possibly fail

Consuming block cache information for other purposes is discouraged. Users must not make assumptions on its contents or rely on its contents in any way. Maintainers assume that this state is internal and won't consider further uses other than the intended for the current development. If you consider your application needs any other information than the ones available through public APIs, please file the corresponding feature request.

Migrating from 0.16.x-beta to 0.17.0-alpha.x

Changes to Demo APP

The demo application now uses the SDKSynchronizer to create addresses and shield funds. DerivationToolViewController was removed. See DerivationTool unit tests for sample code. GetAddressViewController now derives transparent and sapling addresses from Unified Address SendViewController uses Unified Spending Key and type-safe Memo

Changes To SDK

CompactBlockProcessor

public func getUnifiedAddress(accountIndex: Int) -> UnifiedAddress? public func getSaplingAddress(accountIndex: Int) -> SaplingAddress? derived from UA public func getTransparentAddress(accountIndex: Int) -> TransparentAddress? is derived from UA public func getTransparentBalance(accountIndex: Int) throws -> WalletBalance now fetches from account exclusively func refreshUTXOs(tAddress: TransparentAddress, startHeight: BlockHeight) async throws -> RefreshedUTXOs uses TransparentAddress

Initializer

Migration of DataDB and CacheDB are delegated to librustzcash

removed public func getAddress(index account: Int = 0) -> String

Wallet Types

UnifiedSpendingKey to represent Unified Spending Keys. This is a binary encoded not meant to be stored or backed up. This only serves the purpose of letting clients use the least privilege keys at all times for every operation.

Synchronizer

sendToAddress and shieldFunds now take a UnifiedSpendingKey instead of the respective spending and transparent private keys. refreshUTXOs uses TransparentAddress

KeyDeriving protocol

Addresses should be obtained from the Synchronizer by using the get_address functions Transparent and Sapling receivers should be obtained by extracting the receivers of a UA

public extension UnifiedAddress {
    /// Extracts the sapling receiver from this UA if available
    /// - Returns: an `Optional<SaplingAddress>`
    func saplingReceiver() -> SaplingAddress? {
        try? DerivationTool.saplingReceiver(from: self)
    }

    /// Extracts the transparent receiver from this UA if available
    /// - Returns: an `Optional<TransparentAddress>`
    func transparentReceiver() -> TransparentAddress? {
        try? DerivationTool.transparentReceiver(from: self)
    }

Removed func deriveUnifiedFullViewingKeys(seed: [UInt8], numberOfAccounts: Int) throws -> [UnifiedFullViewingKey] func deriveViewingKey(spendingKey: SaplingExtendedSpendingKey) throws -> SaplingExtendedFullViewingKey func deriveSpendingKeys(seed: [UInt8], numberOfAccounts: Int) throws -> [SaplingExtendedSpendingKey] func deriveUnifiedAddress(from ufvk: UnifiedFullViewingKey) throws -> UnifiedAddress func deriveTransparentAddress(seed: [UInt8], account: Int, index: Int) throws -> TransparentAddress func deriveTransparentAccountPrivateKey(seed: [UInt8], account: Int) throws -> TransparentAccountPrivKey func deriveTransparentAddressFromAccountPrivateKey(_ xprv: TransparentAccountPrivKey, index: Int) throws -> TransparentAddress

Added static func saplingReceiver(from unifiedAddress: UnifiedAddress) throws -> SaplingAddress? static func transparentReceiver(from unifiedAddress: UnifiedAddress) throws -> TransparentAddress? static func receiverTypecodesFromUnifiedAddress(_ address: UnifiedAddress) throws -> [UnifiedAddress.ReceiverTypecodes] func deriveUnifiedSpendingKey(seed: [UInt8], accountIndex: Int) throws -> UnifiedSpendingKey public func deriveUnifiedFullViewingKey(from spendingKey: UnifiedSpendingKey) throws -> UnifiedFullViewingKey

Notes on Structured Concurrency

CompactBlockProcessor is now an Swift Actor. This makes it more robust and have its own async environment.

SDK Clients will likely be affected by some async methods on SDKSynchronizer.

We recommend clients that don't support structured concurrency features, to work around this by surrounding the these function calls either in @MainActor contexts either by marking callers as @MainActor or launching tasks on that actor with Task { @MainActor in ... }