RADIX WikiRADIX Wiki

Transaction Structure

A Radix transaction has three layers, each wrapping the previous:

LayerContainsPurpose
IntentHeader + manifestDefines what to do and when
Signed IntentIntent + signaturesAuthorizes the transaction
Notarized TransactionSigned intent + notary signatureFinal submission-ready payload

The header sets when the transaction is valid and who notarises it. Since the Cuttlefish update transactions are V2, and the header is in two parts. The intent header holds the network ID, a validity window of epochs (an epoch lasts about five minutes), an optional window of proposer timestamps, and an intent_discriminator that makes otherwise identical intents distinct; every subintent carries one of its own. The transaction header holds the notary’s public key, whether the notary also counts as a signer, and the tip in basis points. The older V1 header keeps all of this in one struct, with a nonce and a tip percentage in place of the discriminator and basis points. The manifest contains the instructions.

Build → Sign → Submit

1. Build

Construct the transaction intent with a manifest and header. The epoch window determines how long the transaction remains valid. The end epoch has to be later than the start, and the validator rejects a window longer than 8,640 epochs, about 30 days.

2. Sign

One or more parties sign the intent hash with their private keys (Ed25519 or ECDSA secp256k1). For wallet-submitted transactions, the dApp Toolkit handles this automatically.

3. Notarize

The notary signs the signed intent hash. In most dApps, the wallet acts as both signer and notary.

4. Submit

The compiled payload is sent to the network via the Gateway or Core API.

5. Track

Poll the transaction status using the intent hash. Outcomes:

  • Committed – on ledger, as a success or a failure. A committed failure still pays its fee.
  • Permanently rejected – never committed, and retrying cannot change that: the payload is too large, badly encoded or wrongly signed, its epoch or timestamp window has closed, or its intent has already been committed or cancelled.
  • Temporarily rejected – the node retries it later. This covers a window that has not opened yet, a fee payer that could not repay the fee loan, and a user-transaction moratorium such as the one mainnet ran in the epoch before the Eagle Ray fork.

Subintents and Pre-Authorization

Subintents are independent mini-transactions that compose into a single atomic transaction. Each subintent has its own manifest, header, and signers.

Why Subintents?

  • Delegated fee payment – a dApp pays fees on behalf of the user, solving the "double onboarding" problem (user needs XRD before they can do anything)
  • Peer-to-peer trading – buyer and seller each sign a subintent; a matchmaker combines them into an atomic swap
  • Flash loans – a lending subintent provides liquidity, the user's subintent uses it, and a payback subintent returns it – all atomically

Key Instructions

A parent names each child subintent with USE_CHILD, which has to come before every other instruction in the manifest, and refers to it by that name afterwards. The syntax below follows the manifest compiler’s own tests. A child can also run VERIFY_PARENT with an access rule, so that only a chosen counterparty can use it. Nesting stops at three levels of subintent below the transaction intent.

# Parent: declare the child by its subintent hash
USE_CHILD
    NamedIntent("my_child")
    Intent("subtxid_rdx1...");
 
# Parent: hand control to the child, passing everything on the worktop
YIELD_TO_CHILD
    NamedIntent("my_child")
    Expression("ENTIRE_WORKTOP");
 
# Child: hand control back to the parent
YIELD_TO_PARENT
    Expression("ENTIRE_WORKTOP");

Pre-Authorization Flow

Pre-authorization lets users sign subintents in advance. The dApp can later combine them with its own subintents and submit whenever ready.

  1. dApp sends a pre-auth request to the wallet with a subintent manifest
  2. User reviews and signs in the wallet
  3. Wallet returns the signed subintent to the dApp
  4. dApp combines it with other subintents and submits as a complete transaction

Practical example

A user pre-authorizes "swap 100 USDC for GBP" via a subintent. The dApp adds a fee-payment subintent and submits the combined transaction – the user never needs to hold XRD for fees.

Next Steps

  • Transaction Fees – who pays, how much, and how to sponsor fees for your users
HydrateLast updated 19h agov1.4.010 revisionsVerified Sep 14, 2026