Documentation
Deep Dives
Transaction Chaining

Transaction Chaining

Transaction chaining lets you build sequential transactions that depend on outputs from previous transactions without waiting for on-chain confirmation.

How It Works

The chain() method returns three essential pieces:

const [newWalletUTxOs, derivedOutputs, txSignBuilder] = await lucid
  .newTx()
  .pay.ToAddress(recipientAddress, { lovelace: 5_000_000n })
  .chain();
  • newWalletUTxOs: Updated wallet UTXOs (unspent + change outputs)
  • derivedOutputs: All outputs created by the transaction
  • txSignBuilder: Ready for signing and submission

Basic Example

// First transaction
const [newWalletUTxOs, derivedOutputs, txSignBuilder] = await lucid
  .newTx()
  .pay.ToAddress(recipientAddress, { lovelace: 5_000_000n })
  .chain();
 
// Sign and submit
const signedTx = await txSignBuilder.sign.withWallet().complete();
await signedTx.submit();
 
// Update wallet UTXOs
lucid.overrideUTxOs(newWalletUTxOs);
 
// Second transaction can now use updated UTXOs
const [newWalletUTxOs2, derivedOutputs2, txSignBuilder2] = await lucid
  .newTx()
  .pay.ToAddress(recipientAddress2, { lovelace: 3_000_000n })
  .chain();
 
// Sign and submit second transaction
const signedTx2 = await txSignBuilder2.sign.withWallet().complete();
await signedTx2.submit();
 
// Update wallet UTXOs again
lucid.overrideUTxOs(newWalletUTxOs2);

Interactions

// Deposit to contract
const [newWalletUTxOs, contractOutputs, txSignBuilder] = await lucid
  .newTx()
  .pay.ToAddressWithData(
    contractAddress,
    { kind: "inline", value: datum },
    { lovelace: 10_000_000n }
  )
  .chain();
 
// Sign and submit
const signedTx = await txSignBuilder.sign.withWallet().complete();
await signedTx.submit();
 
// Update wallet state
lucid.overrideUTxOs(newWalletUTxOs);
 
// Collect from contract
const [newWalletUTxOs2, derivedOutputs2, txSignBuilder2] = await lucid
  .newTx()
  .collectFrom(contractOutputs, redeemer)
  .attach.SpendingValidator(validator)
  .chain();
 
// Sign and submit
const signedTx2 = await txSignBuilder2.sign.withWallet().complete();
await signedTx2.submit();
 
// Update wallet state again
lucid.overrideUTxOs(newWalletUTxOs2);

Important Notes

  1. Each transaction in a chain must be individually signed and submitted.

  2. You call overrideUTxOs() after each transaction to update the wallet's UTxO state.

  3. If one transaction fails to confirm on-chain, all subsequent transactions that depend on its outputs will also fail.

  4. In memory-intensive applications, free resources after use:

    txBuilder.rawConfig().txBuilder.free();
    txSignBuilder.toTransaction().free();
    signedTx.toTransaction().free();