The settler API
Proposed

One object in.
A receipt out, either way.

The surface is specced, not shipped — this page is the contract being built against, and it is tagged as such throughout. The types are real today: they are the exported shapes the checker on this site already runs.

The one object partners write
profile.ts
import { checkInsurability, type OperationProfile } from "@t3rn/settler";

const profile: OperationProfile = {
  kind:    "XFER",              // XFER | CALL | AGENT | APICALL | STREAM | ANY
  version: "0.1.0",

  // Parties are minted attestations. A bare address is not a party.
  parties: {
    payer:   "att:base:0x8f3a…",
    worker:  "att:agent:0x41d9…",
    referee: "PROOF",           // AUTO | EVALUATOR | PROOF | DOOR
  },

  // What "done" means — sealed BEFORE the work starts, never after.
  acceptance: { digest: "0x9c2e…", grader: "PROOF" },

  // At least one lane the layer can decode. More is better.
  evidence: [{ lane: "CHAIN", ref: "eip155:8453" }],

  value:    { asset: "USDC", amount: "1000000", escrow: "GATE" },
  deadline: { epochs: 12, grace: 2 },   // epochs, never wall time
  refund:   { path: "att:base:0x8f3a…" },
  cover:    { mode: "BOND_ONLY", cap: "1000000" },
};

// The same predicate the API applies, before you spend a call on it.
const check = checkInsurability(profile);
if (!check.ok) {
  // → { refusal: "UNINSURABLE_PROFILE", missing: ["acceptance_spec"] }
  throw new Error(`${check.refusal}: ${check.missing.join(", ")}`);
}
The five verbs
settle.ts
// Everything derivable is derived. You never hand-set a bond or a premium:
// the bond floor comes from b >= p(1-q)/q with q MEASURED per kind and lane,
// and the premium is quoted by the meter.
const terms = await settler.quote(profile);
// → { bondFloor, premiumRef, refereeLanes, capacityLeft }  expires with the epoch

// open() declares the job and locks the escrow. The acceptance digest seals here.
const op = await settler.open(profile);

// Evidence flows in through whichever lane the profile declared.
await op.emit({ kind: "DELIVERY", island: "isl:…", digest: "0x…" });

// finalize() asks the referee to grade against the sealed acceptance.
const receipt = await op.finalize();

// …or nobody shows up, and this needs no one's goodwill:
// past deadline + grace the default is revert, and the refund cites the receipt.
const reverted = await op.timeoutRevert();   // outcome: TIMEOUT

// Free, keyless, forever — and never wrapped by any skin, including ours.
await settler.verify(receipt.id);
Insurance without integration
no-join.ts
// The no-join move: insure an operation the service knows nothing about.
//
// Any operation whose evidence lane is CHAIN can be profiled BUYER-SIDE. The
// worker delivers exactly as it always has; the layer decodes the destination
// event; release-or-refund settles for the buyer. No partnership, no SDK on
// their side, no permission.

const op = await settler.open({
  ...profile,
  parties: {
    payer:  myAttestation,
    worker: "att:external:0x…",  // the oblivious service
    referee: "PROOF",
  },
  evidence: [{ lane: "CHAIN", ref: "eip155:8453" }],
});

// The insured party integrates the record, not the insurer.
The capture doors, for work that is not on a chain
doors.ts
// Off-chain work reaches the layer through four consented doors. All four are
// transports over the SAME two calls — no door adds an operation.

// 1 · The node, inside the workflow itself
await settler.emit({ kind: "DELIVERY", workflow: id, outputDigest: digest });

// 2 · Owner-keyed polling of a platform's own execution list
const runs = await door.poll({ platform: "workflow-host", apiKey: OWNER_KEY });

// 3 · An enterprise log stream, sunk and signed on arrival
door.sink({ transport: "webhook", secret: SHARED });

// 4 · MCP, both directions: the settler ships AS a tool the agent calls, so a
//     declared job needs no surveillance at all.
mcp.tool("settle", { open, finalize, verify });

Every door needs the operator's consent. There is no passive subscription to a stranger's executions, and no overlay can make one workflow run agree with another about what it will do. What this offers a business is different and deliverable: one canonical history, non-equivocation, and a price on lying about it.

Operators: one bond, one rule
operator.ts
// Operators: one bond object, one slashing rule. The legacy insurance deposit
// and the bond become the same thing — there are not two systems.
await settler.bond.post({ ns: "t3", amount: "50000000" });
await settler.identity.mint({ ns: "t3", role: "operator" });

// Idle stake is untouchable and earns nothing. Exposure is created only by an
// explicit act of underwriting, capped inside the master bond.
Two surfaces
Partner SDKRing 1

namespace.enroll · identity.mint · bond.post · job.declare · job.authorize · clear.lock · envelope.emit · verdict.request · dispute.open · receipt.get/list · shares.statement · credits.*

Namespace keys, rotatable and scoped per operation class. Every mutating call is idempotent by client key and metered.

End SDKRing 3

pay402 · receipt.verify · credits.balance/spend

Deliberately thin. No registration, no positions, no visible chain: a user's first contact is buying an assured outcome or checking one.

The rule that governs the whole surface

An operation exists only if it produces a field of the receipt, or reads one. The receipt is the terminal object: it is the evidence, the audit trail and the royalty statement, all the same artifact. Anything that cannot be replayed from sealed evidence is not an operation — it is a liability, and it does not get a verb.