Skip to content

Chen/fix errorhandling#38

Open
chenchan09 wants to merge 14 commits intomainfrom
chen/fix-errorhandling
Open

Chen/fix errorhandling#38
chenchan09 wants to merge 14 commits intomainfrom
chen/fix-errorhandling

Conversation

@chenchan09
Copy link
Contributor

No description provided.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates Vault/SDK error handling and signer flows (including a new “stale keyset” vault error), refactors the sample app UI to demonstrate the new flows, and upgrades build tooling (Gradle/AGP/Kotlin) while removing large generated/obsolete documentation artifacts.

Changes:

  • Add detection/recovery signaling for stale Tink/EncryptedFile keyset mismatches (VAULT-0305) and refactor vault storage/biometric availability checks.
  • Refactor Gas Station signing APIs to support per-call signers and update sample activities/layouts to demonstrate Vault vs custom signer usage and real error scenarios.
  • Upgrade Gradle/AGP/Kotlin and clean up app module dependencies (remove Compose, switch to Material Components), plus delete previously committed verification docs.

Reviewed changes

Copilot reviewed 43 out of 47 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
vault/src/main/java/com/altude/vault/storage/VaultStorage.kt Adds stale keyset detection/purge and refactors keystore initialization + storage error handling.
vault/src/main/java/com/altude/vault/model/VaultStorageCorruptedException.kt Introduces a dedicated exception/error code for stale keyset scenarios.
vault/src/main/java/com/altude/vault/model/VaultSigner.kt Allows optional initial public key injection for caching/UX improvements.
vault/src/main/java/com/altude/vault/model/VaultException.kt Adds VAULT-0305 error code constant.
vault/src/main/java/com/altude/vault/crypto/BiometricHandler.kt Adjusts biometric/credential availability strategy and legacy Android behavior handling.
gradle/wrapper/gradle-wrapper.properties Updates Gradle wrapper version.
gradle/libs.versions.toml Updates AGP and Kotlin versions.
gradle/gradle-daemon-jvm.properties Changes daemon toolchain version settings.
gradle.properties Adds multiple Android/AGP flags for new build behavior.
gasstation/src/main/java/com/altude/gasstation/data/SwapOption.kt Adds defaults to option fields (API convenience).
gasstation/src/main/java/com/altude/gasstation/data/GetHistoryOption.kt Adds defaults to option fields (API convenience).
gasstation/src/main/java/com/altude/gasstation/GaslessManager.kt Refactors signing to use resolved signers, adds per-call signer support, and changes error wrapping.
gasstation/src/main/java/com/altude/gasstation/AltudeGasStation.kt Initializes storage earlier, unlocks vault during init, and passes initial public key into VaultSigner.
gasstation/src/main/java/com/altude/gasstation/Altude.kt Adds setApiKey(FragmentActivity, …) overload and per-call signer parameters for operations.
core/src/main/java/com/altude/core/service/StorageService.kt Refactors keystore reset logic and changes decryption failure behavior to return null instead of throwing.
app/src/main/res/values/themes.xml Switches app theme parent to Material Components (non-Compose UI).
app/src/main/res/layout/activity_vault_example.xml Adds wallet address display/copy UI and reveal button.
app/src/main/res/layout/activity_signer_examples.xml New layout for Vault vs custom signer example screen.
app/src/main/res/layout/activity_main.xml New launcher screen layout for selecting examples.
app/src/main/res/layout/activity_error_handling_example.xml Refactors error handling demo UI and adds clear-vault button.
app/src/main/java/com/altude/android/VaultExampleActivity.kt Refactors to use Altude.setApiKey(activity, …) and Result-based error handling; adds wallet reveal/copy.
app/src/main/java/com/altude/android/SignerExamplesActivity.kt New activity demonstrating Vault vs custom signer usage (global and per-call).
app/src/main/java/com/altude/android/MainActivity.kt Replaces Compose launcher with a simple view-based example selector.
app/src/main/java/com/altude/android/ErrorHandlingExampleActivity.kt Refactors to trigger real SDK calls for error scenarios and adds reset/clear flows.
app/src/main/AndroidManifest.xml Updates launcher to MainActivity and registers new example activities.
app/build.gradle.kts Removes Compose, uses Material Components, adjusts packaging options.
app/src/main/java/com/altude/android/ui/theme/Type.kt Removes Compose theme typography (unused after Compose removal).
app/src/main/java/com/altude/android/ui/theme/Theme.kt Removes Compose theme wrapper (unused after Compose removal).
app/src/main/java/com/altude/android/ui/theme/Color.kt Removes Compose color definitions (unused after Compose removal).
VERIFICATION_COMPLETE.md Removes previously committed verification artifact.
READY_TO_BUILD.md Removes previously committed build-readiness artifact.
QUICK_FIX_REFERENCE.md Removes previously committed quick-fix artifact.
QUICK_FIX_CHECKLIST.md Removes previously committed checklist artifact.
PHASE_6_COMPLETION_SUMMARY.md Removes previously committed phase summary artifact.
INDEX.md Removes previously committed documentation index artifact.
IMPLEMENTATION_GUIDE.md Removes previously committed implementation guide artifact.
GRADLE_FIX_FINAL.md Removes previously committed gradle fix artifact.
GET_STARTED.md Removes previously committed getting-started artifact.
FIX_SUMMARY.md Removes previously committed fix summary artifact.
FIXES_APPLIED_SUMMARY.md Removes previously committed fix summary artifact.
DETAILED_CHANGES.md Removes previously committed detailed changes artifact.
16KB_PAGE_SIZE_FIX_SUMMARY.md Removes previously committed 16KB summary artifact.
16KB_ALIGNMENT_FIX_FINAL.md Removes previously committed 16KB final artifact.
.idea/misc.xml Changes IDE project JDK/language level settings.
.idea/deploymentTargetSelector.xml Adds IDE deployment target state (includes device identifier).
.idea/compiler.xml Changes IDE bytecode target settings.
Files not reviewed (3)
  • .idea/compiler.xml: Language not supported
  • .idea/deploymentTargetSelector.xml: Language not supported
  • .idea/misc.xml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +143 to +145
fun clearVault(context: Context, appId: String): Boolean {
val vaultFile = File(context.filesDir, "$VAULT_FILE_PREFIX${appId}$VAULT_FILE_SUFFIX")
return vaultFile.delete()
purgeVault(context, appId)
return true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply changes based on this feedback

Comment on lines +133 to +160
val isNewVault = !VaultManager.vaultExists(context, appId)

if (isNewVault) {
try {
ensureVaultCreated()
} catch (e: VaultStorageCorruptedException) {
VaultManager.clearVault(context, appId)
ensureVaultCreated()
}
}

// Unlock vault immediately — this prompts biometric ONCE at init time,
// derives the keypair, caches the session, and gives us the public key.
// This is the expected UX: user authenticates when tapping Initialize,
// not silently on the first transaction.
val keypair = VaultManager.unlockVault(
context = context,
appId = appId,
walletIndex = vaultOptions.walletIndex,
sessionTTLSeconds = vaultOptions.sessionTTLSeconds,
authMessages = com.altude.vault.model.VaultSigner.AuthMessages(
title = if (isNewVault) "Set Up Vault" else "Unlock Vault",
description = if (isNewVault)
"Authenticate to secure your new wallet"
else
"Authenticate to unlock your wallet"
)
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chenchan09 should we do this fix?

Comment on lines +59 to +62
val signerToUse = resolveSigner(option.account, signer)
ensureBiometricAuth(signerToUse, "transfer")
// After biometric unlock the public key is always available - use it as account
val ownerKey = signerToUse.publicKey
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply changes based on this feedback

Comment on lines +528 to +537
private fun resolveSigner(account: String = "", overrideSigner: TransactionSigner? = null): TransactionSigner {
val signer = overrideSigner ?: SdkConfig.currentSigner
requireNotNull(signer) {
"Vault signer required. Call AltudeGasStation.init() before using SDK methods."
}
// If account is blank, use the signer's public key (resolved after biometric unlock)
if (account.isNotBlank() && signer.publicKey.toBase58() != account) {
throw IllegalArgumentException("Signer public key ${signer.publicKey.toBase58()} does not match requested account $account")
}
return signer
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply changes based on this feedback

Comment on lines +82 to +89
@Suppress("UNUSED_PARAMETER")
fun initializeKeystore(context: Context, appId: String, requireBiometric: Boolean = true) {
try {
val masterKey = MasterKey.Builder(context, MASTER_KEY_ALIAS)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build()
buildMasterKey(context)
} catch (e: Exception) {
if (isKeyPermanentlyInvalidated(e)) throw BiometricInvalidatedException(cause = e)
throw VaultInitFailedException("Failed to initialize keystore: ${e.message}", cause = e)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply changes based on this feedback

Comment on lines +37 to +48
private fun isKeyPermanentlyInvalidated(e: Exception): Boolean =
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
e.javaClass.name == "android.security.keystore.KeyPermanentlyInvalidatedException"

@SerialName("version")
val version: Int = 1 // For future format changes
)
private fun isStaleKeyset(e: Exception): Boolean {
if (e is AEADBadTagException) return true
var cause: Throwable? = e
while (cause != null) {
if (cause is AEADBadTagException) return true
cause = cause.cause
}
return false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply changes based on this feedback

mocolicious and others added 2 commits March 14, 2026 01:35
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copy link
Contributor

Copilot AI commented Mar 14, 2026

@mocolicious I've opened a new pull request, #39, to work on those changes. Once the pull request is ready, I'll request review from you.

Co-authored-by: mocolicious <6373607+mocolicious@users.noreply.github.com>
Copy link
Contributor

Copilot AI commented Mar 14, 2026

@mocolicious I've opened a new pull request, #40, to work on those changes. Once the pull request is ready, I'll request review from you.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copy link
Contributor

Copilot AI commented Mar 14, 2026

@mocolicious I've opened a new pull request, #41, to work on those changes. Once the pull request is ready, I'll request review from you.

mocolicious and others added 2 commits March 14, 2026 01:39
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copy link
Contributor

Copilot AI commented Mar 14, 2026

@mocolicious I've opened a new pull request, #42, to work on those changes. Once the pull request is ready, I'll request review from you.

Copy link
Contributor

Copilot AI commented Mar 14, 2026

@mocolicious I've opened a new pull request, #43, to work on those changes. Once the pull request is ready, I'll request review from you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants