Skip to content

Latest commit

 

History

History
558 lines (430 loc) · 15 KB

File metadata and controls

558 lines (430 loc) · 15 KB

Stellar SDK Demo - Desktop App (JVM)

Cross-platform desktop application demonstrating the Stellar SDK with Compose Multiplatform UI.

Overview

This is a JVM desktop app that runs on macOS, Windows, and Linux with 100% shared Compose UI:

  • Key Generation: Generate and manage Stellar keypairs
  • Account Management: Fund testnet accounts and fetch account details
  • Payments: Send XLM and custom assets
  • Trustlines: Establish trust to hold issued assets
  • Transaction Details: View transaction operations and events
  • Smart Contracts: Fetch and parse Soroban contract details
  • Contract Deployment: Upload and deploy WASM contracts to testnet
  • Contract Invocation: Invoke hello world, auth, and token contracts with full authorization

The app demonstrates the full power of Compose Multiplatform, sharing the exact same UI code as Android, iOS, and Web.

Architecture

┌──────────────────────────────────────────────┐
│         demo:shared (Kotlin)                 │
│  • All UI screens (Compose)                  │
│  • Business logic (Stellar SDK)              │
│  • Navigation (Voyager)                      │
│  • Material 3 theme                          │
└──────────────────────────────────────────────┘
                    ▼
┌──────────────────────────────────────────────┐
│     demo:desktopApp (~50 lines Kotlin)       │
│  • Main.kt entry point                       │
│  • Window setup and platform configuration   │
│  • Calls shared App() composable             │
└──────────────────────────────────────────────┘

Code Distribution

  • Shared code: ~99% (all UI and business logic)
  • Desktop-specific: ~1% (Window wrapper only)

Why Desktop App for macOS?

Recommended for macOS users who want Compose UI

Feature Desktop App (This) macOS Native App
UI Framework Compose Multiplatform SwiftUI
Code Sharing 100% shared with Android/iOS/Web Business logic only
Bundle Size ~35 MB (includes JVM) ~8 MB (native)
Development Fast (hot reload) Slower (recompile)
Cross-platform macOS/Windows/Linux macOS only
Best For ✅ Most users Native purists

Prerequisites

Development Tools

  • JDK: 11 or higher (17+ recommended)
    # Check Java version
    java -version
  • Gradle: 8.5+ (included via wrapper)

Operating System Support

  • macOS: 11.0 (Big Sur) or newer
  • Windows: 10 or newer
  • Linux: Recent distributions (Ubuntu 20.04+, Fedora 35+, etc.)

Building and Running

Quick Start

# From project root
cd /Users/chris/projects/Stellar/kmp/kmp-stellar-sdk

# Run the desktop app
./gradlew :demo:desktopApp:run

That's it! The app will launch with a native window.

Build Commands

# Run in development mode
./gradlew :demo:desktopApp:run

# Create distributable packages
./gradlew :demo:desktopApp:packageDmg        # macOS (.dmg)
./gradlew :demo:desktopApp:packageMsi        # Windows (.msi)
./gradlew :demo:desktopApp:packageDeb        # Linux (.deb)
./gradlew :demo:desktopApp:packageRpm        # Linux (.rpm)

# Create all distributables
./gradlew :demo:desktopApp:package

# Build JAR only (no installer)
./gradlew :demo:desktopApp:createDistributable

Development Mode

Hot reload is supported for code changes:

  1. Run: ./gradlew :demo:desktopApp:run
  2. Edit Kotlin code in demo/shared/
  3. Rebuild: The app will reflect changes (may need restart)

Project Structure

desktopApp/
├── src/
│   └── jvmMain/
│       └── kotlin/
│           └── com/soneso/demo/desktop/
│               └── Main.kt              # Entry point (15 lines)
└── build.gradle.kts                     # Desktop configuration

Main.kt (Complete File)

package com.soneso.demo.desktop

import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
import com.soneso.demo.App

fun main() = application {
    Window(
        onCloseRequest = ::exitApplication,
        title = "Stellar SDK Demo"
    ) {
        App()  // Shared Compose UI from demo:shared
    }
}

That's all the desktop-specific code!

build.gradle.kts

compose {
    desktop {
        application {
            mainClass = "com.soneso.demo.desktop.MainKt"

            nativeDistributions {
                targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
                packageName = "StellarDemo"
                packageVersion = "1.0.0"

                macOS {
                    iconFile.set(project.file("icon.icns"))
                }
                windows {
                    iconFile.set(project.file("icon.ico"))
                }
                linux {
                    iconFile.set(project.file("icon.png"))
                }
            }
        }
    }
}

Features

All 11 features from the shared module work identically on desktop:

1. Key Generation

  • Generate random Stellar keypairs
  • Display and copy keys to clipboard
  • Sign and verify data
  • Uses: KeyPair.random() from Stellar SDK

2. Fund Testnet Account

  • Request XLM from Friendbot
  • Real-time funding status
  • Error handling
  • Uses: FriendBot.fundTestnetAccount()

3. Fetch Account Details

  • Retrieve account information from Horizon
  • Display balances, sequence number, flags
  • Real-time data fetching
  • Uses: Server.accounts()

4. Trust Asset

  • Establish trustlines for issued assets
  • Build, sign, and submit transactions
  • Uses: ChangeTrustOperation

5. Send Payment

  • Transfer XLM or custom assets
  • Amount validation and signing
  • Uses: PaymentOperation

6. Fetch Transaction Details

  • Fetch and view transaction details from Horizon or Soroban RPC
  • Display operations, events, and smart contract data
  • Expandable operations and events with copy functionality
  • Human-readable SCVal formatting for contract data
  • Uses: HorizonServer.transactions(), SorobanServer.getTransaction()

7. Smart Contract Details

  • Parse WASM contracts
  • View contract metadata and specification
  • Uses: Soroban RPC integration

8. Deploy Smart Contract

  • Upload and deploy WASM contracts
  • One-step or two-step deployment
  • Platform-specific resource loading
  • Uses: ContractClient.deploy(), install(), deployFromWasmId()

9. Invoke Hello World Contract

  • Invoke deployed "Hello World" contract
  • Map-based argument conversion
  • Automatic type handling
  • Uses: ContractClient.invoke(), funcArgsToXdrSCValues(), funcResToNative()

10. Invoke Auth Contract

  • Dynamic authorization handling
  • Same-invoker vs different-invoker scenarios
  • Conditional signing with needsNonInvokerSigningBy()
  • Uses: ContractClient.buildInvoke(), signAuthEntries(), funcResToNative()

11. Invoke Token Contract

  • View: InvokeTokenContractScreen.kt
  • SEP-41 token contract interaction
  • Advanced multi-signature workflows with buildInvoke()
  • Function selection from contract spec
  • Automatic type conversion for token operations
  • Uses: ContractClient.buildInvoke(), token interface support

Technology Stack

Desktop Layer

  • Compose Desktop: Compose Multiplatform for JVM
  • Swing/AWT: Native windowing (under the hood)
  • Coroutines: Async operations support

Shared Layer (from demo:shared)

  • Compose Multiplatform: All UI
  • Material 3: Design system
  • Voyager: Navigation
  • Stellar SDK: All Stellar functionality

Platform Integration

  • Clipboard: Desktop clipboard via Clipboard.desktop.kt
  • Window Management: Native OS windows
  • Keyboard Shortcuts: Native shortcuts work

Distribution

macOS Package (.dmg)

./gradlew :demo:desktopApp:packageDmg

Output: demo/desktopApp/build/compose/binaries/main/dmg/StellarDemo-1.0.0.dmg

Installation:

  1. Download .dmg file
  2. Double-click to mount
  3. Drag app to Applications folder

Windows Installer (.msi)

./gradlew :demo:desktopApp:packageMsi

Output: demo/desktopApp/build/compose/binaries/main/msi/StellarDemo-1.0.0.msi

Installation:

  1. Download .msi file
  2. Double-click to run installer
  3. Follow installation wizard

Linux Package (.deb for Ubuntu/Debian)

./gradlew :demo:desktopApp:packageDeb

Output: demo/desktopApp/build/compose/binaries/main/deb/stellardemo_1.0.0-1_amd64.deb

Installation:

sudo dpkg -i stellardemo_1.0.0-1_amd64.deb
sudo apt-get install -f  # Fix dependencies if needed

Linux Package (.rpm for Fedora/RedHat)

./gradlew :demo:desktopApp:packageRpm

Installation:

sudo rpm -i stellardemo-1.0.0-1.x86_64.rpm

Configuration

Application Metadata

Edit build.gradle.kts to customize:

nativeDistributions {
    packageName = "StellarDemo"           # App name
    packageVersion = "1.0.0"              # Version
    description = "Stellar SDK Demo"      # Description
    copyright = "© 2025 Stellar"          # Copyright
    vendor = "Stellar Development Foundation"  # Vendor
}

Window Configuration

Customize window in Main.kt:

Window(
    onCloseRequest = ::exitApplication,
    title = "Stellar SDK Demo",
    state = rememberWindowState(
        width = 1200.dp,
        height = 800.dp,
        position = WindowPosition(Alignment.Center)
    )
) {
    App()
}

App Icons

Place icons in desktopApp/:

  • macOS: icon.icns (512x512 or multiple sizes)
  • Windows: icon.ico (256x256 or multiple sizes)
  • Linux: icon.png (512x512 PNG)

Keyboard Shortcuts

Global Shortcuts

  • ⌘Q (macOS) / Alt+F4 (Windows/Linux): Quit
  • ⌘W (macOS) / Ctrl+W (Windows/Linux): Close window
  • ⌘C: Copy (in text fields)
  • ⌘V: Paste

App-Specific

All shortcuts from the shared Compose UI work:

  • Text selection and editing
  • Navigation (Tab, Shift+Tab)
  • Form submission (Enter)

Performance

Bundle Sizes

  • macOS .dmg: ~35 MB (includes bundled JRE)
  • Windows .msi: ~40 MB
  • Linux .deb/.rpm: ~35 MB
  • Standalone JAR: ~25 MB (requires system JRE)

Build Times (M1 Mac)

  • First build: 1-2 minutes
  • Incremental build: 10-20 seconds
  • Package creation: 30-60 seconds

Runtime Performance

  • Startup time: 2-3 seconds (cold start)
  • Frame rate: 60 FPS
  • Memory usage: 100-200 MB
  • CPU usage: Low (idle), moderate (during rendering)

Troubleshooting

Build Issues

Gradle daemon issues:

./gradlew --stop
./gradlew :demo:desktopApp:run

Out of memory: Add to gradle.properties:

org.gradle.jvmargs=-Xmx4096m

Compose compiler version mismatch:

  • Ensure Kotlin version matches Compose version
  • Update both in root build.gradle.kts

Runtime Issues

Window doesn't open:

  • Check Java version: java -version (should be 11+)
  • Try with verbose output: ./gradlew :demo:desktopApp:run --info
  • Check if another instance is running

UI rendering issues:

  • Update graphics drivers
  • Try software rendering: Add VM option -Dsun.java2d.opengl=false
  • Update to latest JDK

High CPU usage:

  • Normal during animations and scrolling
  • If persistent, check for infinite recomposition in UI code

Network errors:

  • Check firewall settings
  • Verify internet connection
  • Check Horizon/Soroban URLs are accessible

Platform-Specific Issues

macOS: "App is damaged":

  • App not signed: xattr -cr /Applications/StellarDemo.app
  • Or: System Settings → Privacy & Security → Open Anyway

Windows: "Windows protected your PC":

  • Click "More info" → "Run anyway"
  • App not code-signed (expected for development)

Linux: Missing dependencies:

# Install common dependencies
sudo apt-get install libgl1-mesa-glx libxi6 libxrender1 libxtst6

Advanced Configuration

Custom JRE Bundling

To reduce download size, bundle a custom JRE:

nativeDistributions {
    modules("java.base", "java.desktop", "java.logging")
    // Add only required JRE modules
}

ProGuard/R8 Optimization

For smaller JARs (not recommended for desktop):

compose {
    desktop {
        application {
            buildTypes.release.proguard {
                configurationFiles.from("proguard-rules.pro")
            }
        }
    }
}

Multi-Window Support

Add multiple windows in Main.kt:

fun main() = application {
    Window(onCloseRequest = ::exitApplication, title = "Main") {
        App()
    }

    Window(onCloseRequest = {}, title = "Settings") {
        SettingsScreen()
    }
}

Development Tips

Hot Reload

While running:

  1. Edit code in demo/shared/src/commonMain/
  2. Rebuild: ./gradlew :demo:shared:jvmJar
  3. App will reflect changes (may need manual restart)

Debugging

Add breakpoints in IntelliJ IDEA:

  1. Run → Edit Configurations
  2. Add "Gradle" configuration
  3. Tasks: :demo:desktopApp:run
  4. Set breakpoints in code
  5. Debug (⌃D)

Logging

Add console logging:

println("Debug: $message")
// Or use a logging framework

View logs in terminal where you ran ./gradlew run.

Comparison with macOS Native App

Feature Desktop App (This) macOS Native App
UI Framework Compose Multiplatform SwiftUI
Code Sharing 100% shared UI Business logic only
Bundle Size ~35 MB (JVM) ~8 MB (native)
Startup Time 2-3 seconds <1 second
Development Speed Fast (hot reload) Slower
Cross-platform ✅ macOS/Windows/Linux ❌ macOS only
Native Feel Good (95%) Perfect (100%)
Memory Usage Higher (~150 MB) Lower (~60 MB)
Recommendation ✅ Most users Native purists only

Resources

Desktop Documentation

Stellar Resources

Project Documentation

Support

For issues:

  • Desktop-specific: Check this README and console output
  • UI issues: Check shared module (demo/shared)
  • SDK functionality: See main SDK documentation
  • Stellar protocol: Visit developers.stellar.org

License

Part of the Stellar KMP SDK project. See main repository for license details.