element-x-ada/docs/build-logs/phase3b-build-result.md

3.6 KiB

Phase 3b: Element X ADA - Deferred Features Completion

Date: 2026-03-28
Branch: phase1-dev
Commit: 455f45ed59
Build Status: assembleGplayDebug passes

Summary

Completed the two deferred features from Phase 3:

Task 1: /pay No-Wallet Guard

When a user types /pay but hasn't set up a wallet, they now see a friendly "Wallet Required" prompt instead of hitting an error.

Implementation:

  1. PaymentEntryState - Added new fields:

    • noWalletSetup: Boolean - True when user has no wallet configured
    • isCheckingWallet: Boolean - True during initial wallet state check
    • companion object Loading - Default loading state
  2. PaymentEntryPresenter - Now checks wallet state first:

    • Collects walletManager.walletState via collectAsState()
    • Returns loading state while isLoading or !walletInitialized
    • Returns no-wallet state early if !hasWallet
    • Only proceeds with payment form when wallet exists
  3. PaymentEntryView - Shows appropriate UI based on state:

    • Loading spinner while checking wallet
    • Full-screen "Wallet Required" prompt with "Open Wallet Settings" CTA when no wallet
    • Normal payment form when wallet exists
  4. Navigation Chain - New callback wired through:

    • PaymentEntryNode.Callback.onOpenWalletSettings()
    • PaymentFlowNode → calls callback.onOpenWalletSettings()
    • WalletEntryPoint.Callback.onOpenWalletSettings()
    • MessagesFlowNode → pops payment flow and pushes WalletPanel

Task 2: Payment Timeline Card

Discovery: The payment timeline card was already fully implemented:

  • TimelineItemPaymentContent in wallet:api
  • TimelineItemPaymentContentWrapper in messages:impl
  • TimelineItemContentPaymentFactory to parse payment events
  • TimelineItemPaymentView with status chips, explorer links, testnet badge
  • Wired into TimelineItemEventContentView

Bug Fix: The event type check was wrong:

  • Was: com.sulkta.cardano.payment
  • Fixed to: co.sulkta.payment.request (matches EVENT_TYPE constant)
  • Also added: co.sulkta.payment.status for status update events

Files Changed

File Changes
PaymentEntryState.kt Added noWalletSetup, isCheckingWallet, Loading companion
PaymentEntryPresenter.kt Early wallet check with collectAsState()
PaymentEntryView.kt Loading state, no-wallet prompt, refactored to split content
PaymentEntryNode.kt Added onOpenWalletSettings() to Callback interface
PaymentFlowNode.kt Forwards onOpenWalletSettings() to entry point callback
WalletEntryPoint.kt Added onOpenWalletSettings() to Callback interface
MessagesFlowNode.kt Implements callback to navigate to WalletPanel
TimelineItemContentPaymentFactory.kt Fixed event type check

User Experience

Before

  • User types /pay without wallet → confusing error or crash

After

  • User types /pay without wallet → sees:
    ₳
    
    Wallet Required
    
    You need to set up a Cardano wallet
    before you can send payments.
    
    [Open Wallet Settings]
    [Cancel]
    
  • Tapping "Open Wallet Settings" → navigates to WalletPanel

Verification

docker run --rm -v /tmp/element-x-android:/project \
  -v /tmp/gradle-cache:/root/.gradle -w /project \
  mingc/android-build-box:latest \
  ./gradlew :app:assembleGplayDebug --no-daemon -x test
# BUILD SUCCESSFUL in 2m 8s

Notes

  • Used Metro DI (collectAsState() for reactive wallet state)
  • Maintained presenter pattern - view is dumb, just renders state
  • No new dependencies added
  • Warnings exist but are pre-existing (deprecated APIs, injection hints)