Exposed support for address validation.

This commit is contained in:
Kevin Gorham 2020-01-08 03:57:42 -05:00
parent cf0d86a3da
commit aaa823081b
No known key found for this signature in database
GPG Key ID: CCA55602DF49FC38
6 changed files with 86 additions and 0 deletions

View File

@ -302,6 +302,29 @@ class SdkSynchronizer internal constructor(
twig("Monitoring pending transaction (id: ${it.id}) for updates...")
manager.monitorById(it.id)
}.distinctUntilChanged()
override suspend fun isValidShieldedAddr(address: String) = manager.isValidShieldedAddress(address)
override suspend fun isValidTransparentAddr(address: String) =
manager.isValidTransparentAddress(address)
override suspend fun validateAddress(address: String): Synchronizer.AddressType {
return try {
isValidShieldedAddr(address)
Synchronizer.AddressType.Shielded
} catch (zError: Throwable) {
var message = zError.message
try {
isValidTransparentAddr(address)
Synchronizer.AddressType.Transparent
} catch (tError: Throwable) {
Synchronizer.AddressType.Invalid(
if (message != tError.message) "$message and ${tError.message}" else (message
?: "Invalid")
)
}
}
}
}
/**

View File

@ -111,6 +111,32 @@ interface Synchronizer {
fromAccountIndex: Int = 0
): Flow<PendingTransaction>
/**
* Returns true when the given address is a valid z-addr. Invalid addresses will throw an
* exception. Valid z-addresses have these characteristics: //TODO
*
* @param address the address to validate.
* @throws RuntimeException when the address is invalid.
*/
suspend fun isValidShieldedAddr(address: String): Boolean
/**
* Returns true when the given address is a valid t-addr. Invalid addresses will throw an
* exception. Valid t-addresses have these characteristics: //TODO
*
* @param address the address to validate.
* @throws RuntimeException when the address is invalid.
*/
suspend fun isValidTransparentAddr(address: String): Boolean
/**
* Validates the given address, returning information about why it is invalid.
*
* @param address the address to validate.
*/
suspend fun validateAddress(address: String): AddressType
/**
* Attempts to cancel a transaction that is about to be sent. Typically, cancellation is only
* an option if the transaction has not yet been submitted to the server.
@ -178,4 +204,13 @@ interface Synchronizer {
*/
SYNCED
}
sealed class AddressType {
interface Valid
object Shielded : Valid, AddressType()
object Transparent : Valid, AddressType()
class Invalid(val reason: String = "Invalid") : AddressType()
val isNotValid get() = this !is Valid
}
}

View File

@ -168,6 +168,12 @@ class PersistentTransactionManager(
return pendingTransactionDao { monitorById(id) }
}
override suspend fun isValidShieldedAddress(address: String) =
encoder.isValidShieldedAddress(address)
override suspend fun isValidTransparentAddress(address: String) =
encoder.isValidTransparentAddress(address)
override suspend fun cancel(pendingTx: PendingTransaction): Boolean {
return pendingTransactionDao {
val tx = findById(pendingTx.id)

View File

@ -13,4 +13,7 @@ interface TransactionEncoder {
memo: ByteArray? = byteArrayOf(),
fromAccountIndex: Int = 0
): EncodedTransaction
suspend fun isValidShieldedAddress(address: String): Boolean
suspend fun isValidTransparentAddress(address: String): Boolean
}

View File

@ -20,6 +20,9 @@ interface OutboundTransactionManager {
suspend fun applyMinedHeight(pendingTx: PendingTransaction, minedHeight: Int)
suspend fun monitorById(id: Long): Flow<PendingTransaction>
suspend fun isValidShieldedAddress(address: String): Boolean
suspend fun isValidTransparentAddress(address: String): Boolean
/**
* Attempt to cancel a transaction.
*

View File

@ -34,6 +34,22 @@ class WalletTransactionEncoder(
?: throw TransactionEncoderException.TransactionNotFoundException(transactionId)
}
/**
* 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.
*/
override suspend fun isValidShieldedAddress(address: String): Boolean = withContext(IO) {
rustBackend.isValidShieldedAddr(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.
*/
override suspend fun isValidTransparentAddress(address: String): Boolean = withContext(IO) {
rustBackend.isValidTransparentAddr(address)
}
/**
* Does the proofs and processing required to create a transaction to spend funds and inserts
* the result in the database. On average, this call takes over 10 seconds.