One gateway in front of the whole market
You don't have to run your own PDS, watch the firehose, or write a scorer. The Compute Contract Gateway is a single Hono service that speaks XRPC on one side and the decentralized market on the other — request a VM or a worker with one call, get a receipt and a terminal back.
Two kinds of compute, one endpoint
Full VM
A real machine — SSH in over a websocat relay tunnel (ProxyCommand → dispatcher → tunnel-subscriber on guest → sshd) once the receipt clears. Good for anything that needs a whole OS.
gateway.requestComputeVM
Deno Worker
Ship source + a deno.json instead of provisioning a full VM. Both ephemeral and persistent workers are provisioned through the same VM contract flow (runComputeContract) — they differ only in bidder discovery scope. Tunnel URLs are not returned for workers.
gateway.requestComputeWorkerEphemeral / …Persistent
Pair your gateway with a bidder
Before requesting compute, a gateway and a bidder confirm each other with a small bidirectional attestation.
Gateway writes a badgeBlueKeys record — a challenge naming the bidder's DID, signed and published on the gateway's own repo.
Bidder acknowledges automatically — the bidder software writes a market.bidderAssociation record pointing back. No manual step on the bidder's side.
Request a VM
One call, given a service-auth token and an SSH public key.
goat xrpc procedure "$GATEWAY_URL" com.publicdomainrelay.temp.gateway.requestComputeVM \
Authorization:"Bearer $SVC_TOKEN" \
sshPublicKey="$(cat my-vm-key.pub)" \
tokens:='{"submitRfp":"...","submitAccept":"...","createRecord":"..."}' \
skipSsh:=false \
bidWindowSec:=30 \
computeVm:='{"cpus":1,"mem":"512M","disk":"10G","network":"500G","role":"my-vm"}' \
extraBidderDids:='["'"$BIDDER_DID"'"]'
The gateway returns a receipt plus everything you need to get a shell:
{
"receiptOk": true,
"receiptUri": "at://did:plc:gateway/market.receipt/3abc...",
"receiptCid": "bafyrei...receipt",
"websocatUrl": "wss://my-vm--did-plc-abc123.fedproxy.com",
"vmFqdn": "my-vm--did-plc-abc123.fedproxy.com",
"winnerDid": "did:plc:bob",
"sshReady": true
}
ssh -o ProxyCommand='websocat --binary wss://my-vm--did-plc-abc123.fedproxy.com' \
-o IdentityFile=./my-vm-key \
root@my-vm--did-plc-abc123.fedproxy.com
Gateway CLI options
| Flag | Env | Description |
|---|---|---|
--port | PORT | TCP port |
--hostname | HOSTNAME | Public hostname (default: localhost) |
--private-key-hex | PRIVATE_KEY_HEX | Secp256k1 private key hex (takes priority over --private-key-hex-path) |
--private-key-hex-path | REPO_PRIVATE_KEY_HEX_PATH | Path to load/save private key hex for stable DID |
--pds-state-path | PDS_STATE_PATH | Persistent PDS state (Deno.Kv SQLite) |
--storage-path | STORAGE_PATH | Fallback storage path (aliases --pds-state-path) |
--plc-directory-url | PLC_DIRECTORY_URL | PLC directory (default: https://plc.directory) |
--ingress-proxy-host | INGRESS_PROXY_HOST | XRPC relay dispatcher host (default: xrpc.fedproxy.com) |
--fedproxy-host | FEDPROXY_HOST | FedProxy SSH ingress host (default: fedproxy.com) |
--relay-urls | RELAY_URLS | Comma-separated relay URLs for bidder discovery |
Current limitations
deleteComputeis a planned endpoint (currently returns{ok:true}without performing actual deletion).- The requester identity (
_caller) is accepted but ignored — the gateway always acts as its own DID. - Worker methods call the same
runComputeContractas VM requests (they provision a VM behind the scenes).