AirWallet Docs

What the signer checks

Per coin, what the offline signer verifies before it signs, what it refuses, and when it asks you once more.

The offline signer signs only what it can show you completely. Everything on this page follows from that rule. The everyday wallet runs the same checks on its own sends, but the offline device's check is the one that counts.

Read the recipient, the amount and the fee on the offline screen before you select Sign. If the signer refuses something, do not look for a way around it: a refusal means it could not show you all of what you would be signing.

Fees: asked, never refused

AirWallet never refuses a fee, because a wallet that does can leave you stuck on a busy network. It warns you about a high fee and asks once more about a very high one. The signer asks again even if the online side already did, and it works out the fee from the transaction itself.

CoinWarned aboveAsked once more above
Bitcoin0.002 BTC, or 5% of the amount0.05 BTC
Ethereuma fifth of the network's limitETH 0.05 on Ethereum, 0.01 on Base, Arbitrum, Optimism and Robinhood Chain; 50 POL; 0.1 BNB; 2 AVAX
Solana0.05 SOL
Monero0.001 XMR in all, or 5% of the amount0.01 XMR in all
Zcash0.01 ZEC0.01 ZEC (the usual fee is about 0.0001)

Bitcoin

Before it signs, the signer checks that:

  • Every input is one of the signing wallet's own coins, and none appears twice.
  • Each SegWit (bc1q) coin comes with its whole previous transaction, and the amount matches. Without this, a lying online computer could hide a large fee (CVE-2020-14199). Taproot signatures cover every input's amount on their own.
  • Every output is a kind it can show you (Taproot, SegWit, script or legacy addresses). OP_RETURN notes are allowed only if they hold no bitcoin, because bitcoin put in one is burned.
  • Change goes back to the wallet's own address, worked out from its keys. The online computer's claim about which output is change is never trusted.

It refuses:

  • A lock time given as a date. A lock time as a block height is shown to you.
  • A relative time lock.
  • Transaction versions other than 1 and 2.

It also shows you each output (recipient or change) and the fee. It warns you if nothing leaves the wallet, and if one of your own addresses is far past the last one used.

Bitcoin requests from other apps

PSBTs from Sparrow and similar apps get extra checks. The signer accepts only standard signature types: SIGHASH_ALL for SegWit, and DEFAULT or ALL for Taproot. Requests are capped at 40 KB and 100 inputs or outputs. Some apps send SegWit coins without their previous transaction. For those, the signer remembers the amount each request claimed for every coin it signed. A later request that claims a different amount for one of them is refused.

Bitcoin multisig

As one cosigner of a P2WSH multisig, the signer checks a few things before it signs a coin. The coin's script must match the coin, the keys must be distinct, and this wallet's key must sit at the expected path. If the request lists the multisig's keys, every key of every input must come from that list. Without the list, it still signs, but it shows every output as a payment and says why.

Ethereum and the EVM networks

The signer builds the transaction itself from the fields it shows you, so what it shows is what it signs.

It signs only:

  • plain sends of the network's coin
  • ERC-20 token transfers
  • taking an approval back: approve(spender, 0) or turning off setApprovalForAll. This only removes a permission, and all of it is shown. On the everyday device, ⋯ → Ethereum: token approvals… → Remove makes one. For a watched wallet, the offline device signs it like any send.

It refuses:

  • giving an approval (approve, setApprovalForAll, permits)
  • transferFrom
  • any other contract call
  • creating a contract

A network AirWallet does not know is refused in its own codes. A request from MetaMask or Rabby (eth-sign-request) for an unknown network gets narrower treatment. A plain payment of its coin is signed, with the chain ID shown as "one AirWallet doesn't know". The signature is tied to that chain ID. A contract call there is refused.

For requests from MetaMask or Rabby, the request's bytes must decode to the very transaction the signer shows. Personal messages and newer transaction types (EIP-7702 and on) are refused. Typed data is refused too, except for Safe transactions (below). The review shows the transaction's number (nonce).

A send of nothing to the same wallet is how you call off a waiting transaction. The signer says so when it sees one.

Safe multisig

As one owner of a Safe, the signer reads the Safe transaction strictly. It shows payments, token transfers and the Safe's changes to itself (owners, threshold), including batches of those, line by line. Some changes are asked about once more: enabling a module, setting a guard or fallback handler, or replacing the Safe's code.

The signer refuses:

  • a delegatecall to anything but Safe's official batch contracts, which is how the Bybit theft worked
  • gas refunds
  • approvals and other contract calls
  • Safe message signatures

Solana

The signer refuses a transaction that:

  • Uses address lookup tables, because it then cannot show you all of it.
  • Contains an instruction it does not know.
  • Needs a signature from anyone but the signing wallet.
  • Closes a token account and sends what's in it to someone else.
  • Uses a durable nonce account that is not the wallet's own. A transaction signed on someone else's nonce account could be held and sent at any time later, and you could not call it off.

Token names in a scanned request come from the online computer. They are not saved on the offline device, and the review says so when one is not the name the wallet knows for that token.

Swaps

Jupiter swaps are checked end to end. The signer allows only Jupiter's shared-accounts routes, one swap, paid by the signing wallet. It also checks:

  • Jupiter's real program authority
  • no platform fee
  • slippage under 50%
  • your own token accounts on both sides
  • nothing else touched

The review shows what you pay, the least you'll get (which Jupiter's program enforces), the quote and both tokens.

Staking

The signer stakes only with stake accounts the wallet alone controls, with no lockup. It withdraws only to your own wallets. Changing a stake account's authority is refused.

Solana requests from other apps

Requests from Solflare, Backpack and other apps that use Keystone's codes are checked by the same rules. A message is shown in full and refused if it's over 4 KB.

Squads multisig

Proposals made on this device are reviewed by the same rules, with the multisig's vault as the sender. Approving or executing a proposal made elsewhere cannot be fully checked, because its contents are on the blockchain, not in the code. The signer names the proposal's number, warns you and asks once more.

Monero

Monero's own wallet library builds and signs the transfer. Before you sign, the review shows the recipients, the amounts, the fee and the change. The signer checks two things:

  • change goes only to this wallet, checked by Monero's wallet library and again by AirWallet
  • a set of several transactions is read correctly: Monero's library lists each transaction's destinations as running totals, so the signer reads what the whole set pays once

The first send from a watched wallet takes an extra round: the signer answers with its coins' "key images" (which coins are spent). After that, it's one round each time.

Zcash

The signer checks a Zcash transaction against its own keys before it signs:

  • The network upgrade (consensus branch) must be one it knows.
  • Every spend must really be this wallet's.
  • Every shielded output's encrypted note is decrypted and must be the note it commits to, so you see each recipient and amount. This includes the change.
  • Each shown address must contain its recipient.
  • Transparent inputs must be this wallet's, and transparent outputs' addresses must match their scripts.
  • The fee is computed from all of that.

It refuses:

  • Transparent inputs signed any way but SIGHASH_ALL. Other types would leave where the coins go unsigned.
  • A transparent change address or own address past index 1,000. Nobody looks that far, so coins there could be held for ransom.
  • A transaction that never expires, or stays valid more than 1,000 blocks past the last height the device has seen. Someone holding it signed could send it much later.

A payment to a transparent address carries a warning: that payment is public on the blockchain.

Signatures that cannot leak your key

A signature contains a part that looks random. A dishonest signer could choose that part to leak your key a few bits at a time, and every transaction would still look valid.

AirWallet's signatures are deterministic: the same key and transaction always give the same signature. Here is how, per coin:

  • Solana: Ed25519, deterministic by design
  • Ethereum, and Bitcoin SegWit, nested SegWit and legacy: ECDSA with RFC 6979 nonces
  • Bitcoin Taproot: BIP340 with zero extra randomness, since October 6, 2026
  • Zcash: shielded signatures take their randomness from the key, the transaction and the spend's position, and transparent ones use RFC 6979

A separate program holding the same key can therefore make each signature again. If the two match, nothing is hidden in them. AirWallet's source includes such a program for Solana, Ethereum and Bitcoin, scripts/verify_signatures.py, written apart from the wallet's own code. It asks for the phrase or key, reads nothing else and sends nothing. Run it from a copy of the source, on a computer that stays offline.

Monero's ring signatures are the exception: they cannot be re-made this way. For Monero, you trust the code, which you can read.

Codes from another version

If the offline device cannot read a code made by a different AirWallet version, it says so: "That code was made by a different version of AirWallet". It names its own build date and asks you to update both copies to the same version. It never calls the code "damaged". The same goes for network upgrades: when Zcash or Monero moves to a rule set this copy does not know, it asks you to update AirWallet on both devices.

Note

Signing for other apps' multisig (Safe, Squads, a Bitcoin multisig) and for Solflare, Backpack, Feather and Cake is new as of October 2026. It works with the codes these apps use, but has not been tested with each real app yet. See Multisig.

AirWallet documentation · updated 2026-10-15 · airwallet.tech