Skip to content

Tutorial: Your First Intent ​

End-to-end walkthrough from "I just installed @infrix/client" to "I have a verifiable evidence bundle in hand."

What you'll build ​

A small TypeScript script that:

  1. Submits a GOVERNED_TRANSFER intent.
  2. Reads the compiled plan back.
  3. Approves the plan with the wallet's signing key.
  4. Awaits the outcome.
  5. Verifies the offline.

Same submission, any SDK ​

The full walkthrough below is TypeScript. The same submitIntent call exists in every SDK — pick the one you build in:

typescript
import { Wallet } from "@infrix/wallet";

const wallet = new Wallet({ endpoint: "http://localhost:8080", identity: "acc://alice.acme" });

const intent = await wallet.submitIntent({
  goal: "GOVERNED_TRANSFER",
  params: { from: "acc://alice.acme", to: "acc://bob.acme", amount: 100 },
});
rust
use infrix_wallet::{Wallet, IntentRequest};
use serde_json::json;

let wallet = Wallet::connect("http://localhost:8080", "acc://alice.acme").await?;

let intent = wallet
    .submit_intent(IntentRequest {
        goal: "GOVERNED_TRANSFER".into(),
        params: json!({ "from": "acc://alice.acme", "to": "acc://bob.acme", "amount": 100 }),
    })
    .await?;
typescript
// AssemblyScript SDK — same shape, compiled to WASM.
import { Wallet, IntentRequest } from "@infrix/assemblyscript";

const wallet = new Wallet("http://localhost:8080", "acc://alice.acme");

const intent = wallet.submitIntent(<IntentRequest>{
  goal: "GOVERNED_TRANSFER",
  params: `{"from":"acc://alice.acme","to":"acc://bob.acme","amount":100}`,
});

Setup ​

bash
mkdir first-intent && cd first-intent
npm init -y
npm install @infrix/client @infrix/wallet

In a separate shell, run a devnet:

bash
go run ./cmd/infrix server --anchor-mode=bookkeeping

The bookkeeping mode keeps anchors local — perfect for a tutorial.

The script ​

Save as first-intent.ts:

typescript
import { InfrixClient } from "@infrix/client";
import { Wallet } from "@infrix/wallet";
import { verifyEvidence } from "@infrix/client/evidence";

async function main() {
  const client = new InfrixClient({ endpoint: "http://localhost:8080" });
  const wallet = new Wallet({
    endpoint: "http://localhost:8080",
    identity: "acc://alice.acme",
  });

  // 1. Submit the intent.
  const intent = await wallet.submitIntent({
    goal: "GOVERNED_TRANSFER",
    params: {
      from: "acc://alice.acme",
      to: "acc://bob.acme",
      amount: 100,
    },
  });
  console.log("intent submitted:", intent.id);

  // 2. Read the compiled plan.
  const plan = await intent.plan();
  console.log("plan steps:", plan.steps.map(s => s.stepType));
  console.log("plugin selections:", plan.pluginSelections);

  // 3. Approve.
  await wallet.approveIntent(plan.id);
  console.log("plan approved");

  // 4. Await the outcome.
  const outcome = await intent.outcome();
  console.log("outcome status:", outcome.status);

  // 5. Verify evidence offline.
  const verification = verifyEvidence(outcome.evidenceBundle);
  if (!verification.ok) {
    throw new Error("evidence verification failed: " + verification.reason);
  }
  console.log("evidence verified — chain hash:", verification.chainHash);
}

main().catch(err => {
  console.error(err);
  process.exit(1);
});

Run it ​

bash
npx tsx first-intent.ts

Expected output:

intent submitted: intent-abc123
plan steps: [ 'validate', 'check-policy', 'collect-approvals', 'execute-settlement' ]
plugin selections: { ... }
plan approved
outcome status: settled
evidence verified — chain hash: 0xfeed...

What just happened ​

You exercised every stage of the governance spine:

  • wallet.submitIntent routed the goal through the canonical mediator at /v4/intents.
  • intent.plan() read back the compiled TypeExecutionPlan with its embedded PluginSelections (Reason, ConfidentialityImplications, CostImplications).
  • wallet.approveIntent posted the wallet's signature to /v4/approvals.
  • intent.outcome() polled /v4/intents/{id}/outcome until the plan reached terminal state.
  • verifyEvidence walked the portable evidence package without needing the devnet.

Verify the demo with examples/full-spine-demo ​

The runtime repo's examples/full-spine-demo is the Go-side counterpart of this tutorial. It exercises the same lifecycle in-process and emits a PortableEvidencePackage for offline verification — handy for CI.

bash
go test ./examples/full-spine-demo -v

Every logStage call in the demo's main.go corresponds to a stage in the bullet list above.

Next ​

Released under the MIT License.