Skip to content

Quickstart

MeroKit (import MeroKit) is the native Swift SDK for a remote Calimero node. This page takes you from adding the package to your first authenticated contract call.

  • Swift 5.9+ (built and tested on Swift 6)
  • iOS 15+ / macOS 12+
  • Zero third-party dependencies — built on URLSession, Foundation, and Security.
Package.swift
dependencies: [
.package(url: "https://github.com/calimero-network/swift-sdk.git", from: "0.1.0"),
],
targets: [
.target(name: "MyApp", dependencies: [
.product(name: "MeroKit", package: "swift-sdk"),
// Optional SwiftUI frontend:
.product(name: "MeroKitUI", package: "swift-sdk"),
]),
]
  1. Create the client. Point it at your node; persist tokens in the Keychain.

    import MeroKit
    let mero = Mero(config: MeroConfig(
    baseURL: URL(string: "https://your-node.example")!,
    tokenStore: KeychainTokenStore() // defaults to in-memory otherwise
    ))
  2. Authenticate with a username and password. bootstrapSecret is only needed for the very first login on a fresh node.

    let tokens = try await mero.authenticate(
    Credentials(username: "alice", password: "s3cr3t")
    )
    let authed = await mero.isAuthenticated // true
  3. Call a contract over JSON-RPC. The result is decoded into your Decodable type; arguments are a [String: JSONValue] dictionary literal.

    struct Post: Decodable { let id: String; let title: String }
    let post: Post = try await mero.rpc.execute(
    contextId: "…",
    method: "get_post",
    argsJson: ["id": "42"]
    )
  4. Use the admin & auth APIs for everything else.

    let contexts = try await mero.admin.getContexts()
    let providers = try await mero.auth.getProviders()
  5. Log out — clears the token bundle from memory and the store.

    await mero.logout()

Failures surface as a single MeroError enum (plus the contract’s own RPC errors). Match the cases you care about:

do {
let post: Post = try await mero.rpc.execute(
contextId: "…", method: "get_post", argsJson: ["id": "42"]
)
} catch let error as MeroError {
switch error {
case .authRevoked:
// refresh token reused/revoked — prompt re-login
case .http(let http):
print("HTTP \(http.status)")
case .rpc(let rpc):
print("contract error \(rpc.code): \(rpc.message)")
default:
print(error)
}
}

See the error model for every case.