Interstellar SDK for Android
The Android SDK is the Gradle module :shared (package gg.interstellar.wallet), a Kotlin library that bundles:
- the public
InterstellarSdkAPI (this document), - the Rust core compiled for Android (
.solibraries):substrate-clientbehind the uniffi-generated Kotlin bindings (JNA, thinRustWrapperadapter) + the garbled-circuit renderer (the only hand-written JNI seam — it must hold the AndroidSurfaceobject), - the
TxPinpadViewAndroid view for the VCA confirmation pad (dedicated page), - the currency math helpers (
CurrencyMath,WalletBalances).
It is published as a Maven artifact — gg.interstellar.wallet:shared on GitHub Packages
(private, repository-scoped): you consume the AAR, and the prebuilt native libraries come with
it, so no Rust, no NDK and no cargo are needed on your machine. See
Getting Started.
Requirements
| Requirement | Value |
|---|---|
| Language | Kotlin (Java 17 toolchain) |
| Android | minSdk 24, compileSdk 37 |
| Device key | Android Keystore — P-256 (secp256r1) ECDSA, alias interstellar_mobile_proxy_v1 |
| Backend | An Interstellar worker (L2, wss://), node (L1, ws://) and IPFS endpoint |
The SDK defaults are the local dev stack: wss://127.0.0.1:2090 (worker), ws://127.0.0.1:9944 (node), /ip4/127.0.0.1/tcp/5001 (IPFS) — the DEFAULT_WS_URL / DEFAULT_NODE_URL / DEFAULT_IPFS_ADDR constants. Connecting to a different environment is currently configured at build/integration time by Interstellar — contact us for the values to use. When developing against the local stack, each port needs adb reverse tcp:PORT tcp:PORT.
The one and only entry point
There is no public constructor. The only way to obtain an SDK instance is the async factory — this guarantees you can never hold a half-initialized SDK (registration, key checks and the first balance pull happen inside create):
val sdk = InterstellarSdk.create(
context = applicationContext,
fileSharer = myFileSharer, // required — used by recovery-token export
listener = object : SdkInitListener { // optional
override suspend fun onServerResetDetected() {
// Show a blocking warning UI ("server was reset, re-register?")
// and return ONLY once the user acknowledges.
awaitUserAcknowledgement()
}
},
)
| Parameter | Type | Notes |
|---|---|---|
context | Context | Application context is recommended. |
fileSharer | InterstellarFileSharer | Your implementation; the SDK calls shareData(...) when it produces a recovery token file (filename recovery-token.interstellar.enc, MIME application/octet-stream). |
listener | SdkInitListener? | Server-reset callback (see below). |
create must be called from a coroutine. On completion the SDK is ready to use: registered (or re-registered), with balances cached.
Server-reset semantics
The SDK stores the root account id locally and compares it with the server at init (and at every updateBalances/resume check):
- Fresh install → transparent registration.
- Server root changed / device no longer registered while a local account exists →
onServerResetDetected()is invoked; the SDK suspends inside it until you return, then re-registers automatically. - The same check is available on app resume via
sdk.checkServerReset(listener)— call it when your app comes back to the foreground.
All of this also surfaces toasts through the optional sdk.toastListener (SdkToastListener.onToast(message, duration) with TOAST_LENGTH_SHORT/TOAST_LENGTH_LONG) — implement it if you want the SDK's progress/error feedback (e.g. "Registering…", "Server reset detected") shown in your UI. Toasts are always fired on the main thread.
The auto re-registration described above is a convenience for the current stage (the local stack and the shared testnet, where the server is reset regularly while developing). The production version will do the opposite: if the servers no longer know the device's account, the SDK will plainly fail — your app must tell the user — instead of silently registering a new identity (which would quietly abandon the previous root account and everything on it).
So treat onServerResetDetected as a development-time hook: in production, do not
auto-accept it. Show a blocking error, and let the user retry or restore the account through
the recovery flows.
Resetting the device identity
// USER-initiated full reset: deletes the Keystore key, clears cached state,
// and re-registers as a brand-new account.
sdk.resetKeyPairAndRegister()
Next steps:
- Getting Started — fresh app in Android Studio → root account ID on screen.
- API Reference — every public API, documented.
- VCA Pinpad Integration — how to host
TxPinpadViewand interpretshowTxFailed.