Skip to content

Commit

Permalink
Switch from ZIP 32 account indices to UUID account identifiers (#1640)
Browse files Browse the repository at this point in the history
* Switch from ZIP 32 account indices to UUID account identifiers

* Rename TransactionRecipient.Account

To emphasize the distinction between Account and TransactionRecipient.Account

* Fix `Backend.createAccount` API parameters

* Add `importAccountUfvk` to the Rust backend.

* Propagate accountName and keySource across SDK

* Propagate new importAccount across SDK

* Wrap createAccount setup information

* Wrap importAccount setup information

* Add `Zip32AccountIndex` wrapper

* Update key source parameter

* Remove account from `UnifiedSpendingKey`

* Fix `importAccountByUfvk` API

* Refactor Account.accountUuid to wrapper class

So we can easily keep it typesafe and compare it to each other

* Add `JniAccountUsk`

* Add `seedFingerprint` and `zip32AccountIndex`

To public API `importAccountUfvk`

* Transactions by account UUID

* Refactor default account creation

* Migrate to Rust crate revision with bugfixes to account UUID migration

* Refactor inputs of `importAccountUfvk`

* Use `FirsClassByteArray` for `seed` parameter

---------

Co-authored-by: Honza <[email protected]>
Co-authored-by: Kris Nuttycombe <[email protected]>
Co-authored-by: Honza Rychnovský <[email protected]>
Co-authored-by: Daira-Emma Hopwood <[email protected]>
  • Loading branch information
5 people authored Dec 11, 2024
1 parent ad1325b commit 2cb7315
Show file tree
Hide file tree
Showing 75 changed files with 1,494 additions and 587 deletions.
22 changes: 17 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,30 @@ and this library adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]

### Added
- `Synchronizer.getAccounts()`
- `Synchronizer.walletBalances: StateFlow<Map<Account, AccountBalance>?>` that is replacement for the removed
- `Synchronizer.importAccountByUfvk()` has been added
- `Synchronizer.getAccounts()` returning all the created or imported accounts. See the documentation in `Account`.
- `Synchronizer.walletBalances: StateFlow<Map<AccountUuid, AccountBalance>?>` that is replacement for the removed
`orchardBalances`, `saplingBalances`, and `transparentBalance`
- `getTransactions(accountUuid: AccountUuid)` to get transactions belonging to the given account
- `Zip32AccountIndex`, `AccountUuid`, `AccountUsk`, `AccountPurpose`, `AccountCreateSetup`, and `AcountImportSetup`
model classes have been added to support the new or the changed APIs

### Changed
- `Synchronizer.orchardBalances`, `Synchronizer.saplingBalances`, and `Synchronizer.transparentBalance` have been
replaced by `Synchronizer.walletBalances` that provides these balances based on `Account`
### Changed
- `Account` data class works with `accountUuid: AccountUuid` instead of the previous ZIP 32 account index
- These functions from `DerivationTool` have been refactored to work with the new `Zip32AccountIndex` instead of the
`Account` data class: `deriveUnifiedSpendingKey`, `deriveUnifiedAddress`, `deriveArbitraryAccountKey`
- `WalletCoordinator` now provides a way to instantiate `Synchronizer` with the new `accountName` and `keySource`
parameters
- `UnifiedSpendingKey` does not hold `Account` information anymore, it has been replaced by `AccountUsk` model class
in a few internal cases
- `Synchronizer.send` extension function receives `Account` on input
- `PendingTransaction` sealed class descendants have been renamed

### Removed
- `Synchronizer.sendToAddress` and `Synchronizer.shieldFunds` have been removed, use
`Synchronizer.createProposedTransactions` and `Synchronizer.proposeShielding` instead
- `Synchronizer.orchardBalances`, `Synchronizer.saplingBalances`, and `Synchronizer.transparentBalance`
(use `Synchronizer.walletBalances` instead).

### Fixed
- The `CompactBlockProcessor` now correctly distinguishes between `Response.Failure.Server.Unavailable` and other
Expand Down
38 changes: 16 additions & 22 deletions backend-lib/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions backend-lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ rayon = "1.7"
# JNI
anyhow = "1"
jni = { version = "0.21", default-features = false }
uuid = "1"

# Logging
log-panics = "2.0.0"
Expand Down Expand Up @@ -69,3 +70,10 @@ xz2 = { version = "0.1", features = ["static"] }
name = "zcashwalletsdk"
path = "src/main/rust/lib.rs"
crate-type = ["staticlib", "cdylib"]

[patch.crates-io]
zcash_address = { git = "https://github.com/zcash/librustzcash", rev = "c2ebc05be118a972352801a328e6c61f69bb8a16" }
zcash_client_backend = { git = "https://github.com/zcash/librustzcash", rev = "c2ebc05be118a972352801a328e6c61f69bb8a16" }
zcash_client_sqlite = { git = "https://github.com/zcash/librustzcash", rev = "c2ebc05be118a972352801a328e6c61f69bb8a16" }
zcash_primitives = { git = "https://github.com/zcash/librustzcash", rev = "c2ebc05be118a972352801a328e6c61f69bb8a16" }
zcash_proofs = { git = "https://github.com/zcash/librustzcash", rev = "c2ebc05be118a972352801a328e6c61f69bb8a16" }
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package cash.z.ecc.android.sdk.internal

import cash.z.ecc.android.sdk.internal.model.JniAccount
import cash.z.ecc.android.sdk.internal.model.JniAccountUsk
import cash.z.ecc.android.sdk.internal.model.JniBlockMeta
import cash.z.ecc.android.sdk.internal.model.JniRewindResult
import cash.z.ecc.android.sdk.internal.model.JniScanRange
import cash.z.ecc.android.sdk.internal.model.JniScanSummary
import cash.z.ecc.android.sdk.internal.model.JniSubtreeRoot
import cash.z.ecc.android.sdk.internal.model.JniTransactionDataRequest
import cash.z.ecc.android.sdk.internal.model.JniUnifiedSpendingKey
import cash.z.ecc.android.sdk.internal.model.JniWalletSummary
import cash.z.ecc.android.sdk.internal.model.ProposalUnsafe

Expand All @@ -24,7 +24,7 @@ interface Backend {
suspend fun initBlockMetaDb(): Int

suspend fun proposeTransfer(
accountIndex: Int,
accountUuid: ByteArray,
to: String,
value: Long,
memo: ByteArray? = null
Expand All @@ -35,12 +35,12 @@ interface Backend {
*/
@Throws(RuntimeException::class)
suspend fun proposeTransferFromUri(
accountIndex: Int,
accountUuid: ByteArray,
uri: String
): ProposalUnsafe

suspend fun proposeShielding(
accountIndex: Int,
accountUuid: ByteArray,
shieldingThreshold: Long,
memo: ByteArray? = null,
transparentReceiver: String? = null
Expand Down Expand Up @@ -85,10 +85,28 @@ interface Backend {
*/
@Throws(RuntimeException::class)
suspend fun createAccount(
accountName: String,
keySource: String?,
seed: ByteArray,
treeState: ByteArray,
recoverUntil: Long?
): JniUnifiedSpendingKey
recoverUntil: Long?,
): JniAccountUsk

/**
* @throws RuntimeException as a common indicator of the operation failure
*/
@Throws(RuntimeException::class)
@Suppress("LongParameterList")
suspend fun importAccountUfvk(
accountName: String,
keySource: String?,
ufvk: String,
treeState: ByteArray,
recoverUntil: Long?,
purpose: Int,
seedFingerprint: ByteArray?,
zip32AccountIndex: Long?,
): JniAccount

/**
* @throws RuntimeException as a common indicator of the operation failure
Expand All @@ -109,13 +127,13 @@ interface Backend {
fun isValidTexAddr(addr: String): Boolean

@Throws(RuntimeException::class)
suspend fun getCurrentAddress(accountIndex: Int): String
suspend fun getCurrentAddress(accountUuid: ByteArray): String

fun getTransparentReceiver(ua: String): String?

fun getSaplingReceiver(ua: String): String?

suspend fun listTransparentReceivers(accountIndex: Int): List<String>
suspend fun listTransparentReceivers(accountUuid: ByteArray): List<String>

fun getBranchIdForHeight(height: Long): Long

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ interface Derivation {
fun deriveUnifiedAddress(
seed: ByteArray,
networkId: Int,
accountIndex: Int
accountIndex: Long
): String

fun deriveUnifiedSpendingKey(
seed: ByteArray,
networkId: Int,
accountIndex: Int
): JniUnifiedSpendingKey
accountIndex: Long
): ByteArray

/**
* @return a unified full viewing key.
Expand Down Expand Up @@ -66,7 +66,7 @@ interface Derivation {
contextString: ByteArray,
seed: ByteArray,
networkId: Int,
accountIndex: Int
accountIndex: Long
): ByteArray

companion object {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package cash.z.ecc.android.sdk.internal.jni

import cash.z.ecc.android.sdk.internal.model.JniAccount

/**
* The number of bytes in the account UUID parameter. It's used e.g. in [JniAccount.accountUuid], or
* [JniUnifiedSpendingKey.accountUuid]
*/
const val JNI_ACCOUNT_UUID_BYTES_SIZE = 16

/**
* The number of bytes in the seed fingerprint parameter. It's used e.g. in [JniAccount.seedFingerprint]
*/
const val JNI_ACCOUNT_SEED_FP_BYTES_SIZE = 32
Loading

0 comments on commit 2cb7315

Please sign in to comment.