Skip to content

Build Stellar Wallet Connect UI — Secret Key Signing Flow and LOBSTR Deep Link Support #223

@portableDD

Description

@portableDD

Labels

Frontend

Description

ByteChain Academy is built for the Stellar ecosystem and wallet identity is a core part of the Web3 experience. The backend wallet linking API (Issue 20) implements the challenge-response flow, but there is no frontend UI to connect, disconnect, or display a user's linked Stellar wallet. This issue builds the complete wallet connect UI — a connect button in the settings page, the signature flow using the Stellar SDK in the browser, and wallet address display across the platform.

Background & Context

  • frontend/app/settings/page.tsx (Issue 23) has a section for wallet linking but no implementation
  • Backend endpoints (Issue 20): POST /api/v1/users/me/wallet/challenge, POST /api/v1/users/me/wallet/verify, DELETE /api/v1/users/me/wallet, GET /api/v1/users/me/wallet
  • The Stellar wallet connect flow: (1) call challenge endpoint to get a challenge string, (2) sign the challenge with the user's Stellar secret key using @stellar/stellar-sdk in the browser, (3) submit the signature to the verify endpoint
  • Two connection methods should be supported: manual secret key entry (for development and power users) and a "Connect with LOBSTR" deep link (LOBSTR is Stellar's most popular mobile wallet)
  • Wallet addresses (Stellar public keys starting with "G") should be displayed in truncated format: GABCD...WXYZ

Requirements

  • Create frontend/components/wallet/wallet-connect-card.tsx — a card component used in the settings page showing:
    • If no wallet linked: "Connect Stellar Wallet" button that opens the connect modal
    • If wallet linked: truncated wallet address with a copy button, a "Disconnect" button, and a Stellar explorer link
  • Create frontend/components/wallet/wallet-connect-modal.tsx — modal with two tabs:
    • Secret Key tab: text input for Stellar secret key (starts with "S"), a warning that secret keys should never be shared, a "Sign & Connect" button that (1) calls the challenge endpoint, (2) signs locally using Keypair.fromSecret(key).sign(Buffer.from(challenge)), (3) calls verify endpoint with the base64 signature
    • LOBSTR tab: instructions for mobile users with a deep link button lobstr://sign?... and a QR code showing the challenge for the LOBSTR app to scan and sign
  • Install @stellar/stellar-sdk in the frontend
  • Add wallet address display to the profile page header (truncated, with copy button)
  • Handle errors: invalid secret key format, signature verification failure, wallet already claimed by another account

Suggested Execution

Branch: git checkout -b feat/stellar-wallet-connect-ui

Files to create:

  • frontend/components/wallet/wallet-connect-card.tsx
  • frontend/components/wallet/wallet-connect-modal.tsx
  • frontend/components/wallet/wallet-address-display.tsx
  • frontend/hooks/use-wallet.ts

Files to update:

  • frontend/app/settings/page.tsx
  • frontend/app/profile/page.tsx

Implement:

  • npm install @stellar/stellar-sdk
  • useWallet hook — useQuery for GET /api/v1/users/me/wallet, useMutation for verify and disconnect
  • WalletConnectCard — connected vs disconnected states
  • WalletConnectModal — two-tab UI, secret key signing flow with Keypair.fromSecret() and keypair.sign()
  • IMPORTANT: clear the secret key from component state immediately after signing — never persist it
  • WalletAddressDisplay — truncates GABCD...WXYZ format, copy-to-clipboard button with toast
  • Error handling: StrKey.isValidEd25519SecretSeed() for input validation before attempting to sign

Test & Validate:

  • Connect flow: enter a valid Stellar testnet secret key → wallet linked and displayed in settings
  • Disconnect: wallet address removed from user account
  • Invalid secret key format shows validation error before calling any API
  • Copying wallet address shows a toast confirmation
  • Profile page shows linked wallet address in truncated format
  • Attempting to link a wallet already claimed by another account shows descriptive error

Acceptance Criteria

  • WalletConnectCard shows correct connected/disconnected state based on backend data
  • Secret key tab: signing flow calls challenge → sign → verify in sequence
  • LOBSTR tab: deep link and QR code displayed with instructions
  • Secret key is cleared from state immediately after use
  • Invalid secret key format is validated before any API call
  • Linked wallet address displayed in truncated format on settings and profile pages
  • Copy button copies full wallet address to clipboard
  • Disconnect removes wallet address from the account

Example Commit Message

feat: build Stellar wallet connect UI with secret key signing and LOBSTR deep link support

Guidelines

  • Assignment required before starting
  • PR description must include Closes #[issue_id]
  • Join our Telegram: https://t.me/ByteChainAcademy
  • Complexity: High (200 pts)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions