[#1195] Integrate Current Balances widget to Send
- Closes #1195 - The fixture recipient address type changed from the unified to the sapling on several tests to avoid temporary address TODO text obtained from the SDK fixture - WalletDisplayValues have the updateAvailable optional with false as a default value - Changelog updated
This commit is contained in:
parent
1944916606
commit
7e27bdddff
|
@ -12,6 +12,7 @@ directly impact users rather than highlighting other key architectural updates.*
|
|||
### Added
|
||||
- The current balance UI on top of the Account screen has been reworked. It now displays the currently available
|
||||
balance as well.
|
||||
- The same current balance UI was also incorporated into the Send Form screen.
|
||||
|
||||
## [0.2.0 (530)] - 2024-01-16
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import cash.z.ecc.android.sdk.model.Zatoshi
|
|||
import cash.z.ecc.android.sdk.model.ZecSend
|
||||
|
||||
object ZecSendFixture {
|
||||
const val ADDRESS: String = WalletAddressFixture.UNIFIED_ADDRESS_STRING
|
||||
const val ADDRESS: String = WalletAddressFixture.SAPLING_ADDRESS_STRING
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
val AMOUNT = Zatoshi(123)
|
||||
|
|
|
@ -52,7 +52,8 @@ internal fun ComposeContentTestRule.setAmount(amount: String) {
|
|||
internal fun ComposeContentTestRule.setValidAddress() {
|
||||
onNodeWithText(getStringResource(R.string.send_to)).also {
|
||||
it.performTextClearance()
|
||||
it.performTextInput(WalletAddressFixture.UNIFIED_ADDRESS_STRING)
|
||||
// Using sapling address here, as the unified is not available in the fixture. This will change.
|
||||
it.performTextInput(WalletAddressFixture.SAPLING_ADDRESS_STRING)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,10 +5,11 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.ui.test.junit4.ComposeContentTestRule
|
||||
import cash.z.ecc.android.sdk.model.WalletBalance
|
||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||
import cash.z.ecc.android.sdk.model.ZecSend
|
||||
import cash.z.ecc.sdk.fixture.ZatoshiFixture
|
||||
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
||||
import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture
|
||||
import co.electriccoin.zcash.ui.screen.send.ext.Saver
|
||||
import co.electriccoin.zcash.ui.screen.send.model.SendArgumentsWrapper
|
||||
import co.electriccoin.zcash.ui.screen.send.model.SendStage
|
||||
|
@ -96,13 +97,24 @@ class SendViewTestSetup(
|
|||
|
||||
ZcashTheme {
|
||||
Send(
|
||||
mySpendableBalance = ZatoshiFixture.new(Zatoshi.MAX_INCLUSIVE),
|
||||
walletSnapshot =
|
||||
WalletSnapshotFixture.new(
|
||||
saplingBalance =
|
||||
WalletBalance(
|
||||
total = Zatoshi(Zatoshi.MAX_INCLUSIVE.div(100)),
|
||||
available = Zatoshi(Zatoshi.MAX_INCLUSIVE.div(100))
|
||||
)
|
||||
),
|
||||
sendStage = sendStage,
|
||||
sendArgumentsWrapper = initialSendArgumentWrapper,
|
||||
onSendStageChange = setSendStage,
|
||||
zecSend = zecSend,
|
||||
onZecSendChange = setZecSend,
|
||||
onBack = onBackAction,
|
||||
goBalances = {
|
||||
// TODO [#1194]: Cover Current balances UI widget with tests
|
||||
// TODO [#1194]: https://github.com/Electric-Coin-Company/zashi-android/issues/1194
|
||||
},
|
||||
onSettings = { onSettingsCount.incrementAndGet() },
|
||||
onCreateAndSend = {
|
||||
onCreateCount.incrementAndGet()
|
||||
|
|
|
@ -6,12 +6,13 @@ import androidx.compose.ui.test.junit4.createComposeRule
|
|||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.test.filters.MediumTest
|
||||
import cash.z.ecc.android.sdk.fixture.WalletFixture
|
||||
import cash.z.ecc.android.sdk.model.WalletBalance
|
||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||
import cash.z.ecc.sdk.fixture.ZatoshiFixture
|
||||
import cash.z.ecc.sdk.fixture.ZecSendFixture
|
||||
import co.electriccoin.zcash.ui.R
|
||||
import co.electriccoin.zcash.ui.fixture.MockSynchronizer
|
||||
import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture
|
||||
import co.electriccoin.zcash.ui.screen.send.WrapSend
|
||||
import co.electriccoin.zcash.ui.screen.send.assertOnConfirmation
|
||||
import co.electriccoin.zcash.ui.screen.send.assertOnForm
|
||||
|
@ -39,7 +40,14 @@ class SendViewIntegrationTest {
|
|||
)
|
||||
}
|
||||
private val synchronizer = MockSynchronizer.new()
|
||||
private val balance = ZatoshiFixture.new(Zatoshi.MAX_INCLUSIVE)
|
||||
private val walletSnapshot =
|
||||
WalletSnapshotFixture.new(
|
||||
saplingBalance =
|
||||
WalletBalance(
|
||||
total = Zatoshi(Zatoshi.MAX_INCLUSIVE.div(100)),
|
||||
available = Zatoshi(Zatoshi.MAX_INCLUSIVE.div(100))
|
||||
)
|
||||
)
|
||||
|
||||
@Test
|
||||
@MediumTest
|
||||
|
@ -54,10 +62,11 @@ class SendViewIntegrationTest {
|
|||
WrapSend(
|
||||
sendArgumentsWrapper = null,
|
||||
synchronizer = synchronizer,
|
||||
spendableBalance = balance,
|
||||
walletSnapshot = walletSnapshot,
|
||||
spendingKey = spendingKey,
|
||||
goToQrScanner = {},
|
||||
goBack = {},
|
||||
goBalances = {},
|
||||
hasCameraFeature = true,
|
||||
goSettings = {}
|
||||
)
|
||||
|
|
|
@ -107,7 +107,7 @@ class SendViewTest : UiTestPrerequisites() {
|
|||
launch {
|
||||
testSetup.getLastZecSend().also {
|
||||
assertNotNull(it)
|
||||
assertEquals(WalletAddressFixture.unified(), it.destination)
|
||||
assertEquals(WalletAddressFixture.sapling(), it.destination)
|
||||
assertEquals(Zatoshi(12345678900000), it.amount)
|
||||
assertEquals(ZecRequestFixture.MESSAGE.value, it.memo.value)
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ class SendViewTest : UiTestPrerequisites() {
|
|||
launch {
|
||||
testSetup.getLastZecSend().also {
|
||||
assertNotNull(it)
|
||||
assertEquals(WalletAddressFixture.unified(), it.destination)
|
||||
assertEquals(WalletAddressFixture.sapling(), it.destination)
|
||||
assertEquals(Zatoshi(12345678900000), it.amount)
|
||||
assertEquals(ZecRequestFixture.MESSAGE.value, it.memo.value)
|
||||
}
|
||||
|
@ -201,7 +201,7 @@ class SendViewTest : UiTestPrerequisites() {
|
|||
launch {
|
||||
testSetup.getLastZecSend().also {
|
||||
assertNotNull(it)
|
||||
assertEquals(WalletAddressFixture.unified(), it.destination)
|
||||
assertEquals(WalletAddressFixture.sapling(), it.destination)
|
||||
assertEquals(Zatoshi(12345678900000), it.amount)
|
||||
assertEquals(ZecRequestFixture.MESSAGE.value, it.memo.value)
|
||||
}
|
||||
|
@ -280,7 +280,7 @@ class SendViewTest : UiTestPrerequisites() {
|
|||
launch {
|
||||
testSetup.getLastZecSend().also {
|
||||
assertNotNull(it)
|
||||
assertEquals(WalletAddressFixture.unified(), it.destination)
|
||||
assertEquals(WalletAddressFixture.sapling(), it.destination)
|
||||
assertEquals(Zatoshi(12345600000), it.amount)
|
||||
assertTrue(it.memo.value.isEmpty())
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ data class WalletDisplayValues(
|
|||
internal fun getNextValues(
|
||||
context: Context,
|
||||
walletSnapshot: WalletSnapshot,
|
||||
updateAvailable: Boolean
|
||||
updateAvailable: Boolean = false
|
||||
): WalletDisplayValues {
|
||||
var progress = PercentDecimal.ZERO_PERCENT
|
||||
val zecAmountText = walletSnapshot.totalBalance().toZecString()
|
||||
|
|
|
@ -166,8 +166,6 @@ private fun Status(
|
|||
.testTag(AccountTag.STATUS_VIEWS),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault))
|
||||
|
||||
if (walletDisplayValues.zecAmountText.isNotEmpty()) {
|
||||
BalanceWidget(
|
||||
walletSnapshot = walletSnapshot,
|
||||
|
|
|
@ -102,6 +102,7 @@ internal fun WrapHome(
|
|||
activity = activity,
|
||||
goToQrScanner = goScan,
|
||||
goBack = homeGoBack,
|
||||
goBalances = { forceHomePageIndexFlow.tryEmit(ForcePage(HomeScreenIndex.BALANCES)) },
|
||||
goSettings = goSettings,
|
||||
sendArgumentsWrapper = sendArgumentsWrapper
|
||||
)
|
||||
|
|
|
@ -14,11 +14,10 @@ import androidx.compose.runtime.saveable.rememberSaveable
|
|||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import cash.z.ecc.android.sdk.Synchronizer
|
||||
import cash.z.ecc.android.sdk.model.UnifiedSpendingKey
|
||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||
import cash.z.ecc.android.sdk.model.ZecSend
|
||||
import cash.z.ecc.sdk.extension.send
|
||||
import co.electriccoin.zcash.spackle.Twig
|
||||
import co.electriccoin.zcash.ui.common.model.spendableBalance
|
||||
import co.electriccoin.zcash.ui.common.model.WalletSnapshot
|
||||
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
|
||||
import co.electriccoin.zcash.ui.design.component.CircularScreenProgressIndicator
|
||||
import co.electriccoin.zcash.ui.screen.send.ext.Saver
|
||||
|
@ -28,11 +27,13 @@ import co.electriccoin.zcash.ui.screen.send.view.Send
|
|||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
@Suppress("LongParameterList")
|
||||
internal fun WrapSend(
|
||||
activity: ComponentActivity,
|
||||
sendArgumentsWrapper: SendArgumentsWrapper?,
|
||||
goToQrScanner: () -> Unit,
|
||||
goBack: () -> Unit,
|
||||
goBalances: () -> Unit,
|
||||
goSettings: () -> Unit,
|
||||
) {
|
||||
val hasCameraFeature = activity.packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)
|
||||
|
@ -41,17 +42,18 @@ internal fun WrapSend(
|
|||
|
||||
val synchronizer = walletViewModel.synchronizer.collectAsStateWithLifecycle().value
|
||||
|
||||
val spendableBalance = walletViewModel.walletSnapshot.collectAsStateWithLifecycle().value?.spendableBalance()
|
||||
val walletSnapshot = walletViewModel.walletSnapshot.collectAsStateWithLifecycle().value
|
||||
|
||||
val spendingKey = walletViewModel.spendingKey.collectAsStateWithLifecycle().value
|
||||
|
||||
WrapSend(
|
||||
sendArgumentsWrapper,
|
||||
synchronizer,
|
||||
spendableBalance,
|
||||
walletSnapshot,
|
||||
spendingKey,
|
||||
goToQrScanner,
|
||||
goBack,
|
||||
goBalances,
|
||||
goSettings,
|
||||
hasCameraFeature
|
||||
)
|
||||
|
@ -63,10 +65,11 @@ internal fun WrapSend(
|
|||
internal fun WrapSend(
|
||||
sendArgumentsWrapper: SendArgumentsWrapper?,
|
||||
synchronizer: Synchronizer?,
|
||||
spendableBalance: Zatoshi?,
|
||||
walletSnapshot: WalletSnapshot?,
|
||||
spendingKey: UnifiedSpendingKey?,
|
||||
goToQrScanner: () -> Unit,
|
||||
goBack: () -> Unit,
|
||||
goBalances: () -> Unit,
|
||||
goSettings: () -> Unit,
|
||||
hasCameraFeature: Boolean
|
||||
) {
|
||||
|
@ -99,14 +102,14 @@ internal fun WrapSend(
|
|||
onBackAction()
|
||||
}
|
||||
|
||||
if (null == synchronizer || null == spendableBalance || null == spendingKey) {
|
||||
if (null == synchronizer || null == walletSnapshot || null == spendingKey) {
|
||||
// TODO [#1146]: Consider moving CircularScreenProgressIndicator from Android layer to View layer
|
||||
// TODO [#1146]: Improve this by allowing screen composition and updating it after the data is available
|
||||
// TODO [#1146]: https://github.com/Electric-Coin-Company/zashi-android/issues/1146
|
||||
CircularScreenProgressIndicator()
|
||||
} else {
|
||||
Send(
|
||||
mySpendableBalance = spendableBalance,
|
||||
walletSnapshot = walletSnapshot,
|
||||
sendArgumentsWrapper = sendArgumentsWrapper,
|
||||
sendStage = sendStage,
|
||||
onSendStageChange = setSendStage,
|
||||
|
@ -129,6 +132,7 @@ internal fun WrapSend(
|
|||
}
|
||||
},
|
||||
onQrScannerOpen = goToQrScanner,
|
||||
goBalances = goBalances,
|
||||
hasCameraFeature = hasCameraFeature
|
||||
)
|
||||
}
|
||||
|
|
|
@ -7,10 +7,8 @@ import androidx.compose.foundation.layout.Column
|
|||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.imePadding
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
|
@ -55,6 +53,9 @@ import cash.z.ecc.sdk.fixture.MemoFixture
|
|||
import cash.z.ecc.sdk.fixture.ZatoshiFixture
|
||||
import co.electriccoin.zcash.spackle.Twig
|
||||
import co.electriccoin.zcash.ui.R
|
||||
import co.electriccoin.zcash.ui.common.BalanceWidget
|
||||
import co.electriccoin.zcash.ui.common.model.WalletSnapshot
|
||||
import co.electriccoin.zcash.ui.common.model.spendableBalance
|
||||
import co.electriccoin.zcash.ui.common.test.CommonTag
|
||||
import co.electriccoin.zcash.ui.design.MINIMAL_WEIGHT
|
||||
import co.electriccoin.zcash.ui.design.component.Body
|
||||
|
@ -65,6 +66,8 @@ import co.electriccoin.zcash.ui.design.component.PrimaryButton
|
|||
import co.electriccoin.zcash.ui.design.component.SmallTopAppBar
|
||||
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
||||
import co.electriccoin.zcash.ui.design.theme.ZcashTheme.dimens
|
||||
import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture
|
||||
import co.electriccoin.zcash.ui.screen.account.model.WalletDisplayValues
|
||||
import co.electriccoin.zcash.ui.screen.send.SendTag
|
||||
import co.electriccoin.zcash.ui.screen.send.ext.ABBREVIATION_INDEX
|
||||
import co.electriccoin.zcash.ui.screen.send.ext.abbreviated
|
||||
|
@ -80,7 +83,7 @@ private fun PreviewSendForm() {
|
|||
ZcashTheme(forceDarkMode = false) {
|
||||
GradientSurface {
|
||||
Send(
|
||||
mySpendableBalance = ZatoshiFixture.new(),
|
||||
walletSnapshot = WalletSnapshotFixture.new(),
|
||||
sendArgumentsWrapper = null,
|
||||
sendStage = SendStage.Form,
|
||||
onSendStageChange = {},
|
||||
|
@ -90,6 +93,7 @@ private fun PreviewSendForm() {
|
|||
onQrScannerOpen = {},
|
||||
onBack = {},
|
||||
onSettings = {},
|
||||
goBalances = {},
|
||||
hasCameraFeature = true
|
||||
)
|
||||
}
|
||||
|
@ -153,7 +157,7 @@ private fun PreviewSendConfirmation() {
|
|||
@Suppress("LongParameterList")
|
||||
@Composable
|
||||
fun Send(
|
||||
mySpendableBalance: Zatoshi,
|
||||
walletSnapshot: WalletSnapshot,
|
||||
sendArgumentsWrapper: SendArgumentsWrapper?,
|
||||
sendStage: SendStage,
|
||||
onSendStageChange: (SendStage) -> Unit,
|
||||
|
@ -163,6 +167,7 @@ fun Send(
|
|||
onSettings: () -> Unit,
|
||||
onCreateAndSend: (ZecSend) -> Unit,
|
||||
onQrScannerOpen: () -> Unit,
|
||||
goBalances: () -> Unit,
|
||||
hasCameraFeature: Boolean
|
||||
) {
|
||||
Scaffold(topBar = {
|
||||
|
@ -173,7 +178,7 @@ fun Send(
|
|||
)
|
||||
}) { paddingValues ->
|
||||
SendMainContent(
|
||||
myBalance = mySpendableBalance,
|
||||
walletSnapshot = walletSnapshot,
|
||||
sendArgumentsWrapper = sendArgumentsWrapper,
|
||||
onBack = onBack,
|
||||
sendStage = sendStage,
|
||||
|
@ -182,6 +187,7 @@ fun Send(
|
|||
onZecSendChange = onZecSendChange,
|
||||
onSendSubmit = onCreateAndSend,
|
||||
onQrScannerOpen = onQrScannerOpen,
|
||||
goBalances = goBalances,
|
||||
hasCameraFeature = hasCameraFeature,
|
||||
modifier =
|
||||
Modifier
|
||||
|
@ -228,7 +234,7 @@ private fun SendTopAppBar(
|
|||
@Suppress("LongParameterList")
|
||||
@Composable
|
||||
private fun SendMainContent(
|
||||
myBalance: Zatoshi,
|
||||
walletSnapshot: WalletSnapshot,
|
||||
sendArgumentsWrapper: SendArgumentsWrapper?,
|
||||
zecSend: ZecSend?,
|
||||
onZecSendChange: (ZecSend) -> Unit,
|
||||
|
@ -237,13 +243,14 @@ private fun SendMainContent(
|
|||
onSendStageChange: (SendStage) -> Unit,
|
||||
onSendSubmit: (ZecSend) -> Unit,
|
||||
onQrScannerOpen: () -> Unit,
|
||||
goBalances: () -> Unit,
|
||||
hasCameraFeature: Boolean,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
when {
|
||||
(sendStage == SendStage.Form || null == zecSend) -> {
|
||||
SendForm(
|
||||
myBalance = myBalance,
|
||||
walletSnapshot = walletSnapshot,
|
||||
sendArgumentsWrapper = sendArgumentsWrapper,
|
||||
previousZecSend = zecSend,
|
||||
onCreateZecSend = {
|
||||
|
@ -251,6 +258,7 @@ private fun SendMainContent(
|
|||
onZecSendChange(it)
|
||||
},
|
||||
onQrScannerOpen = onQrScannerOpen,
|
||||
goBalances = goBalances,
|
||||
hasCameraFeature = hasCameraFeature,
|
||||
modifier = modifier
|
||||
)
|
||||
|
@ -296,11 +304,12 @@ private fun SendMainContent(
|
|||
@Suppress("LongMethod", "LongParameterList", "CyclomaticComplexMethod")
|
||||
@Composable
|
||||
private fun SendForm(
|
||||
myBalance: Zatoshi,
|
||||
walletSnapshot: WalletSnapshot,
|
||||
sendArgumentsWrapper: SendArgumentsWrapper?,
|
||||
previousZecSend: ZecSend?,
|
||||
onCreateZecSend: (ZecSend) -> Unit,
|
||||
onQrScannerOpen: () -> Unit,
|
||||
goBalances: () -> Unit,
|
||||
hasCameraFeature: Boolean,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
|
@ -340,24 +349,28 @@ private fun SendForm(
|
|||
Column(
|
||||
modifier =
|
||||
Modifier
|
||||
.imePadding()
|
||||
.fillMaxSize()
|
||||
.fillMaxHeight()
|
||||
.verticalScroll(rememberScrollState())
|
||||
.then(modifier),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Header(
|
||||
text = stringResource(id = R.string.send_balance, myBalance.toZecString()),
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
Body(
|
||||
text = stringResource(id = R.string.send_balance_subtitle),
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
val walletDisplayValues =
|
||||
WalletDisplayValues.getNextValues(
|
||||
context = LocalContext.current,
|
||||
walletSnapshot = walletSnapshot
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(dimens.spacingLarge))
|
||||
Spacer(modifier = Modifier.height(dimens.spacingDefault))
|
||||
|
||||
if (walletDisplayValues.zecAmountText.isNotEmpty()) {
|
||||
BalanceWidget(
|
||||
walletSnapshot = walletSnapshot,
|
||||
isReferenceToBalances = true,
|
||||
onReferenceClick = goBalances
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(dimens.spacingXlarge))
|
||||
|
||||
FormTextField(
|
||||
value = recipientAddressString,
|
||||
|
@ -487,7 +500,7 @@ private fun SendForm(
|
|||
val sendButtonEnabled =
|
||||
amountZecString.isNotBlank() &&
|
||||
sendValueCheck > 0L &&
|
||||
myBalance.value >= (sendValueCheck + ZcashSdk.MINERS_FEE.value) &&
|
||||
walletSnapshot.spendableBalance().value >= (sendValueCheck + ZcashSdk.MINERS_FEE.value) &&
|
||||
recipientAddressString.length > ABBREVIATION_INDEX
|
||||
|
||||
PrimaryButton(
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
<string name="send_back">Back</string>
|
||||
<string name="send_back_content_description">Back</string>
|
||||
<string name="send_scan_content_description">Scan</string>
|
||||
<string name="send_balance" formatted="true"><xliff:g id="balance" example="12.345">%1$s</xliff:g> ZEC Available</string>
|
||||
<string name="send_balance_subtitle">Additional funds may be in transit.</string>
|
||||
<string name="send_to">Who would you like to send ZEC to?</string>
|
||||
<string name="send_amount">How much?</string>
|
||||
<string name="send_memo">Memo</string>
|
||||
|
|
Loading…
Reference in New Issue