SDK

Kotlin

Android and plain JVM. Headless today: you get the decision, you render it. One dependency, and it exists for a reason worth reading.

Install

build.gradle.kts
dependencies {
implementation("dev.ripstop:ripstop:0.1.0")
}

Quickstart

Kotlin
// Off the main thread: init performs the first check.
val ripstop = Ripstop.init(
apiKey = "rs_pub_your_key",
appVersion = BuildConfig.VERSION_NAME,
storage = SharedPrefsStorage(context),
)

when (val decision = ripstop.check()) {
is RsDecision.ForceUpdate -> showBlockingWall(decision)
is RsDecision.SoftUpdate -> showDismissibleSheet(decision)
is RsDecision.Maintenance -> showMaintenance(decision)
RsDecision.None -> Unit // carry on
}

The when is exhaustive: if the protocol grows a decision, your app stops compiling instead of silently showing nobody anything.

Storage is yours to wire

The library does not depend on Android, which is why it cannot ship a SharedPreferences implementation, and why it stays usable from plain JVM code and from tests. Four lines:

Kotlin
class SharedPrefsStorage(context: Context) : RipstopStorage {
private val prefs = context.getSharedPreferences("ripstop", Context.MODE_PRIVATE)
override fun read(key: String) = prefs.getString(key, null)
override fun write(key: String, value: String) { prefs.edit().putString(key, value).apply() }
override fun remove(key: String) { prefs.edit().remove(key).apply() }
}

Why not the standard library for Ed25519

The JVM has had Ed25519 in JCA since Java 15. Android does not expose it below API 33. An SDK built on JCA would therefore stop verifying signatures on most of the installed base while appearing to work. That is the worst kind of failure, because nothing reports it.

So this uses net.i2p.crypto:eddsa: ~100 KB, pure Java, works everywhere the library does. It is the only dependency.

HTTP is yours too

The default transport is HttpURLConnection, which is in Android and in the JDK. An SDK you add to protect a release should not pick your HTTP client for you. Pass a Transport to route through OkHttp, or through a stub in tests.

Options

OptionDefaultWhat it does
apiKeyno defaultYour app’s public SDK key. Safe to ship
appVersionno defaultThe running build; rules evaluate against it
platformandroidWhich platform’s rules to read
localeenWhich wall copy to resolve; falls back to en per key
minFetchIntervalMillis6 hoursHow long a payload is fresh enough to skip the network
timeoutMillis5000Fetch budget. After that, cache
storagein-memoryPass a SharedPreferences-backed one in production
signingKeyspinnedOverride for self-hosted deployments and tests
transportHttpURLConnectionInject OkHttp, or a stub

Threading

init and check block, deliberately. The SDK does not choose a coroutine scope or a threading model for you, so wrap them in whatever your app already uses.

Source

⌘K