Skip to content
Tenzro
Documentation menu
Build and operate

SDKs

The official Tenzro SDKs — TypeScript, Rust, Python, Go, C/C++, Swift, Kotlin and .NET — hardware device keys, and how signing and credentials work.

Tenzro publishes eight official SDKs, each a client over the node's JSON-RPC surface. TypeScript, Rust and Python carry the full surface (wallet, identity, inference, payments, settlement, storage, agents and more) and a gateway that can call any method the node serves; Go, C/C++, Swift, Kotlin and .NET cover the core read surface today (chain id, status, balance and the rest) and grow from there.

SDKRepositoryInstall
TypeScripttenzro-sdk-typescriptnpm install tenzro-sdk
Rusttenzro-sdk-rustcargo add tenzro-sdk
Pythontenzro-sdk-pythonpip install git+https://github.com/tenzro/tenzro-sdk-python (not yet on PyPI)
Gotenzro-sdk-gogo get github.com/tenzro/tenzro-sdk-go
C / C++tenzro-sdk-cppcmake -S . -B build && cmake --build build (source build; no TLS yet — see the repo)
Swifttenzro-sdk-swiftSwift Package Manager, https://github.com/tenzro/tenzro-sdk-swift
Kotlin / Javatenzro-sdk-kotlinJitPack or a git dependency (not yet on Maven Central — see the repo)
.NETtenzro-sdk-dotnetProject reference (not yet on NuGet.org — see the repo)

All SDKs are open source under Apache 2.0. The rest of this page covers TypeScript and Rust, the two with the full surface; each other SDK's own README has its real quickstart and compatibility notes.

TypeScript, Rust and Python in depth

What a registry serves today differs from the source, and this page documents the source (version 0.9.0 of the TypeScript and Rust SDKs, 0.2.0 of the Python SDK, in sdk/ of tenzro-network). A call added after the published release is only in the source build.

bash
# TypeScript (Node 18+, browsers, edge runtimes): published, latest 0.7.0
npm install tenzro-sdk

# Rust: published, latest 0.7.0
cargo add tenzro-sdk

# Python (3.10+): not published to PyPI yet; build from the repository
git clone https://github.com/tenzro/tenzro-network.git
pip install ./tenzro-network/sdk/tenzro-py
PackageWherePublishedIn the repository
tenzro-sdk (TypeScript)npm0.7.00.9.0
@tenzro/device-key (TPM / Secure Enclave keys for Node.js)npm0.1.1in the repository
@tenzro/inject (injected window.tenzro provider)npmnot publishedsdk/tenzro-inject
tenzro-sdk (Rust)crates.io0.7.00.9.0
tenzro (Python)PyPInot published0.2.0 (sdk/tenzro-py)
tenzro-device-key (Python)PyPInot publishedin the repository

Signing needs hardware: on a server or desktop the SDKs sign with the machine's TPM 2.0 or Secure Enclave through @tenzro/device-key (TypeScript) or tenzro-device-key (Python); in a browser they use a passkey. Without one they refuse to sign. Every method the SDKs bind is documented with its params, result and errors in the generated JSON-RPC reference.

Connect

The TypeScript client takes an endpoint for JSON-RPC and an apiEndpoint for the Web API (health and status).

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

const client = new TenzroClient({
  endpoint: "https://rpc.tenzro.com",
  apiEndpoint: "https://api.tenzro.com",
});

const height = await client.getBlockNumber();
const finalized = await client.getFinalizedBlock();
const balance = await client.getBalance("0xYourAddress"); // bigint, in wei

If you leave out apiEndpoint, the client derives it from endpoint for the public endpoints and for a local node (localhost:8545 maps to localhost:8080).

The Rust client is built from an SdkConfig:

rust
use tenzro_sdk::{TenzroClient, config::SdkConfig};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = SdkConfig::builder()
        .endpoint("https://rpc.tenzro.com")
        .timeout(30_000)
        .max_retries(3)
        .build()?;
    let client = TenzroClient::connect(config).await?;

    println!("height: {}", client.block_number().await?);
    let models = client.inference().list_models().await?;
    println!("{} models", models.len());
    Ok(())
}

TenzroClient::new("https://rpc.tenzro.com") is the one-line form with default settings.

Run inference

List models and send a chat request through the provider client:

ts
const models = await client.inference.listModels();

const reply = await client.provider.chat("<model id>", [
  { role: "user", content: "Summarize the latest block in one sentence." },
]);
rust
use tenzro_sdk::provider::ChatMessage;

let reply = client
    .provider()
    .chat("<model id>", vec![ChatMessage {
        role: "user".into(),
        content: "Summarize the latest block in one sentence.".into(),
        ..Default::default()
    }])
    .await?;

If you do not want to pick a model yourself, client.inference.routeIntent(...) resolves a use case and budget to a model, and chatByIntent(...) runs the request in one call.

The node also serves OpenAI-compatible routes (/v1/chat/completions, /v1/responses, /v1/embeddings, /v1/audio/transcriptions, /v1/audio/speech and more), so any OpenAI client library works when you point its base URL at https://rpc.tenzro.com/v1. See OpenAI-compatible APIs.

Signing and credentials

Tenzro Network is closed by default: anything that moves money or changes state needs a signature from the account that pays. The SDKs never hold your keys. You pass in a signer backed by a passkey, a TPM 2.0 or a Secure Enclave key, and the SDK builds the canonical transaction hash, asks the signer for the composite hybrid signature (classical plus ML-DSA-65) and submits the signed transaction with eth_sendRawTransaction.

ts
// signer: a HybridSigner backed by your passkey or device key
const txHash = await client.wallet.sendSelfCustody({
  signer,
  to: "0xRecipient",
  value: 1_000_000_000_000_000_000n, // 1 TNZO in wei
});
rust
// signer: Arc<dyn HybridSigner> backed by your device key
let tx_hash = client
    .wallet()
    .send_self_custody(&signer, recipient, 1_000_000_000_000_000_000u128)
    .await?;

In the browser, a passkey enrols with client.passkeyRpc.enroll and signs transactions from its account as a HybridSigner whose P-256 leg is its WebAuthn assertion (user verification required). See Hardware-rooted keys and Console and passkey wallet.

Other credentials are read from the environment in server runtimes, so they stay out of your code:

VariableHeader sentUsed for
TENZRO_BEARER_JWT and TENZRO_DPOP_PROOFAuthorization: DPoP ... and DPoPOAuth 2.1 sessions bound to a DPoP key
TENZRO_ADMIN_TOKENX-Tenzro-Admin-TokenOperator-only methods on your own node

AuthClient (client.auth in TypeScript, client.auth() in Rust) handles onboarding for humans, delegated agents and autonomous agents and returns DPoP-bound tokens. HardwareDpopProver mints the DPoP proofs with the machine's hardware P-256 key, and jwkThumbprint computes the key's thumbprint. See RPC access.

The ML-DSA-65 leg is mandatory for account transactions. An account signs nothing until it has enrolled its ML-DSA-65 key, and a new account's first transaction is the enrollment. client.accountKeys().sendEnrolling in the TypeScript SDK, and send_enrolling in the Rust and Python SDKs, send a transaction and, if the node answers that no key is enrolled, enrol the hardware's key and send it again. The CLI equivalent is tenzro pq-hybrid enroll. See Cryptography.

Call any method

Typed clients cover the common paths. Everything else is reachable through the gateway, which reads the method list from the node itself, so a newer node simply reports more:

ts
const dir = await client.gateway.methods({ contains: "forecast" });
for (const m of dir.methods) console.log(m.method, m.gate, m.class);

const result = await client.gateway.call("tenzro_getSupplyMetrics", {});
rust
let dir = client.gateway().methods(None, Some("forecast")).await?;
let result = client.gateway().call("tenzro_getSupplyMetrics", serde_json::json!({})).await?;

The gateway runs through the same access checks as a direct JSON-RPC call. It reaches exactly what your credentials allow.

Choosing

  • TypeScript for web and desktop apps, agents, serverless and edge functions.
  • Rust for daemons, high-volume services and anything that embeds a node.
  • Python for scripts, notebooks and ML pipelines.
  • Go, C/C++, Swift, Kotlin/Java or .NET for native apps, games, mobile, embedded devices or a platform's own stack — each covers the core read surface today; see that SDK's own repository for its exact methods and compatibility.
  • The CLI for scripts and operator tasks.

For every client and method, see the SDK reference.

ExploreJoin the network