The Kotlin SDK is currently under active development. Expect minor API evolution while the SDK hardens.
Install
The package is published as com.worldcoin:idkit to GitHub Packages.
dependencyResolutionManagement {
repositories {
mavenCentral()
maven {
url = uri("https://maven.pkg.github.com/worldcoin/idkit")
credentials {
username = System.getenv("GITHUB_ACTOR")
password = System.getenv("GITHUB_TOKEN") // requires read:packages
}
}
}
}
dependencies {
implementation("com.worldcoin:idkit:<version>")
}
Request flow
import com.worldcoin.idkit.CredentialRequest
import com.worldcoin.idkit.CredentialType
import com.worldcoin.idkit.IdKit
import com.worldcoin.idkit.anyOf
import com.worldcoin.idkit.allOf
import uniffi.idkit_core.Environment
import uniffi.idkit_core.StatusWrapper
val rpContext = IdKit.rpContext(
rpId = "rp_xxxxx",
nonce = backend.nonce,
createdAt = backend.createdAt.toULong(),
expiresAt = backend.expiresAt.toULong(),
signature = backend.sig,
)
val config = IdKit.requestConfig(
appId = "app_xxxxx",
action = "my-action",
rpContext = rpContext,
allowLegacyProofs = false,
environment = Environment.PRODUCTION,
)
val orb = CredentialRequest(CredentialType.ORB, signal = "user-123")
val face = CredentialRequest(CredentialType.FACE, signal = "user-123")
val request = IdKit.request(config).constraints(allOf(anyOf(orb, face)))
val connectUrl = request.connectUrl()
val status = request.pollStatus(pollIntervalMs = 2000u, timeoutMs = 120000u)
if (status is StatusWrapper.Confirmed) {
val result = status.result
}
Presets
import com.worldcoin.idkit.IdKit
import com.worldcoin.idkit.orbLegacy
val request = IdKit.request(config).preset(orbLegacy(signal = "user-123"))
Use presets only for migration from older IDKit versions. They are intended
to preserve compatibility with both World ID 4.0 and World ID 3.0 (legacy).
Session flow
Session configuration lives in uniffi.idkit_core.IdKitSessionConfig.
import com.worldcoin.idkit.CredentialRequest
import com.worldcoin.idkit.CredentialType
import com.worldcoin.idkit.anyOf
import uniffi.idkit_core.Environment
import uniffi.idkit_core.IdKitSessionConfig
import uniffi.idkit_core.Preset
import uniffi.idkit_core.StatusWrapper
import uniffi.idkit_core.createSession
import uniffi.idkit_core.proveSession
val sessionConfig = IdKitSessionConfig(
appId = "app_xxxxx",
rpContext = rpContext,
actionDescription = "Sign in",
bridgeUrl = null,
overrideConnectBaseUrl = null,
environment = Environment.PRODUCTION,
)
val createBuilder = createSession(sessionConfig)
val createRequest = createBuilder.constraints(anyOf(CredentialRequest(CredentialType.ORB)))
val createStatus = createRequest.pollStatus(pollIntervalMs = 2000u, timeoutMs = 120000u)
if (createStatus is StatusWrapper.Confirmed) {
val sessionId = createStatus.result.sessionId
val proveBuilder = proveSession(sessionId, sessionConfig)
val proveRequest = proveBuilder.preset(Preset.OrbLegacy(signal = null))
val proveStatus = proveRequest.pollStatus(pollIntervalMs = 2000u, timeoutMs = 120000u)
}
Session flows are always v4. allowLegacyProofs is not used for session requests.
Polling patterns
pollStatusOnce() for manual loops
pollStatus(pollIntervalMs, timeoutMs) for compatibility with existing call sites
statusFlow() extension (from KotlinCompat.kt) for coroutine-driven updates
import com.worldcoin.idkit.statusFlow
import kotlinx.coroutines.flow.collectLatest
import kotlin.time.Duration.Companion.seconds
import uniffi.idkit_core.StatusWrapper
request.statusFlow(2.seconds).collectLatest { status ->
when (status) {
StatusWrapper.WaitingForConnection -> Unit
StatusWrapper.AwaitingConfirmation -> Unit
is StatusWrapper.Confirmed -> println(status.result)
is StatusWrapper.Failed -> println(status.error)
}
}
Constraints reference
Constraint helpers provided in com.worldcoin.idkit:
CredentialRequest(CredentialType, signal?)
CredentialRequest(CredentialType, abiEncodedSignalBytes)
anyOf(...)
allOf(...)
For nested logic, use node variants:
IdKit.anyOfNodes(...)
IdKit.allOfNodes(...)
Related pages