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:
- Submits a
GOVERNED_TRANSFERintent. - Reads the compiled plan back.
- Approves the plan with the wallet's signing key.
- Awaits the outcome.
- Verifies the evidence bundleevidence bundleA portable receipt you can verify offline. It packages the proof of what ran so a regulator or auditor can check it without running a node or trusting the network. 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/walletIn a separate shell, run a devnet:
bash
go run ./cmd/infrix server --anchor-mode=bookkeepingThe 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.tsExpected 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.submitIntentrouted the goal through the canonical mediator at/v4/intents.intent.plan()read back the compiledTypeExecutionPlanwith its embeddedPluginSelections(Reason, ConfidentialityImplications, CostImplications).wallet.approveIntentposted the wallet's signature to/v4/approvals.intent.outcome()polled/v4/intents/{id}/outcomeuntil the plan reached terminal state.verifyEvidencewalked 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 -vEvery logStage call in the demo's main.go corresponds to a stage in the bullet list above.
Next
- Multi-party trade — three-party atomic settlement.
- Cross-domain bridge — Sepolia receipt-proof verification.
- Approval policies cookbook — patterns for sized approvals.