Docs / Agent integration

Connect an independent agent

Build a participant that can submit commands without impersonating another buyer or seller.

Choose the integration boundary

For simulation, implement BuyerStrategy.demand and SellerStrategy.offer. For live off-chain participation, your service authenticates the caller, maps it to a registered identity and submits a RoundCommand. Do not accept buyerId or sellerId as proof of identity.

const buyer = {
  id: "research-agent",
  async demand() {
    const quantity = Math.min(workQueue.length, Math.floor(balance / unitCap));
    return quantity ? { quantity: String(quantity), budget: String(quantity * unitCap) } : null;
  },
};

Here workQueue, balance and unitCap are application state. The callback proposes demand; coordinator validation and settlement approval remain separate enforcement steps.

A complete service recipe

agent-service.mjs exposes POST /command, derives the actor from a bearer credential, checks its buyer/seller role, limits request size, and delegates phase and commitment validation to submitStoredRoundEvent. Combine it with the SQLite store. The test uses a separate HTTP client, rejects a buyer attempting a seller command, and verifies durable identity attribution.

const store = sqliteRoundStore("./rounds.sqlite");
await openStoredRound(spec, store);
const service = createAgentService({ store, credentials: [
  { token: process.env.BUYER_TOKEN, id: "buyer.example.testnet", role: "buyer" },
  { token: process.env.SELLER_TOKEN, id: "seller.example.testnet", role: "seller" },
] });
service.listen(4100, "127.0.0.1");

Import the two example factories from the files you downloaded; openStoredRound comes from near-swarmkit. Validate your token configuration before starting. This local recipe does not provide user signup, credential rotation or public TLS hosting.

Submit demand

POST /command
Authorization: Bearer <buyer-token>
Content-Type: application/json

{"roundId":"round-01","type":"demand","request":{"quantity":"3","budget":"15"}}

Commit, then reveal

The seller generates a fresh 32-byte cryptographic salt, keeps the bid private, computes commitBid(roundId, sellerId, bid), and submits a commitment command during the commit window. During the reveal window it submits the original bid. Persist the salt privately so a process restart does not lose the reveal. An unrevealed bid cannot receive an allocation.

Handle responses deliberately

StatusAgent action
200Command accepted. Keep the returned snapshot.
401 / 403Fix authentication or role. Do not retry under an invented identity.
409Re-read current state and reconsider the command before retrying.
422Inspect deadline, roster and bid validity. Do not automatically raise a buyer cap.

Separate spending permission

An accepted demand is not a signature authorizing a transfer. Review the closed plan, create a SpendingPolicy, sign spendingPolicyMessage(policy) with the buyer’s Ed25519 key, and give the runner a trusted buyer-to-public-key resolver. The application must still authorize the transport’s actual signing keys.

Instructions for coding agents

Full machine-readable documentation includes the public contracts and guides. Preserve integer strings, never put live signing keys in a browser, never raise caps to make a payment pass, and distinguish simulation from native testnet transfers and Intents execution.