Add `SdkSynchronizer.createAccount()` method
It is currently hidden from the public API, implemented for testing purposes.
This commit is contained in:
parent
c6fd783317
commit
f69cacb9e6
|
@ -6,6 +6,9 @@ Change Log
|
||||||
### Added
|
### Added
|
||||||
- `cash.z.ecc.android.sdk`:
|
- `cash.z.ecc.android.sdk`:
|
||||||
- `Synchronizer.isValidUnifiedAddr`
|
- `Synchronizer.isValidUnifiedAddr`
|
||||||
|
- `cash.z.ecc.android.sdk.model`:
|
||||||
|
- `FirstClassByteArray`
|
||||||
|
- `UnifiedSpendingKey`
|
||||||
- `cash.z.ecc.android.sdk.tool`:
|
- `cash.z.ecc.android.sdk.tool`:
|
||||||
- `DerivationTool.deriveTransparentAccountPrivateKey`
|
- `DerivationTool.deriveTransparentAccountPrivateKey`
|
||||||
- `DerivationTool.deriveTransparentAddressFromAccountPrivateKey`
|
- `DerivationTool.deriveTransparentAddressFromAccountPrivateKey`
|
||||||
|
|
|
@ -591,7 +591,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "equihash"
|
name = "equihash"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/zcash/librustzcash.git?rev=6cb0d212195a32b7456c866bcd367fc98967b668#6cb0d212195a32b7456c866bcd367fc98967b668"
|
source = "git+https://github.com/zcash/librustzcash.git?rev=774ffadf5a0120a74d70d281974d079ccd58c600#774ffadf5a0120a74d70d281974d079ccd58c600"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"blake2b_simd",
|
"blake2b_simd",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
|
@ -609,7 +609,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "f4jumble"
|
name = "f4jumble"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/zcash/librustzcash.git?rev=6cb0d212195a32b7456c866bcd367fc98967b668#6cb0d212195a32b7456c866bcd367fc98967b668"
|
source = "git+https://github.com/zcash/librustzcash.git?rev=774ffadf5a0120a74d70d281974d079ccd58c600#774ffadf5a0120a74d70d281974d079ccd58c600"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"blake2b_simd",
|
"blake2b_simd",
|
||||||
]
|
]
|
||||||
|
@ -2037,7 +2037,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zcash_address"
|
name = "zcash_address"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/zcash/librustzcash.git?rev=6cb0d212195a32b7456c866bcd367fc98967b668#6cb0d212195a32b7456c866bcd367fc98967b668"
|
source = "git+https://github.com/zcash/librustzcash.git?rev=774ffadf5a0120a74d70d281974d079ccd58c600#774ffadf5a0120a74d70d281974d079ccd58c600"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bech32",
|
"bech32",
|
||||||
"bs58",
|
"bs58",
|
||||||
|
@ -2048,12 +2048,13 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zcash_client_backend"
|
name = "zcash_client_backend"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
source = "git+https://github.com/zcash/librustzcash.git?rev=6cb0d212195a32b7456c866bcd367fc98967b668#6cb0d212195a32b7456c866bcd367fc98967b668"
|
source = "git+https://github.com/zcash/librustzcash.git?rev=774ffadf5a0120a74d70d281974d079ccd58c600#774ffadf5a0120a74d70d281974d079ccd58c600"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
"bech32",
|
"bech32",
|
||||||
"bls12_381",
|
"bls12_381",
|
||||||
"bs58",
|
"bs58",
|
||||||
|
"byteorder",
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
"ff",
|
"ff",
|
||||||
"group",
|
"group",
|
||||||
|
@ -2061,6 +2062,7 @@ dependencies = [
|
||||||
"hex",
|
"hex",
|
||||||
"jubjub",
|
"jubjub",
|
||||||
"log",
|
"log",
|
||||||
|
"memuse",
|
||||||
"nom",
|
"nom",
|
||||||
"orchard",
|
"orchard",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
|
@ -2084,7 +2086,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zcash_client_sqlite"
|
name = "zcash_client_sqlite"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
source = "git+https://github.com/zcash/librustzcash.git?rev=6cb0d212195a32b7456c866bcd367fc98967b668#6cb0d212195a32b7456c866bcd367fc98967b668"
|
source = "git+https://github.com/zcash/librustzcash.git?rev=774ffadf5a0120a74d70d281974d079ccd58c600#774ffadf5a0120a74d70d281974d079ccd58c600"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bech32",
|
"bech32",
|
||||||
"bs58",
|
"bs58",
|
||||||
|
@ -2108,7 +2110,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zcash_encoding"
|
name = "zcash_encoding"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/zcash/librustzcash.git?rev=6cb0d212195a32b7456c866bcd367fc98967b668#6cb0d212195a32b7456c866bcd367fc98967b668"
|
source = "git+https://github.com/zcash/librustzcash.git?rev=774ffadf5a0120a74d70d281974d079ccd58c600#774ffadf5a0120a74d70d281974d079ccd58c600"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"nonempty",
|
"nonempty",
|
||||||
|
@ -2117,7 +2119,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zcash_note_encryption"
|
name = "zcash_note_encryption"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/zcash/librustzcash.git?rev=6cb0d212195a32b7456c866bcd367fc98967b668#6cb0d212195a32b7456c866bcd367fc98967b668"
|
source = "git+https://github.com/zcash/librustzcash.git?rev=774ffadf5a0120a74d70d281974d079ccd58c600#774ffadf5a0120a74d70d281974d079ccd58c600"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chacha20 0.9.0",
|
"chacha20 0.9.0",
|
||||||
"chacha20poly1305 0.10.1",
|
"chacha20poly1305 0.10.1",
|
||||||
|
@ -2130,7 +2132,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zcash_primitives"
|
name = "zcash_primitives"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
source = "git+https://github.com/zcash/librustzcash.git?rev=6cb0d212195a32b7456c866bcd367fc98967b668#6cb0d212195a32b7456c866bcd367fc98967b668"
|
source = "git+https://github.com/zcash/librustzcash.git?rev=774ffadf5a0120a74d70d281974d079ccd58c600#774ffadf5a0120a74d70d281974d079ccd58c600"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes",
|
"aes",
|
||||||
"bip0039",
|
"bip0039",
|
||||||
|
@ -2167,7 +2169,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zcash_proofs"
|
name = "zcash_proofs"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
source = "git+https://github.com/zcash/librustzcash.git?rev=6cb0d212195a32b7456c866bcd367fc98967b668#6cb0d212195a32b7456c866bcd367fc98967b668"
|
source = "git+https://github.com/zcash/librustzcash.git?rev=774ffadf5a0120a74d70d281974d079ccd58c600#774ffadf5a0120a74d70d281974d079ccd58c600"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bellman",
|
"bellman",
|
||||||
"blake2b_simd",
|
"blake2b_simd",
|
||||||
|
|
|
@ -21,8 +21,8 @@ log-panics = "2.0.0"
|
||||||
schemer = "0.2"
|
schemer = "0.2"
|
||||||
secp256k1 = "0.21"
|
secp256k1 = "0.21"
|
||||||
secrecy = "0.8"
|
secrecy = "0.8"
|
||||||
zcash_client_backend = { version = "0.5", features = ["transparent-inputs"] }
|
zcash_client_backend = { version = "0.5", features = ["transparent-inputs", "unstable"] }
|
||||||
zcash_client_sqlite = { version = "0.3", features = ["transparent-inputs"] }
|
zcash_client_sqlite = { version = "0.3", features = ["transparent-inputs", "unstable"] }
|
||||||
zcash_primitives = "0.7"
|
zcash_primitives = "0.7"
|
||||||
zcash_proofs = "0.7"
|
zcash_proofs = "0.7"
|
||||||
|
|
||||||
|
@ -30,11 +30,11 @@ zcash_proofs = "0.7"
|
||||||
[patch.crates-io]
|
[patch.crates-io]
|
||||||
group = { git = "https://github.com/zkcrypto/group.git", rev = "a7f3ceb2373e9fe536996f7b4d55c797f3e667f0" }
|
group = { git = "https://github.com/zkcrypto/group.git", rev = "a7f3ceb2373e9fe536996f7b4d55c797f3e667f0" }
|
||||||
orchard = { git = 'https://github.com/zcash/orchard.git', rev='f206b3f5d4e31bba75d03d9d03d5fa25825a9384' }
|
orchard = { git = 'https://github.com/zcash/orchard.git', rev='f206b3f5d4e31bba75d03d9d03d5fa25825a9384' }
|
||||||
zcash_client_backend = { git = 'https://github.com/zcash/librustzcash.git', rev='6cb0d212195a32b7456c866bcd367fc98967b668' }
|
zcash_client_backend = { git = 'https://github.com/zcash/librustzcash.git', rev='774ffadf5a0120a74d70d281974d079ccd58c600' }
|
||||||
zcash_client_sqlite = { git = 'https://github.com/zcash/librustzcash.git', rev='6cb0d212195a32b7456c866bcd367fc98967b668' }
|
zcash_client_sqlite = { git = 'https://github.com/zcash/librustzcash.git', rev='774ffadf5a0120a74d70d281974d079ccd58c600' }
|
||||||
zcash_note_encryption = { git = 'https://github.com/zcash/librustzcash.git', rev='6cb0d212195a32b7456c866bcd367fc98967b668' }
|
zcash_note_encryption = { git = 'https://github.com/zcash/librustzcash.git', rev='774ffadf5a0120a74d70d281974d079ccd58c600' }
|
||||||
zcash_primitives = { git = 'https://github.com/zcash/librustzcash.git', rev='6cb0d212195a32b7456c866bcd367fc98967b668' }
|
zcash_primitives = { git = 'https://github.com/zcash/librustzcash.git', rev='774ffadf5a0120a74d70d281974d079ccd58c600' }
|
||||||
zcash_proofs = { git = 'https://github.com/zcash/librustzcash.git', rev='6cb0d212195a32b7456c866bcd367fc98967b668' }
|
zcash_proofs = { git = 'https://github.com/zcash/librustzcash.git', rev='774ffadf5a0120a74d70d281974d079ccd58c600' }
|
||||||
|
|
||||||
## Uncomment this to test librustzcash changes locally
|
## Uncomment this to test librustzcash changes locally
|
||||||
#[patch.crates-io]
|
#[patch.crates-io]
|
||||||
|
|
|
@ -49,6 +49,7 @@ import cash.z.ecc.android.sdk.internal.transaction.WalletTransactionEncoder
|
||||||
import cash.z.ecc.android.sdk.internal.twig
|
import cash.z.ecc.android.sdk.internal.twig
|
||||||
import cash.z.ecc.android.sdk.internal.twigTask
|
import cash.z.ecc.android.sdk.internal.twigTask
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
|
import cash.z.ecc.android.sdk.model.UnifiedSpendingKey
|
||||||
import cash.z.ecc.android.sdk.model.WalletBalance
|
import cash.z.ecc.android.sdk.model.WalletBalance
|
||||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||||
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
|
@ -622,6 +623,14 @@ class SdkSynchronizer internal constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Account management
|
||||||
|
//
|
||||||
|
|
||||||
|
// Not ready to be a public API; internal for testing only
|
||||||
|
internal suspend fun createAccount(seed: ByteArray): UnifiedSpendingKey =
|
||||||
|
processor.createAccount(seed)
|
||||||
|
|
||||||
//
|
//
|
||||||
// Send / Receive
|
// Send / Receive
|
||||||
//
|
//
|
||||||
|
|
|
@ -5,6 +5,7 @@ import cash.z.ecc.android.sdk.db.entity.ConfirmedTransaction
|
||||||
import cash.z.ecc.android.sdk.db.entity.PendingTransaction
|
import cash.z.ecc.android.sdk.db.entity.PendingTransaction
|
||||||
import cash.z.ecc.android.sdk.ext.ZcashSdk
|
import cash.z.ecc.android.sdk.ext.ZcashSdk
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
|
import cash.z.ecc.android.sdk.model.UnifiedSpendingKey
|
||||||
import cash.z.ecc.android.sdk.model.WalletBalance
|
import cash.z.ecc.android.sdk.model.WalletBalance
|
||||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||||
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
|
@ -159,6 +160,33 @@ interface Synchronizer {
|
||||||
// Operations
|
// Operations
|
||||||
//
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the next available account-level spend authority, given the current set of
|
||||||
|
* [ZIP 316](https://zips.z.cash/zip-0316) account identifiers known, to the wallet
|
||||||
|
* database.
|
||||||
|
*
|
||||||
|
* The caller should store the byte encoding of the returned spending key in a secure
|
||||||
|
* fashion. This encoding **MUST NOT** be exposed to users. It is an internal encoding
|
||||||
|
* that is inherently unstable, and only intended to be passed between the SDK and the
|
||||||
|
* storage backend. The caller **MUST NOT** allow this encoding to be exported or
|
||||||
|
* imported.
|
||||||
|
*
|
||||||
|
* 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).
|
||||||
|
*
|
||||||
|
* @param seed the wallet's seed phrase.
|
||||||
|
*
|
||||||
|
* @return the newly created ZIP 316 account identifier, along with the binary
|
||||||
|
* encoding of the `UnifiedSpendingKey` for the newly created account.
|
||||||
|
*/
|
||||||
|
// This is not yet ready to be a public API
|
||||||
|
// suspend fun createAccount(seed: ByteArray): UnifiedSpendingKey
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the shielded address for the given account. This is syntactic sugar for
|
* Gets the shielded address for the given account. This is syntactic sugar for
|
||||||
* [getShieldedAddress] because we use z-addrs by default.
|
* [getShieldedAddress] because we use z-addrs by default.
|
||||||
|
|
|
@ -41,6 +41,7 @@ import cash.z.ecc.android.sdk.internal.twigTask
|
||||||
import cash.z.ecc.android.sdk.jni.RustBackend
|
import cash.z.ecc.android.sdk.jni.RustBackend
|
||||||
import cash.z.ecc.android.sdk.jni.RustBackendWelding
|
import cash.z.ecc.android.sdk.jni.RustBackendWelding
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
|
import cash.z.ecc.android.sdk.model.UnifiedSpendingKey
|
||||||
import cash.z.ecc.android.sdk.model.WalletBalance
|
import cash.z.ecc.android.sdk.model.WalletBalance
|
||||||
import cash.z.wallet.sdk.rpc.Service
|
import cash.z.wallet.sdk.rpc.Service
|
||||||
import io.grpc.StatusRuntimeException
|
import io.grpc.StatusRuntimeException
|
||||||
|
@ -1016,6 +1017,11 @@ class CompactBlockProcessor internal constructor(
|
||||||
suspend fun getLastScannedHeight() =
|
suspend fun getLastScannedHeight() =
|
||||||
repository.lastScannedHeight()
|
repository.lastScannedHeight()
|
||||||
|
|
||||||
|
// TODO(str4d): CompactBlockProcessor is the wrong place for this, but it's where all the other APIs that need
|
||||||
|
// access to the RustBackend live. This should be refactored.
|
||||||
|
internal suspend fun createAccount(seed: ByteArray): UnifiedSpendingKey =
|
||||||
|
rustBackend.createAccount(seed)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get address corresponding to the given account for this wallet.
|
* Get address corresponding to the given account for this wallet.
|
||||||
*
|
*
|
||||||
|
|
|
@ -7,6 +7,7 @@ import cash.z.ecc.android.sdk.internal.ext.deleteSuspend
|
||||||
import cash.z.ecc.android.sdk.internal.model.Checkpoint
|
import cash.z.ecc.android.sdk.internal.model.Checkpoint
|
||||||
import cash.z.ecc.android.sdk.internal.twig
|
import cash.z.ecc.android.sdk.internal.twig
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
|
import cash.z.ecc.android.sdk.model.UnifiedSpendingKey
|
||||||
import cash.z.ecc.android.sdk.model.WalletBalance
|
import cash.z.ecc.android.sdk.model.WalletBalance
|
||||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||||
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
|
@ -52,6 +53,16 @@ internal class RustBackend private constructor(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun createAccount(seed: ByteArray): UnifiedSpendingKey {
|
||||||
|
return withContext(SdkDispatchers.DATABASE_IO) {
|
||||||
|
createAccount(
|
||||||
|
dataDbFile.absolutePath,
|
||||||
|
seed,
|
||||||
|
networkId = network.id
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun initAccountsTable(vararg keys: UnifiedFullViewingKey): Boolean {
|
override suspend fun initAccountsTable(vararg keys: UnifiedFullViewingKey): Boolean {
|
||||||
val ufvks = Array(keys.size) { keys[it].encoding }
|
val ufvks = Array(keys.size) { keys[it].encoding }
|
||||||
|
|
||||||
|
@ -405,6 +416,9 @@ internal class RustBackend private constructor(
|
||||||
networkId: Int
|
networkId: Int
|
||||||
): Boolean
|
): Boolean
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
private external fun createAccount(dbDataPath: String, seed: ByteArray, networkId: Int): UnifiedSpendingKey
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
private external fun getCurrentAddress(
|
private external fun getCurrentAddress(
|
||||||
dbDataPath: String,
|
dbDataPath: String,
|
||||||
|
|
|
@ -2,6 +2,7 @@ package cash.z.ecc.android.sdk.jni
|
||||||
|
|
||||||
import cash.z.ecc.android.sdk.internal.model.Checkpoint
|
import cash.z.ecc.android.sdk.internal.model.Checkpoint
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
|
import cash.z.ecc.android.sdk.model.UnifiedSpendingKey
|
||||||
import cash.z.ecc.android.sdk.model.WalletBalance
|
import cash.z.ecc.android.sdk.model.WalletBalance
|
||||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||||
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
|
@ -42,6 +43,8 @@ internal interface RustBackendWelding {
|
||||||
|
|
||||||
suspend fun initDataDb(seed: ByteArray?): Int
|
suspend fun initDataDb(seed: ByteArray?): Int
|
||||||
|
|
||||||
|
suspend fun createAccount(seed: ByteArray): UnifiedSpendingKey
|
||||||
|
|
||||||
fun isValidShieldedAddr(addr: String): Boolean
|
fun isValidShieldedAddr(addr: String): Boolean
|
||||||
|
|
||||||
fun isValidTransparentAddr(addr: String): Boolean
|
fun isValidTransparentAddr(addr: String): Boolean
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
package cash.z.ecc.android.sdk.model
|
||||||
|
|
||||||
|
class FirstClassByteArray(val byteArray: ByteArray) {
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (javaClass != other?.javaClass) return false
|
||||||
|
|
||||||
|
other as FirstClassByteArray
|
||||||
|
|
||||||
|
if (!byteArray.contentEquals(other.byteArray)) return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode() = byteArray.contentHashCode()
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package cash.z.ecc.android.sdk.model
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A [ZIP 316](https://zips.z.cash/zip-0316) Unified Spending Key.
|
||||||
|
*
|
||||||
|
* This is the spend authority for an account under the wallet's seed.
|
||||||
|
*
|
||||||
|
* An instance of this class contains all of the per-pool spending keys that could be
|
||||||
|
* derived at the time of its creation. As such, it is not suitable for long-term storage,
|
||||||
|
* export/import, or backup purposes.
|
||||||
|
*/
|
||||||
|
data class UnifiedSpendingKey internal constructor(
|
||||||
|
/**
|
||||||
|
* A [ZIP 316](https://zips.z.cash/zip-0316) account identifier.
|
||||||
|
*/
|
||||||
|
val account: Int,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The binary encoding of the [ZIP 316](https://zips.z.cash/zip-0316) Unified Spending
|
||||||
|
* Key for [account].
|
||||||
|
*
|
||||||
|
* This encoding **MUST NOT** be exposed to users. It is an internal encoding that is
|
||||||
|
* inherently unstable, and only intended to be passed between the SDK and the storage
|
||||||
|
* backend. Wallets **MUST NOT** allow this encoding to be exported or imported.
|
||||||
|
*/
|
||||||
|
internal val bytes: FirstClassByteArray
|
||||||
|
) {
|
||||||
|
// Override to prevent leaking key to logs
|
||||||
|
override fun toString() = "UnifiedSpendingKey(account=$account)"
|
||||||
|
|
||||||
|
fun copyBytes() = bytes.byteArray.copyOf()
|
||||||
|
}
|
|
@ -11,9 +11,10 @@ use std::str::FromStr;
|
||||||
use android_logger::Config;
|
use android_logger::Config;
|
||||||
use failure::format_err;
|
use failure::format_err;
|
||||||
use hdwallet::traits::{Deserialize, Serialize};
|
use hdwallet::traits::{Deserialize, Serialize};
|
||||||
|
use jni::objects::JValue;
|
||||||
use jni::{
|
use jni::{
|
||||||
objects::{JClass, JString},
|
objects::{JClass, JString},
|
||||||
sys::{jboolean, jbyteArray, jint, jlong, jobjectArray, jstring, JNI_FALSE, JNI_TRUE},
|
sys::{jboolean, jbyteArray, jint, jlong, jobject, jobjectArray, jstring, JNI_FALSE, JNI_TRUE},
|
||||||
JNIEnv,
|
JNIEnv,
|
||||||
};
|
};
|
||||||
use log::Level;
|
use log::Level;
|
||||||
|
@ -35,7 +36,7 @@ use zcash_client_backend::{
|
||||||
decode_extended_spending_key, encode_extended_full_viewing_key,
|
decode_extended_spending_key, encode_extended_full_viewing_key,
|
||||||
encode_extended_spending_key, AddressCodec,
|
encode_extended_spending_key, AddressCodec,
|
||||||
},
|
},
|
||||||
keys::{sapling, UnifiedFullViewingKey},
|
keys::{sapling, Era, UnifiedFullViewingKey},
|
||||||
wallet::{OvkPolicy, WalletTransparentOutput},
|
wallet::{OvkPolicy, WalletTransparentOutput},
|
||||||
};
|
};
|
||||||
use zcash_client_sqlite::wallet::init::WalletMigrationError;
|
use zcash_client_sqlite::wallet::init::WalletMigrationError;
|
||||||
|
@ -145,6 +146,58 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_initDataDb(
|
||||||
unwrap_exc_or(&env, res, -1)
|
unwrap_exc_or(&env, res, -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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 store
|
||||||
|
/// the returned spending key 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).
|
||||||
|
///
|
||||||
|
/// [ZIP 316]: https://zips.z.cash/zip-0316
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_createAccount(
|
||||||
|
env: JNIEnv<'_>,
|
||||||
|
_: JClass<'_>,
|
||||||
|
db_data: JString<'_>,
|
||||||
|
seed: jbyteArray,
|
||||||
|
network_id: jint,
|
||||||
|
) -> jobject {
|
||||||
|
let res = panic::catch_unwind(|| {
|
||||||
|
let network = parse_network(network_id as u32)?;
|
||||||
|
let db_data = wallet_db(&env, network, db_data)?;
|
||||||
|
let seed = SecretVec::new(env.convert_byte_array(seed).unwrap());
|
||||||
|
|
||||||
|
let mut db_ops = db_data.get_update_ops()?;
|
||||||
|
let (account, usk) = db_ops
|
||||||
|
.create_account(&seed)
|
||||||
|
.map_err(|e| format_err!("Error while initializing accounts: {}", e))?;
|
||||||
|
|
||||||
|
let encoded = usk.to_bytes(Era::Orchard);
|
||||||
|
let output = env.new_object(
|
||||||
|
"cash/z/ecc/android/sdk/model/UnifiedSpendingKey",
|
||||||
|
"(I[B)V",
|
||||||
|
&[
|
||||||
|
JValue::Int(u32::from(account) as i32),
|
||||||
|
JValue::Object(env.byte_array_from_slice(&encoded)?.into()),
|
||||||
|
],
|
||||||
|
)?;
|
||||||
|
Ok(output.into_inner())
|
||||||
|
});
|
||||||
|
unwrap_exc_or(&env, res, ptr::null_mut())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Initialises the data database with the given set of unified full viewing keys.
|
||||||
|
///
|
||||||
|
/// This should only be used in special cases for implementing wallet recovery; prefer
|
||||||
|
/// `RustBackend.createAccount` for normal account creation purposes.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_initAccountsTableWithKeys(
|
pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_initAccountsTableWithKeys(
|
||||||
env: JNIEnv<'_>,
|
env: JNIEnv<'_>,
|
||||||
|
|
Loading…
Reference in New Issue