Skip to main content

Interstellar SDK for Android

The Android SDK is the Gradle module :shared (package gg.interstellar.wallet), a Kotlin library that bundles:

  • the public InterstellarSdk API (this document),
  • the Rust core compiled for Android (.so libraries): substrate-client behind the uniffi-generated Kotlin bindings (JNA, thin RustWrapper adapter) + the garbled-circuit renderer (the only hand-written JNI seam — it must hold the Android Surface object),
  • the TxPinpadView Android 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​

RequirementValue
LanguageKotlin (Java 17 toolchain)
AndroidminSdk 24, compileSdk 37
Device keyAndroid Keystore — P-256 (secp256r1) ECDSA, alias interstellar_mobile_proxy_v1
BackendAn Interstellar worker (L2, wss://), node (L1, ws://) and IPFS endpoint
Endpoint defaults

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()
}
},
)
ParameterTypeNotes
contextContextApplication context is recommended.
fileSharerInterstellarFileSharerYour implementation; the SDK calls shareData(...) when it produces a recovery token file (filename recovery-token.interstellar.enc, MIME application/octet-stream).
listenerSdkInitListener?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.

For now — a convenience, not the final behaviour

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: