TypeScript SDK Quickstart
Get up and running with the Tenzro TypeScript SDK in under 5 minutes. You will connect to the testnet, create a wallet, check your balance, send TNZO, register a decentralized identity, list available AI models, and run inference -- all from TypeScript. Works in Node.js and the browser.
Prerequisites
- Node.js 18+ or Bun 1.0+
- Internet connection (for testnet RPC calls)
Estimated time: 5 minutes
Step 1: Create a New Project
Create a new project and install the SDK:
mkdir my-tenzro-app && cd my-tenzro-app
npm init -y
npm install tenzro-sdk
npm install -D typescript tsx @types/node
npx tsc --initOr with Bun:
mkdir my-tenzro-app && cd my-tenzro-app
bun init
bun add tenzro-sdkStep 2: Connect to Testnet
Create src/index.ts and connect to the Tenzro testnet. The SDK exports a pre-configured TESTNET_CONFIG:
import { TenzroClient, TESTNET_CONFIG } from "tenzro-sdk";
async function main() {
// Connect to testnet
const client = new TenzroClient(TESTNET_CONFIG);
// Verify connection
const info = await client.nodeInfo();
console.log("Connected to Tenzro Network");
console.log(" Chain ID:", info.chain_id);
console.log(" Block height:", info.block_height);
console.log(" Peers:", info.peer_count);
}
main().catch(console.error);Run it:
npx tsx src/index.tsExpected output:
Connected to Tenzro Network
Chain ID: 1337
Block height: 482910
Peers: 5Custom Endpoints
To connect to a local node, create a custom config: { endpoint: "http://localhost:8545", timeout: 30000 }. The TESTNET_CONFIG points to https://rpc.tenzro.network.
Step 3: Create a Wallet
Create a new wallet using the WalletClient:
import { TenzroClient, TESTNET_CONFIG } from "tenzro-sdk";
async function main() {
const client = new TenzroClient(TESTNET_CONFIG);
// Create a new Ed25519 wallet
const walletInfo = await client.wallet.createWallet();
console.log("Wallet created!");
console.log(" Address:", walletInfo.address);
}
main().catch(console.error);Step 4: Fund from Faucet
Request 100 testnet TNZO tokens from the faucet (24-hour cooldown per address):
// Request testnet tokens
const faucet = await client.requestFaucet(walletInfo.address);
console.log("Faucet:", faucet.amount, "TNZO received");
console.log(" Tx hash:", faucet.tx_hash);Step 5: Check Balance
Query the wallet balance:
// Get TNZO balance (returns bigint in wei)
const balance = await client.wallet.getBalance(walletInfo.address);
console.log("Balance:", balance.toString(), "wei");
// Convert to human-readable TNZO (18 decimals)
const tnzo = Number(balance) / 1e18;
console.log("Balance:", tnzo, "TNZO");Step 6: Send TNZO
Transfer TNZO to another address:
Every Tenzro transaction is hybrid post-quantum signed: a classical Ed25519 signature and an ML-DSA-65 (FIPS 204) signature, both verified synchronously by the node against the canonical Transaction::hash()preimage (which commits to the wallet's ML-DSA-65 public key). An invalid or missing signature on either leg returns JSON-RPC error -32003.
The recommended flow is client.wallet.signAndSend(...), a thin wrapper over tenzro_signAndSendTransaction. Auth is mandatory — the SDK attaches your DPoP-bound bearer JWT, the node identifies the signing wallet, signs both legs, verifies them, and submits to the mempool atomically. Private keys never travel over the wire.
// Send 1 TNZO via atomic server-side hybrid sign + submit
const txHash = await client.wallet.signAndSend({
from: walletInfo.address,
to: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb4",
value: 1_000_000_000_000_000_000n, // 1 TNZO in wei
});
console.log("Transaction sent:", txHash);
// Check updated balance
const newBalance = await client.wallet.getBalance(walletInfo.address);
console.log("New balance:", Number(newBalance) / 1e18, "TNZO");Offline / pre-signed submission
For batched or air-gapped flows, call tenzro_signTransaction to obtain{signature, public_key, pq_signature, pq_public_key, timestamp, tx_hash}, then resubmit later via eth_sendRawTransaction with all six fields intact. Missing any field returns -32003.
Step 7: Register an Identity
Register a TDIP identity using the IdentityClient:
// Register a human identity
const idResult = await client.identity.registerHuman("Alice");
console.log("Identity registered!");
console.log(" DID:", idResult.did);
console.log(" Status:", idResult.status);
// Resolve the identity
const resolved = await client.identity.resolve(idResult.did);
console.log(" Type:", resolved.identity_type);
console.log(" KYC Tier:", resolved.kyc_tier);Expected output:
Identity registered!
DID: did:tenzro:human:550e8400-e29b-41d4-a716-446655440001
Status: active
Type: human
KYC Tier: 0Step 8: List Models and Run Inference
Discover available AI models and send an inference request:
// List available models
const models = await client.inference.listModels();
console.log("Available models:", models.length);
for (const model of models) {
console.log(` ${model.model_id} - ${model.name} (${model.status})`);
}
// Run inference
const response = await client.inference.request(
"gemma3-270m", // model ID
"Explain blockchain in one sentence.", // prompt
100, // max tokens
);
console.log("Response:", response.output);
console.log("Tokens:", response.tokens_used);
console.log("Cost:", response.cost, "TNZO");Step 9: The AppClient Pattern
For building user-facing applications, use AppClient instead of TenzroClient. The AppClient wraps a master wallet and provides a paymaster pattern where you sponsor gas for your users:
import { AppClient } from "tenzro-sdk";
async function main() {
// Create an AppClient with your master wallet
const app = await AppClient.new(
"https://rpc.tenzro.network",
process.env.MASTER_PRIVATE_KEY!,
);
// Create a user wallet (funded from master)
const user = await app.createUserWallet(
"alice",
100_000_000_000_000_000n, // 0.1 TNZO initial funding
);
console.log("User wallet:", user.address);
// Set spending limits
await app.setUserLimits(
user.address,
5_000_000_000_000_000_000n, // 5 TNZO/day
1_000_000_000_000_000_000n, // 1 TNZO/tx
);
// Sponsor an inference request (gas paid by master wallet)
const result = await app.sponsorInference(
user.address,
"gemma3-270m",
"Hello from my app!",
);
console.log("Output:", result.output);
console.log("Cost:", result.cost, "TNZO");
// Check usage stats
const stats = await app.getUsageStats();
console.log("Total gas spent:", stats.totalGasSpent.toString());
console.log("Total transactions:", stats.transactionCount);
}
main().catch(console.error);TenzroClient vs AppClient
TenzroClient is for direct interaction -- each user manages their own wallet and gas. AppClient is for developer-funded applications -- you control a master wallet and sponsor transactions on behalf of your users. AppClient is ideal for building web apps, mobile apps, and SaaS products where you do not want users to manage crypto.
Complete Example
Here is the full quickstart in a single file:
import { TenzroClient, TESTNET_CONFIG } from "tenzro-sdk";
async function main() {
// 1. Connect
const client = new TenzroClient(TESTNET_CONFIG);
const info = await client.nodeInfo();
console.log("Connected (chain", info.chain_id + ")");
// 2. Create wallet
const wallet = await client.wallet.createWallet();
console.log("Wallet:", wallet.address);
// 3. Fund from faucet
const faucet = await client.requestFaucet(wallet.address);
console.log("Funded:", faucet.amount, "TNZO");
// 4. Check balance
const balance = await client.wallet.getBalance(wallet.address);
console.log("Balance:", Number(balance) / 1e18, "TNZO");
// 5. Register identity
const id = await client.identity.registerHuman("Alice");
console.log("DID:", id.did);
// 6. List models
const models = await client.inference.listModels();
console.log("Models:", models.length);
// 7. Run inference
const response = await client.inference.request(
"gemma3-270m",
"What is Tenzro Network?",
100,
);
console.log("Response:", response.output);
}
main().catch(console.error);Sub-Client Reference
The TenzroClient exposes these sub-clients as properties:
| Property | Type | Purpose |
|---|---|---|
client.wallet | WalletClient | Create wallets, balances, send transactions |
client.inference | InferenceClient | List models, run inference |
client.identity | IdentityClient | Register/resolve TDIP identities |
client.payment | PaymentClient | MPP, x402, native payment flows |
client.agent | AgentClient | Register agents, messaging, task delegation |
client.governance | GovernanceClient | Proposals, voting, voting power |
client.settlement | SettlementClient | Escrow, micropayments |
client.token | TokenClient | Create tokens, cross-VM transfers |
client.staking | StakingClient | Stake/unstake, register as provider |
client.bridge | BridgeClient | Cross-chain bridges |
client.crypto | CryptoClient | Sign, verify, encrypt, key exchange |
client.streaming | StreamingClient | SSE streaming, real-time events |
client.canton | CantonClient | Canton/DAML enterprise integration |
client.tee | TeeClient | TEE attestation, enclave operations |
client.zk | ZkClient | ZK proof generation and verification |
client.contract | ContractClient | Deploy and call smart contracts |
What You Learned
- Installation --
npm install tenzro-sdk - Connection -- connecting with
TenzroClientandTESTNET_CONFIG - Wallets -- creating, funding, checking balances, and sending TNZO
- Identity -- registering TDIP identities and resolving DIDs
- Inference -- listing models and running AI inference
- AppClient -- the paymaster pattern for building user-facing apps
Next Steps
- Rust SDK Quickstart -- same flow in Rust
- Build a Gasless App with Paymaster -- deep dive into AppClient
- Build an AI Coding Assistant -- streaming inference with payments
- Build E2E Encrypted Messaging -- X25519 key exchange + AES-256-GCM
Build More with Tenzro
Ready to build something more complex? Explore the full SDK documentation and examples.