Adjust `Synchronizer.proposeShielding` API
- Returns `null` when there are no funds to shield or the shielding threshold is not met. - Throws an exception if there are funds to shield in more than one transparent receiver within the account. - Has an optional parameter for specifying which transparent receiver to shield funds from. Part of Electric-Coin-Company/zcash-android-wallet-sdk#680.
This commit is contained in:
parent
e36bbdec7a
commit
abffb3f9ee
|
@ -31,8 +31,9 @@ interface Backend {
|
||||||
suspend fun proposeShielding(
|
suspend fun proposeShielding(
|
||||||
account: Int,
|
account: Int,
|
||||||
shieldingThreshold: Long,
|
shieldingThreshold: Long,
|
||||||
memo: ByteArray? = byteArrayOf()
|
memo: ByteArray? = byteArrayOf(),
|
||||||
): ProposalUnsafe
|
transparentReceiver: String? = null
|
||||||
|
): ProposalUnsafe?
|
||||||
|
|
||||||
suspend fun createProposedTransaction(
|
suspend fun createProposedTransaction(
|
||||||
proposal: ProposalUnsafe,
|
proposal: ProposalUnsafe,
|
||||||
|
|
|
@ -308,19 +308,23 @@ class RustBackend private constructor(
|
||||||
override suspend fun proposeShielding(
|
override suspend fun proposeShielding(
|
||||||
account: Int,
|
account: Int,
|
||||||
shieldingThreshold: Long,
|
shieldingThreshold: Long,
|
||||||
memo: ByteArray?
|
memo: ByteArray?,
|
||||||
): ProposalUnsafe {
|
transparentReceiver: String?
|
||||||
|
): ProposalUnsafe? {
|
||||||
return withContext(SdkDispatchers.DATABASE_IO) {
|
return withContext(SdkDispatchers.DATABASE_IO) {
|
||||||
ProposalUnsafe.parse(
|
|
||||||
proposeShielding(
|
proposeShielding(
|
||||||
dataDbFile.absolutePath,
|
dataDbFile.absolutePath,
|
||||||
account,
|
account,
|
||||||
shieldingThreshold,
|
shieldingThreshold,
|
||||||
memo ?: ByteArray(0),
|
memo ?: ByteArray(0),
|
||||||
|
transparentReceiver,
|
||||||
networkId = networkId,
|
networkId = networkId,
|
||||||
useZip317Fees = IS_USE_ZIP_317_FEES
|
useZip317Fees = IS_USE_ZIP_317_FEES
|
||||||
|
)?.let {
|
||||||
|
ProposalUnsafe.parse(
|
||||||
|
it
|
||||||
)
|
)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -588,9 +592,10 @@ class RustBackend private constructor(
|
||||||
account: Int,
|
account: Int,
|
||||||
shieldingThreshold: Long,
|
shieldingThreshold: Long,
|
||||||
memo: ByteArray,
|
memo: ByteArray,
|
||||||
|
transparentReceiver: String?,
|
||||||
networkId: Int,
|
networkId: Int,
|
||||||
useZip317Fees: Boolean
|
useZip317Fees: Boolean
|
||||||
): ByteArray
|
): ByteArray?
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@Suppress("LongParameterList")
|
@Suppress("LongParameterList")
|
||||||
|
|
|
@ -1482,6 +1482,7 @@ pub extern "C" fn Java_cash_z_ecc_android_sdk_internal_jni_RustBackend_proposeSh
|
||||||
account: jint,
|
account: jint,
|
||||||
shielding_threshold: jlong,
|
shielding_threshold: jlong,
|
||||||
memo: JByteArray<'local>,
|
memo: JByteArray<'local>,
|
||||||
|
transparent_receiver: JString<'local>,
|
||||||
network_id: jint,
|
network_id: jint,
|
||||||
use_zip317_fees: jboolean,
|
use_zip317_fees: jboolean,
|
||||||
) -> jbyteArray {
|
) -> jbyteArray {
|
||||||
|
@ -1494,10 +1495,36 @@ pub extern "C" fn Java_cash_z_ecc_android_sdk_internal_jni_RustBackend_proposeSh
|
||||||
.map_err(|()| format_err!("Invalid shielding threshold, out of range"))?;
|
.map_err(|()| format_err!("Invalid shielding threshold, out of range"))?;
|
||||||
let memo_bytes = env.convert_byte_array(memo).unwrap();
|
let memo_bytes = env.convert_byte_array(memo).unwrap();
|
||||||
|
|
||||||
|
let transparent_receiver =
|
||||||
|
match utils::java_nullable_string_to_rust(env, &transparent_receiver) {
|
||||||
|
None => Ok(None),
|
||||||
|
Some(addr) => match Address::decode(&network, &addr) {
|
||||||
|
None => Err(format_err!("Transparent receiver is for the wrong network")),
|
||||||
|
Some(addr) => match addr {
|
||||||
|
Address::Sapling(_) | Address::Unified(_) => Err(format_err!(
|
||||||
|
"Transparent receiver is not a transparent address"
|
||||||
|
)),
|
||||||
|
Address::Transparent(addr) => {
|
||||||
|
if db_data
|
||||||
|
.get_transparent_receivers(account)?
|
||||||
|
.contains_key(&addr)
|
||||||
|
{
|
||||||
|
Ok(Some(addr))
|
||||||
|
} else {
|
||||||
|
Err(format_err!(
|
||||||
|
"Transparent receiver does not belong to account {}",
|
||||||
|
u32::from(account),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}?;
|
||||||
|
|
||||||
let min_confirmations = 0;
|
let min_confirmations = 0;
|
||||||
let min_confirmations_for_heights = NonZeroU32::new(1).unwrap();
|
let min_confirmations_for_heights = NonZeroU32::new(1).unwrap();
|
||||||
|
|
||||||
let from_addrs: Vec<TransparentAddress> = db_data
|
let account_receivers = db_data
|
||||||
.get_target_and_anchor_heights(min_confirmations_for_heights)
|
.get_target_and_anchor_heights(min_confirmations_for_heights)
|
||||||
.map_err(|e| format_err!("Error while fetching anchor height: {}", e))
|
.map_err(|e| format_err!("Error while fetching anchor height: {}", e))
|
||||||
.and_then(|opt_anchor| {
|
.and_then(|opt_anchor| {
|
||||||
|
@ -1515,9 +1542,23 @@ pub extern "C" fn Java_cash_z_ecc_android_sdk_internal_jni_RustBackend_proposeSh
|
||||||
e
|
e
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
})?
|
})?;
|
||||||
.into_keys()
|
|
||||||
.collect();
|
let from_addrs = if let Some((addr, _)) = transparent_receiver.map_or_else(||
|
||||||
|
if account_receivers.len() > 1 {
|
||||||
|
Err(format_err!(
|
||||||
|
"Account has more than one transparent receiver with funds to shield; this is not yet supported by the SDK. Provide a specific transparent receiver to shield funds from."
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
Ok(account_receivers.iter().next().map(|(a, v)| (*a, *v)))
|
||||||
|
},
|
||||||
|
|addr| Ok(account_receivers.get(&addr).map(|value| (addr, *value)))
|
||||||
|
)?.filter(|(_, value)| *value >= shielding_threshold.into()) {
|
||||||
|
[addr]
|
||||||
|
} else {
|
||||||
|
// There are no transparent funds to shield; don't create a proposal.
|
||||||
|
return Ok(ptr::null_mut());
|
||||||
|
};
|
||||||
|
|
||||||
let memo = Memo::from_bytes(&memo_bytes).unwrap();
|
let memo = Memo::from_bytes(&memo_bytes).unwrap();
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,10 @@ pub(crate) fn java_string_to_rust(env: &mut JNIEnv, jstring: &JString) -> String
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn java_nullable_string_to_rust(env: &mut JNIEnv, jstring: &JString) -> Option<String> {
|
||||||
|
(!jstring.is_null()).then(|| java_string_to_rust(env, jstring))
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn rust_bytes_to_java<'a>(
|
pub(crate) fn rust_bytes_to_java<'a>(
|
||||||
env: &JNIEnv<'a>,
|
env: &JNIEnv<'a>,
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
|
|
|
@ -129,12 +129,14 @@ class TestWallet(
|
||||||
|
|
||||||
synchronizer.getTransparentBalance(transparentAddress).let { walletBalance ->
|
synchronizer.getTransparentBalance(transparentAddress).let { walletBalance ->
|
||||||
if (walletBalance.value > 0L) {
|
if (walletBalance.value > 0L) {
|
||||||
|
synchronizer.proposeShielding(shieldedSpendingKey.account, Zatoshi(100000))?.let {
|
||||||
synchronizer.createProposedTransactions(
|
synchronizer.createProposedTransactions(
|
||||||
synchronizer.proposeShielding(shieldedSpendingKey.account, Zatoshi(100000)),
|
it,
|
||||||
shieldedSpendingKey
|
shieldedSpendingKey
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,14 +68,16 @@ class GetBalanceFragment : BaseDemoFragment<FragmentGetBalanceBinding>() {
|
||||||
Account.DEFAULT
|
Account.DEFAULT
|
||||||
)
|
)
|
||||||
sharedViewModel.synchronizerFlow.value?.let { synchronizer ->
|
sharedViewModel.synchronizerFlow.value?.let { synchronizer ->
|
||||||
|
synchronizer.proposeShielding(usk.account, Zatoshi(100000))?.let { it1 ->
|
||||||
synchronizer.createProposedTransactions(
|
synchronizer.createProposedTransactions(
|
||||||
synchronizer.proposeShielding(usk.account, Zatoshi(100000)),
|
it1,
|
||||||
usk
|
usk
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
monitorChanges()
|
monitorChanges()
|
||||||
}
|
}
|
||||||
|
|
|
@ -230,12 +230,14 @@ class WalletViewModel(application: Application) : AndroidViewModel(application)
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
val spendingKey = spendingKey.filterNotNull().first()
|
val spendingKey = spendingKey.filterNotNull().first()
|
||||||
kotlin.runCatching {
|
kotlin.runCatching {
|
||||||
|
synchronizer.proposeShielding(spendingKey.account, Zatoshi(100000))?.let {
|
||||||
synchronizer.createProposedTransactions(
|
synchronizer.createProposedTransactions(
|
||||||
synchronizer.proposeShielding(spendingKey.account, Zatoshi(100000)),
|
it,
|
||||||
spendingKey
|
spendingKey
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.onSuccess { mutableSendState.value = SendState.Sent(it.toList()) }
|
}
|
||||||
|
.onSuccess { it?.let { mutableSendState.value = SendState.Sent(it.toList()) } }
|
||||||
.onFailure { mutableSendState.value = SendState.Error(it) }
|
.onFailure { mutableSendState.value = SendState.Error(it) }
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -132,12 +132,14 @@ class TestWallet(
|
||||||
Twig.debug { "FOUND utxo balance of total: $walletBalance" }
|
Twig.debug { "FOUND utxo balance of total: $walletBalance" }
|
||||||
|
|
||||||
if (walletBalance.value > 0L) {
|
if (walletBalance.value > 0L) {
|
||||||
|
synchronizer.proposeShielding(spendingKey.account, Zatoshi(100000))?.let {
|
||||||
synchronizer.createProposedTransactions(
|
synchronizer.createProposedTransactions(
|
||||||
synchronizer.proposeShielding(spendingKey.account, Zatoshi(100000)),
|
it,
|
||||||
spendingKey
|
spendingKey
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,8 +89,9 @@ internal class FakeRustBackend(
|
||||||
override suspend fun proposeShielding(
|
override suspend fun proposeShielding(
|
||||||
account: Int,
|
account: Int,
|
||||||
shieldingThreshold: Long,
|
shieldingThreshold: Long,
|
||||||
memo: ByteArray?
|
memo: ByteArray?,
|
||||||
): ProposalUnsafe {
|
transparentReceiver: String?
|
||||||
|
): ProposalUnsafe? {
|
||||||
TODO("Not yet implemented")
|
TODO("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -570,8 +570,9 @@ class SdkSynchronizer private constructor(
|
||||||
override suspend fun proposeShielding(
|
override suspend fun proposeShielding(
|
||||||
account: Account,
|
account: Account,
|
||||||
shieldingThreshold: Zatoshi,
|
shieldingThreshold: Zatoshi,
|
||||||
memo: String
|
memo: String,
|
||||||
): Proposal = txManager.proposeShielding(account, shieldingThreshold, memo)
|
transparentReceiver: String?
|
||||||
|
): Proposal? = txManager.proposeShielding(account, shieldingThreshold, memo, transparentReceiver)
|
||||||
|
|
||||||
@Throws(TransactionEncoderException::class)
|
@Throws(TransactionEncoderException::class)
|
||||||
override suspend fun createProposedTransactions(
|
override suspend fun createProposedTransactions(
|
||||||
|
@ -636,7 +637,7 @@ class SdkSynchronizer private constructor(
|
||||||
message = "Upcoming SDK 2.1 will create multiple transactions at once for some recipients.",
|
message = "Upcoming SDK 2.1 will create multiple transactions at once for some recipients.",
|
||||||
replaceWith =
|
replaceWith =
|
||||||
ReplaceWith(
|
ReplaceWith(
|
||||||
"createProposedTransactions(proposeShielding(usk.account, shieldingThreshold, memo), usk)"
|
"proposeShielding(usk.account, shieldingThreshold, memo)?.let { createProposedTransactions(it, usk) }"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@Throws(TransactionEncoderException::class, TransactionSubmitException::class)
|
@Throws(TransactionEncoderException::class, TransactionSubmitException::class)
|
||||||
|
|
|
@ -193,12 +193,23 @@ interface Synchronizer {
|
||||||
* @param shieldingThreshold the minimum transparent balance required before a
|
* @param shieldingThreshold the minimum transparent balance required before a
|
||||||
* proposal will be created.
|
* proposal will be created.
|
||||||
* @param memo the optional memo to include as part of the proposal's transactions.
|
* @param memo the optional memo to include as part of the proposal's transactions.
|
||||||
|
* @param transparentReceiver a specific transparent receiver within the account that
|
||||||
|
* should be the source of transparent funds. Default is
|
||||||
|
* null which will select whichever of the account's
|
||||||
|
* transparent receivers has funds to shield.
|
||||||
|
*
|
||||||
|
* @return the proposal, or null if the transparent balance that would be shielded is
|
||||||
|
* zero or below `shieldingThreshold`.
|
||||||
|
*
|
||||||
|
* @throws Exception if `transparentReceiver` is null and there are transparent funds
|
||||||
|
* in more than one of the account's transparent receivers.
|
||||||
*/
|
*/
|
||||||
suspend fun proposeShielding(
|
suspend fun proposeShielding(
|
||||||
account: Account,
|
account: Account,
|
||||||
shieldingThreshold: Zatoshi,
|
shieldingThreshold: Zatoshi,
|
||||||
memo: String = ZcashSdk.DEFAULT_SHIELD_FUNDS_MEMO_PREFIX
|
memo: String = ZcashSdk.DEFAULT_SHIELD_FUNDS_MEMO_PREFIX,
|
||||||
): Proposal
|
transparentReceiver: String? = null
|
||||||
|
): Proposal?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the transactions in the given proposal.
|
* Creates the transactions in the given proposal.
|
||||||
|
@ -247,7 +258,7 @@ interface Synchronizer {
|
||||||
message = "Upcoming SDK 2.1 will create multiple transactions at once for some recipients.",
|
message = "Upcoming SDK 2.1 will create multiple transactions at once for some recipients.",
|
||||||
replaceWith =
|
replaceWith =
|
||||||
ReplaceWith(
|
ReplaceWith(
|
||||||
"createProposedTransactions(proposeShielding(usk.account, shieldingThreshold, memo), usk)"
|
"proposeShielding(usk.account, shieldingThreshold, memo)?.let { createProposedTransactions(it, usk) }"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
suspend fun shieldFunds(
|
suspend fun shieldFunds(
|
||||||
|
|
|
@ -35,8 +35,9 @@ internal interface TypesafeBackend {
|
||||||
suspend fun proposeShielding(
|
suspend fun proposeShielding(
|
||||||
account: Account,
|
account: Account,
|
||||||
shieldingThreshold: Long,
|
shieldingThreshold: Long,
|
||||||
memo: ByteArray? = byteArrayOf()
|
memo: ByteArray? = byteArrayOf(),
|
||||||
): Proposal
|
transparentReceiver: String? = null
|
||||||
|
): Proposal?
|
||||||
|
|
||||||
suspend fun createProposedTransaction(
|
suspend fun createProposedTransaction(
|
||||||
proposal: Proposal,
|
proposal: Proposal,
|
||||||
|
|
|
@ -54,15 +54,19 @@ internal class TypesafeBackendImpl(private val backend: Backend) : TypesafeBacke
|
||||||
override suspend fun proposeShielding(
|
override suspend fun proposeShielding(
|
||||||
account: Account,
|
account: Account,
|
||||||
shieldingThreshold: Long,
|
shieldingThreshold: Long,
|
||||||
memo: ByteArray?
|
memo: ByteArray?,
|
||||||
): Proposal =
|
transparentReceiver: String?
|
||||||
Proposal.fromUnsafe(
|
): Proposal? =
|
||||||
backend.proposeShielding(
|
backend.proposeShielding(
|
||||||
account.value,
|
account.value,
|
||||||
shieldingThreshold,
|
shieldingThreshold,
|
||||||
memo
|
memo,
|
||||||
)
|
transparentReceiver
|
||||||
|
)?.let {
|
||||||
|
Proposal.fromUnsafe(
|
||||||
|
it
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun createProposedTransaction(
|
override suspend fun createProposedTransaction(
|
||||||
proposal: Proposal,
|
proposal: Proposal,
|
||||||
|
|
|
@ -59,12 +59,23 @@ internal interface OutboundTransactionManager {
|
||||||
* @param shieldingThreshold the minimum transparent balance required before a
|
* @param shieldingThreshold the minimum transparent balance required before a
|
||||||
* proposal will be created.
|
* proposal will be created.
|
||||||
* @param memo the optional memo to include as part of the proposal's transactions.
|
* @param memo the optional memo to include as part of the proposal's transactions.
|
||||||
|
* @param transparentReceiver a specific transparent receiver within the account that
|
||||||
|
* should be the source of transparent funds. Default is
|
||||||
|
* null which will select whichever of the account's
|
||||||
|
* transparent receivers has funds to shield.
|
||||||
|
*
|
||||||
|
* @return the proposal, or null if the transparent balance that would be shielded is
|
||||||
|
* zero or below `shieldingThreshold`.
|
||||||
|
*
|
||||||
|
* @throws Exception if `transparentReceiver` is null and there are transparent funds
|
||||||
|
* in more than one of the account's transparent receivers.
|
||||||
*/
|
*/
|
||||||
suspend fun proposeShielding(
|
suspend fun proposeShielding(
|
||||||
account: Account,
|
account: Account,
|
||||||
shieldingThreshold: Zatoshi,
|
shieldingThreshold: Zatoshi,
|
||||||
memo: String
|
memo: String,
|
||||||
): Proposal
|
transparentReceiver: String?
|
||||||
|
): Proposal?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the transactions in the given proposal.
|
* Creates the transactions in the given proposal.
|
||||||
|
|
|
@ -53,8 +53,9 @@ internal class OutboundTransactionManagerImpl(
|
||||||
override suspend fun proposeShielding(
|
override suspend fun proposeShielding(
|
||||||
account: Account,
|
account: Account,
|
||||||
shieldingThreshold: Zatoshi,
|
shieldingThreshold: Zatoshi,
|
||||||
memo: String
|
memo: String,
|
||||||
): Proposal = encoder.proposeShielding(account, shieldingThreshold, memo.toByteArray())
|
transparentReceiver: String?
|
||||||
|
): Proposal? = encoder.proposeShielding(account, shieldingThreshold, memo.toByteArray(), transparentReceiver)
|
||||||
|
|
||||||
override suspend fun createProposedTransactions(
|
override suspend fun createProposedTransactions(
|
||||||
proposal: Proposal,
|
proposal: Proposal,
|
||||||
|
|
|
@ -64,12 +64,23 @@ internal interface TransactionEncoder {
|
||||||
* @param shieldingThreshold the minimum transparent balance required before a
|
* @param shieldingThreshold the minimum transparent balance required before a
|
||||||
* proposal will be created.
|
* proposal will be created.
|
||||||
* @param memo the optional memo to include as part of the proposal's transactions.
|
* @param memo the optional memo to include as part of the proposal's transactions.
|
||||||
|
* @param transparentReceiver a specific transparent receiver within the account that
|
||||||
|
* should be the source of transparent funds. Default is
|
||||||
|
* null which will select whichever of the account's
|
||||||
|
* transparent receivers has funds to shield.
|
||||||
|
*
|
||||||
|
* @return the proposal, or null if the transparent balance that would be shielded is
|
||||||
|
* zero or below `shieldingThreshold`.
|
||||||
|
*
|
||||||
|
* @throws Exception if `transparentReceiver` is null and there are transparent funds
|
||||||
|
* in more than one of the account's transparent receivers.
|
||||||
*/
|
*/
|
||||||
suspend fun proposeShielding(
|
suspend fun proposeShielding(
|
||||||
account: Account,
|
account: Account,
|
||||||
shieldingThreshold: Zatoshi,
|
shieldingThreshold: Zatoshi,
|
||||||
memo: ByteArray? = byteArrayOf()
|
memo: ByteArray? = byteArrayOf(),
|
||||||
): Proposal
|
transparentReceiver: String? = null
|
||||||
|
): Proposal?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the transactions in the given proposal.
|
* Creates the transactions in the given proposal.
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package cash.z.ecc.android.sdk.internal.transaction
|
package cash.z.ecc.android.sdk.internal.transaction
|
||||||
|
|
||||||
|
import cash.z.ecc.android.sdk.exception.SdkException
|
||||||
import cash.z.ecc.android.sdk.exception.TransactionEncoderException
|
import cash.z.ecc.android.sdk.exception.TransactionEncoderException
|
||||||
import cash.z.ecc.android.sdk.ext.masked
|
import cash.z.ecc.android.sdk.ext.masked
|
||||||
import cash.z.ecc.android.sdk.internal.SaplingParamTool
|
import cash.z.ecc.android.sdk.internal.SaplingParamTool
|
||||||
|
@ -97,11 +98,12 @@ internal class TransactionEncoderImpl(
|
||||||
override suspend fun proposeShielding(
|
override suspend fun proposeShielding(
|
||||||
account: Account,
|
account: Account,
|
||||||
shieldingThreshold: Zatoshi,
|
shieldingThreshold: Zatoshi,
|
||||||
memo: ByteArray?
|
memo: ByteArray?,
|
||||||
): Proposal {
|
transparentReceiver: String?
|
||||||
|
): Proposal? {
|
||||||
@Suppress("TooGenericExceptionCaught")
|
@Suppress("TooGenericExceptionCaught")
|
||||||
return try {
|
return try {
|
||||||
backend.proposeShielding(account, shieldingThreshold.value, memo)
|
backend.proposeShielding(account, shieldingThreshold.value, memo, transparentReceiver)
|
||||||
} catch (t: Throwable) {
|
} catch (t: Throwable) {
|
||||||
// TODO [#680]: if this error matches: Insufficient balance (have 0, need 1000 including fee)
|
// TODO [#680]: if this error matches: Insufficient balance (have 0, need 1000 including fee)
|
||||||
// then consider custom error that says no UTXOs existed to shield
|
// then consider custom error that says no UTXOs existed to shield
|
||||||
|
@ -239,7 +241,9 @@ internal class TransactionEncoderImpl(
|
||||||
return try {
|
return try {
|
||||||
saplingParamTool.ensureParams(saplingParamTool.properties.paramsDirectory)
|
saplingParamTool.ensureParams(saplingParamTool.properties.paramsDirectory)
|
||||||
Twig.debug { "params exist! attempting to shield..." }
|
Twig.debug { "params exist! attempting to shield..." }
|
||||||
val proposal = backend.proposeShielding(usk.account, 100000, memo)
|
val proposal =
|
||||||
|
backend.proposeShielding(usk.account, 100000, memo)
|
||||||
|
?: throw SdkException("Insufficient balance (have 0, need 100000 including fee)", null)
|
||||||
backend.createProposedTransaction(proposal, usk)
|
backend.createProposedTransaction(proposal, usk)
|
||||||
} catch (t: Throwable) {
|
} catch (t: Throwable) {
|
||||||
// TODO [#680]: if this error matches: Insufficient balance (have 0, need 1000 including fee)
|
// TODO [#680]: if this error matches: Insufficient balance (have 0, need 1000 including fee)
|
||||||
|
|
Loading…
Reference in New Issue