> For the complete documentation index, see [llms.txt](https://help.multisig.ledger.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://help.multisig.ledger.com/guides/cli-guides/proposing-signing-and-executing.md).

# Proposing, signing and executing

This page is the CLI counterpart to [2. Transaction Lifecycle](https://help.multisig.ledger.com/guides/2.-transaction-lifecycle-including-off-chain-signatures), covering the same four phases: propose, collect signatures, execute, and verify, as shell commands instead of TypeScript / Python / curl.

### What you'll learn

* Propose a Safe transaction with `lem tx propose`.
* Have additional owners add their signatures with `lem tx sign`.
* Submit the transaction on-chain with `lem tx execute`.
* Verify execution and handle indexer lag.

### Prerequisites

* `lem` installed (see **Installation**).
* A paired signer (see **Configuring a signer**).
* A Safe where the connected signer is an owner.
* The Safe funded with enough native gas for execution.

### Step-by-step

#### 1. Propose a transaction

Build, sign, and submit a new Safe transaction in a single command. The connected signer is recorded as the proposer, and their signature counts as the first confirmation.

```
lem tx propose \
  --address 0xYourSafeAddress \
  --chain-id 11155111 \
  --to 0xRecipientAddress \
  --value 100000000000000
```

* \--address: the Safe.
* `--chain-id`: numeric chain ID. See the **Overview** page for supported networks.
* \--to: the recipient (any EVM address).
* \--value: the amount, in **wei**, sent from the Safe.

`lem` will:

1. Resolve the next nonce automatically (accounts for queued proposals).
2. Ask your signer to approve the EIP-712 hash (on-device for USB Ledger).
3. POST the proposal + signature to the Transaction Service.
4. Print the canonical payload, including the safeTxHash:

```
{
  "safeAddress": "0xYourSafeAddress",
  "safeTransactionData": {
    "to": "0xRecipientAddress",
    "value": "100000000000000",
    "data": "0x",
    "operation": 0,
    "nonce": "12",
    "safeTxGas": "0",
    "baseGas": "0",
    "gasPrice": "0",
    "gasToken": "0x0000000000000000000000000000000000000000",
    "refundReceiver": "0x0000000000000000000000000000000000000000"
  },
  "safeTxHash": "0xYourSafeTxHash",
  "senderAddress": "0xYourSignerAddress",
  "senderSignature": "0x...",
  "origin": "{\"app\":\"les-multisig-cli\"}"
}
```

Capture the `safeTxHash`. That is the handle for everything that follows.

> **Today** `lem tx propose` is scoped to ETH transfers. For richer payloads (ERC-20 transfers, contract calls, MultiSend batches), use the Ledger Multisig UI or the API Kit. See [Guide 3](https://help.multisig.ledger.com/guides/3.-batch-transactions) and [Guide 5](https://help.multisig.ledger.com/guides/5.-erc20-token-transfers).

#### 2. Collect signatures

Other Safe owners run `lem tx sign` to confirm the same `safeTxHash`. They need their own `lem connect` session.

```
lem tx sign --chain-id 11155111 0xYourSafeTxHash
```

The signer is asked to confirm on-device. After approval, `lem` POSTs the new confirmation to the Transaction Service and prints the updated count:

```
{
  "safeTxHash": "0xYourSafeTxHash",
  "safeAddress": "0xYourSafeAddress",
  "signer": "0xCoOwnerAddress",
  "confirmations": 2,
  "confirmationsRequired": 2
}
```

`lem tx sign` short-circuits with a clear error in three situations:

| Situation                     | Behaviour                                                             |
| ----------------------------- | --------------------------------------------------------------------- |
| Transaction already executed  | Exit code 1, message Transaction has already been executed.           |
| Threshold already met         | Exit code 1, message Transaction already has enough signatures (N/M). |
| This signer already confirmed | Exit code 1, message This owner has already signed the transaction.   |

Check progress at any time with `lem tx show --safe-tx-hash 0xYourSafeTxHash --pretty`. Move on when `confirmations.length === confirmationsRequired`.

#### 3. Execute on-chain

With the threshold met, any owner can bundle the collected signatures and submit on-chain:

```
lem tx execute --chain-id 11155111 0xYourSafeTxHash
```

The executing signer pays gas, and `lem` returns the on-chain `transactionHash` plus the `safeTxHash` it executed:

```
{
  "safeTxHash": "0x...",
  "transactionHash": "0x...",
  "status": "submitted"
}
```

The same hardware-confirmation pattern applies: the device prompts you to approve the on-chain submission. From this point the transaction is at the mercy of the EVM. `lem` does not wait for inclusion by default.

#### 4. Verify execution

The Transaction Service typically catches up within 10–60 seconds. Re-fetch the transaction:

```
sleep 15
lem tx show --safe-tx-hash 0xYourSafeTxHash --pretty
```

Confirm `isExecuted: true`, `isSuccessful: true`, and that `transactionHash` matches what `lem tx execute` returned.

### Key concepts

> **Off-chain proposal, on-chain execution.** Propose and sign only update the Transaction Service. They are gas-free, idempotent, and visible across the platform. Execute is the single moment gas is spent and chain state changes.

> **Determinism via** `safeTxHash`. Every command that mutates a transaction takes `--safe-tx-hash` (or accepts it positionally for `tx sign` / `tx execute` / `tx show`). The hash is computed locally during propose and is independent of any RPC.

### Tips and pitfalls

* **Indexer lag is real.** If `lem tx show` reports `isExecuted: false` 5 seconds after `lem tx execute`, that is normal. Wait and retry.
* **A returned** `transactionHash` can still be a revert. `lem tx execute` reports whatever the receipt yields. Always inspect `isSuccessful` in the post-execute `tx show` output, or pull the receipt with your usual RPC tooling, before declaring victory.
* **Fund the executor.** The signer running `lem tx execute` must have native gas on the target chain. The Safe's balance is for the transfer. The executor's balance is for gas.
* **Ordering by nonce.** Safe enforces strict nonce ordering. If you queue tx A (nonce 7) and tx B (nonce 8) and execute B first, B will revert. Use `lem safe nonce` and `lem tx list` to keep ordering straight.
* **Re-running** `lem tx execute` is a no-op once on-chain. If the transaction is already executed, the Transaction Service will not re-submit it. `lem` will surface that as an error.

### Next steps

* **Command reference**
* **Building agent workflows**
