How do I create an offline transaction on an air-gapped device and broadcast it to the network?
Option 1 Kukai
First make sure you have a secure offline environment for your wallet. You can either have a dedicated computer for it or a bootable Linux USB Flash Drive (with e.g. Tails) that never connects to internet.
Always download the Kukai wallet from the official links on Github and verify the SHA256 checksum. It is important to ensure that you are using a legitimate software without any extra piece of code added on top. Move your Kukai wallet app to your offline system using for example a pen drive. Create or import your wallet following the instructions in the app. Then export a view-only wallet from your full wallet. The view-only contains only your public key.
Step 1 (online)
Import your view-only wallet into the client or website. Make an operation inside your wallet. An unsigned operation will be created and exported to a file. Move the file to your offline wallet.
Step 2 (offline)
Go to the offline signing view and import the unsigned operation. The operation will now be parsed and visible in the wallet so you know exactly what you are about to sign. After verification, sign and export the signed operation back to the view-only wallet. Step 3 (online)
In the final step, you need to broadcast the signed operation to the network. Import the signed operation in the offline-signing view and broadcast it from the last section.
Option 2 AirGap
Part 1 Download AirGap Vault & Wallet
Step 1 Download & Install AirGap Vault app
Step 2 Download & Install AirGap Wallet app
Part 2 Setup AirGap Vault
Open the AirGap Vault mobile App on your phone, read through the disclaimer.
Select “Generate”. “Generate” a new secret, you can also import an existing mnemonic phrase. We recommend that you generate a new secret on the air gapped device and not import one that was previously used in a device with network connectivity.
Accept the permission request. You have to give AirGap Vault video and audio permission, this is needed for the secret generation.
Generate your secret. The enhanced entropy concept adds video, audio, accelerator and touch data to the entropy seed alongside the device’s pre-shipped secure random generator in order to generate a cryptographically secure seed used for the secret generation.
Read & understand the rules. If your phone gets damaged or lost, you can still access your funds with the secret mnemonic phrase. To keep your secret safe, you need to follow these rules.
Write your secret on a piece of paper. In order to have a backup of your secret, you need to write the following words on a piece of paper. Remember the rules!
Verify your secret. Verify the secret you wrote down on a piece of paper, by ordering the mnemonic words in the right order.
Security level & secret name Give your secret a name, so that you can identify it easier later.
Use your fingerprint to store the secret in the secure enclave of the mobile device, set a password and confirm it for additional security.
Enter password of secret. Access the secret in the secure enclave of the AirGap Vault app by fingerprint and password.
AirGap Vault — secret created.Your secret has been created and is now safely stored in the secure enclave of the mobile phone. It can only be accessed by fingerprint and password through the AirGap Vault app.
Part 3 Sync AirGap Vault with AirGap Wallet
Add a new wallet. A wallet consists of the public address and the derivation path of a specific coin.
Select the coin
Allow access to the secret. Access the secret in the secure enclave of the AirGap Vault app by fingerprint and password.
Select the newly added wallet. A new wallet for the selected coin has now been created.
Select “Sync”. AirGap Vault needs to “sync” the wallet with AirGap Wallet.
“Sync” the wallet with AirGap Wallet. AirGap Wallet has never access to the secret, the “sync” will use the extended public key.
Wallet has been synced to AirGap Wallet, is now visible. The wallet has now been synced from AirGap Vault to AirGap Wallet, you can now use this wallet to prepare transactions.
Part 4 Create a new transaction
Create a new transaction with “Send”. To create a new transaction, select “Send” in the wallet where you want to send funds from.
Enter transaction details. Enter the address, you can also scan an address QR code. Enter the amount and select the Fee you’re willing to pay for the transaction.
Created transaction can now be signed by AirGap Vault. The transaction is now prepared, you need to sign it with AirGap Vault either by scanning the QR code or on the same device with app switching.
Sign transaction with AirGap Vault. The transaction prepared transaction is now ready to be signed in AirGap Vault.
Unlock the secret. Access the secret in the secure enclave of the AirGap Vault app by fingerprint and password.
Signed Transaction.The transaction has been signed with your secret and is ready to be broadcasted. Scan the QR with the AirGap Wallet app or broadcast it on the same device.
Confirm transaction in AirGap Wallet to broadcast. After confirming the transaction in AirGap Wallet it will be broadcasted to the blockchain.
All transactions included in the Tezos must reference a block hash within the past 60 block hashes. This acts as an additional layer of notarization of the chain, besides the consensus but it means you need a few extra steps to sign transactions offline.
One way to do this is to use the RPC:
You need a running node for this, but it doesn't have to be connected to the Internet for this. You will also need to manually provide the hash of a recent block.
You'll have to sign the data you get out of it to get a "signed operation" but, unfortunately, that is not supported in the CLI yet.
You then need to sign the operation, which you can do using the tezos cli with
./tezos-client sign bytes <bytes> for <src>
You will need to add the "03" byte in front of the operation. This acts as a watermark for the signer.
Finally you need to combine the signature and the unsigned operation, unfortunately that is not supported in the CLI yet.
Another way is to use a smart-contract that accepts signed Michelson data and takes action based on it (for instance, send funds to an address specified in the parameters). The benefit of this approach is that you do not need to know a recent hash when signing the message itself. You can just use the tezos cli with the command
./tezos-client typecheck data <data> against type <type>
./tezos-client sign bytes <data> for <src>
You will then have to send this message to the smart contract with a regular transaction, but that transaction can be performed with a key that only controls a very small amount of funds, just what is needed to pay for the transaction fee.