https://github.com/youneedwork/wallet-core-kmp-example
https://github.com/youneedwork/wallet-core-kmp-example
Last synced: 10 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/youneedwork/wallet-core-kmp-example
- Owner: YouNeedWork
- Created: 2025-08-08T02:40:01.000Z (11 months ago)
- Default Branch: master
- Last Pushed: 2025-08-12T02:10:40.000Z (11 months ago)
- Last Synced: 2025-08-22T22:39:13.716Z (10 months ago)
- Language: Kotlin
- Size: 196 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
## Kotlin Multiplatform Wallet-Core + Compose Example
[中文版本 (Chinese)](./README_ZH.md)
This repository showcases how to integrate the following core capabilities in a Kotlin Multiplatform (Android & iOS) application using Compose Multiplatform:
1. Trust Wallet `wallet-core` (mnemonic generation, key & address derivation, message signing & verification)
2. Voyager for cross-platform screen navigation + ScreenModel (state/business logic)
3. In-app browser via `compose-webview-multiplatform`
4. Cross-platform networking with Ktor `HttpClient` (OkHttp on Android, Darwin engine on iOS)
5. Centralized dependency version management with `libs.versions.toml`
Primary shared module: `composeApp` (shared code in `composeApp/src/commonMain`).
---
## Tech Stack
| Capability | Description | Key Dependencies |
| -------------- | -------------------------------------------- | --------------------------------------------------- |
| UI | Compose Multiplatform (Material3, Resources) | `org.jetbrains.compose` |
| Navigation | Voyager Navigator + ScreenModel | `cafe.adriel.voyager:*` |
| In-app Browser | Compose WebView Multiplatform | `io.github.kevinnzou:compose-webview-multiplatform` |
| Wallet | Trust Wallet Core Kotlin bindings | `com.trustwallet:wallet-core-kotlin*` |
| Logging | Kermit | `co.touchlab:kermit` |
| Concurrency | Kotlinx Coroutines | `org.jetbrains.kotlinx:kotlinx-coroutines-*` |
| Networking | Ktor Client (core + OkHttp + Darwin) | `io.ktor:ktor-client-*` |
---
## Wallet-Core Integration
The project uses Trust Wallet Core Kotlin bindings for multi-chain wallet operations (mnemonic, keys, addresses, signing):
In `gradle/libs.versions.toml`:
```
wallet-core-kotlin = com.trustwallet:wallet-core-kotlin:{version}
wallet-core-kotlin-android = com.trustwallet:wallet-core-kotlin-android:{version}
wallet-core-kotlin-iosarm64 = ...
wallet-core-kotlin-iossimulatorarm64 = ...
wallet-core-kotlin-iosx64 = ...
```
In `composeApp/build.gradle.kts`:
```
commonMain.dependencies { implementation(libs.wallet.core.kotlin) }
androidMain.dependencies { implementation(libs.wallet.core.kotlin.android) }
iosMain.dependencies { implementation(libs.wallet.core.kotlin.iosarm64 /* etc */) }
```
Android entry point (`MainActivity.kt`) loads the native library:
```kotlin
System.loadLibrary("TrustWalletCore")
```
Usage sample (`HomeScreen.rt.kt`):
```kotlin
val wallet = HDWallet(256, "") // 256-bit entropy -> mnemonic (English default)
val mnemonic = wallet.mnemonic
val btcAddress = wallet.getAddressForCoin(CoinType.Bitcoin)
val ethAddress = wallet.getAddressForCoin(CoinType.Ethereum)
val key = wallet.getKeyForCoin(CoinType.Ethereum)
val sig = EthereumMessageSigner.signMessage(key, "123")
val verified = EthereumMessageSigner.verifyMessage(key.getPublicKey(CoinType.Ethereum), "123", sig)
```
Notes:
- Never use an empty passphrase in production.
- Avoid logging mnemonics / private keys (shown here only for demonstration).
- iOS does not need a manual `loadLibrary` (static framework bundle).
---
## Navigation & ScreenModel (Voyager)
Voyager provides a lightweight, multiplatform navigation and state model pattern.
Key concepts:
- `Screen` = a navigation unit with a `Content()` composable.
- `ScreenModel` = lifecycle-aware state holder (analogous to ViewModel).
Example:
```kotlin
class HomeScreen : Screen {
override val key: ScreenKey = uniqueScreenKey
@Composable override fun Content() {
val screenModel = rememberScreenModel { HomeScreenModel() }
val state by screenModel.state.collectAsState()
// Render based on state
}
}
```
Benefits:
1. Works naturally with Compose
2. Consistent navigation abstraction across platforms
3. Lifecycle scoping simplifies resource cleanup
Suggested enhancements:
- A centralized `NavigatorHost` to manage stack + deep links
- Define a sealed `Route` hierarchy to avoid stringly-typed routes
---
## In-App Browser (WebView)
Dependency: `compose-webview-multiplatform` (added to `commonMain`).
Example (pseudo):
```kotlin
@Composable
fun InAppBrowser(url: String) {
// WebView(state = rememberWebViewState(url)) { /* custom config */ }
}
```
Use cases:
- Campaign / marketing pages
- Third-party auth / payment callbacks
- Viewing block explorer links
Potential extensions:
- URL scheme interception for DApps / WalletConnect
- JS bridge for native <-> web interactions
---
## Ktor HttpClient (Multiplatform Networking)
Located in `Greeting.kt`:
```kotlin
private val client = HttpClient()
suspend fun greeting(): String = client.get("https://www.baidu.com/").bodyAsText()
```
Engines:
- Android -> OkHttp (`ktor-client-okhttp`)
- iOS -> Darwin (`ktor-client-darwin`)
Recommended configuration:
```kotlin
HttpClient {
expectSuccess = true
install(ContentNegotiation) { json() }
install(Logging) { level = LogLevel.INFO }
defaultRequest { header("User-Agent", "KMP-App") }
}
```
Error handling:
- Repository layer returning `Result` or custom sealed classes
- Platform-specific mapping for UI error messages
---
## Project Structure
```
composeApp/
src/
commonMain/ <-- shared business logic, UI (Compose), navigation, wallet, networking
androidMain/ <-- Android-specific (Activity, loadLibrary)
iosMain/ <-- iOS-specific (framework export)
gradle/libs.versions.toml <-- centralized dependency versions
```
---
## Build & Run
Android:
```
./gradlew :composeApp:assembleDebug
```
iOS:
```
./gradlew :composeApp:syncFramework
# Open the Xcode project under iosApp/ and run
```
Desktop (if a desktop target is later added):
```
./gradlew :composeApp:run
```
---
## Security Considerations (wallet-core)
1. Do not log mnemonics / private keys in production.
2. Use secure storage (Android Keystore / iOS Keychain) for sensitive data.
3. Verify user intent before signing arbitrary messages (phishing protection).
4. Track wallet-core release notes for breaking changes during upgrades.
5. Ensure thread safety if sharing an `HDWallet` instance; prefer derived public keys for read-only operations.
---
## Possible Next Steps
- Abstract a `WalletRepository` supporting multiple chains + caching (addresses, balances)
- Sealed `Route` + navigation extensions
- Dependency Injection (Koin / Kodein) for HttpClient & ScreenModels
- Network: timeouts, retry, offline cache policies
- Integrate WalletConnect / EIP-4361 (SIWE) auth flow
- JS bridge in WebView for account & signing interactions
---
## License
Educational example only. Add an appropriate LICENSE before distribution.
---
Feedback / contributions welcome. See the Chinese version here: [中文说明](./README_ZH.md)