Tenzro
Canton on Tenzro

Canton agentic.

Tenzro Network exposes Canton DAML as a first-class destination for autonomous agents. Mandate-bound writes, scoped party reads, and operator analytics — built on top of the existing Canton surface (tenzro_submitDamlCommand, tenzro_listDamlContracts, tenzro_canton_*), composed with the new agent delegation fields shipped on tenzro_createApiKey.
STATUS
Testnet
STABILITY
Stable
AUTHORIZATION
Mandate + Delegation
REFERENCE
canton-agentic
01

Three RPCs

  • tenzro_canton_submitWithMandate — submit a DAML command bound to an AP2 mandate pair. Validates the cart against AP2 invariants + TDIP DelegationScope + runtime SpendingPolicy + optional on-chain escrow + optional Stripe SPT ceiling.
  • tenzro_canton_watchParty— active-contracts snapshot for a single party. Gated against the API key's can_read_as_parties allow-list.
  • tenzro_canton_aggregateAnalytics — operator admin-read of rolled-up per-key Canton call counters, grouped by subject or key_id.
02

Mandate-bound write

The autonomous agent presents two things on every Canton write: a scoped API key with can_act_as_parties populated, and an AP2 cart mandate pair (a checkout VDC signed by the principal + a payment VDC signed by the agent).

{
  "jsonrpc": "2.0",
  "method": "tenzro_canton_submitWithMandate",
  "params": {
    "mandate": {
      "checkout": { /* AP2 checkout VDC */ },
      "payment":  { /* AP2 payment VDC */ }
    },
    "command_type": "create",
    "template_id": "#splice-amulet:Splice.AmuletRules:Transfer",
    "create_arguments": {
      "to": "Counterparty::abc123...",
      "amount": "1000000",
      "memo": "settlement-2026-06"
    }
  },
  "id": 1
}

The handler executes fail-closed at every step: parse → AP2 validate with delegation enforcement → forward the stripped command to the existing DAML submit handler → return both receipts.

03

Scoped read

tenzro_canton_watchParty is the agent-facing read surface. Authorization: the presenting API key must satisfy can_read_as(party) (which can_act_as_parties implies).

{
  "jsonrpc": "2.0",
  "method": "tenzro_canton_watchParty",
  "params": {
    "party": "TenzroLabs::abc123...",
    "template_ids": ["#splice-amulet:Splice.AmuletRules:Holding"]
  },
  "id": 1
}
04

Operator analytics

tenzro_canton_aggregateAnalytics rolls up the per-key counters CantonAnalyticsManager tracks. Admin-token-gated; tenants can't read across each other.

{
  "buckets": [
    { "key": "did:tenzro:machine:abc...", "total_calls": 12450, "last_called_at": 1717977600 },
    { "key": "did:tenzro:machine:def...", "total_calls": 3187,  "last_called_at": 1717976000 }
  ],
  "row_count": 2,
  "group_by": "subject"
}
05

Workflow templates

The Canton-settlement reference workflow template wraps submitWithMandate as a single-step workflow. Tenants instantiate it via tenzro_useResource; the workflow executor handles the dispatch.

See Resources for the full workflow runtime model.

06

SDK access

Rust SDK — the canton_agent() accessor on TenzroClient:

let client = TenzroClient::connect(SdkConfig::testnet()).await?;
let canton = client.canton_agent();
let receipt = canton.submit_with_mandate(params).await?;

TypeScript SDK — the CantonAgentClient class:

import { TenzroClient, CantonAgentClient } from '@tenzro/sdk';
const client = new TenzroClient({ rpcUrl: 'https://rpc.tenzro.network' });
const canton = new CantonAgentClient(client.rpc);
const receipt = await canton.submitWithMandate(params);
← All docs