Transaction Flow
A transaction in ootle.ts goes through five stages: build, resolve, sign, seal, and submit. The SDK provides both individual functions for each stage and an all-in-one convenience helper.
The pipeline
Section titled “The pipeline”TransactionBuilder.buildUnsignedTransaction() → resolveTransaction(provider, unsignedTx) // fill in substate versions → signTransaction([signer], resolvedTx) // seal keypair + Schnorr signatures → sealTransaction(signed) // BOR-encode into TransactionEnvelope → submitTransaction(provider, envelope) // submit to network → watchTransaction(provider, txId) // wait for finalizationIndividual steps
Section titled “Individual steps”import { resolveTransaction, signTransaction, sealTransaction, submitTransaction, watchTransaction, classifyOutcome,} from "@tari-project/ootle";
// 1. Resolve — fills in missing substate versionsconst resolved = await resolveTransaction(provider, unsignedTx);
// 2. Sign — generates a seal keypair, collects Schnorr signaturesconst signed = await signTransaction([signer], resolved);
// 3. Seal — BOR-encodes the signed transaction into a TransactionEnvelopeconst envelope = sealTransaction(signed);
// 4. Submit — sends the envelope to the networkconst txId = await submitTransaction(provider, envelope);
// 5. Watch — waits for finalization (SSE + polling fallback)const receipt = await watchTransaction(provider, txId, { timeoutMs: 30_000 });
// 6. Inspect the outcomeconst outcome = classifyOutcome(receipt.result);// { outcome: "Commit" }// | { outcome: "FeeIntentCommit", reason: string }// | { outcome: "Reject", reason: string }All-in-one helpers
Section titled “All-in-one helpers”import { sendTransaction, sendDryRun } from "@tari-project/ootle";
// Resolve → sign → seal → submit → watch in a single callconst receipt = await sendTransaction(provider, signer, unsignedTx);
// Dry-run: simulates without committing stateconst result = await sendDryRun(provider, signer, unsignedTx);sendTransaction accepts either a single Signer or an array of signers. All signatures are collected before sealing and submitting.
Transaction outcomes
Section titled “Transaction outcomes”classifyOutcome returns one of three outcomes:
| Outcome | Meaning |
|---|---|
Commit | Transaction fully committed |
FeeIntentCommit | Fee deducted but execution aborted |
Reject | Transaction rejected entirely |
watchTransaction throws on both Reject and FeeIntentCommit outcomes. Use classifyOutcome directly on the raw IndexerGetTransactionResultResponse for non-throwing outcome inspection. PendingTransaction.watch() (from ootle-indexer) does not throw — the caller decides how to handle each outcome.