2020-09-11 00:33:25 -07:00
|
|
|
package cash.z.ecc.android.sdk.tool
|
|
|
|
|
|
|
|
import cash.z.ecc.android.sdk.jni.RustBackend
|
|
|
|
import cash.z.ecc.android.sdk.jni.RustBackendWelding
|
2022-08-02 06:29:09 -07:00
|
|
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
2022-08-04 10:09:19 -07:00
|
|
|
import cash.z.ecc.android.sdk.type.UnifiedFullViewingKey
|
2020-09-11 00:33:25 -07:00
|
|
|
|
2022-08-23 06:49:00 -07:00
|
|
|
@Suppress("UtilityClassWithPublicConstructor")
|
2020-09-11 00:33:25 -07:00
|
|
|
class DerivationTool {
|
2021-03-10 10:10:03 -08:00
|
|
|
|
2022-08-23 06:49:00 -07:00
|
|
|
@Suppress("TooManyFunctions")
|
2020-09-11 00:33:25 -07:00
|
|
|
companion object : RustBackendWelding.Derivation {
|
|
|
|
|
|
|
|
/**
|
2022-08-04 10:09:19 -07:00
|
|
|
* Given a seed and a number of accounts, return the associated Unified Full Viewing Keys.
|
2020-09-11 00:33:25 -07:00
|
|
|
*
|
|
|
|
* @param seed the seed from which to derive viewing keys.
|
|
|
|
* @param numberOfAccounts the number of accounts to use. Multiple accounts are not fully
|
|
|
|
* supported so the default value of 1 is recommended.
|
|
|
|
*
|
2022-08-04 10:09:19 -07:00
|
|
|
* @return the UFVKs derived from the seed, encoded as Strings.
|
2020-09-11 00:33:25 -07:00
|
|
|
*/
|
2022-08-23 13:28:01 -07:00
|
|
|
override suspend fun deriveUnifiedFullViewingKeys(
|
2022-08-23 06:49:00 -07:00
|
|
|
seed: ByteArray,
|
|
|
|
network: ZcashNetwork,
|
|
|
|
numberOfAccounts: Int
|
2022-08-23 13:28:01 -07:00
|
|
|
): Array<UnifiedFullViewingKey> =
|
2020-09-11 00:33:25 -07:00
|
|
|
withRustBackendLoaded {
|
2022-08-04 10:09:19 -07:00
|
|
|
deriveUnifiedFullViewingKeysFromSeed(seed, numberOfAccounts, networkId = network.id).map {
|
|
|
|
UnifiedFullViewingKey(it)
|
2021-03-31 23:23:41 -07:00
|
|
|
}.toTypedArray()
|
2020-09-11 00:33:25 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Given a spending key, return the associated viewing key.
|
|
|
|
*
|
|
|
|
* @param spendingKey the key from which to derive the viewing key.
|
|
|
|
*
|
|
|
|
* @return the viewing key that corresponds to the spending key.
|
|
|
|
*/
|
2022-08-23 06:49:00 -07:00
|
|
|
override suspend fun deriveViewingKey(
|
|
|
|
spendingKey: String,
|
|
|
|
network: ZcashNetwork
|
|
|
|
): String = withRustBackendLoaded {
|
2021-04-09 18:43:07 -07:00
|
|
|
deriveExtendedFullViewingKey(spendingKey, networkId = network.id)
|
2020-09-11 00:33:25 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Given a seed and a number of accounts, return the associated spending keys.
|
|
|
|
*
|
|
|
|
* @param seed the seed from which to derive spending keys.
|
|
|
|
* @param numberOfAccounts the number of accounts to use. Multiple accounts are not fully
|
|
|
|
* supported so the default value of 1 is recommended.
|
|
|
|
*
|
|
|
|
* @return the spending keys that correspond to the seed, formatted as Strings.
|
|
|
|
*/
|
2022-08-23 06:49:00 -07:00
|
|
|
override suspend fun deriveSpendingKeys(
|
|
|
|
seed: ByteArray,
|
|
|
|
network: ZcashNetwork,
|
|
|
|
numberOfAccounts: Int
|
|
|
|
): Array<String> = withRustBackendLoaded {
|
|
|
|
deriveExtendedSpendingKeys(seed, numberOfAccounts, networkId = network.id)
|
|
|
|
}
|
2020-09-11 00:33:25 -07:00
|
|
|
|
|
|
|
/**
|
2022-08-04 10:09:19 -07:00
|
|
|
* Given a seed and account index, return the associated Unified Address.
|
2020-09-11 00:33:25 -07:00
|
|
|
*
|
|
|
|
* @param seed the seed from which to derive the address.
|
|
|
|
* @param accountIndex the index of the account to use for deriving the address. Multiple
|
|
|
|
* accounts are not fully supported so the default value of 1 is recommended.
|
|
|
|
*
|
|
|
|
* @return the address that corresponds to the seed and account index.
|
|
|
|
*/
|
2022-08-04 10:09:19 -07:00
|
|
|
override suspend fun deriveUnifiedAddress(seed: ByteArray, network: ZcashNetwork, accountIndex: Int): String =
|
2020-09-11 00:33:25 -07:00
|
|
|
withRustBackendLoaded {
|
2022-08-04 10:09:19 -07:00
|
|
|
deriveUnifiedAddressFromSeed(seed, accountIndex, networkId = network.id)
|
2020-09-11 00:33:25 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2022-08-04 10:09:19 -07:00
|
|
|
* Given a Unified Full Viewing Key string, return the associated Unified Address.
|
2020-09-11 00:33:25 -07:00
|
|
|
*
|
|
|
|
* @param viewingKey the viewing key to use for deriving the address. The viewing key is tied to
|
|
|
|
* a specific account so no account index is required.
|
|
|
|
*
|
|
|
|
* @return the address that corresponds to the viewing key.
|
|
|
|
*/
|
2022-08-23 13:28:01 -07:00
|
|
|
override suspend fun deriveUnifiedAddress(
|
2022-08-23 06:49:00 -07:00
|
|
|
viewingKey: String,
|
|
|
|
network: ZcashNetwork
|
|
|
|
): String = withRustBackendLoaded {
|
2022-08-04 10:09:19 -07:00
|
|
|
deriveUnifiedAddressFromViewingKey(viewingKey, networkId = network.id)
|
2020-09-11 00:33:25 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// WIP probably shouldn't be used just yet. Why?
|
|
|
|
// - because we need the private key associated with this seed and this function doesn't return it.
|
|
|
|
// - the underlying implementation needs to be split out into a few lower-level calls
|
2022-08-23 06:49:00 -07:00
|
|
|
override suspend fun deriveTransparentAddress(
|
|
|
|
seed: ByteArray,
|
|
|
|
network: ZcashNetwork,
|
|
|
|
account: Int,
|
|
|
|
index: Int
|
|
|
|
): String = withRustBackendLoaded {
|
2021-04-09 18:43:07 -07:00
|
|
|
deriveTransparentAddressFromSeed(seed, account, index, networkId = network.id)
|
2021-02-17 13:07:57 -08:00
|
|
|
}
|
|
|
|
|
2022-08-23 06:49:00 -07:00
|
|
|
override suspend fun deriveTransparentAddressFromPublicKey(
|
|
|
|
publicKey: String,
|
|
|
|
network: ZcashNetwork
|
|
|
|
): String = withRustBackendLoaded {
|
2022-08-17 06:48:02 -07:00
|
|
|
deriveTransparentAddressFromPubKey(pk = publicKey, networkId = network.id)
|
2021-03-31 23:23:41 -07:00
|
|
|
}
|
|
|
|
|
2022-08-23 13:28:01 -07:00
|
|
|
override suspend fun deriveTransparentAddressFromAccountPrivateKey(
|
2022-08-23 06:49:00 -07:00
|
|
|
privateKey: String,
|
2022-08-23 13:28:01 -07:00
|
|
|
network: ZcashNetwork,
|
|
|
|
index: Int
|
2022-08-23 06:49:00 -07:00
|
|
|
): String = withRustBackendLoaded {
|
2022-08-22 13:36:51 -07:00
|
|
|
deriveTransparentAddressFromAccountPrivKey(sk = privateKey, index = index, networkId = network.id)
|
2021-02-17 13:07:57 -08:00
|
|
|
}
|
|
|
|
|
2022-08-23 13:28:01 -07:00
|
|
|
override suspend fun deriveTransparentAccountPrivateKey(
|
2022-08-23 06:49:00 -07:00
|
|
|
seed: ByteArray,
|
|
|
|
network: ZcashNetwork,
|
2022-08-23 13:28:01 -07:00
|
|
|
account: Int
|
2022-08-23 06:49:00 -07:00
|
|
|
): String = withRustBackendLoaded {
|
2022-05-18 18:04:30 -07:00
|
|
|
deriveTransparentAccountPrivKeyFromSeed(seed, account, networkId = network.id)
|
2020-09-11 00:33:25 -07:00
|
|
|
}
|
|
|
|
|
2022-08-17 06:48:02 -07:00
|
|
|
@Suppress("UNUSED_PARAMETER")
|
2022-08-04 10:09:19 -07:00
|
|
|
fun validateUnifiedFullViewingKey(viewingKey: UnifiedFullViewingKey, networkId: Int = ZcashNetwork.Mainnet.id) {
|
2022-08-17 06:48:02 -07:00
|
|
|
// TODO [#654] https://github.com/zcash/zcash-android-wallet-sdk/issues/654
|
2020-09-11 00:33:25 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A helper function to ensure that the Rust libraries are loaded before any code in this
|
|
|
|
* class attempts to interact with it, indirectly, by invoking JNI functions. It would be
|
|
|
|
* nice to have an annotation like @UsesSystemLibrary for this
|
|
|
|
*/
|
2021-10-21 13:05:02 -07:00
|
|
|
private suspend fun <T> withRustBackendLoaded(block: () -> T): T {
|
|
|
|
RustBackend.rustLibraryLoader.load()
|
2020-09-11 00:33:25 -07:00
|
|
|
return block()
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// JNI functions
|
|
|
|
//
|
|
|
|
|
|
|
|
@JvmStatic
|
|
|
|
private external fun deriveExtendedSpendingKeys(
|
|
|
|
seed: ByteArray,
|
2021-04-09 18:43:07 -07:00
|
|
|
numberOfAccounts: Int,
|
2022-06-23 05:31:02 -07:00
|
|
|
networkId: Int
|
2020-09-11 00:33:25 -07:00
|
|
|
): Array<String>
|
|
|
|
|
|
|
|
@JvmStatic
|
2022-08-04 10:09:19 -07:00
|
|
|
private external fun deriveUnifiedFullViewingKeysFromSeed(
|
2020-09-11 00:33:25 -07:00
|
|
|
seed: ByteArray,
|
2021-04-09 18:43:07 -07:00
|
|
|
numberOfAccounts: Int,
|
2022-06-23 05:31:02 -07:00
|
|
|
networkId: Int
|
2022-08-04 10:09:19 -07:00
|
|
|
): Array<String>
|
2020-09-11 00:33:25 -07:00
|
|
|
|
|
|
|
@JvmStatic
|
2021-04-09 18:43:07 -07:00
|
|
|
private external fun deriveExtendedFullViewingKey(spendingKey: String, networkId: Int): String
|
2020-09-11 00:33:25 -07:00
|
|
|
|
|
|
|
@JvmStatic
|
2022-08-04 10:09:19 -07:00
|
|
|
private external fun deriveUnifiedAddressFromSeed(
|
2020-09-11 00:33:25 -07:00
|
|
|
seed: ByteArray,
|
2021-04-09 18:43:07 -07:00
|
|
|
accountIndex: Int,
|
2022-06-23 05:31:02 -07:00
|
|
|
networkId: Int
|
2020-09-11 00:33:25 -07:00
|
|
|
): String
|
|
|
|
|
|
|
|
@JvmStatic
|
2022-08-04 10:09:19 -07:00
|
|
|
private external fun deriveUnifiedAddressFromViewingKey(key: String, networkId: Int): String
|
2020-09-11 00:33:25 -07:00
|
|
|
|
|
|
|
@JvmStatic
|
2022-08-23 06:49:00 -07:00
|
|
|
private external fun deriveTransparentAddressFromSeed(
|
|
|
|
seed: ByteArray,
|
|
|
|
account: Int,
|
|
|
|
index: Int,
|
|
|
|
networkId: Int
|
|
|
|
): String
|
2021-02-17 13:07:57 -08:00
|
|
|
|
|
|
|
@JvmStatic
|
2021-04-09 18:43:07 -07:00
|
|
|
private external fun deriveTransparentAddressFromPubKey(pk: String, networkId: Int): String
|
2021-03-31 23:23:41 -07:00
|
|
|
|
|
|
|
@JvmStatic
|
2022-05-18 18:04:30 -07:00
|
|
|
private external fun deriveTransparentAddressFromAccountPrivKey(sk: String, index: Int, networkId: Int): String
|
2021-02-17 13:07:57 -08:00
|
|
|
|
|
|
|
@JvmStatic
|
2022-08-23 13:28:01 -07:00
|
|
|
private external fun deriveTransparentAccountPrivKeyFromSeed(
|
2022-08-23 06:49:00 -07:00
|
|
|
seed: ByteArray,
|
|
|
|
account: Int,
|
|
|
|
networkId: Int
|
|
|
|
): String
|
2020-09-11 00:33:25 -07:00
|
|
|
}
|
2021-03-10 10:10:03 -08:00
|
|
|
}
|