[#525] Add `AddressType.Unified` and `Synchronizer.isValidUnifiedAddr`
This commit is contained in:
parent
cfdd3640a9
commit
46af668449
10
CHANGELOG.md
10
CHANGELOG.md
|
@ -4,9 +4,8 @@ Change Log
|
|||
## Unreleased
|
||||
|
||||
### Added
|
||||
- `cash.z.ecc.android.sdk.type.UnifiedFullViewingKey`, representing a Unified Full Viewing
|
||||
Key as specified in [ZIP 316](https://zips.z.cash/zip-0316#encoding-of-unified-full-incoming-viewing-keys).
|
||||
- TODO: Actually encode per ZIP 316.
|
||||
- `cash.z.ecc.android.sdk`:
|
||||
- `Synchronizer.isValidUnifiedAddr`
|
||||
- `cash.z.ecc.android.sdk.tool`:
|
||||
- `DerivationTool.deriveTransparentAccountPrivateKey`
|
||||
- `DerivationTool.deriveTransparentAddressFromAccountPrivateKey`
|
||||
|
@ -14,6 +13,11 @@ Change Log
|
|||
- `DerivationTool.deriveUnifiedFullViewingKeys`
|
||||
- `DerivationTool.validateUnifiedFullViewingKey`
|
||||
- Still unimplemented.
|
||||
- `cash.z.ecc.android.sdk.type`:
|
||||
- `AddressType.Unified`
|
||||
- `UnifiedFullViewingKey`, representing a Unified Full Viewing Key as specified in
|
||||
[ZIP 316](https://zips.z.cash/zip-0316#encoding-of-unified-full-incoming-viewing-keys).
|
||||
- TODO: Actually encode per ZIP 316.
|
||||
|
||||
### Changed
|
||||
- The following methods now take or return `UnifiedFullViewingKey` instead of
|
||||
|
|
|
@ -55,6 +55,7 @@ import cash.z.ecc.android.sdk.tool.DerivationTool
|
|||
import cash.z.ecc.android.sdk.type.AddressType
|
||||
import cash.z.ecc.android.sdk.type.AddressType.Shielded
|
||||
import cash.z.ecc.android.sdk.type.AddressType.Transparent
|
||||
import cash.z.ecc.android.sdk.type.AddressType.Unified
|
||||
import cash.z.ecc.android.sdk.type.ConsensusMatchType
|
||||
import cash.z.wallet.sdk.rpc.Service
|
||||
import io.grpc.ManagedChannel
|
||||
|
@ -698,21 +699,22 @@ class SdkSynchronizer internal constructor(
|
|||
override suspend fun isValidTransparentAddr(address: String) =
|
||||
txManager.isValidTransparentAddress(address)
|
||||
|
||||
override suspend fun isValidUnifiedAddr(address: String) =
|
||||
txManager.isValidUnifiedAddress(address)
|
||||
|
||||
override suspend fun validateAddress(address: String): AddressType {
|
||||
return try {
|
||||
if (isValidShieldedAddr(address)) Shielded else Transparent
|
||||
} catch (zError: Throwable) {
|
||||
var message = zError.message
|
||||
try {
|
||||
if (isValidTransparentAddr(address)) Transparent else Shielded
|
||||
} catch (tError: Throwable) {
|
||||
AddressType.Invalid(
|
||||
if (message != tError.message) "$message and ${tError.message}" else (
|
||||
message
|
||||
?: "Invalid"
|
||||
)
|
||||
)
|
||||
if (isValidShieldedAddr(address)) {
|
||||
Shielded
|
||||
} else if (isValidTransparentAddr(address)) {
|
||||
Transparent
|
||||
} else if (isValidUnifiedAddr(address)) {
|
||||
Unified
|
||||
} else {
|
||||
AddressType.Invalid("Not a Zcash address")
|
||||
}
|
||||
} catch (@Suppress("TooGenericExceptionCaught") error: Throwable) {
|
||||
AddressType.Invalid(error.message ?: "Invalid")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -241,6 +241,20 @@ interface Synchronizer {
|
|||
*/
|
||||
suspend fun isValidTransparentAddr(address: String): Boolean
|
||||
|
||||
/**
|
||||
* Returns true when the given address is a valid ZIP 316 unified address.
|
||||
*
|
||||
* This method is intended for type checking (e.g. form validation). Invalid
|
||||
* addresses will throw an exception.
|
||||
*
|
||||
* @param address the address to validate.
|
||||
*
|
||||
* @return true when the given address is a valid unified address.
|
||||
*
|
||||
* @throws RuntimeException when the address is invalid.
|
||||
*/
|
||||
suspend fun isValidUnifiedAddr(address: String): Boolean
|
||||
|
||||
/**
|
||||
* Validate whether the server and this SDK share the same consensus branch. This is
|
||||
* particularly important to check around network updates so that any wallet that's connected to
|
||||
|
@ -256,10 +270,11 @@ interface Synchronizer {
|
|||
|
||||
/**
|
||||
* Validates the given address, returning information about why it is invalid. This is a
|
||||
* convenience method that combines the behavior of [isValidShieldedAddr] and
|
||||
* [isValidTransparentAddr] into one call so that the developer doesn't have to worry about
|
||||
* handling the exceptions that they throw. Rather, exceptions are converted to
|
||||
* [AddressType.Invalid] which has a `reason` property describing why it is invalid.
|
||||
* convenience method that combines the behavior of [isValidShieldedAddr],
|
||||
* [isValidTransparentAddr], and [isValidUnifiedAddr] into one call so that the developer
|
||||
* doesn't have to worry about handling the exceptions that they throw. Rather, exceptions
|
||||
* are converted to [AddressType.Invalid] which has a `reason` property describing why it is
|
||||
* invalid.
|
||||
*
|
||||
* @param address the address to validate.
|
||||
*
|
||||
|
|
|
@ -234,6 +234,9 @@ class PersistentTransactionManager(
|
|||
override suspend fun isValidTransparentAddress(address: String) =
|
||||
encoder.isValidTransparentAddress(address)
|
||||
|
||||
override suspend fun isValidUnifiedAddress(address: String) =
|
||||
encoder.isValidUnifiedAddress(address)
|
||||
|
||||
override suspend fun cancel(pendingId: Long): Boolean {
|
||||
return pendingTransactionDao {
|
||||
val tx = findById(pendingId)
|
||||
|
|
|
@ -51,6 +51,16 @@ interface TransactionEncoder {
|
|||
*/
|
||||
suspend fun isValidTransparentAddress(address: String): Boolean
|
||||
|
||||
/**
|
||||
* Utility function to help with validation. This is not called during [createTransaction]
|
||||
* because this class asserts that all validation is done externally by the UI, for now.
|
||||
*
|
||||
* @param address the address to validate
|
||||
*
|
||||
* @return true when the given address is a valid ZIP 316 Unified Address
|
||||
*/
|
||||
suspend fun isValidUnifiedAddress(address: String): Boolean
|
||||
|
||||
/**
|
||||
* Return the consensus branch that the encoder is using when making transactions.
|
||||
*/
|
||||
|
|
|
@ -97,6 +97,15 @@ interface OutboundTransactionManager {
|
|||
*/
|
||||
suspend fun isValidTransparentAddress(address: String): Boolean
|
||||
|
||||
/**
|
||||
* Return true when the given address is a valid ZIP 316 Unified Address.
|
||||
*
|
||||
* @param address the address to validate.
|
||||
*
|
||||
* @return true when the given address is a valid ZIP 316 Unified Address.
|
||||
*/
|
||||
suspend fun isValidUnifiedAddress(address: String): Boolean
|
||||
|
||||
/**
|
||||
* Attempt to cancel a transaction.
|
||||
*
|
||||
|
|
|
@ -81,6 +81,17 @@ internal class WalletTransactionEncoder(
|
|||
override suspend fun isValidTransparentAddress(address: String): Boolean =
|
||||
rustBackend.isValidTransparentAddr(address)
|
||||
|
||||
/**
|
||||
* Utility function to help with validation. This is not called during [createTransaction]
|
||||
* because this class asserts that all validation is done externally by the UI, for now.
|
||||
*
|
||||
* @param address the address to validate
|
||||
*
|
||||
* @return true when the given address is a valid ZIP 316 Unified Address
|
||||
*/
|
||||
override suspend fun isValidUnifiedAddress(address: String): Boolean =
|
||||
rustBackend.isValidUnifiedAddr(address)
|
||||
|
||||
override suspend fun getConsensusBranchId(): Long {
|
||||
val height = repository.lastScannedHeight()
|
||||
if (height < rustBackend.network.saplingActivationHeight) {
|
||||
|
|
|
@ -310,6 +310,9 @@ internal class RustBackend private constructor(
|
|||
override fun isValidTransparentAddr(addr: String) =
|
||||
isValidTransparentAddress(addr, networkId = network.id)
|
||||
|
||||
override fun isValidUnifiedAddr(addr: String) =
|
||||
isValidUnifiedAddress(addr, networkId = network.id)
|
||||
|
||||
override fun getBranchIdForHeight(height: BlockHeight): Long =
|
||||
branchIdForHeight(height.value, networkId = network.id)
|
||||
|
||||
|
@ -409,6 +412,9 @@ internal class RustBackend private constructor(
|
|||
@JvmStatic
|
||||
private external fun isValidTransparentAddress(addr: String, networkId: Int): Boolean
|
||||
|
||||
@JvmStatic
|
||||
private external fun isValidUnifiedAddress(addr: String, networkId: Int): Boolean
|
||||
|
||||
@JvmStatic
|
||||
private external fun getBalance(dbDataPath: String, account: Int, networkId: Int): Long
|
||||
|
||||
|
|
|
@ -46,6 +46,8 @@ internal interface RustBackendWelding {
|
|||
|
||||
fun isValidTransparentAddr(addr: String): Boolean
|
||||
|
||||
fun isValidUnifiedAddr(addr: String): Boolean
|
||||
|
||||
suspend fun getShieldedAddress(account: Int = 0): String
|
||||
|
||||
suspend fun getTransparentAddress(account: Int = 0, index: Int = 0): String
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
package cash.z.ecc.android.sdk.type
|
||||
|
||||
/**
|
||||
* Validation helper class, representing the types of addresses, either Shielded, Transparent or
|
||||
* Invalid. Used in conjuction with [cash.z.ecc.android.sdk.Synchronizer.validateAddress].
|
||||
* Validation helper class, representing the types of addresses, either Shielded,
|
||||
* Transparent, Unified, or Invalid. Used in conjuction with
|
||||
* [cash.z.ecc.android.sdk.Synchronizer.validateAddress].
|
||||
*/
|
||||
sealed class AddressType {
|
||||
/**
|
||||
|
@ -20,6 +21,11 @@ sealed class AddressType {
|
|||
*/
|
||||
object Transparent : Valid, AddressType()
|
||||
|
||||
/**
|
||||
* An instance of [AddressType] corresponding to a valid ZIP 316 unified address.
|
||||
*/
|
||||
object Unified : Valid, AddressType()
|
||||
|
||||
/**
|
||||
* An instance of [AddressType] corresponding to an invalid address.
|
||||
*
|
||||
|
|
|
@ -466,6 +466,27 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_isValidTran
|
|||
unwrap_exc_or(&env, res, JNI_FALSE)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_isValidUnifiedAddress(
|
||||
env: JNIEnv<'_>,
|
||||
_: JClass<'_>,
|
||||
addr: JString<'_>,
|
||||
network_id: jint,
|
||||
) -> jboolean {
|
||||
let res = panic::catch_unwind(|| {
|
||||
let network = parse_network(network_id as u32)?;
|
||||
let addr = utils::java_string_to_rust(&env, addr);
|
||||
|
||||
match RecipientAddress::decode(&network, &addr) {
|
||||
Some(addr) => match addr {
|
||||
RecipientAddress::Shielded(_) | RecipientAddress::Transparent(_) => Ok(JNI_FALSE),
|
||||
},
|
||||
None => Err(format_err!("Address is for the wrong network")),
|
||||
}
|
||||
});
|
||||
unwrap_exc_or(&env, res, JNI_FALSE)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_getBalance(
|
||||
env: JNIEnv<'_>,
|
||||
|
|
Loading…
Reference in New Issue