Skip to content

Quick Start

This guide walks through consuming an existing Tx3 protocol from your application. We’ll generate a typed client from a compiled .tii, bind parties and a signer, and drive the full resolve → sign → submit → wait lifecycle against a TRP server. Every code step is shown in TypeScript, Rust, Go, and Python — pick the tab that matches your stack and the narrative still applies.

We’re assuming you already have:

  • A Tx3 project (a trix.toml plus a main.tx3) — for example the transfer protocol from the authoring quick-start.
  • A TRP server reachable from your machine. The simplest setup is to run trix devnet locally; for testnet/mainnet, point at a hosted TRP endpoint (Demeter, Blockfrost-via-TRP, etc.).
  • The toolchain for your target language installed (Node.js 18+, Rust 1.78+, Go 1.22+, or Python 3.10+).

Configure codegen

Tx3 produces typed clients via trix codegen. Open your project’s trix.toml and add a [[bindings]] entry for your target language. The output path is where the generated client will be written; declare more than one entry if you want to target multiple languages from the same protocol.

[[bindings]]
plugin = "typescript"
output = "./generated/ts"

Generate the client

From the project root, run:

Terminal window
trix codegen

This produces:

  • A .tii artifact describing the protocol’s interface (transactions, parties, profiles).
  • A typed module under the output directory that exposes one builder method per tx declared in your .tx3 file.

Re-run trix codegen whenever you change main.tx3. The generated code is meant to be checked into source control alongside your application — treat it like a lockfile, not a build artifact.

Install the runtime SDK

In the application that will use the generated client, install the runtime SDK. It ships the Tx3Client, party bindings, signer abstractions, and the TRP transport layer; the generated module wraps these in a typed surface specific to your protocol.

Terminal window
npm install tx3-sdk

Load the protocol

The .tii artifact carries the protocol’s interface: every transaction template, the parties it expects you to bind, the profiles it was compiled for. Each SDK exposes a Protocol.fromFile-shaped entry point.

import { Protocol } from "tx3-sdk";
const protocol = await Protocol.fromFile("./generated/ts/transfer.tii");

Connect to a TRP server

TRP is the wire protocol the SDK uses to ask a backend “given this TIR and these arguments, produce a balanced transaction.” When you run trix devnet, a local TRP endpoint comes up automatically. For preprod/mainnet, point at a hosted TRP server.

import { TrpClient } from "tx3-sdk";
const trp = new TrpClient({ endpoint: "http://localhost:3000/rpc" });

Bind parties, signer, and profile

Every party declared in the .tx3 file needs a binding at runtime. Party.signer(...) ties a party to a key that can produce witnesses; Party.address(...) binds a read-only address. withProfile(...) selects which environment block (devnet/preview/preprod/mainnet) the SDK uses when it asks TRP to resolve.

Each SDK ships two signer kinds: a CardanoSigner that derives keys from a BIP39 mnemonic at the standard Cardano path, and a generic Ed25519Signer for raw key material. The snippets below show whichever flavour is most idiomatic per language.

import { Tx3Client, Party, Ed25519Signer } from "tx3-sdk";
const signer = Ed25519Signer.fromHex("addr_test1...", "deadbeef...");
const tx3 = new Tx3Client(protocol, trp)
.withProfile("devnet")
.withParty("sender", Party.signer(signer))
.withParty("receiver", Party.address("addr_test1..."));

Drive a transaction end-to-end

tx("name").arg(...) builds an invocation; the four-stage chain takes it from there. Each stage returns a typed handle for the next: ResolvedTx → SignedTx → SubmittedTx. waitForConfirmed polls the chain (via TRP) until the transaction reaches the requested stability level; waitForFinalized waits for stronger finality.

import { PollConfig } from "tx3-sdk";
const status = await tx3
.tx("transfer")
.arg("quantity", 10_000_000n)
.resolve()
.then((r) => r.sign())
.then((s) => s.submit())
.then((sub) => sub.waitForConfirmed(PollConfig.default()));
console.log(status.stage); // "confirmed"

What’s next

  • Find the canonical repository and package registry for each SDK on the SDKs page.
  • Learn more about the codegen workflow — supported targets, output layout, and how to wire generated code into your build.
  • Understand the protocols underneath (TII, TRP) if you want to know how the wire format works.