Quickstart
mero-kotlin (com.calimero.mero) is the native Kotlin SDK for a remote
Calimero node. This page takes you
from adding the dependency to your first authenticated contract call.
Requirements
Section titled “Requirements”- Kotlin 2.x, coroutines +
Flowthroughout. - Android minSdk 24, compileSdk 34.
- Dependencies (pulled in transitively): OkHttp (+
okhttp-sse), kotlinx.serialization, AndroidX Security, AndroidX Browser.
Install
Section titled “Install”Published to GitHub Packages on each v* tag. Add the repository (see
PUBLISHING.md
for the credentials snippet), then the dependency:
dependencies { implementation("com.calimero.mero:mero-core:0.1.0") implementation("com.calimero.mero:mero-compose:0.1.0") // optional Compose UI}dependencies { implementation 'com.calimero.mero:mero-core:0.1.0' implementation 'com.calimero.mero:mero-compose:0.1.0' // optional Compose UI}Coordinates are com.calimero.mero:{mero-core,mero-compose}:<version>.
Your first calls
Section titled “Your first calls”Every SDK call is a suspend function — call them from a coroutine (a
lifecycleScope/viewModelScope launch, or another suspend function).
-
Create the client. Point it at your node; persist tokens in encrypted storage and give the cross-process refresh lock a file.
import com.calimero.mero.Meroimport com.calimero.mero.MeroConfigimport com.calimero.mero.storage.EncryptedPrefsTokenStoreimport java.io.Fileval mero = Mero(MeroConfig(baseUrl = "https://your-node.example",tokenStore = EncryptedPrefsTokenStore(context), // in-memory otherwiserefreshLockFile = File(context.filesDir, "mero-refresh.lock"),)) -
Authenticate with a username and password.
bootstrapSecretis only needed for the very first login on a fresh node.import com.calimero.mero.Credentialsmero.authenticate(Credentials(username = "alice", password = "s3cr3t"))val authed = mero.isAuthenticated // true -
Call a contract over JSON-RPC. The result is decoded with kotlinx.serialization into your
@Serializabletype; arguments are aJsonObject.import kotlinx.serialization.Serializableimport kotlinx.serialization.json.buildJsonObjectimport kotlinx.serialization.json.put@Serializable data class Post(val id: String, val title: String)val post: Post = mero.rpc.execute(contextId = "…",method = "get_post",argsJson = buildJsonObject { put("id", "42") },) -
Use the admin & auth APIs for everything else.
val contexts = mero.admin.getContexts()val providers = mero.auth.getProviders() -
Log out — clears the token bundle from memory and the store (and, when a
clientIdis supplied, best-effort revokes it server-side).mero.logout()
Handle errors
Section titled “Handle errors”Failures are thrown as subclasses of MeroException. Catch the ones you care
about:
import com.calimero.mero.http.AuthRevokedExceptionimport com.calimero.mero.http.HttpExceptionimport com.calimero.mero.rpc.RpcException
try { val post: Post = mero.rpc.execute( contextId = "…", method = "get_post", argsJson = buildJsonObject { put("id", "42") }, )} catch (e: AuthRevokedException) { // refresh token reused/revoked — prompt re-login} catch (e: RpcException) { println("contract error ${e.code}: ${e.message}")} catch (e: HttpException) { println("HTTP ${e.status}")}See the error model for every type.
Next steps
Section titled “Next steps”- Authentication — direct login, SSO, and the token lifecycle.
- System overview — how the SDK is layered.
- Executing methods — the RPC client and
JsonObjectargs. - Compose frontend — drop-in
MeroClient+ composables.