Skip to content

GoPlausible/liquid-auth-android

Repository files navigation

Liquid Auth Android

Android wallet app and client library for Liquid Auth — FIDO2/WebAuthn authentication with Algorand wallet binding and WebRTC peer-to-peer signaling.

Improved by GoPlausible, originated by the Algorand Foundation's Liquid Auth Android reference design. Redesigned with native OkHttp WebSocket transport (no Socket.io), discoverable credential support, and a streamlined authentication flow optimized for synced passkeys across devices.

Related Projects

Project Package / App Description
Liquid Auth Cloud @goplausible/liquid-auth-cloud Cloudflare Workers auth server — edge-deployed, serverless, zero idle cost
Liquid Auth Client (TypeScript) @goplausible/liquid-client Browser client — native WebSocket, FIDO2 + WebRTC signaling
Rocca Wallet React Native / Expo app Cross-platform wallet — FIDO2 passkeys + WebRTC
WebRTC Payment SDK @goplausible/webrtc-payment-sdk Used in — micropayment-gated WebRTC streams on Algorand

What Makes This Different

  • No Socket.io — uses OkHttp's native WebSocket client, eliminating the io.socket:socket.io-client dependency and engine.io overhead
  • Cloud-native protocol{ event, data } JSON envelope matching the Cloudflare Durable Object (WalletRoom) protocol exactly
  • Discoverable assertions — tries sign-in with existing passkeys first (handles synced passkeys from desktop gracefully), falls back to registration only when needed
  • Room routing via URL — connects to /ws?requestId=xxx so both peers land in the same Durable Object instance

Architecture

liquid/                           # Library (AAR)
  connect/
    SignalClient.kt               # WebRTC signaling over native WebSocket
    SignalInterface.kt            # Interfaces + LinkMessage
    PeerApi.kt                    # WebRTC peer connection wrapper
    AuthMessage.kt                # QR code / deep link parsing
  fido2/
    AttestationApi.kt             # FIDO2 registration HTTP API
    AssertionApi.kt               # FIDO2 authentication HTTP API (+ discoverable)
  crypto/
    Base64Ext.kt                  # Encoding utilities

demo/                             # Demo wallet app (APK)
  AnswerActivity.kt               # Main activity — scan QR, authenticate, peer
  OfferActivity.kt                # Offer side for testing

Quick Start

Download the APK

The demo APK is available from the deployed Liquid Auth Cloud instance:

https://liquidauth.goplausible.xyz/download/liquid-auth.apk

Or build it locally (see below).

Build from Monorepo

Requires Android Studio (provides bundled JDK + Android SDK).

# From the webrtc-micropayment-sdk root:

npm run build:android           # Build library (release AAR)
npm run build:android:debug     # Build library (debug AAR)
npm run build:android:demo      # Build demo APK (debug)
npm run clean:android           # Clean build artifacts
npm run lint:android            # Lint the library
npm run test:android            # Run unit tests
npm run upload:apk              # Upload demo APK to R2

Build from Android Studio

Open vendor/liquid-auth-android in Android Studio and run the demo target on a physical device (recommended — FIDO2 requires a secure lock screen).

Authentication Flow

1. App scans QR code (liquid://host/?requestId=xxx)
   or receives deep link from mobile browser

2. Check for saved local credential
   ├── Found → assertion with known credId
   └── Not found → try discoverable assertion (synced passkeys)
       ├── Success → signed in
       └── No passkeys → register new credential (attestation)

3. FIDO2 attestation includes Liquid extension:
   { type: "algorand", address, signature, requestId, device }

4. Server broadcasts auth event to requestId room

5. WebRTC signaling begins over WebSocket
   → offer/answer/candidates exchanged
   → DataChannel opens for encrypted P2P messaging

Integration

Using the Library

Add to your build.gradle.kts:

dependencies {
    implementation("com.github.GoPlausible:liquid-auth-android:main-SNAPSHOT")
}

SignalClient

val httpClient = OkHttpClient.Builder().cookieJar(cookies).build()
val signalClient = SignalClient(url, context, httpClient)

// Generate a QR code
val bitmap = signalClient.qrCode(requestId, logo)

// Peer connection (answer side)
val dataChannel = signalClient.peer(requestId, "answer", iceServers)

// Handle messages
signalClient.handleDataChannel(dataChannel, onMessage = { msg ->
    Log.d("Message", msg)
})

Configuration

The demo app requires these build config fields (set in demo/build.gradle.kts):

Field Description
NODELY_TURN_USERNAME Nodely TURN server username
NODELY_TURN_CREDENTIAL Nodely TURN server credential
TURN_USERNAME Metered TURN server username
TURN_CREDENTIAL Metered TURN server credential

The app's signing key must be registered in the server's /.well-known/assetlinks.json for FIDO2 to work.

License

MIT

About

Liquid Auth Android client — native WebSocket, Algorand FIDO2 wallet

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors