Local protocol mode — Anvil, development executor keys, and synthetic Nitro registration are not production trust assumptions.

Build with Takusen

Build a Solidity consumer

Install the protocol-v2 Solidity SDK and safely resolve a complete Takusen result set on any supported EVM chain.

Install the versioned consumer SDK

npm from a source checkoutsh
npm pack ./packages/solidity
npm install ./takusen-solidity-2.0.0.tgz
Foundrysh
forge install takusen-io/takusen
Foundry remappingtoml
@takusen/solidity/=lib/takusen/packages/solidity/src/

The repository package is versioned 2.0.0 and produces a validated npm tarball; after its first registry publication the equivalent install command is npm install @takusen/solidity@2. The SDK major version equals protocolVersion(). Version 2 guarantees the existing consumer struct layouts, enum members and numeric ordering, function selectors, output encodings, and schema-hash formula. Additive helpers may arrive in minor versions; a breaking interface change requires protocol version 3 and an SDK major release.

API request to on-chain resolution

  1. Discover an active, healthy deployment with GET /v1/chain and use its verified resultsContract and protocolVersion fields.
  2. Create the x402 challenge with a structured outputSchema. extensions.takusen.binding returns onchainRequestId, inputHash, the ordered onchainModels array, modelSetHash, schemaHash, complete outputSchema, settlementDomain, chainId, resultsContract, and protocolVersion before execution begins.
  3. Use your application's authorized registrar to bind that challenge payload to the action the answer may affect, then submit the unchanged body with PAYMENT-SIGNATURE. The 202 response repeats the binding payload, and GET /v1/requests/{id} returns it later.
  4. Wait for the public RequestFinalized event, or use an application-owned early policy that is mathematically irreversible. Any account may then submit the permissionless resolution transaction.
  5. The consumer verifies the registered commitments, complete ordered model set, finalization, successful typed outputs, application-owned policy, and replay state before invoking your internal application callback.
Importssolidity
import {ITakusenResults} from "@takusen/solidity/src/interfaces/ITakusenResults.sol";
import {TakusenOutput} from "@takusen/solidity/src/libraries/TakusenOutput.sol";
import {TakusenConsumerBase} from "@takusen/solidity/src/base/TakusenConsumerBase.sol";
import {TakusenBooleanConsumer} from "@takusen/solidity/src/base/TakusenBooleanConsumer.sol";

Public reads, bound application effects

ITakusenResults is intentionally public: any address can read requestState, requestModels, and every modelResult. Request registration does not hide or permission those records. It only binds one exact public request commitment to the application action it is allowed to trigger, preventing a resolver from substituting another valid request with a favorable answer.

Registration must happen while the results contract still reports NONE, before any model answer is visible. The first x402 challenge provides the complete binding payload and a ten-minute confirmation window before payment submission or execution, avoiding a race. The application decides who may register—an application backend, governance contract, or signed-intent adapter—while resolve remains permissionless after binding. The packaged base verifies inputHash, modelSetHash, schemaHash, lifecycle completeness, and replay state.

If payment or admission is abandoned, the authorized registrar may cancel the binding while the results contract still reports NONE and bind a replacement request to the same action. Cancellation is rejected as soon as any result is public, preventing the application from outcome-shopping after seeing model answers.

Policy belongs to the application contract

TakusenConsumerBase supplies lifecycle, complete-set, model-bound, gas-bound, and replay checks but deliberately does not choose an agreement policy. The packaged BooleanConsumer uses a fixed strict majority of expectedModels / 2 + 1. It rejects ties and sub-majorities, and its early path uses that same threshold, so remaining unpublished models cannot reverse the decision.

Automation without a trusted callback

An EVM contract cannot initiate its own transaction. Takusen therefore keeps settlement independent from application code: RequestFinalized publishes authoritative public state, then a resolver calls the consumer. The resolver supplies gas and evidence but no authority; the contract simulates or rejects unregistered, incomplete, replayed, or non-agreeing requests.

The Hardhat example includes an event-driven TypeScript resolver and a callback-style TakusenApp. It subscribes before its catch-up scan, waits a configurable confirmation count, simulates resolution, and then submits. Production automation should derive confirmations from the selected domain, persist its processed block, cap gas, and retry dropped transactions. Because resolution is permissionless and replay-safe, users and competing automation providers remain a fallback if the default resolver stops.

Downstream testing and chain addresses

MockTakusenResults lets application tests install explicit request and per-model states without importing escrow administration. The SDK tests public reads, registrar authorization, request substitution, caller-threshold manipulation, ties, schema decoding, replay protection, and early resolution. The Hardhat example compiles the callback application and type-checks its resolver.

The npm package includes deployments/testnet.json as a chain-ID-keyed convenience snapshot containing settlementDomain, resultsContract, escrow, verifier, resultRelay, protocolVersion, and activation status for Base development and BSC testnet simulation. Because testnet is rip-and-replace, live GET /v1/chain remains authoritative: require active, healthy, and authoritySynchronized, then verify protocolVersion() before constructing or calling the consumer.

Both TakusenEscrow on the paying domain and TakusenResultRelay on a non-paying destination implement the same ITakusenResults interface. Consumer code does not need a chain-specific result decoder.