Add zec.rocks lightwalletd server options (#1401)

- Default wallet option changed to zec.rocks:443
- Changleog update
This commit is contained in:
Honza Rychnovský 2024-04-26 13:02:07 +02:00 committed by GitHub
parent 9ca5548ca3
commit 9b2bad6f10
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 160 additions and 117 deletions

View File

@ -9,6 +9,10 @@ directly impact users rather than highlighting other key architectural updates.*
## [Unreleased]
### Changed
- We have added one more group of server options (zec.rocks) for increased coverage and reliability
- zec.rocks:443 is now default wallet option
## [1.0 (630)] - 2024-04-24
### Changed

View File

@ -21,9 +21,7 @@ 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.android.sdk.tool.DerivationTool
import cash.z.ecc.sdk.extension.defaultForNetwork
import cash.z.ecc.sdk.type.fromResources
import co.electriccoin.lightwallet.client.model.LightWalletEndpoint
import co.electriccoin.zcash.global.getInstance
import co.electriccoin.zcash.spackle.Twig
import co.electriccoin.zcash.ui.common.ANDROID_STATE_FLOW_TIMEOUT
@ -42,6 +40,7 @@ import co.electriccoin.zcash.ui.preference.StandardPreferenceSingleton
import co.electriccoin.zcash.ui.screen.account.ext.TransactionOverviewExt
import co.electriccoin.zcash.ui.screen.account.ext.getSortHeight
import co.electriccoin.zcash.ui.screen.account.state.TransactionHistorySyncState
import co.electriccoin.zcash.ui.screen.chooseserver.AvailableServerProvider
import kotlinx.collections.immutable.toPersistentList
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
@ -295,7 +294,7 @@ class WalletViewModel(application: Application) : AndroidViewModel(application)
PersistableWallet.new(
application = application,
zcashNetwork = zcashNetwork,
endpoint = LightWalletEndpoint.defaultForNetwork(zcashNetwork),
endpoint = AvailableServerProvider.getDefaultServer(zcashNetwork),
walletInitMode = WalletInitMode.NewWallet
)
persistWallet(newWallet)

View File

@ -1,7 +1,6 @@
package co.electriccoin.zcash.ui.screen.chooseserver
import cash.z.ecc.android.sdk.model.ZcashNetwork
import cash.z.ecc.sdk.extension.Mainnet
import cash.z.ecc.sdk.extension.Testnet
import co.electriccoin.lightwallet.client.model.LightWalletEndpoint
import kotlinx.collections.immutable.toImmutableList
@ -9,20 +8,14 @@ import kotlinx.collections.immutable.toImmutableList
// TODO [#1273]: Add ChooseServer Tests #1273
// TODO [#1273]: https://github.com/Electric-Coin-Company/zashi-android/issues/1273
@Suppress("UnusedPrivateProperty")
object AvailableServerProvider {
// North America | [na.lightwalletd.com](http://na.lightwalletd.com/) | 443
// South America | [sa.lightwalletd.com](http://sa.lightwalletd.com/) | 443
// Europe & Africa | [eu.lightwalletd.com](http://eu.lightwalletd.com/) | 443
// Asia & Oceania | [ai.lightwalletd.com](http://ai.lightwalletd.com/) | 443
// Plus current network defaults:
// Mainnet: mainnet.lightwalletd.com | 9067
// Testnet: lightwalletd.testnet.electriccoin.co | 9067
private const val NH_HOST_NA = "na.lightwalletd.com" // NON-NLS
private const val NH_HOST_SA = "sa.lightwalletd.com" // NON-NLS
private const val NH_HOST_EU = "eu.lightwalletd.com" // NON-NLS
private const val NH_HOST_AI = "ai.lightwalletd.com" // NON-NLS
private const val NH_PORT = 443
private const val ZR_HOST = "zec.rocks" // NON-NLS
private const val ZR_HOST_NA = "na.zec.rocks" // NON-NLS
private const val ZR_HOST_SA = "sa.zec.rocks" // NON-NLS
private const val ZR_HOST_EU = "eu.zec.rocks" // NON-NLS
private const val ZR_HOST_AP = "ap.zec.rocks" // NON-NLS
private const val ZR_PORT = 443
private const val YW_HOST_1 = "lwd1.zcash-infra.com" // NON-NLS
private const val YW_HOST_2 = "lwd2.zcash-infra.com" // NON-NLS
@ -34,10 +27,24 @@ object AvailableServerProvider {
private const val YW_HOST_8 = "lwd8.zcash-infra.com" // NON-NLS
private const val YW_PORT = 9067
// NH servers are currently unused and are subject of removal in the future
private const val NH_HOST_NA = "na.lightwalletd.com" // NON-NLS
private const val NH_HOST_SA = "sa.lightwalletd.com" // NON-NLS
private const val NH_HOST_EU = "eu.lightwalletd.com" // NON-NLS
private const val NH_HOST_AI = "ai.lightwalletd.com" // NON-NLS
private const val NH_PORT = 443
fun toList(network: ZcashNetwork) =
buildList {
if (network == ZcashNetwork.Mainnet) {
add(LightWalletEndpoint.Mainnet)
add(LightWalletEndpoint(ZR_HOST, ZR_PORT, true))
// Custom server item comes here in the view layer
add(LightWalletEndpoint(ZR_HOST_NA, ZR_PORT, true))
add(LightWalletEndpoint(ZR_HOST_SA, ZR_PORT, true))
add(LightWalletEndpoint(ZR_HOST_EU, ZR_PORT, true))
add(LightWalletEndpoint(ZR_HOST_AP, ZR_PORT, true))
add(LightWalletEndpoint(YW_HOST_1, YW_PORT, true))
add(LightWalletEndpoint(YW_HOST_2, YW_PORT, true))
@ -47,15 +54,12 @@ object AvailableServerProvider {
add(LightWalletEndpoint(YW_HOST_6, YW_PORT, true))
add(LightWalletEndpoint(YW_HOST_7, YW_PORT, true))
add(LightWalletEndpoint(YW_HOST_8, YW_PORT, true))
add(LightWalletEndpoint(NH_HOST_NA, NH_PORT, true))
add(LightWalletEndpoint(NH_HOST_SA, NH_PORT, true))
add(LightWalletEndpoint(NH_HOST_EU, NH_PORT, true))
add(LightWalletEndpoint(NH_HOST_AI, NH_PORT, true))
} else {
add(LightWalletEndpoint.Testnet)
}
}.toImmutableList()
fun getDefaultServer(zcashNetwork: ZcashNetwork): LightWalletEndpoint = toList(zcashNetwork).first()
}
// This regex validates server URLs with ports in format: <hostname>:<port>

View File

@ -1,7 +1,10 @@
@file:Suppress("TooManyFunctions")
package co.electriccoin.zcash.ui.screen.chooseserver.view
import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
@ -11,6 +14,9 @@ import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.DividerDefaults
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@ -25,7 +31,6 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import cash.z.ecc.android.sdk.internal.Twig
import cash.z.ecc.android.sdk.model.PersistableWallet
@ -41,7 +46,6 @@ import co.electriccoin.zcash.ui.design.component.GradientSurface
import co.electriccoin.zcash.ui.design.component.PrimaryButton
import co.electriccoin.zcash.ui.design.component.RadioButton
import co.electriccoin.zcash.ui.design.component.SmallTopAppBar
import co.electriccoin.zcash.ui.design.component.SubHeader
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.screen.chooseserver.ChooseServerTag
import co.electriccoin.zcash.ui.screen.chooseserver.validateCustomServerValue
@ -70,7 +74,7 @@ private fun PreviewChooseServer() {
}
@Composable
@Suppress("LongParameterList")
@Suppress("LongMethod", "LongParameterList")
fun ChooseServer(
availableServers: ImmutableList<LightWalletEndpoint>,
onBack: () -> Unit,
@ -82,80 +86,6 @@ fun ChooseServer(
isShowingSuccessDialog: Boolean,
setShowSuccessDialog: (Boolean) -> Unit,
walletRestoringState: WalletRestoringState,
) {
Scaffold(
topBar = {
ChooseServerTopAppBar(
onBack = onBack,
showRestoring = walletRestoringState == WalletRestoringState.RESTORING,
)
}
) { paddingValues ->
ChooseServerMainContent(
modifier =
Modifier
.verticalScroll(
rememberScrollState()
)
.padding(
top = paddingValues.calculateTopPadding(),
bottom = paddingValues.calculateBottomPadding(),
start = ZcashTheme.dimens.screenHorizontalSpacingRegular,
end = ZcashTheme.dimens.screenHorizontalSpacingRegular
)
.fillMaxWidth(),
availableServers = availableServers,
onServerChange = onServerChange,
setShowErrorDialog = setShowErrorDialog,
validationResult = validationResult,
wallet = wallet,
)
// Show validation popups
if (isShowingErrorDialog && validationResult is ServerValidation.InValid) {
ValidationErrorDialog(
reason = validationResult.reason.message,
onDone = { setShowErrorDialog(false) }
)
} else if (isShowingSuccessDialog) {
SaveSuccessDialog(
onDone = { setShowSuccessDialog(false) }
)
}
}
}
@Composable
private fun ChooseServerTopAppBar(
onBack: () -> Unit,
showRestoring: Boolean
) {
SmallTopAppBar(
restoringLabel =
if (showRestoring) {
stringResource(id = R.string.restoring_wallet_label)
} else {
null
},
modifier = Modifier.testTag(ChooseServerTag.CHOOSE_SERVER_TOP_APP_BAR),
showTitleLogo = true,
backText = stringResource(id = R.string.choose_server_back).uppercase(),
backContentDescriptionText = stringResource(R.string.choose_server_back_content_description),
onBack = onBack,
)
}
const val CUSTOM_SERVER_OPTION_INDEX = 1
@Composable
@Suppress("LongMethod", "LongParameterList")
private fun ChooseServerMainContent(
availableServers: ImmutableList<LightWalletEndpoint>,
onServerChange: (LightWalletEndpoint) -> Unit,
validationResult: ServerValidation,
wallet: PersistableWallet,
modifier: Modifier = Modifier,
setShowErrorDialog: (Boolean) -> Unit,
) {
val options =
availableServers.toMutableList().apply {
@ -193,27 +123,84 @@ private fun ChooseServerMainContent(
mutableStateOf(initialCustomServerValue)
}
Column(modifier = modifier) {
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingLarge))
SubHeader(
text = stringResource(id = R.string.choose_server_title),
textAlign = TextAlign.Center,
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingLarge))
ServerList(
Scaffold(
topBar = {
ChooseServerTopAppBar(
onBack = onBack,
showRestoring = walletRestoringState == WalletRestoringState.RESTORING,
)
},
bottomBar = {
ChooseServerBottomBar(
customServerValue = customServerValue,
onServerChange = onServerChange,
options = options,
selectedOption = selectedOption,
setShowErrorDialog = setShowErrorDialog,
validationResult = validationResult,
wallet = wallet
)
}
) { paddingValues ->
ChooseServerMainContent(
customServerValue = customServerValue,
modifier =
Modifier
.verticalScroll(
rememberScrollState()
)
.padding(
top = paddingValues.calculateTopPadding(),
bottom = paddingValues.calculateBottomPadding(),
start = ZcashTheme.dimens.screenHorizontalSpacingRegular,
end = ZcashTheme.dimens.screenHorizontalSpacingRegular
)
.fillMaxWidth(),
options = options,
selectedOption = selectedOption,
setSelectedOption = setSelectedOption,
customServerValue = customServerValue,
setCustomServerValue = setCustomServerValue,
modifier = Modifier.fillMaxWidth()
setSelectedOption = setSelectedOption,
)
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingLarge))
// Show validation popups
if (isShowingErrorDialog && validationResult is ServerValidation.InValid) {
ValidationErrorDialog(
reason = validationResult.reason.message,
onDone = { setShowErrorDialog(false) }
)
} else if (isShowingSuccessDialog) {
SaveSuccessDialog(
onDone = { setShowSuccessDialog(false) }
)
}
}
}
@Composable
@Suppress("LongParameterList")
fun ChooseServerBottomBar(
customServerValue: String,
onServerChange: (LightWalletEndpoint) -> Unit,
options: ImmutableList<LightWalletEndpoint>,
selectedOption: Int,
setShowErrorDialog: (Boolean) -> Unit,
validationResult: ServerValidation,
wallet: PersistableWallet,
modifier: Modifier = Modifier,
) {
Column(
modifier =
modifier.then(
Modifier
.background(MaterialTheme.colorScheme.surface)
)
) {
HorizontalDivider(
thickness = DividerDefaults.Thickness,
color = ZcashTheme.colors.dividerColor
)
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingSmall))
SaveButton(
enabled = validationResult != ServerValidation.Running,
@ -227,13 +214,62 @@ private fun ChooseServerMainContent(
},
setShowErrorDialog = setShowErrorDialog,
selectedOption = selectedOption,
modifier = Modifier.padding(horizontal = ZcashTheme.dimens.spacingUpLarge)
modifier = Modifier.padding(horizontal = ZcashTheme.dimens.screenHorizontalSpacingBig)
)
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingHuge))
}
}
@Composable
private fun ChooseServerTopAppBar(
onBack: () -> Unit,
showRestoring: Boolean
) {
SmallTopAppBar(
titleText = stringResource(id = R.string.choose_server_title),
restoringLabel =
if (showRestoring) {
stringResource(id = R.string.restoring_wallet_label)
} else {
null
},
modifier = Modifier.testTag(ChooseServerTag.CHOOSE_SERVER_TOP_APP_BAR),
showTitleLogo = true,
backText = stringResource(id = R.string.choose_server_back).uppercase(),
backContentDescriptionText = stringResource(R.string.choose_server_back_content_description),
onBack = onBack,
)
}
const val CUSTOM_SERVER_OPTION_INDEX = 1
@Composable
@Suppress("LongParameterList")
private fun ChooseServerMainContent(
customServerValue: String,
options: ImmutableList<LightWalletEndpoint>,
selectedOption: Int,
setCustomServerValue: (String) -> Unit,
setSelectedOption: (Int) -> Unit,
modifier: Modifier = Modifier,
) {
Column(modifier = modifier) {
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault))
ServerList(
options = options,
selectedOption = selectedOption,
setSelectedOption = setSelectedOption,
customServerValue = customServerValue,
setCustomServerValue = setCustomServerValue,
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault))
}
}
@OptIn(ExperimentalFoundationApi::class)
@Composable
@Suppress("LongParameterList")