Writing a client, and using the API from a Replay.RE bundle#
Any client#
A client needs three things: an HTTP POST, HMAC-SHA256 and a way to make a unique nonce.
- Build the operation payload as a JSON string.
- Choose
ts(Unix seconds, within 30 s of the server) and a uniquenonce. sig = base64url(HMAC-SHA256(secret, "v1\n" + path + "\n" + kid + "\n" + ts + "\n" + nonce + "\n" + payload)).- POST
{ "v":1, "kid", "ts", "nonce", "payload", "sig" }tohttps://host/v1/.... - Parse the response envelope, compute
HMAC(secret, "v1resp\n" + nonce + "\n" + status + "\n" + payload), compare it withsigin constant time and reject the answer if it differs. - Parse
payloadas JSON.
tools/ldb_client.py is a complete, 80-line example. Test your signing against the vectors in
SECURITY.md.
If the client's clock may be wrong, call GET /v1/health first and use the returned time to compute an offset.
For idempotent writes, send a stable idempotencyKey in the payload and re-send the same request after a timeout; you get
the original result instead of a second write.
Replay.RE BlackICE bundles#
BlackICE server components run in a sandbox. The facts that shape this API (from the SDK 1.1.0 index and docs.replay.re):
- The only outbound channel is
re.net.Http.Get(url, headers?, timeoutMs)andre.net.Http.Post(url, body, headers?, timeoutMs). NoPUT,PATCHorDELETE, which is why every operation here is aPOST. - Calls return a
Future<HttpResponse>and can be awaited.HttpResponsehasStatus,Error,Ok,Text()andHeader(name). - Destinations must be listed in the bundle's
config.toml:
toml
[Networking]
allowed = ["db.example.com"]
- A bundle's
vfs/folder is a private, plain-file area on the server and is never streamed to clients. It is where the connector bundle reads its key secret from. File permissions on the game server are the only protection, so lock them down.
The companion bundle lt_database (folder lt_database)
wraps all of this: other server bundles use its C# helper methods (Sync, Insert, Find,
Update, Upsert, Delete, Count, Flush), which call the Call and TakeResult exports and never see a key, a URL or an HTTP response. It has no client component, so players have
nothing to call. See that repository's README for installation and the export reference.
Quick setup of the pair:
- Run this API with a key
gameserverlimited to your namespaces and to the game server's address. - In the bundle's
config.tomlallow the API host under[Networking]. - Put the secret into the bundle's
vfs/folder as described in the bundle README and set the API URL and key id. - From your own bundle, declare your tables once at start-up with
Syncand use the other exports at runtime.
The public bundle guide includes compiled C# examples.
When write-behind is enabled on the API, check Db.IsQueued(result) before expecting generated IDs or row counts.
Db.Flush(ns, done) waits for a flush; every write helper accepts immediate: true. Check flush halted and remaining
before depending on the queued writes. See Write-behind.