> For the complete documentation index, see [llms.txt](https://docs.put.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.put.com/cli/offline-transaction-signing.md).

# Offline Transaction Signing

## Offline Transaction Signing

Some security models require keeping signing keys, and thus the signing process, separated from transaction creation and network broadcast.&#x20;

Examples include:

* Collecting signatures from geographically disparate signers in a multi-signature scheme
* Signing transactions using an airgapped signing device

This document describes using PUT's CLI to separately sign and submit a transaction.

## Commands Supporting Offline Signing\#

At present, the following commands support offline signing:

* `create-stake-account`
* `create-stake-account-checked`
* `deactivate-stake`
* `delegate-stake`
* `split-stake`
* `stake-authorize`
* `stake-authorize-checked`
* `stake-set-lockup`
* `stake-set-lockup-checked`
* `transfer`
* `withdraw-stake`
* `create-vote-account`
* `vote-authorize-voter`
* `vote-authorize-voter-checked`
* `vote-authorize-withdrawer`
* `vote-authorize-withdrawer-checked`
* `vote-update-commission`
* `vote-update-validator`
* `withdraw-from-vote-account`

## Signing Transactions Offline

To sign a transaction offline, pass the following arguments on the command line

1. `--sign-only`, prevents the client from submitting the signed transaction to the network. Instead, the pubkey/signature pairs are printed to stdout.
2. `--blockhash BASE58_HASH`, allows the caller to specify the value used to fill the transaction's `recent_blockhash` field. This serves a number of purposes, namely: *Eliminates the need to connect to the network and query a recent blockhash via RPC* Enables the signers to coordinate the blockhash in a multiple-signature scheme

### Example: Offline Signing a Payment

Command

```
put@offline$ put transfer --sign-only --blockhash 5Tx8F3jgSHx21CbtjwmdaKPLM5tWmreWAnPrbqHomSJF \
    recipient-keypair.json 1
```

Output

```
Blockhash: 5Tx8F3jgSHx21CbtjwmdaKPLM5tWmreWAnPrbqHomSJF
Signers (Pubkey=Signature):
  FhtzLVsmcV7S5XqGD79ErgoseCLhZYmEZnz9kQg1Rp7j=4vC38p4bz7XyiXrk6HtaooUqwxTWKocf45cstASGtmrD398biNJnmTcUCVEojE7wVQvgdYbjHJqRFZPpzfCQpmUN

{"blockhash":"5Tx8F3jgSHx21CbtjwmdaKPLM5tWmreWAnPrbqHomSJF","signers":["FhtzLVsmcV7S5XqGD79ErgoseCLhZYmEZnz9kQg1Rp7j=4vC38p4bz7XyiXrk6HtaooUqwxTWKocf45cstASGtmrD398biNJnmTcUCVEojE7wVQvgdYbjHJqRFZPpzfCQpmUN"]}'
```

## Submitting Offline Signed Transactions to the Network

To submit a transaction that has been signed offline to the network, pass the following arguments on the command line

1. `--blockhash BASE58_HASH`, must be the same blockhash as was used to sign
2. `--signer BASE58_PUBKEY=BASE58_SIGNATURE`, one for each offline signer. This includes the pubkey/signature pairs directly in the transaction rather than signing it with any local keypair(s)

### Example: Submitting an Offline Signed Payment <a href="#example-submitting-an-offline-signed-payment" id="example-submitting-an-offline-signed-payment"></a>

Command

```
put@online$ put transfer --blockhash 5Tx8F3jgSHx21CbtjwmdaKPLM5tWmreWAnPrbqHomSJF \
    --signer FhtzLVsmcV7S5XqGD79ErgoseCLhZYmEZnz9kQg1Rp7j=4vC38p4bz7XyiXrk6HtaooUqwxTWKocf45cstASGtmrD398biNJnmTcUCVEojE7wVQvgdYbjHJqRFZPpzfCQpmUN
    recipient-keypair.json 1
```

Output

```
4vC38p4bz7XyiXrk6HtaooUqwxTWKocf45cstASGtmrD398biNJnmTcUCVEojE7wVQvgdYbjHJqRFZPpzfCQpmUN
```

## Offline Signing Over Multiple Sessions <a href="#offline-signing-over-multiple-sessions" id="offline-signing-over-multiple-sessions"></a>

Offline signing can also take place over multiple sessions. In this scenario, pass the absent signer's public key for each role.&#x20;

All pubkeys that were specified, but no signature was generated for will be listed as absent in the offline signing output

### Example: Transfer with Two Offline Signing Sessions <a href="#example-transfer-with-two-offline-signing-sessions" id="example-transfer-with-two-offline-signing-sessions"></a>

Command (Offline Session #1)

```
put@offline1$ put transfer Fdri24WUGtrCXZ55nXiewAj6RM18hRHPGAjZk3o6vBut 10 \
--blockhash 7ALDjLv56a8f6sH6upAZALQKkXyjAwwENH9GomyM8Dbc \
--sign-only \
--keypair fee_payer.json \
--from 674RgFMgdqdRoVtMqSBg7mHFbrrNm1h1r721H1ZMquHL
```

Output (Offline Session #1)

```
Blockhash: 7ALDjLv56a8f6sH6upAZALQKkXyjAwwENH9GomyM8Dbc
Signers (Pubkey=Signature):
    3bo5YiRagwmRikuH6H1d2gkKef5nFZXE3gJeoHxJbPjy=ohGKvpRC46jAduwU9NW8tP91JkCT5r8Mo67Ysnid4zc76tiiV1Ho6jv3BKFSbBcr2NcPPCarmfTLSkTHsJCtdYi
  Absent Signers (Pubkey):
    674RgFMgdqdRoVtMqSBg7mHFbrrNm1h1r721H1ZMquHL
```

Command (Offline Session #2)

```
put@offline2$ put transfer Fdri24WUGtrCXZ55nXiewAj6RM18hRHPGAjZk3o6vBut 10 \
  --blockhash 7ALDjLv56a8f6sH6upAZALQKkXyjAwwENH9GomyM8Dbc \
  --sign-only \
  --keypair from.json \
  --fee-payer 3bo5YiRagwmRikuH6H1d2gkKef5nFZXE3gJeoHxJbPjy
```

Output (Offline Session #2)

```
Blockhash: 7ALDjLv56a8f6sH6upAZALQKkXyjAwwENH9GomyM8Dbc
Signers (Pubkey=Signature):
  674RgFMgdqdRoVtMqSBg7mHFbrrNm1h1r721H1ZMquHL=3vJtnba4dKQmEAieAekC1rJnPUndBcpvqRPRMoPWqhLEMCty2SdUxt2yvC1wQW6wVUa5putZMt6kdwCaTv8gk7sQ
Absent Signers (Pubkey):3bo5YiRagwmRikuH6H1d2gkKef5nFZXE3gJeoHxJbPjy
```

Command (Online Submission)

```
put@online$ put transfer Fdri24WUGtrCXZ55nXiewAj6RM18hRHPGAjZk3o6vBut 10 \
  --blockhash 7ALDjLv56a8f6sH6upAZALQKkXyjAwwENH9GomyM8Dbc \
  --from 674RgFMgdqdRoVtMqSBg7mHFbrrNm1h1r721H1ZMquHL \
  --signer 674RgFMgdqdRoVtMqSBg7mHFbrrNm1h1r721H1ZMquHL=3vJtnba4dKQmEAieAekC1rJnPUndBcpvqRPRMoPWqhLEMCty2SdUxt2yvC1wQW6wVUa5putZMt6kdwCaTv8gk7sQ \
  --fee-payer 3bo5YiRagwmRikuH6H1d2gkKef5nFZXE3gJeoHxJbPjy \
  --signer 3bo5YiRagwmRikuH6H1d2gkKef5nFZXE3gJeoHxJbPjy=ohGKvpRC46jAduwU9NW8tP91JkCT5r8Mo67Ysnid4zc76tiiV1Ho6jv3BKFSbBcr2NcPPCarmfTLSkTHsJCtdYi
```

Output (Online Submission)

```
ohGKvpRC46jAduwU9NW8tP91JkCT5r8Mo67Ysnid4zc76tiiV1Ho6jv3BKFSbBcr2NcPPCarmfTLSkTHsJCtdYi
```

## Buying More Time to Sign <a href="#buying-more-time-to-sign" id="buying-more-time-to-sign"></a>

Typically a PUT transaction must be signed and accepted by the network within a number of slots from the blockhash in its `recent_blockhash` field (\~1min at the time of this writing). If your signing procedure takes longer than this, a Durable Transaction Nonce can give you the extra time you need.
