0xBS
For device operators

Firmware SDK — wrap() as a merchant

A $3 ESP32 does not custody keys or speak PCI. It wraps a function. Agents anywhere settle USDC; the MCU fulfills.

The commercial surface

0xBs treats MCU-class silicon as a fulfillment node, not a wallet. Payment negotiation lives on the control plane (HTTP 402 / x402). Firmware exposes capabilities through wrap() and optional setPrice(). When a funded agent — Claude via MCP, ChatGPT via an Action, or any x402-fetch client — invokes the public device, settlement clears to the operator wallet, then MQTT delivers the command. GPIO, sensors, and actuators run only after settlement.

Install

Arduino library: clone OxBS into ~/Documents/Arduino/libraries, or add the clean OxBS.zip. Install PubSubClient and ArduinoJson v7. Connect Wi-Fi in your sketch — the SDK never calls WiFi.begin().

Wrap an existing function

From the console, copy connectorId, the one-time apiKey, and each serviceId. Do not flash the public deviceId.

#include <WiFi.h>#include <OxBS.h>OxBS oxbs;void setup() {  WiFi.begin("WIFI_SSID", "WIFI_PASSWORD");  while (WiFi.status() != WL_CONNECTED) delay(500);  oxbs.wrap("FORWARD_SERVICE_ID", [](JsonVariantConst args, JsonObject result) {    int seconds = constrain((int)(args["seconds"] | 1), 1, 6);    driveForward();    oxbs.wait(seconds * 1000);    stopMotors();    result["action"] = "forward";    result["seconds"] = seconds;  });  oxbs.setPrice("FORWARD_SERVICE_ID", [](JsonVariantConst args) {    int seconds = constrain((int)(args["seconds"] | 1), 1, 6);    return OxBS::usd(seconds * 0.01f);  });  oxbs.begin("CONNECTOR_ID", "API_KEY");}void loop() {  oxbs.loop();}

Static quotes use oxbs.setPrice(id, "$0.01"). Dynamic quotes take a function of the agent's params. Inside wrap, use oxbs.wait(ms) instead of delay so the MQTT session stays alive.

What the MCU never does

  • No on-device wallet, seed, or EIP-3009 signer.
  • No HTTP 402 parser on the silicon.
  • No public internet listener. The device is an MQTT subscriber; the control plane is the only party that maps deviceId connectorId.

That split is the point: commodity BOM becomes a globally addressable merchant because the payment rail is off-device and standard.

Examples

  • sdk/examples/L298NCar — motors priced per second of actuation.
  • sdk/examples/WrapService — static vs argument-derived quotes on an onboard LED.

Next

Register the device first: Connect a device. Then share the public deviceId with agents — Claude & ChatGPT.

On this page