daitchain

Rent compute as a tenant

A tenant submits AI jobs to the network. There are two paths: a single-shot lease through x/compute_market, and a state-channel session for high-frequency inference. The state channel path is what every interactive workload should use.

Stake

None required at the User tier. The Heavy tier (369 DAIT lock) buys priority queue access in x/compute_market. See x/staking_tiers.

Path A: single lease via the marketplace

Best for batch jobs, fine-tuning, evaluation runs. The auction window is 30 blocks (~30s) and bids run as a reverse Dutch auction.

Submit a deployment

An SDL (Stack Definition Language) manifest describes the job. Minimal SDL:

version: "1"
job:
  model: qwen2.5-32b-instruct
  attributes:
    gpu_class: hopper-or-newer
    region: na-east
    replayable: true
  price_ceiling_uDAIT: 50
  duration_blocks: 3600   # ~60 min at 999ms blocks
  escrow_uDAIT: 200000
dait-cli deploy job.sdl

Watch the auction settle

dait-cli auction watch <deployment_id>

The auction iterator selects the lowest-price bid that matches all attribute filters. Ties are broken by earliest bid height, then by lexicographic provider_addr.

Send work and pay

Once the lease is active, the host's gRPC endpoint and TEE pubkey are in the lease record. Standard cosmos-sdk events fire on BidWon, LeaseStarted, LeaseClosed.

Path B: state channel for interactive use

Best for chat, IDE assistants, agents in tight loops. Open with one tx, transact off-chain, close with one tx.

// TypeScript
import { DaitClient } from "@dait/core";
import { ComputeSession } from "@dait/compute";

const dait = new DaitClient({ rpcUrl: "https://rpc.daitchain.io", wallet });

const session = await ComputeSession.open(dait, {
  modelId:    "qwen2.5-32b-instruct",
  hostAddr:   "dait1abc...",        // optional; auto-selected if omitted
  maxCalls:   10_000,
  escrow_uDAIT: 5_000_000n,
  deadlineMs: Date.now() + 24 * 3600 * 1000,
});

const reply = await session.infer({ prompt: "Hello, world." });
console.log(reply.text);
console.log(reply.receipt.tokens_out, "tokens at", reply.receipt.price_uDAIT, "uDAIT");

await session.close();   // cooperative

What the SDK verifies for you

On every inference reply the SDK runs the steps in SPUR-IC ยง7:

  1. Decode X-DAIT-Receipt protobuf.
  2. Reject if channel_id does not match.
  3. Reject if call_seq is not last + 1.
  4. Verify host signature against the TEE-bound pubkey.
  5. Verify the TEE quote chains to a trusted root and binds the pubkey.
  6. Recompute request and response hashes.
  7. Update local ChannelState, increment turn_num, sign, ship on next request.

Any failed step is a non-recoverable fault. The SDK throws, persists the offending receipt, and surfaces a recommendation to call session.dispute().

Closing a channel

See also