2. Transaction Lifecycle (including off-chain signatures)

Create, sign, propose, execute, and verify a Safe transaction end-to-end using the Ledger Enterprise Multisig API.

What you'll learn

  • Initialize both the Protocol Kit (transaction creation/signing) and the API Kit (proposal/indexing)

  • Build and sign an ETH transfer as a Safe transaction

  • Propose the signed transaction to the Ledger Multisig Transaction Service

  • Execute the transaction on-chain once the signature threshold is met

  • Verify execution status through the API

Prerequisites

  • Node.js 18+

  • A Safe on Sepolia (or another supported chain) where you control at least one owner key

  • A private key for a Safe owner: use a testnet-only key

  • Sepolia ETH in the Safe for gas and the transfer amount

  • viem: used for receipt verification

Install the SDK:

npm install @safe-global/api-kit @safe-global/protocol-kit @safe-global/types-kit viem

Configuration

The TX_SERVICE_URL points at the Ledger-hosted Transaction Service. Transactions proposed here appear in the Ledger Enterprise Multisig UIarrow-up-right.

Supported chains: Ethereum (1), Optimism (10), BSC (56), Polygon (137), Base (8453), Arbitrum (42161), Sepolia (11155111).

Step-by-step

1

Initialize the Protocol Kit and API Kit

The Protocol Kit connects to the blockchain and handles transaction creation and signing. The API Kit talks to the Transaction Service for proposal and querying.

REST API: GET /v1/safes/{address}/ - used internally by getSafeInfo to verify ownership.

2

Create the transaction

Define the transaction parameters and create a Safe transaction object. For a simple ETH transfer, set data to "0x" and operation to Call.

The Protocol Kit automatically sets the nonce, safeTxGas, baseGas, gasPrice, gasToken, and refundReceiver fields based on the current Safe state.

3

Sign the transaction

Compute the Safe transaction hash and sign it with the owner's private key. This produces an off-chain (EIP-712) signature with no gas is spent.

The safeTxHash is the unique identifier for this transaction within the Safe. It is not an on-chain transaction hash.

4

Propose the transaction

Submit the signed transaction to the Transaction Service. This stores it off-chain and makes it visible to other owners in the Ledger Multisig UI.

REST API: POST /v1/safes/{address}/multisig-transactions/ - the request body includes the full transaction data, the safeTxHash, the sender address, and the signature.

After proposing, the transaction is visible in the Ledger Enterprise Multisig UI and other owners can sign the transaction.

5

Check confirmations and execute

Retrieve the pending transaction, check if enough signatures have been collected to meet the threshold, and execute on-chain if ready.

REST API: GET /v1/multisig-transactions/{safeTxHash}/ - retrieves a single transaction by its Safe transaction hash, including all collected confirmations.

If the threshold is not yet met, other owners can confirm using:

REST API: POST /v1/multisig-transactions/{safeTxHash}/confirmations/

6

Verify execution

After execution, query the Transaction Service to confirm the transaction was indexed as executed and successful.

Key concepts

Off-chain signatures, on-chain execution. Safe transactions use a two-phase model:

  • Propose: The transaction data and an owner's signature are submitted to the Transaction Service (off-chain, no gas).

  • Execute: Once enough signatures meet the threshold, any account can submit the transaction on-chain (costs gas).

This means a 3-of-5 Safe only pays gas once - when the final executor submits all collected signatures in a single on-chain call.

For the full guide, see Transactions with Off-chain Signaturesarrow-up-right.

Tips and pitfalls

  • Indexing lag. After executeTransaction returns, the Transaction Service may take 10–60 seconds to index the receipt. If you query immediately, isExecuted may still be false and isSuccessful may be null. The on-chain transaction is confirmed. The indexer catches up within a minute or two.

  • executeTransaction can return a hash for a reverted tx. The Protocol Kit returns a transaction hash even if the on-chain transaction reverts. Always check the receipt status independently.

  • Signer must be an owner. The proposeTransaction call will fail if senderAddress is not a current owner (or delegate) of the Safe. Verify ownership before proposing.

  • Nonce management. The Protocol Kit automatically picks the next nonce. If you need to queue transactions in a specific order, pass options: { nonce } to createTransaction.

Next steps

3. Batch Transactionschevron-right

Last updated