Skip to content
Merged
Show file tree
Hide file tree
Changes from 50 commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
cee8601
Add a class for network config
Radiokot Feb 12, 2026
06e2cf4
Get non-backend network fields from the session
Radiokot Feb 12, 2026
c1ff139
Move backends into the session
Radiokot Feb 12, 2026
091ecb3
Separate parts of wallet storage per network
Radiokot Feb 13, 2026
92fcc4f
Reject WC requests for different networks
Radiokot Feb 13, 2026
df23f54
Make Testnet a Preview wallet
Radiokot Feb 13, 2026
35c4d0e
Store networks in the app database
Radiokot Feb 16, 2026
cab285c
Add network switch use case
Radiokot Feb 17, 2026
f7bce28
Add network adding use case
Radiokot Feb 18, 2026
88af2c9
Delete the FCM token on network switch
Radiokot Feb 18, 2026
bb30885
WIP debug the switch
Radiokot Feb 19, 2026
cff1363
Merge branch 'main' into network-switch
Radiokot Feb 20, 2026
d3e59bc
Add fetching genesis hash from wallet-proxy
Radiokot Feb 24, 2026
d643c8d
Add initial view model for new network screen
Radiokot Feb 24, 2026
10ecd44
Add initial view model for netoworks screen
Radiokot Feb 24, 2026
20b2246
Merge branch 'main' into network-switch
Radiokot Feb 24, 2026
c8af3a8
Merge branch 'main' into network-switch
Radiokot Feb 25, 2026
8a20a38
Remove Spaceseven from app network
Radiokot Feb 25, 2026
51cca97
Add edit mode to the networks VM
Radiokot Feb 26, 2026
c9a2f7b
Add Networks preference
Radiokot Feb 26, 2026
be6f155
Add initial networks list allowing the switch
Radiokot Feb 26, 2026
fefb5a7
Show network on the send token receipt screen
Radiokot Feb 27, 2026
121c68b
Show network on delegation confirmation screen
Radiokot Feb 27, 2026
257f614
Add active background for primary container
Radiokot Feb 27, 2026
2c3d001
Show network connected toast on main screen
Radiokot Feb 27, 2026
f70c546
Add disabled state for InputFieldView
Radiokot Feb 27, 2026
91fd820
Add fields and buttons to the edit network screen
Radiokot Mar 2, 2026
b4ec35e
Change the way data is validated and fetched
Radiokot Mar 2, 2026
e53f8ff
Add errors for fields
Radiokot Mar 2, 2026
097f952
Allow changing network from the welcome screen
Radiokot Mar 3, 2026
3d1cb06
Add the dev mode preference
Radiokot Mar 3, 2026
f18cb97
Allow changing network from the recover screen
Radiokot Mar 3, 2026
5076223
Add validation to the network edit screen
Radiokot Mar 4, 2026
809fbd7
WIP save new networks
Radiokot Mar 4, 2026
c697a7c
Merge branch 'main' into network-switch
Radiokot Mar 4, 2026
014a4fe
Allow saving new networks
Radiokot Mar 4, 2026
d29660c
Allow editing networks
Radiokot Mar 4, 2026
4235412
Fix not saving recent changes when Save is clicked
Radiokot Mar 4, 2026
926b251
Merge branch 'main' into network-switch
Radiokot Mar 5, 2026
097aeae
Exit networks edit mode when saved successfully
Radiokot Mar 5, 2026
8195a78
Fix incorrect stagenet genesis hash
Radiokot Mar 5, 2026
2420415
Do not show edit button without custom networks
Radiokot Mar 5, 2026
08d7239
Allow deleting networks
Radiokot Mar 5, 2026
a70f55b
Add network delete confirmation
Radiokot Mar 6, 2026
5892818
Add discard changes confirmation dialog
Radiokot Mar 10, 2026
733b745
Add Network toggle in NetworksActivity
zaiatsartem Mar 10, 2026
9565a81
Merge branch 'network-switch' of github.com:Concordium/cryptox-androi…
zaiatsartem Mar 10, 2026
6b44f9d
Fix incorrect stable provider authority
Radiokot Mar 18, 2026
c865061
Merge branch 'main' into network-switch
Radiokot Mar 26, 2026
9a0cb1c
Update the changelog
Radiokot Mar 26, 2026
0f146ec
Add stable package to the internal testing
Radiokot Mar 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ jobs:
java-version: "${{env.java_version}}"
distribution: corretto

- name: Build project (Stagenet)
run: ./gradlew app:assembleStagenetDebug --stacktrace
- name: Build preview
run: ./gradlew app:assemblePreviewDebug --stacktrace
4 changes: 2 additions & 2 deletions .github/workflows/end_to_end_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
distribution: corretto

- name: Build project (Stagenet)
run: chmod +x ./gradlew && ./gradlew app:assembleStagenetDebug --stacktrace
run: chmod +x ./gradlew && ./gradlew app:assemblePreviewDebug --stacktrace

# Log APK Path and store it as an environment variable
- name: Log APK Path
Expand Down Expand Up @@ -120,4 +120,4 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: failed-test-screenshots
path: cryptox-android-autotests/screenshots/
path: cryptox-android-autotests/screenshots/
10 changes: 2 additions & 8 deletions .github/workflows/firebase_internal_testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,8 @@ jobs:
env:
SOURCE_TAG: ${{ steps.branch_name.outputs.SOURCE_TAG }}

- name: Build and distribute Testnet APK
run: ./gradlew app:assembleTstnetRelease app:appDistributionUploadTstnetRelease --stacktrace

- name: Build and distribute Stagenet APK
run: ./gradlew app:assembleStagenetRelease app:appDistributionUploadStagenetRelease --stacktrace

- name: Build and distribute Mainnet APK
run: ./gradlew app:assembleMainnetRelease app:appDistributionUploadMainnetRelease --stacktrace
- name: Build and distribute Preview APK
run: ./gradlew app:assemblePreviewRelease app:appDistributionUploadPreviewRelease --stacktrace

- name: Upload the APKs
uses: actions/upload-artifact@v4
Expand Down
16 changes: 8 additions & 8 deletions .github/workflows/release_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,23 +49,23 @@ jobs:
env:
SOURCE_TAG: ${{ steps.branch_name.outputs.SOURCE_TAG }}

- name: Build Testnet APK for standalone release
run: ./gradlew app:assembleTstnetRelease --stacktrace
- name: Build Preview APK for standalone release
run: ./gradlew app:assemblePreviewRelease --stacktrace
env:
CONFIGURABLE_SIGNING_PROPERTIES_FILE: standalone-release-signing.properties

- name: Build Testnet bundle for Google Play upload
run: ./gradlew app:bundleTstnetRelease --stacktrace
- name: Build Preview bundle for Google Play upload
run: ./gradlew app:bundlePreviewRelease --stacktrace
env:
CONFIGURABLE_SIGNING_PROPERTIES_FILE: play-upload-signing.properties

- name: Build Mainnet APK for standalone release
run: ./gradlew app:assembleMainnetRelease --stacktrace
- name: Build Stable APK for standalone release
run: ./gradlew app:assembleStableRelease --stacktrace
env:
CONFIGURABLE_SIGNING_PROPERTIES_FILE: standalone-release-signing.properties

- name: Build Mainnet bundle for Google Play upload
run: ./gradlew app:bundleMainnetRelease --stacktrace
- name: Build Stable bundle for Google Play upload
run: ./gradlew app:bundleStableRelease --stacktrace
env:
CONFIGURABLE_SIGNING_PROPERTIES_FILE: play-upload-signing.properties

Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Support for sponsored Smart contract updates
- Support for sponsored delegation configuration transaction
- Support for switching networks in the Developer mode

### Fixed

Expand Down
27 changes: 13 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,8 @@ and organizations that require a reliable, efficient, and regulatory-compliant b
The Concordium wallet was formerly known as "CryptoX".

## Download
| Mainnet| Testnet|
|:------:|:------:|
|[Google Play](https://play.google.com/store/apps/details?id=com.pioneeringtechventures.wallet&hl=en) | [GitHub](https://github.com/Concordium/cryptox-android/releases/latest)|[Google Play](https://play.google.com/store/apps/details?id=com.pioneeringtechventures.wallet.testnet&hl=en) | [GitHub](https://github.com/Concordium/cryptox-android/releases/latest)|
[Google Play](https://play.google.com/store/apps/details?id=com.pioneeringtechventures.wallet&hl=en)
[GitHub](https://github.com/Concordium/cryptox-android/releases/latest)

*APKs attached to GitHub releases have signature different from the packages distributed through GooglePlay, therefore can't be installed over each other without manual uninstall.*

Expand All @@ -40,19 +39,19 @@ The Concordium wallet was formerly known as "CryptoX".
Concordium Wallet can establish WalletConnect sessions initiated by [Wallet Connectors from the JS SDK](https://github.com/Concordium/concordium-node-sdk-js/tree/main/packages/wallet-connectors).
If you can't use the JS SDK, you can implement WalletConnect flow manually using the JS SDK as a reference implementation.

On the device, the wallet responds to a general `wc:` or an explicit `cryptox-wc:` (or `cryptox-wc-testnet:` for Testnet) URI schemes.
On the device, the wallet responds to a general `wc:` or an explicit `cryptox-wc:` URI schemes.
Launching a `wc:` URI may require the user to select which app to use if they have multiple crypto wallets installed,
while a `cryptox-wc:` (or `cryptox-wc-testnet:` for Testnet) URI explicitly launches Concordium Wallet.
while a `cryptox-wc:` URI explicitly launches Concordium Wallet.

To launch Concordium Wallet for WalletConnect session establishment from your app, either use:
- An original `wc:` URI provided by WalletConnect or Concordium JS SDK
- An explicit `cryptox-wc://wc?uri=...` (or `cryptox-wc-testnet:` for Testnet) URI, where the `uri` query param is the URL-encoded original `wc:` URI
- An explicit `cryptox-wc://wc?uri=...` URI, where the `uri` query param is the URL-encoded original `wc:` URI

The same URI can be turned into a QR code and scanned with the QR scanner from the Concordium Wallet main screen.

To launch Concordium Wallet for WalletConnect session request handling (signing transaction, creating an ID proof) from your app, either use:
- An original `wc:` URI provided by Concordium JS SDK
- An explitit app redirect URI from the WalletConnect session metadata, adding `requestId` query parameter with the WalletConnect request ID (large number). For example, `cryptox-wc://r?requestId=1759846918165693`. Do not hardcode this URI, use the one from the session metadata.
- An explicit app redirect URI from the WalletConnect session metadata, adding `requestId` query parameter with the WalletConnect request ID (large number). For example, `cryptox-wc://r?requestId=1759846918165693`. Do not hardcode this URI, use the one from the session metadata.

To make Concordium Wallet go back to your app or the browser once the request handling is finished,
add the `go_back=true` query parameter to the URI you launch.
Expand All @@ -64,13 +63,12 @@ A good example of WalletConnect integration is the [Testnet WalletConnect test b
The app requires Java 17 JDK for development.

### Build variants
- Testnet (`tstnet`) – Public Concordium test network, fake funds and identities.
- Stagenet (`stagenet`) – Unstable Concordium test network, fake funds and identities.
- Mainnet (`mainnet`) – Public Concordium network, real funds and identities.
- Stable (`stable`) – A build that is tested and ready for Mainnet
- Preview (`preview`) – A build that may contain unstable features or features not yet live on Mainnet

### Distribution for internal testing
Builds for internal testing tagged as QA (`-qa.X`) are assembled and distributed through Firebase App distribution by the [corresponding pipeline](.github/workflows/firebase_internal_testing.yml).
Update the version in `main`, tag the commit with the version name and push the changes.
Update the version in `main` or the release branch, tag the commit with the version name and push the changes.

[Track the Internal testing pipeline](https://github.com/Concordium/cryptox-android/deployments/Internal%20testing)

Expand All @@ -79,9 +77,10 @@ APKs can be downloaded from the GitHub workflow artifacts or from the Firebase c
This project is tested with BrowserStack.

### Building for release
Builds for releases tagged with semver version (`X.Y.Z`) or release candidate (`-rc.X`)
are assembled by the [corresponding pipeline](.github/workflows/release_build.yml).
Update the version in `main`, tag the commit with the version name and push the changes.
Builds for releases are tagged with semver version (`X.Y.Z`) for stable release,
or with release candidate version (`X.Y.Z-rc.X`) for preview release.
They are assembled by the [corresponding pipeline](.github/workflows/release_build.yml).
Update the version in `main` or the release branch, tag the commit with the version name and push the changes.

[Track the Release pipeline](https://github.com/Concordium/cryptox-android/deployments/Releases)

Expand Down
85 changes: 26 additions & 59 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ plugins {
}

def SCHEME_BASE = "cryptoxmwallet"
def WC_SCHEME_BASE = "cryptox-wc"
def PROVIDER_AUTHORITY_BASE = "com.pioneeringtechventures.wallet.DataFileProvider"

def configurableSigningProperties = new Properties()
Expand Down Expand Up @@ -43,7 +42,6 @@ android {

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

buildConfigField("boolean", "SHOW_GTU_DROP", "false")
buildConfigField("Long", "ACCOUNT_UPDATE_FREQUENCY_SEC", "60l")
buildConfigField("Long", "FAST_ACCOUNT_UPDATE_FREQUENCY_SEC", "5l")

Expand Down Expand Up @@ -83,84 +81,53 @@ android {
buildFeatures {
viewBinding true
buildConfig true
flavorDimensions += "network"
flavorDimensions += "channel"
}

productFlavors {
// Unstable Concordium test network, fake funds and identities.
stagenet {
dimension "network"
applicationIdSuffix ".stagenet"
buildConfigField("String", "EXPORT_CHAIN", "\"staging\"")
buildConfigField("String", "ENV_NAME", "\"staging\"")
buildConfigField("String", "URL_PROXY_BASE", "\"https://wallet-proxy.stagenet.concordium.com\"")
buildConfigField("String", "URL_EXPLORER_BASE", "\"https://stagenet.ccdscan.io/\"")
buildConfigField("String", "URL_NOTIFICATIONS_BASE", "\"https://notification-api.stagenet.concordium.com/api/\"")
buildConfigField("String[]", "WC_CHAINS", "{\"ccd:stagenet\",\"ccd:853288fa5a45554d3cbbf8a756b85abc\"}")
buildConfigField("boolean", "SHOW_GTU_DROP", "true")

def scheme = SCHEME_BASE + "-stagenet"
// Stable channel – tested and ready for Mainnet.
stable {
dimension "channel"

// Default network for the stable build is Mainnet.
// Must not be changed for backward compatibility.
buildConfigField("String", "DEFAULT_NETWORK_GENESIS_HASH", "\"9dd9ca4d19e9393877d2c44b70f89acbfc0883c2243e5eeaecc0d1cd0503f478\"")

def scheme = SCHEME_BASE
buildConfigField("String", "SCHEME", "\"${scheme}\"")
resValue "string", "scheme", "\"${scheme}\""
resValue "string", "wc_scheme", "\"${WC_SCHEME_BASE + "-stagenet"}\""

def providerAuthority = PROVIDER_AUTHORITY_BASE + "-stagenet"
resValue "string", "PROVIDER_AUTHORITY", "\"${providerAuthority}\""
def providerAuthority = PROVIDER_AUTHORITY_BASE
resValue "string", "provider_authority", "\"${providerAuthority}\""
buildConfigField("String", "PROVIDER_AUTHORITY", "\"${providerAuthority}\"")

firebaseAppDistribution {
appId = '1:124880082147:android:44ec3892cba12e73c7e1d6'
appId = '1:124880082147:android:250469ea97158747c7e1d6'
groups = "concordium-team"
}
}

// Public Concordium test network, fake funds and identities.
// It is called 'tstnet' because flavour names can't start with 'test'
tstnet {
dimension "network"
applicationIdSuffix ".testnet"
buildConfigField("String", "EXPORT_CHAIN", "\"testnet\"")
buildConfigField("String", "ENV_NAME", "\"testnet\"")
buildConfigField("String", "URL_PROXY_BASE", "\"https://wallet-proxy.testnet.concordium.com\"")
buildConfigField("String", "URL_EXPLORER_BASE", "\"https://testnet.ccdscan.io/\"")
buildConfigField("String", "URL_NOTIFICATIONS_BASE", "\"https://notification-api.testnet.concordium.com/api/\"")
buildConfigField("String[]", "WC_CHAINS", "{\"ccd:testnet\",\"ccd:4221332d34e1694168c2a0c0b3fd0f27\"}")
buildConfigField("boolean", "SHOW_GTU_DROP", "true")
def scheme = SCHEME_BASE + "-testnet"
buildConfigField("String", "SCHEME", "\"${scheme}\"")
resValue "string", "scheme", "\"${scheme}\""
resValue "string", "wc_scheme", "\"${WC_SCHEME_BASE + "-testnet"}\""
def providerAuthority = PROVIDER_AUTHORITY_BASE + "-testnet"
resValue "string", "PROVIDER_AUTHORITY", "\"${providerAuthority}\""
buildConfigField("String", "PROVIDER_AUTHORITY", "\"${providerAuthority}\"")
// Preview channel – unstable features or features not yet live on Mainnet.
preview {
dimension "channel"

firebaseAppDistribution {
appId = '1:124880082147:android:40bb3b4880d6aa92c7e1d6'
groups = "concordium-team"
}
}
// Default network for the preview build is Testnet.
// Must not be changed for backward compatibility.
buildConfigField("String", "DEFAULT_NETWORK_GENESIS_HASH", "\"4221332d34e1694168c2a0c0b3fd0f273809612cb13d000d5c2e00e85f50f796\"")

// Public Concordium network, real funds and identities.
mainnet {
dimension "network"
buildConfigField("String", "EXPORT_CHAIN", "\"mainnet\"")
buildConfigField("String", "ENV_NAME", "\"production\"")
buildConfigField("String", "URL_PROXY_BASE", "\"https://wallet-proxy.mainnet.concordium.software\"")
buildConfigField("String", "URL_EXPLORER_BASE", "\"https://ccdscan.io/\"")
buildConfigField("String", "URL_NOTIFICATIONS_BASE", "\"https://notification-api.mainnet.concordium.software/api/\"")
buildConfigField("String[]", "WC_CHAINS", "{\"ccd:mainnet\",\"ccd:9dd9ca4d19e9393877d2c44b70f89acb\"}")
buildConfigField("boolean", "SHOW_GTU_DROP", "false")
// Keep "-testnet" for backward compatibility, used to be a Testnet wallet.
applicationIdSuffix ".testnet"

def scheme = SCHEME_BASE
def scheme = SCHEME_BASE + "-preview"
buildConfigField("String", "SCHEME", "\"${scheme}\"")
resValue "string", "scheme", "\"${scheme}\""
resValue "string", "wc_scheme", "\"${WC_SCHEME_BASE}\""

def providerAuthority = PROVIDER_AUTHORITY_BASE
resValue "string", "PROVIDER_AUTHORITY", "\"${providerAuthority}\""
def providerAuthority = PROVIDER_AUTHORITY_BASE + "-preview"
resValue "string", "provider_authority", "\"${providerAuthority}\""
buildConfigField("String", "PROVIDER_AUTHORITY", "\"${providerAuthority}\"")

firebaseAppDistribution {
appId = '1:124880082147:android:250469ea97158747c7e1d6'
appId = '1:124880082147:android:40bb3b4880d6aa92c7e1d6'
groups = "concordium-team"
}
}
Expand Down
Loading
Loading