[#1528] Coinbase on-ramp integration
* [#1528] Coinbase integration Closes #1528 * [#1528] CI hotfix Closes #1528 * Remove duplicate lines * Improve CI scripts + variable renaming * Remove coinbase button in testnet build * Update changelogs --------- Co-authored-by: Honza <rychnovsky.honza@gmail.com>
This commit is contained in:
parent
fa9ea0c03a
commit
35c01df313
|
@ -63,9 +63,11 @@ jobs:
|
||||||
# GOOGLE_PLAY_WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.GOOGLE_PLAY_WORKLOAD_IDENTITY_PROVIDER }}
|
# GOOGLE_PLAY_WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.GOOGLE_PLAY_WORKLOAD_IDENTITY_PROVIDER }}
|
||||||
GOOGLE_PLAY_SERVICE_ACCOUNT_KEY: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_KEY }}
|
GOOGLE_PLAY_SERVICE_ACCOUNT_KEY: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_KEY }}
|
||||||
GOOGLE_PLAY_PUBLISHER_API_KEY: ${{ secrets.GOOGLE_PLAY_PUBLISHER_API_KEY }}
|
GOOGLE_PLAY_PUBLISHER_API_KEY: ${{ secrets.GOOGLE_PLAY_PUBLISHER_API_KEY }}
|
||||||
|
COINBASE_APP_ID: ${{ secrets.COINBASE_APP_ID }}
|
||||||
if: "${{ env.GOOGLE_PLAY_CLOUD_PROJECT != '' &&
|
if: "${{ env.GOOGLE_PLAY_CLOUD_PROJECT != '' &&
|
||||||
env.GOOGLE_PLAY_SERVICE_ACCOUNT_KEY != '' &&
|
env.GOOGLE_PLAY_SERVICE_ACCOUNT_KEY != '' &&
|
||||||
env.GOOGLE_PLAY_PUBLISHER_API_KEY != ''
|
env.GOOGLE_PLAY_PUBLISHER_API_KEY != '' &&
|
||||||
|
env.COINBASE_APP_ID != ''
|
||||||
}}"
|
}}"
|
||||||
run: echo "defined=true" >> $GITHUB_OUTPUT
|
run: echo "defined=true" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
@ -154,6 +156,7 @@ jobs:
|
||||||
ORG_GRADLE_PROJECT_ZCASH_RELEASE_KEYSTORE_PASSWORD: ${{ secrets.UPLOAD_KEYSTORE_PASSWORD }}
|
ORG_GRADLE_PROJECT_ZCASH_RELEASE_KEYSTORE_PASSWORD: ${{ secrets.UPLOAD_KEYSTORE_PASSWORD }}
|
||||||
ORG_GRADLE_PROJECT_ZCASH_RELEASE_KEY_ALIAS: ${{ secrets.UPLOAD_KEY_ALIAS }}
|
ORG_GRADLE_PROJECT_ZCASH_RELEASE_KEY_ALIAS: ${{ secrets.UPLOAD_KEY_ALIAS }}
|
||||||
ORG_GRADLE_PROJECT_ZCASH_RELEASE_KEY_ALIAS_PASSWORD: ${{ secrets.UPLOAD_KEY_ALIAS_PASSWORD }}
|
ORG_GRADLE_PROJECT_ZCASH_RELEASE_KEY_ALIAS_PASSWORD: ${{ secrets.UPLOAD_KEY_ALIAS_PASSWORD }}
|
||||||
|
ORG_GRADLE_PROJECT_ZCASH_COINBASE_APP_ID: ${{ secrets.COINBASE_APP_ID }}
|
||||||
run: |
|
run: |
|
||||||
./gradlew :app:publishToGooglePlay
|
./gradlew :app:publishToGooglePlay
|
||||||
- name: Collect Artifacts
|
- name: Collect Artifacts
|
||||||
|
|
|
@ -63,6 +63,17 @@ jobs:
|
||||||
if: "${{ env.EMULATOR_WTF_API_KEY != '' }}"
|
if: "${{ env.EMULATOR_WTF_API_KEY != '' }}"
|
||||||
run: echo "defined=true" >> $GITHUB_OUTPUT
|
run: echo "defined=true" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
check_coinbase_secrets:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
has-secrets: ${{ steps.check_coinbase_secrets.outputs.defined }}
|
||||||
|
steps:
|
||||||
|
- id: check_coinbase_secrets
|
||||||
|
env:
|
||||||
|
COINBASE_APP_ID: ${{ secrets.COINBASE_APP_ID }}
|
||||||
|
if: "${{ env.COINBASE_APP_ID != '' }}"
|
||||||
|
run: echo "defined=true" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
check_properties:
|
check_properties:
|
||||||
needs: validate_gradle_wrapper
|
needs: validate_gradle_wrapper
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
@ -252,8 +263,8 @@ jobs:
|
||||||
|
|
||||||
# Emulator.wtf is preferred if it has an API key.
|
# Emulator.wtf is preferred if it has an API key.
|
||||||
test_android_modules_ftl:
|
test_android_modules_ftl:
|
||||||
if: needs.check_firebase_secrets.outputs.has-secrets == 'true' && needs.check_emulator_wtf_secrets.outputs.has-secrets == 'false'
|
if: needs.check_firebase_secrets.outputs.has-secrets == 'true' && needs.check_emulator_wtf_secrets.outputs.has-secrets == 'false' && needs.check_coinbase_secrets.outputs.has-secrets == 'true'
|
||||||
needs: [validate_gradle_wrapper, check_firebase_secrets, check_emulator_wtf_secrets]
|
needs: [validate_gradle_wrapper, check_firebase_secrets, check_emulator_wtf_secrets, check_coinbase_secrets]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
@ -295,6 +306,7 @@ jobs:
|
||||||
ORG_GRADLE_PROJECT_ZCASH_FIREBASE_TEST_LAB_API_KEY_PATH: ${{ steps.auth_test_lab.outputs.credentials_file_path }}
|
ORG_GRADLE_PROJECT_ZCASH_FIREBASE_TEST_LAB_API_KEY_PATH: ${{ steps.auth_test_lab.outputs.credentials_file_path }}
|
||||||
# Because Fulladle doesn't allow Test Orchestrator to be enabled/disabled for a specific submodule, it must be enabled for all modules
|
# Because Fulladle doesn't allow Test Orchestrator to be enabled/disabled for a specific submodule, it must be enabled for all modules
|
||||||
ORG_GRADLE_PROJECT_IS_USE_TEST_ORCHESTRATOR: true
|
ORG_GRADLE_PROJECT_IS_USE_TEST_ORCHESTRATOR: true
|
||||||
|
ORG_GRADLE_PROJECT_ZCASH_COINBASE_APP_ID: ${{ secrets.COINBASE_APP_ID }}
|
||||||
run: |
|
run: |
|
||||||
./gradlew runFlank
|
./gradlew runFlank
|
||||||
- name: Collect Artifacts
|
- name: Collect Artifacts
|
||||||
|
@ -316,8 +328,8 @@ jobs:
|
||||||
path: ~/artifacts
|
path: ~/artifacts
|
||||||
|
|
||||||
test_android_modules_wtf_coverage:
|
test_android_modules_wtf_coverage:
|
||||||
if: needs.check_emulator_wtf_secrets.outputs.has-secrets == 'true'
|
if: needs.check_emulator_wtf_secrets.outputs.has-secrets == 'true' && needs.check_coinbase_secrets.outputs.has-secrets == 'true'
|
||||||
needs: [ validate_gradle_wrapper, check_emulator_wtf_secrets ]
|
needs: [ validate_gradle_wrapper, check_emulator_wtf_secrets, check_coinbase_secrets ]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
@ -342,6 +354,7 @@ jobs:
|
||||||
ORG_GRADLE_PROJECT_ZCASH_DEBUG_APP_NAME_SUFFIX: ""
|
ORG_GRADLE_PROJECT_ZCASH_DEBUG_APP_NAME_SUFFIX: ""
|
||||||
ORG_GRADLE_PROJECT_ZCASH_EMULATOR_WTF_API_KEY: ${{ secrets.EMULATOR_WTF_API_KEY }}
|
ORG_GRADLE_PROJECT_ZCASH_EMULATOR_WTF_API_KEY: ${{ secrets.EMULATOR_WTF_API_KEY }}
|
||||||
ORG_GRADLE_PROJECT_IS_ANDROID_INSTRUMENTATION_TEST_COVERAGE_ENABLED: true
|
ORG_GRADLE_PROJECT_IS_ANDROID_INSTRUMENTATION_TEST_COVERAGE_ENABLED: true
|
||||||
|
ORG_GRADLE_PROJECT_ZCASH_COINBASE_APP_ID: ${{ secrets.COINBASE_APP_ID }}
|
||||||
run: |
|
run: |
|
||||||
./gradlew testDebugWithEmulatorWtf :ui-integration-test:testZcashmainnetDebugWithEmulatorWtf
|
./gradlew testDebugWithEmulatorWtf :ui-integration-test:testZcashmainnetDebugWithEmulatorWtf
|
||||||
- name: Collect Artifacts
|
- name: Collect Artifacts
|
||||||
|
@ -363,8 +376,8 @@ jobs:
|
||||||
path: ~/artifacts
|
path: ~/artifacts
|
||||||
|
|
||||||
test_android_modules_wtf_no_coverage:
|
test_android_modules_wtf_no_coverage:
|
||||||
if: needs.check_emulator_wtf_secrets.outputs.has-secrets == 'true'
|
if: needs.check_emulator_wtf_secrets.outputs.has-secrets == 'true' && needs.check_coinbase_secrets.outputs.has-secrets == 'true'
|
||||||
needs: [ validate_gradle_wrapper, check_emulator_wtf_secrets ]
|
needs: [ validate_gradle_wrapper, check_emulator_wtf_secrets, check_coinbase_secrets ]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
@ -389,6 +402,7 @@ jobs:
|
||||||
ORG_GRADLE_PROJECT_ZCASH_DEBUG_APP_NAME_SUFFIX: ""
|
ORG_GRADLE_PROJECT_ZCASH_DEBUG_APP_NAME_SUFFIX: ""
|
||||||
ORG_GRADLE_PROJECT_ZCASH_EMULATOR_WTF_API_KEY: ${{ secrets.EMULATOR_WTF_API_KEY }}
|
ORG_GRADLE_PROJECT_ZCASH_EMULATOR_WTF_API_KEY: ${{ secrets.EMULATOR_WTF_API_KEY }}
|
||||||
ORG_GRADLE_PROJECT_IS_ANDROID_INSTRUMENTATION_TEST_COVERAGE_ENABLED: false
|
ORG_GRADLE_PROJECT_IS_ANDROID_INSTRUMENTATION_TEST_COVERAGE_ENABLED: false
|
||||||
|
ORG_GRADLE_PROJECT_ZCASH_COINBASE_APP_ID: ${{ secrets.COINBASE_APP_ID }}
|
||||||
run: |
|
run: |
|
||||||
./gradlew :app:testZcashmainnetDebugWithEmulatorWtf :ui-screenshot-test:testZcashmainnetDebugWithEmulatorWtf
|
./gradlew :app:testZcashmainnetDebugWithEmulatorWtf :ui-screenshot-test:testZcashmainnetDebugWithEmulatorWtf
|
||||||
- name: Collect Artifacts
|
- name: Collect Artifacts
|
||||||
|
@ -411,8 +425,8 @@ jobs:
|
||||||
|
|
||||||
# Performs a button mash test on the debug build of the app with strict mode enabled
|
# Performs a button mash test on the debug build of the app with strict mode enabled
|
||||||
test_robo_debug:
|
test_robo_debug:
|
||||||
if: needs.check_firebase_secrets.outputs.has-secrets == 'true'
|
if: needs.check_firebase_secrets.outputs.has-secrets == 'true' && needs.check_coinbase_secrets.outputs.has-secrets == 'true'
|
||||||
needs: [check_firebase_secrets]
|
needs: [check_firebase_secrets, check_coinbase_secrets]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
packages: read
|
packages: read
|
||||||
|
@ -447,6 +461,7 @@ jobs:
|
||||||
env:
|
env:
|
||||||
ORG_GRADLE_PROJECT_ZCASH_SUPPORT_EMAIL_ADDRESS: ${{ vars.SUPPORT_EMAIL_ADDRESS }}
|
ORG_GRADLE_PROJECT_ZCASH_SUPPORT_EMAIL_ADDRESS: ${{ vars.SUPPORT_EMAIL_ADDRESS }}
|
||||||
ORG_GRADLE_PROJECT_IS_CRASH_ON_STRICT_MODE_VIOLATION: true
|
ORG_GRADLE_PROJECT_IS_CRASH_ON_STRICT_MODE_VIOLATION: true
|
||||||
|
ORG_GRADLE_PROJECT_ZCASH_COINBASE_APP_ID: ${{ secrets.COINBASE_APP_ID }}
|
||||||
run: |
|
run: |
|
||||||
./gradlew :app:assembleDebug
|
./gradlew :app:assembleDebug
|
||||||
- name: Authenticate to Google Cloud for Firebase Test Lab
|
- name: Authenticate to Google Cloud for Firebase Test Lab
|
||||||
|
@ -464,11 +479,13 @@ jobs:
|
||||||
# This first environment variable is used by Flank, since the temporary token is missing the project name
|
# This first environment variable is used by Flank, since the temporary token is missing the project name
|
||||||
GOOGLE_CLOUD_PROJECT: ${{ vars.FIREBASE_TEST_LAB_PROJECT }}
|
GOOGLE_CLOUD_PROJECT: ${{ vars.FIREBASE_TEST_LAB_PROJECT }}
|
||||||
ORG_GRADLE_PROJECT_ZCASH_FIREBASE_TEST_LAB_API_KEY_PATH: ${{ steps.auth_test_lab.outputs.credentials_file_path }}
|
ORG_GRADLE_PROJECT_ZCASH_FIREBASE_TEST_LAB_API_KEY_PATH: ${{ steps.auth_test_lab.outputs.credentials_file_path }}
|
||||||
|
ORG_GRADLE_PROJECT_COINBASE_APP_ID: ${{ secrets.COINBASE_APP_ID }}
|
||||||
run: |
|
run: |
|
||||||
./gradlew :app:runFlankSanityConfigDebug
|
./gradlew :app:runFlankSanityConfigDebug
|
||||||
|
|
||||||
build:
|
build:
|
||||||
needs: validate_gradle_wrapper
|
if: needs.check_coinbase_secrets.outputs.has-secrets == 'true'
|
||||||
|
needs: [validate_gradle_wrapper, check_coinbase_secrets]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
@ -515,6 +532,7 @@ jobs:
|
||||||
ORG_GRADLE_PROJECT_ZCASH_RELEASE_KEYSTORE_PASSWORD: android
|
ORG_GRADLE_PROJECT_ZCASH_RELEASE_KEYSTORE_PASSWORD: android
|
||||||
ORG_GRADLE_PROJECT_ZCASH_RELEASE_KEY_ALIAS: androiddebugkey
|
ORG_GRADLE_PROJECT_ZCASH_RELEASE_KEY_ALIAS: androiddebugkey
|
||||||
ORG_GRADLE_PROJECT_ZCASH_RELEASE_KEY_ALIAS_PASSWORD: android
|
ORG_GRADLE_PROJECT_ZCASH_RELEASE_KEY_ALIAS_PASSWORD: android
|
||||||
|
ORG_GRADLE_PROJECT_ZCASH_COINBASE_APP_ID: ${{ secrets.COINBASE_APP_ID }}
|
||||||
run: |
|
run: |
|
||||||
./gradlew :app:assembleDebug :app:bundleRelease :app:packageZcashmainnetReleaseUniversalApk
|
./gradlew :app:assembleDebug :app:bundleRelease :app:packageZcashmainnetReleaseUniversalApk
|
||||||
- name: Collect Artifacts
|
- name: Collect Artifacts
|
||||||
|
@ -538,8 +556,8 @@ jobs:
|
||||||
|
|
||||||
# Performs a button mash test on the release build of the app
|
# Performs a button mash test on the release build of the app
|
||||||
test_robo_release:
|
test_robo_release:
|
||||||
if: needs.check_firebase_secrets.outputs.has-secrets == 'true'
|
if: needs.check_firebase_secrets.outputs.has-secrets == 'true' && needs.check_coinbase_secrets.outputs.has-secrets == 'true'
|
||||||
needs: [build, check_firebase_secrets]
|
needs: [build, check_firebase_secrets, check_coinbase_secrets]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
packages: read
|
packages: read
|
||||||
|
@ -579,6 +597,7 @@ jobs:
|
||||||
# This first environment variable is used by Flank, since the temporary token is missing the project name
|
# This first environment variable is used by Flank, since the temporary token is missing the project name
|
||||||
GOOGLE_CLOUD_PROJECT: ${{ vars.FIREBASE_TEST_LAB_PROJECT }}
|
GOOGLE_CLOUD_PROJECT: ${{ vars.FIREBASE_TEST_LAB_PROJECT }}
|
||||||
ORG_GRADLE_PROJECT_ZCASH_FIREBASE_TEST_LAB_API_KEY_PATH: ${{ steps.auth_test_lab.outputs.credentials_file_path }}
|
ORG_GRADLE_PROJECT_ZCASH_FIREBASE_TEST_LAB_API_KEY_PATH: ${{ steps.auth_test_lab.outputs.credentials_file_path }}
|
||||||
|
ORG_GRADLE_PROJECT_ZCASH_COINBASE_APP_ID: ${{ secrets.COINBASE_APP_ID }}
|
||||||
run: |
|
run: |
|
||||||
unzip ${BINARIES_ZIP_PATH}
|
unzip ${BINARIES_ZIP_PATH}
|
||||||
./gradlew :app:runFlankSanityConfigRelease
|
./gradlew :app:runFlankSanityConfigRelease
|
||||||
|
|
|
@ -10,6 +10,7 @@ and this application adheres to [Semantic Versioning](https://semver.org/spec/v2
|
||||||
- Transaction resubmission feature has been added. It periodically searches for unmined sent transactions that
|
- Transaction resubmission feature has been added. It periodically searches for unmined sent transactions that
|
||||||
are still within their expiry window and resubmits them if there are any.
|
are still within their expiry window and resubmits them if there are any.
|
||||||
- The Choose server screen now provides a new search for the three fastest servers feature
|
- The Choose server screen now provides a new search for the three fastest servers feature
|
||||||
|
- Coinbase Onramp integration button has been added to the Advanced Settings screen
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Choose server screen has been redesigned
|
- Choose server screen has been redesigned
|
||||||
|
|
|
@ -121,6 +121,7 @@ tasks {
|
||||||
"ZCASH_GOOGLE_PLAY_DEPLOY_TRACK" to "internal",
|
"ZCASH_GOOGLE_PLAY_DEPLOY_TRACK" to "internal",
|
||||||
"ZCASH_GOOGLE_PLAY_DEPLOY_STATUS" to "draft",
|
"ZCASH_GOOGLE_PLAY_DEPLOY_STATUS" to "draft",
|
||||||
|
|
||||||
|
"ZCASH_COINBASE_APP_ID" to "",
|
||||||
"SDK_INCLUDED_BUILD_PATH" to "",
|
"SDK_INCLUDED_BUILD_PATH" to "",
|
||||||
"BIP_39_INCLUDED_BUILD_PATH" to ""
|
"BIP_39_INCLUDED_BUILD_PATH" to ""
|
||||||
)
|
)
|
||||||
|
@ -192,12 +193,16 @@ fladle {
|
||||||
|
|
||||||
flankVersion.set(libs.versions.flank.get())
|
flankVersion.set(libs.versions.flank.get())
|
||||||
|
|
||||||
filesToDownload.set(listOf(
|
filesToDownload.set(
|
||||||
".*/matrix_.*/.*test_results_merged\\.xml",
|
listOf(
|
||||||
".*/matrix_.*/.*/artifacts/sdcard/googletest/test_outputfiles/.*\\.png"
|
".*/matrix_.*/.*test_results_merged\\.xml",
|
||||||
))
|
".*/matrix_.*/.*/artifacts/sdcard/googletest/test_outputfiles/.*\\.png"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
directoriesToPull.set(listOf(
|
directoriesToPull.set(
|
||||||
"/sdcard/googletest/test_outputfiles"
|
listOf(
|
||||||
))
|
"/sdcard/googletest/test_outputfiles"
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ directly impact users rather than highlighting other key architectural updates.*
|
||||||
- Transaction resubmission feature has been added. It periodically searches for unmined sent transactions that
|
- Transaction resubmission feature has been added. It periodically searches for unmined sent transactions that
|
||||||
are still within their expiry window and resubmits them if there are any.
|
are still within their expiry window and resubmits them if there are any.
|
||||||
- The Choose server screen now provides a new search for the three fastest servers feature
|
- The Choose server screen now provides a new search for the three fastest servers feature
|
||||||
|
- Coinbase Onramp integration button has been added to the Advanced Settings screen
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Choose server screen has been redesigned
|
- Choose server screen has been redesigned
|
||||||
|
|
|
@ -84,6 +84,10 @@ IS_SECURE_SCREEN_PROTECTION_ACTIVE=true
|
||||||
# Set whether the screen rotation is enabled or the screen orientation is locked in the portrait mode.
|
# Set whether the screen rotation is enabled or the screen orientation is locked in the portrait mode.
|
||||||
IS_SCREEN_ROTATION_ENABLED=false
|
IS_SCREEN_ROTATION_ENABLED=false
|
||||||
|
|
||||||
|
# Set the Coinbase app project ID to test the Coinbase Onramp integrations locally. Keep it empty as our CI actions
|
||||||
|
# set it up.
|
||||||
|
ZCASH_COINBASE_APP_ID=
|
||||||
|
|
||||||
# Set keystore details to enable build signing. Typically these
|
# Set keystore details to enable build signing. Typically these
|
||||||
# are overridden via ~/.gradle/gradle.properties to allow secure injection.
|
# are overridden via ~/.gradle/gradle.properties to allow secure injection.
|
||||||
# Debug keystore is useful if using Google Maps or Firebase, which require API keys to be linked
|
# Debug keystore is useful if using Google Maps or Firebase, which require API keys to be linked
|
||||||
|
@ -184,6 +188,7 @@ ANDROIDX_STARTUP_VERSION=1.1.1
|
||||||
ANDROIDX_TEST_SERVICE_VERSION=1.4.2
|
ANDROIDX_TEST_SERVICE_VERSION=1.4.2
|
||||||
ANDROIDX_UI_AUTOMATOR_VERSION=2.3.0
|
ANDROIDX_UI_AUTOMATOR_VERSION=2.3.0
|
||||||
ANDROIDX_WORK_MANAGER_VERSION=2.9.0
|
ANDROIDX_WORK_MANAGER_VERSION=2.9.0
|
||||||
|
ANDROIDX_BROWSER_VERSION=1.8.0
|
||||||
CORE_LIBRARY_DESUGARING_VERSION=2.0.4
|
CORE_LIBRARY_DESUGARING_VERSION=2.0.4
|
||||||
FIREBASE_BOM_VERSION_MATCHER=32.8.1
|
FIREBASE_BOM_VERSION_MATCHER=32.8.1
|
||||||
GOOGLE_AUTH_LIB_JAVA_VERSION=1.18.0
|
GOOGLE_AUTH_LIB_JAVA_VERSION=1.18.0
|
||||||
|
|
|
@ -167,6 +167,7 @@ dependencyResolutionManagement {
|
||||||
val androidxTestRunnerVersion = extra["ANDROIDX_TEST_RUNNER_VERSION"].toString()
|
val androidxTestRunnerVersion = extra["ANDROIDX_TEST_RUNNER_VERSION"].toString()
|
||||||
val androidxUiAutomatorVersion = extra["ANDROIDX_UI_AUTOMATOR_VERSION"].toString()
|
val androidxUiAutomatorVersion = extra["ANDROIDX_UI_AUTOMATOR_VERSION"].toString()
|
||||||
val androidxWorkManagerVersion = extra["ANDROIDX_WORK_MANAGER_VERSION"].toString()
|
val androidxWorkManagerVersion = extra["ANDROIDX_WORK_MANAGER_VERSION"].toString()
|
||||||
|
val androidxBrowserVersion = extra["ANDROIDX_BROWSER_VERSION"].toString()
|
||||||
val coreLibraryDesugaringVersion = extra["CORE_LIBRARY_DESUGARING_VERSION"].toString()
|
val coreLibraryDesugaringVersion = extra["CORE_LIBRARY_DESUGARING_VERSION"].toString()
|
||||||
val flankVersion = extra["FLANK_VERSION"].toString()
|
val flankVersion = extra["FLANK_VERSION"].toString()
|
||||||
val jacocoVersion = extra["JACOCO_VERSION"].toString()
|
val jacocoVersion = extra["JACOCO_VERSION"].toString()
|
||||||
|
@ -220,6 +221,7 @@ dependencyResolutionManagement {
|
||||||
library("androidx-startup", "androidx.startup:startup-runtime:$androidxStartupVersion")
|
library("androidx-startup", "androidx.startup:startup-runtime:$androidxStartupVersion")
|
||||||
library("androidx-viewmodel-compose", "androidx.lifecycle:lifecycle-viewmodel-compose:$androidxLifecycleVersion")
|
library("androidx-viewmodel-compose", "androidx.lifecycle:lifecycle-viewmodel-compose:$androidxLifecycleVersion")
|
||||||
library("androidx-workmanager", "androidx.work:work-runtime-ktx:$androidxWorkManagerVersion")
|
library("androidx-workmanager", "androidx.work:work-runtime-ktx:$androidxWorkManagerVersion")
|
||||||
|
library("androidx-browser", "androidx.browser:browser:$androidxBrowserVersion")
|
||||||
library("desugaring", "com.android.tools:desugar_jdk_libs:$coreLibraryDesugaringVersion")
|
library("desugaring", "com.android.tools:desugar_jdk_libs:$coreLibraryDesugaringVersion")
|
||||||
library("firebase-bom", "com.google.firebase:firebase-bom:${extra["FIREBASE_BOM_VERSION_MATCHER"]}")
|
library("firebase-bom", "com.google.firebase:firebase-bom:${extra["FIREBASE_BOM_VERSION_MATCHER"]}")
|
||||||
library("firebase-installations", "com.google.firebase", "firebase-installations").withoutVersion()
|
library("firebase-installations", "com.google.firebase", "firebase-installations").withoutVersion()
|
||||||
|
|
|
@ -25,8 +25,28 @@ import androidx.compose.ui.unit.sp
|
||||||
import co.electriccoin.zcash.ui.design.R
|
import co.electriccoin.zcash.ui.design.R
|
||||||
import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens
|
import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens
|
||||||
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
||||||
|
import co.electriccoin.zcash.ui.design.util.getValue
|
||||||
import co.electriccoin.zcash.ui.design.util.orDark
|
import co.electriccoin.zcash.ui.design.util.orDark
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ZashiSettingsListItem(
|
||||||
|
state: ButtonState,
|
||||||
|
@DrawableRes icon: Int,
|
||||||
|
trailing: @Composable () -> Unit = {
|
||||||
|
Image(
|
||||||
|
painter = painterResource(R.drawable.ic_chevron_right orDark R.drawable.ic_chevron_right_dark),
|
||||||
|
contentDescription = state.text.getValue(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
ZashiSettingsListItem(
|
||||||
|
text = state.text.getValue(),
|
||||||
|
icon = icon,
|
||||||
|
trailing = trailing,
|
||||||
|
onClick = state.onClick
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ZashiSettingsListItem(
|
fun ZashiSettingsListItem(
|
||||||
text: String,
|
text: String,
|
||||||
|
|
|
@ -74,6 +74,14 @@ androidComponents {
|
||||||
comment = "Whether is the SecureScreen sensitive data protection enabled"
|
comment = "Whether is the SecureScreen sensitive data protection enabled"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
variant.buildConfigFields.put(
|
||||||
|
"ZCASH_COINBASE_APP_ID",
|
||||||
|
BuildConfigField(
|
||||||
|
type = "String",
|
||||||
|
value = "\"${project.property("ZCASH_COINBASE_APP_ID")?.toString().orEmpty()}\"",
|
||||||
|
comment = "App ID of the Coinbase Onramp integration"
|
||||||
|
)
|
||||||
|
)
|
||||||
// To configure screen orientation in runtime
|
// To configure screen orientation in runtime
|
||||||
variant.buildConfigFields.put(
|
variant.buildConfigFields.put(
|
||||||
"IS_SCREEN_ROTATION_ENABLED",
|
"IS_SCREEN_ROTATION_ENABLED",
|
||||||
|
@ -96,6 +104,7 @@ dependencies {
|
||||||
implementation(libs.androidx.splash)
|
implementation(libs.androidx.splash)
|
||||||
implementation(libs.androidx.workmanager)
|
implementation(libs.androidx.workmanager)
|
||||||
api(libs.bundles.androidx.biometric)
|
api(libs.bundles.androidx.biometric)
|
||||||
|
implementation(libs.androidx.browser)
|
||||||
implementation(libs.bundles.androidx.camera)
|
implementation(libs.bundles.androidx.camera)
|
||||||
implementation(libs.bundles.androidx.compose.core)
|
implementation(libs.bundles.androidx.compose.core)
|
||||||
implementation(libs.bundles.androidx.compose.extended)
|
implementation(libs.bundles.androidx.compose.extended)
|
||||||
|
|
|
@ -2,6 +2,7 @@ package co.electriccoin.zcash.di
|
||||||
|
|
||||||
import co.electriccoin.zcash.ui.common.provider.GetDefaultServersProvider
|
import co.electriccoin.zcash.ui.common.provider.GetDefaultServersProvider
|
||||||
import co.electriccoin.zcash.ui.common.provider.GetVersionInfoProvider
|
import co.electriccoin.zcash.ui.common.provider.GetVersionInfoProvider
|
||||||
|
import co.electriccoin.zcash.ui.common.provider.GetZcashCurrencyProvider
|
||||||
import org.koin.core.module.dsl.factoryOf
|
import org.koin.core.module.dsl.factoryOf
|
||||||
import org.koin.dsl.module
|
import org.koin.dsl.module
|
||||||
|
|
||||||
|
@ -9,4 +10,5 @@ val providerModule =
|
||||||
module {
|
module {
|
||||||
factoryOf(::GetDefaultServersProvider)
|
factoryOf(::GetDefaultServersProvider)
|
||||||
factoryOf(::GetVersionInfoProvider)
|
factoryOf(::GetVersionInfoProvider)
|
||||||
|
factoryOf(::GetZcashCurrencyProvider)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package co.electriccoin.zcash.di
|
||||||
import co.electriccoin.zcash.ui.common.usecase.GetPersistableWalletUseCase
|
import co.electriccoin.zcash.ui.common.usecase.GetPersistableWalletUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.GetSelectedEndpointUseCase
|
import co.electriccoin.zcash.ui.common.usecase.GetSelectedEndpointUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.GetSynchronizerUseCase
|
import co.electriccoin.zcash.ui.common.usecase.GetSynchronizerUseCase
|
||||||
|
import co.electriccoin.zcash.ui.common.usecase.GetTransparentAddressUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.ObserveConfigurationUseCase
|
import co.electriccoin.zcash.ui.common.usecase.ObserveConfigurationUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.ObserveFastestServersUseCase
|
import co.electriccoin.zcash.ui.common.usecase.ObserveFastestServersUseCase
|
||||||
import co.electriccoin.zcash.ui.common.usecase.ObserveSelectedEndpointUseCase
|
import co.electriccoin.zcash.ui.common.usecase.ObserveSelectedEndpointUseCase
|
||||||
|
@ -27,4 +28,5 @@ val useCaseModule =
|
||||||
singleOf(::GetSelectedEndpointUseCase)
|
singleOf(::GetSelectedEndpointUseCase)
|
||||||
singleOf(::ObserveConfigurationUseCase)
|
singleOf(::ObserveConfigurationUseCase)
|
||||||
singleOf(::RescanBlockchainUseCase)
|
singleOf(::RescanBlockchainUseCase)
|
||||||
|
singleOf(::GetTransparentAddressUseCase)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
package co.electriccoin.zcash.ui.common.provider
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import cash.z.ecc.sdk.type.ZcashCurrency
|
||||||
|
|
||||||
|
class GetZcashCurrencyProvider(private val application: Application) {
|
||||||
|
operator fun invoke() = ZcashCurrency.fromResources(application)
|
||||||
|
|
||||||
|
fun getLocalizedName() = ZcashCurrency.getLocalizedName(application)
|
||||||
|
}
|
|
@ -6,10 +6,12 @@ import cash.z.ecc.android.sdk.Synchronizer
|
||||||
import cash.z.ecc.android.sdk.WalletCoordinator
|
import cash.z.ecc.android.sdk.WalletCoordinator
|
||||||
import cash.z.ecc.android.sdk.model.FastestServersResult
|
import cash.z.ecc.android.sdk.model.FastestServersResult
|
||||||
import cash.z.ecc.android.sdk.model.PersistableWallet
|
import cash.z.ecc.android.sdk.model.PersistableWallet
|
||||||
|
import cash.z.ecc.android.sdk.model.WalletAddresses
|
||||||
import cash.z.ecc.sdk.ANDROID_STATE_FLOW_TIMEOUT
|
import cash.z.ecc.sdk.ANDROID_STATE_FLOW_TIMEOUT
|
||||||
import co.electriccoin.lightwallet.client.model.LightWalletEndpoint
|
import co.electriccoin.lightwallet.client.model.LightWalletEndpoint
|
||||||
import co.electriccoin.zcash.preference.EncryptedPreferenceProvider
|
import co.electriccoin.zcash.preference.EncryptedPreferenceProvider
|
||||||
import co.electriccoin.zcash.preference.StandardPreferenceProvider
|
import co.electriccoin.zcash.preference.StandardPreferenceProvider
|
||||||
|
import co.electriccoin.zcash.spackle.Twig
|
||||||
import co.electriccoin.zcash.ui.common.model.FastestServersState
|
import co.electriccoin.zcash.ui.common.model.FastestServersState
|
||||||
import co.electriccoin.zcash.ui.common.model.OnboardingState
|
import co.electriccoin.zcash.ui.common.model.OnboardingState
|
||||||
import co.electriccoin.zcash.ui.common.provider.GetDefaultServersProvider
|
import co.electriccoin.zcash.ui.common.provider.GetDefaultServersProvider
|
||||||
|
@ -48,6 +50,7 @@ interface WalletRepository {
|
||||||
val secretState: StateFlow<SecretState?>
|
val secretState: StateFlow<SecretState?>
|
||||||
val fastestServers: StateFlow<FastestServersState>
|
val fastestServers: StateFlow<FastestServersState>
|
||||||
val persistableWallet: Flow<PersistableWallet?>
|
val persistableWallet: Flow<PersistableWallet?>
|
||||||
|
val addresses: StateFlow<WalletAddresses?>
|
||||||
|
|
||||||
fun persistWallet(persistableWallet: PersistableWallet)
|
fun persistWallet(persistableWallet: PersistableWallet)
|
||||||
|
|
||||||
|
@ -160,6 +163,21 @@ class WalletRepositoryImpl(
|
||||||
(it as? SecretState.Ready?)?.persistableWallet
|
(it as? SecretState.Ready?)?.persistableWallet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val addresses: StateFlow<WalletAddresses?> =
|
||||||
|
synchronizer
|
||||||
|
.filterNotNull()
|
||||||
|
.map {
|
||||||
|
runCatching {
|
||||||
|
WalletAddresses.new(it)
|
||||||
|
}.onFailure {
|
||||||
|
Twig.warn { "Wait until the SDK starts providing the addresses" }
|
||||||
|
}.getOrNull()
|
||||||
|
}.stateIn(
|
||||||
|
scope,
|
||||||
|
SharingStarted.WhileSubscribed(ANDROID_STATE_FLOW_TIMEOUT),
|
||||||
|
null
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Persists a wallet asynchronously. Clients observe [secretState] to see the side effects.
|
* Persists a wallet asynchronously. Clients observe [secretState] to see the side effects.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
package co.electriccoin.zcash.ui.common.usecase
|
||||||
|
|
||||||
|
import co.electriccoin.zcash.ui.common.repository.WalletRepository
|
||||||
|
import kotlinx.coroutines.flow.filterNotNull
|
||||||
|
import kotlinx.coroutines.flow.first
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
|
||||||
|
class GetTransparentAddressUseCase(
|
||||||
|
private val walletRepository: WalletRepository
|
||||||
|
) {
|
||||||
|
suspend operator fun invoke() = walletRepository.addresses.filterNotNull().map { it.transparent }.first()
|
||||||
|
}
|
|
@ -223,20 +223,7 @@ class WalletViewModel(
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
|
|
||||||
val addresses: StateFlow<WalletAddresses?> =
|
val addresses: StateFlow<WalletAddresses?> = walletRepository.addresses
|
||||||
synchronizer
|
|
||||||
.filterNotNull()
|
|
||||||
.map {
|
|
||||||
runCatching {
|
|
||||||
WalletAddresses.new(it)
|
|
||||||
}.onFailure {
|
|
||||||
Twig.warn { "Wait until the SDK starts providing the addresses" }
|
|
||||||
}.getOrNull()
|
|
||||||
}.stateIn(
|
|
||||||
viewModelScope,
|
|
||||||
SharingStarted.WhileSubscribed(ANDROID_STATE_FLOW_TIMEOUT),
|
|
||||||
null
|
|
||||||
)
|
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
val transactionHistoryState =
|
val transactionHistoryState =
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package co.electriccoin.zcash.ui.screen.advancedsettings
|
package co.electriccoin.zcash.ui.screen.advancedsettings
|
||||||
|
|
||||||
|
import co.electriccoin.zcash.ui.design.component.ButtonState
|
||||||
|
|
||||||
data class AdvancedSettingsState(
|
data class AdvancedSettingsState(
|
||||||
val onBack: () -> Unit,
|
val onBack: () -> Unit,
|
||||||
val onRecoveryPhraseClick: () -> Unit,
|
val onRecoveryPhraseClick: () -> Unit,
|
||||||
|
@ -7,4 +9,5 @@ data class AdvancedSettingsState(
|
||||||
val onChooseServerClick: () -> Unit,
|
val onChooseServerClick: () -> Unit,
|
||||||
val onCurrencyConversionClick: () -> Unit,
|
val onCurrencyConversionClick: () -> Unit,
|
||||||
val onDeleteZashiClick: () -> Unit,
|
val onDeleteZashiClick: () -> Unit,
|
||||||
|
val coinbaseButton: ButtonState?,
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,11 +2,14 @@
|
||||||
|
|
||||||
package co.electriccoin.zcash.ui.screen.advancedsettings
|
package co.electriccoin.zcash.ui.screen.advancedsettings
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
|
import androidx.browser.customtabs.CustomTabsIntent
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import co.electriccoin.zcash.di.koinActivityViewModel
|
import co.electriccoin.zcash.di.koinActivityViewModel
|
||||||
|
import co.electriccoin.zcash.ui.common.compose.LocalActivity
|
||||||
import co.electriccoin.zcash.ui.common.compose.LocalNavController
|
import co.electriccoin.zcash.ui.common.compose.LocalNavController
|
||||||
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
|
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
|
||||||
import co.electriccoin.zcash.ui.screen.advancedsettings.view.AdvancedSettings
|
import co.electriccoin.zcash.ui.screen.advancedsettings.view.AdvancedSettings
|
||||||
|
@ -20,6 +23,7 @@ internal fun WrapAdvancedSettings(
|
||||||
goExportPrivateData: () -> Unit,
|
goExportPrivateData: () -> Unit,
|
||||||
goSeedRecovery: () -> Unit,
|
goSeedRecovery: () -> Unit,
|
||||||
) {
|
) {
|
||||||
|
val activity = LocalActivity.current
|
||||||
val navController = LocalNavController.current
|
val navController = LocalNavController.current
|
||||||
val walletViewModel = koinActivityViewModel<WalletViewModel>()
|
val walletViewModel = koinActivityViewModel<WalletViewModel>()
|
||||||
val viewModel = koinViewModel<AdvancedSettingsViewModel>()
|
val viewModel = koinViewModel<AdvancedSettingsViewModel>()
|
||||||
|
@ -41,6 +45,18 @@ internal fun WrapAdvancedSettings(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
viewModel.coinbaseNavigationCommand.collect { uri ->
|
||||||
|
val intent =
|
||||||
|
CustomTabsIntent.Builder()
|
||||||
|
.setUrlBarHidingEnabled(true)
|
||||||
|
.setShowTitle(true)
|
||||||
|
.setShareState(CustomTabsIntent.SHARE_STATE_OFF)
|
||||||
|
.build()
|
||||||
|
intent.launchUrl(activity, Uri.parse(uri))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
viewModel.backNavigationCommand.collect {
|
viewModel.backNavigationCommand.collect {
|
||||||
navController.popBackStack()
|
navController.popBackStack()
|
||||||
|
|
|
@ -26,12 +26,14 @@ import androidx.compose.ui.unit.sp
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
||||||
import co.electriccoin.zcash.ui.design.component.BlankBgScaffold
|
import co.electriccoin.zcash.ui.design.component.BlankBgScaffold
|
||||||
|
import co.electriccoin.zcash.ui.design.component.ButtonState
|
||||||
import co.electriccoin.zcash.ui.design.component.ZashiSettingsListItem
|
import co.electriccoin.zcash.ui.design.component.ZashiSettingsListItem
|
||||||
import co.electriccoin.zcash.ui.design.component.ZashiSmallTopAppBar
|
import co.electriccoin.zcash.ui.design.component.ZashiSmallTopAppBar
|
||||||
import co.electriccoin.zcash.ui.design.component.ZashiTopAppBarBackNavigation
|
import co.electriccoin.zcash.ui.design.component.ZashiTopAppBarBackNavigation
|
||||||
import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens
|
import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens
|
||||||
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
||||||
import co.electriccoin.zcash.ui.design.util.orDark
|
import co.electriccoin.zcash.ui.design.util.orDark
|
||||||
|
import co.electriccoin.zcash.ui.design.util.stringRes
|
||||||
import co.electriccoin.zcash.ui.screen.advancedsettings.AdvancedSettingsState
|
import co.electriccoin.zcash.ui.screen.advancedsettings.AdvancedSettingsState
|
||||||
import co.electriccoin.zcash.ui.screen.advancedsettings.AdvancedSettingsTag
|
import co.electriccoin.zcash.ui.screen.advancedsettings.AdvancedSettingsTag
|
||||||
import co.electriccoin.zcash.ui.screen.exchangerate.ZashiButton
|
import co.electriccoin.zcash.ui.screen.exchangerate.ZashiButton
|
||||||
|
@ -92,6 +94,13 @@ fun AdvancedSettings(
|
||||||
R.drawable.ic_advanced_settings_currency_conversion_dark,
|
R.drawable.ic_advanced_settings_currency_conversion_dark,
|
||||||
onClick = state.onCurrencyConversionClick
|
onClick = state.onCurrencyConversionClick
|
||||||
)
|
)
|
||||||
|
if (state.coinbaseButton != null) {
|
||||||
|
HorizontalDivider(color = ZcashTheme.zashiColors.divider)
|
||||||
|
ZashiSettingsListItem(
|
||||||
|
icon = R.drawable.ic_advanced_settings_coinbase,
|
||||||
|
state = state.coinbaseButton
|
||||||
|
)
|
||||||
|
}
|
||||||
Spacer(modifier = Modifier.height(24.dp))
|
Spacer(modifier = Modifier.height(24.dp))
|
||||||
Spacer(modifier = Modifier.weight(1f))
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
Row(
|
Row(
|
||||||
|
@ -161,6 +170,11 @@ private fun AdvancedSettingsPreview() =
|
||||||
onChooseServerClick = {},
|
onChooseServerClick = {},
|
||||||
onCurrencyConversionClick = {},
|
onCurrencyConversionClick = {},
|
||||||
onDeleteZashiClick = {},
|
onDeleteZashiClick = {},
|
||||||
|
coinbaseButton =
|
||||||
|
ButtonState(
|
||||||
|
text = stringRes("Coinbase"),
|
||||||
|
onClick = {}
|
||||||
|
)
|
||||||
),
|
),
|
||||||
topAppBarSubTitleState = TopAppBarSubTitleState.None,
|
topAppBarSubTitleState = TopAppBarSubTitleState.None,
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,16 +2,28 @@ package co.electriccoin.zcash.ui.screen.advancedsettings.viewmodel
|
||||||
|
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import co.electriccoin.zcash.ui.BuildConfig
|
||||||
import co.electriccoin.zcash.ui.NavigationTargets
|
import co.electriccoin.zcash.ui.NavigationTargets
|
||||||
|
import co.electriccoin.zcash.ui.R
|
||||||
|
import co.electriccoin.zcash.ui.common.provider.GetVersionInfoProvider
|
||||||
|
import co.electriccoin.zcash.ui.common.provider.GetZcashCurrencyProvider
|
||||||
|
import co.electriccoin.zcash.ui.common.usecase.GetTransparentAddressUseCase
|
||||||
|
import co.electriccoin.zcash.ui.design.component.ButtonState
|
||||||
|
import co.electriccoin.zcash.ui.design.util.stringRes
|
||||||
import co.electriccoin.zcash.ui.screen.advancedsettings.AdvancedSettingsState
|
import co.electriccoin.zcash.ui.screen.advancedsettings.AdvancedSettingsState
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class AdvancedSettingsViewModel : ViewModel() {
|
class AdvancedSettingsViewModel(
|
||||||
val state: StateFlow<AdvancedSettingsState> =
|
getVersionInfo: GetVersionInfoProvider,
|
||||||
|
getZcashCurrency: GetZcashCurrencyProvider,
|
||||||
|
private val getTransparentAddress: GetTransparentAddressUseCase,
|
||||||
|
) : ViewModel() {
|
||||||
|
private val forceShowCoinbaseForDebug = getVersionInfo().let { it.isDebuggable && !it.isRunningUnderTestService }
|
||||||
|
|
||||||
|
val state =
|
||||||
MutableStateFlow(
|
MutableStateFlow(
|
||||||
AdvancedSettingsState(
|
AdvancedSettingsState(
|
||||||
onBack = ::onBack,
|
onBack = ::onBack,
|
||||||
|
@ -19,12 +31,23 @@ class AdvancedSettingsViewModel : ViewModel() {
|
||||||
onExportPrivateDataClick = {},
|
onExportPrivateDataClick = {},
|
||||||
onChooseServerClick = ::onChooseServerClick,
|
onChooseServerClick = ::onChooseServerClick,
|
||||||
onCurrencyConversionClick = ::onCurrencyConversionClick,
|
onCurrencyConversionClick = ::onCurrencyConversionClick,
|
||||||
onDeleteZashiClick = {}
|
onDeleteZashiClick = {},
|
||||||
|
coinbaseButton =
|
||||||
|
ButtonState(
|
||||||
|
// Set the wallet currency by app build is more future-proof, although we hide it from the UI
|
||||||
|
// in the Testnet build
|
||||||
|
text = stringRes(R.string.advanced_settings_coinbase, getZcashCurrency.getLocalizedName()),
|
||||||
|
onClick = { onBuyWithCoinbaseClicked() }
|
||||||
|
).takeIf {
|
||||||
|
!getVersionInfo().isTestnet &&
|
||||||
|
(BuildConfig.ZCASH_COINBASE_APP_ID.isNotEmpty() || forceShowCoinbaseForDebug)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
).asStateFlow()
|
).asStateFlow()
|
||||||
|
|
||||||
val navigationCommand = MutableSharedFlow<String>()
|
val navigationCommand = MutableSharedFlow<String>()
|
||||||
val backNavigationCommand = MutableSharedFlow<Unit>()
|
val backNavigationCommand = MutableSharedFlow<Unit>()
|
||||||
|
val coinbaseNavigationCommand = MutableSharedFlow<String>()
|
||||||
|
|
||||||
private fun onChooseServerClick() =
|
private fun onChooseServerClick() =
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
|
@ -36,6 +59,32 @@ class AdvancedSettingsViewModel : ViewModel() {
|
||||||
navigationCommand.emit(NavigationTargets.SETTINGS_EXCHANGE_RATE_OPT_IN)
|
navigationCommand.emit(NavigationTargets.SETTINGS_EXCHANGE_RATE_OPT_IN)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun onBuyWithCoinbaseClicked() {
|
||||||
|
viewModelScope.launch {
|
||||||
|
val appId = BuildConfig.ZCASH_COINBASE_APP_ID
|
||||||
|
|
||||||
|
when {
|
||||||
|
appId.isEmpty() && forceShowCoinbaseForDebug ->
|
||||||
|
coinbaseNavigationCommand.emit("https://www.coinbase.com") // fallback debug url
|
||||||
|
|
||||||
|
appId.isEmpty() && forceShowCoinbaseForDebug -> {
|
||||||
|
// should not happen
|
||||||
|
}
|
||||||
|
|
||||||
|
appId.isNotEmpty() -> {
|
||||||
|
val address = getTransparentAddress().address
|
||||||
|
val url =
|
||||||
|
"https://pay.coinbase.com/buy/select-asset?appId=$appId&addresses={\"${address}\":[\"zcash\"]}"
|
||||||
|
coinbaseNavigationCommand.emit(url)
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
// should not happen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun onBack() =
|
fun onBack() =
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
backNavigationCommand.emit(Unit)
|
backNavigationCommand.emit(Unit)
|
||||||
|
|
|
@ -94,7 +94,7 @@ class SettingsViewModel(
|
||||||
combine(isLoading, troubleshootingState) { isLoading, troubleshootingState ->
|
combine(isLoading, troubleshootingState) { isLoading, troubleshootingState ->
|
||||||
SettingsState(
|
SettingsState(
|
||||||
isLoading = isLoading,
|
isLoading = isLoading,
|
||||||
version = stringRes(R.string.settings_version, getVersionInfo().versionName),
|
version = stringRes(R.string.settings_version, versionInfo.versionName),
|
||||||
settingsTroubleshootingState = troubleshootingState,
|
settingsTroubleshootingState = troubleshootingState,
|
||||||
onBack = ::onBack,
|
onBack = ::onBack,
|
||||||
onAdvancedSettingsClick = ::onAdvancedSettingsClick,
|
onAdvancedSettingsClick = ::onAdvancedSettingsClick,
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<string name="advanced_settings_export">Export Private Data</string>
|
<string name="advanced_settings_export">Export Private Data</string>
|
||||||
<string name="advanced_settings_choose_server">Choose a Server</string>
|
<string name="advanced_settings_choose_server">Choose a Server</string>
|
||||||
<string name="advanced_settings_currency_conversion">Currency Conversion</string>
|
<string name="advanced_settings_currency_conversion">Currency Conversion</string>
|
||||||
<string name="advanced_settings_coinbase">Buy ZEC with Coinbase</string>
|
<string name="advanced_settings_coinbase">Buy <xliff:g id="currency" example="ZEC">%1$s</xliff:g> with Coinbase</string>
|
||||||
<string name="advanced_settings_info">You will be asked to confirm on the next screen</string>
|
<string name="advanced_settings_info">You will be asked to confirm on the next screen</string>
|
||||||
<string name="advanced_settings_delete_button">Delete Zashi</string>
|
<string name="advanced_settings_delete_button">Delete Zashi</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in New Issue