Skip to content
Tenzro
Documentation menu
Execution and interoperability

Canton

Reach Canton networks through a Tenzro node: party-bound API keys, per-tenant isolation, mandate-bound agent writes and operator controls.

Canton is the privacy-preserving network that runs DAML contracts. On Tenzro Network 1, Canton is an operator-provided integration: a node operator connects the node to one or more Canton participants (Canton 3.5 and later, JSON Ledger API v2) and offers access to developers and agents through scoped API keys. The node handles party resolution, per-tenant isolation and TNZO settlement, so an application or agent talks to Canton with the same client it uses for the rest of Tenzro.

What you can do

TaskCLIJSON-RPC
Check the connectiontenzro canton health, tenzro canton versiontenzro_canton_health, tenzro_canton_version
See your user and partytenzro canton my-usertenzro_canton_getMyUser
List synchronizers and partiestenzro canton domains, tenzro canton connected-synchronizers, tenzro canton partiestenzro_listCantonDomains, tenzro_canton_connectedSynchronizers, tenzro_canton_listParties
List active contractstenzro canton contractstenzro_listDamlContracts
Watch one party's contractstenzro canton watch-partytenzro_canton_watchParty
Submit a create or exercisetenzro canton submittenzro_submitDamlCommand
Agent write under a mandatetenzro canton submit-with-mandatetenzro_canton_submitWithMandate
Upload a DAR, list packagestenzro canton upload-dar, tenzro canton packagestenzro_canton_uploadDar, tenzro_canton_listPackages
Canton Coin balance and fee scheduletenzro canton coin-balance, tenzro canton fee-scheduletenzro_canton_coinBalance, tenzro_canton_feeSchedule
Look up a transactiontenzro canton get-transactiontenzro_canton_getTransaction
Your own usage counterstenzro canton my-analyticstenzro_canton_getMyAnalytics

Access

Every Canton call carries an API key with the canton scope, issued by the operator of the node you connect to. Send it as the X-Tenzro-Api-Key header, the api_key JSON-RPC parameter, or --api-key (or TENZRO_API_KEY) on the CLI.

A key gates Canton because the Canton ledger sits outside Tenzro and the node reaches it with credentials the operator supplies. Keys do not gate the rest of the network: publishing an agent, skill, workflow or MCP server stays permissionless. See API keys and RPC access.

Network selection. A node can serve several Canton networks, and a key is authorised for some of them. Name the target with the canton_network parameter, the X-Canton-Network header or --canton-network. If you name none, the node uses your key's only network, or else its own default. A key authorised for several networks that names none gets error -32004 listing the networks it may use.

Rate tiers. Each key has a tier that bounds requests over a sliding 60-second window: free (read-only), standard and priority. Over budget returns -32005 with retry_after_ms, requests_per_minute and tier. Agent writes under a mandate need standard or above.

Tenancy and parties

Each developer team or agent is isolated behind its own key, and each key is bound to its own Canton user and party.

  • When an operator issues a key with a Canton binding, the node allocates a party for the tenant, registers a Canton user with that party as its primary party, and grants it the right to act as that party, in one step. Re-issuing for an existing user reuses its party.
  • On every call, the node uses the key's primary party as actAs and as the requesting party for reads. A key without a Canton binding cannot submit; the operator's own party is never used on a tenant's behalf.
  • To act as another party, pass act_as (or --act-as). The node allows it only if the party is on the key's can_act_as_parties list. Reads of another party need it on can_read_as_parties. Anything else returns -32004.
  • Canton enforces the same rights again on its side, so a misconfigured client cannot exceed them.

Operators who need a dedicated OAuth client per tenant can enable per-tenant identity providers. The node then creates an upstream OAuth client for each new key, mints and caches the tenant's Canton token on the server side, and forwards it on the tenant's calls. The tenant's only credential is its Tenzro API key; revoking the key removes the upstream client and the Canton rights together. Tenants with their own identity provider can instead send a token in the X-Canton-Auth: Bearer <jwt> header.

Agents on Canton

Autonomous agents can write to Canton under a spending mandate, so a principal stays in control of what the agent commits to. An agent presents two things on each write:

  1. A key whose can_act_as_parties includes the party the agent acts for.
  2. An AP2 mandate pair: a checkout credential signed by the principal and a payment credential signed by the agent.

The node validates the mandate pair, the agent's delegation scope and the runtime spending policy, and optionally an on-chain escrow, before it forwards the command. Any failed check stops the write. The response carries both the mandate receipt and the Canton transaction.

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tenzro_canton_submitWithMandate",
  "params": {
    "mandate": {
      "checkout": { "...": "AP2 checkout credential" },
      "payment":  { "...": "AP2 payment credential" }
    },
    "command_type": "create",
    "template_id": "ComputeJob:Job",
    "create_arguments": {
      "buyer": "Buyer::1220ab...",
      "provider": "Provider::1220cd...",
      "gpuHours": "12.0"
    }
  }
}

From the CLI, pass the two credentials as files:

bash
tenzro canton submit-with-mandate \
  --checkout-vdc ./checkout.json --payment-vdc ./payment.json \
  --command-type create --template ComputeJob:Job \
  --create-arguments '{"buyer":"Buyer::1220ab...","provider":"Provider::1220cd...","gpuHours":"12.0"}' \
  --api-key "$TENZRO_API_KEY" --rpc https://rpc.tenzro.xyz

For reads, an agent uses tenzro_canton_watchParty with a party and optional template filter; the key must be allowed to read as that party. See Agent commerce for mandates and spending policies.

SDKs

The TypeScript and Rust tenzro-sdk packages expose a Canton client with the same methods and the same act_as override:

ts
import { TenzroClient } from "tenzro-sdk";

const client = new TenzroClient({ endpoint: "https://rpc.tenzro.xyz" });
const receipt = await client.canton.submitWithMandate(mandate, {
  command_type: "create",
  template_id: "ComputeJob:Job",
  create_arguments: args,
});

Operator controls

Operators manage Canton through admin methods, which need the node's admin credential and are never reachable with a tenant key:

  • Party and rights management: tenzro canton allocate-party, tenzro canton grant-rights, tenzro canton list-rights.
  • Identity providers: tenzro_canton_createIdp, tenzro_canton_listIdps, tenzro_canton_deleteIdp.
  • Workflow anchoring: tenzro_mirrorWorkflowToCanton and tenzro_mirrorObligationToCanton record Tenzro workflows and their obligations as contracts on a Canton synchronizer.
  • Usage across tenants: tenzro_canton_listApiKeyAnalytics and tenzro_canton_aggregateAnalytics return per-key call and error counts. Tenants read only their own with tenzro_canton_getMyAnalytics.
  • Reconnecting a synchronizer after an outage or planned disconnection.

Running Canton access is one way an operator can earn from a node; see Operators and roles.