overview
Latch is an optional second lock for a token on Solana. Every coin launched on the Latch launchpad carries it from its first block. While it's off, the coin behaves like any other. Turn it on for your balance, and your tokens can only move with a one-time code that lives on your device, not in your wallet. Anyone who gets your wallet key, by a leak or one day by AI or a quantum computer, still can't move them.
- it protects
- Your balance of the coin, from being sent or sold by anyone but you, even someone holding your wallet key.
- it never changes
- Buying. Nobody can turn the latch on for you, and nobody but you can turn it off.
getting started
- Open the coin. Go to the app, connect your wallet, and open the coin from the launchpad or by pasting its address.
- Choose a passphrase. At least 12 characters. It seals your codes in this browser and is never sent anywhere.
- Choose a backup. 24 recovery words you write down (you type three back to confirm), or an encrypted backup file. With a file, you download it first, then continue to your wallet.
- Your codes are made. Your browser makes 1,024 one-time codes in about a second. Only a fingerprint of them goes on chain, so nobody can work the codes out from it.
- Approve once. One wallet approval records the fingerprint, and the latch is on.
Costs: about 0.0014 SOL of rent for the latch record, which stays, plus network fees. Your first send or sell while latched adds about 0.02 SOL of rent for the space your code is written into; it comes back when you lift the latch.
using a latched balance
- send
- Enter your passphrase, then approve once. The page signs the transfer with your next code, uploads the code in three parts, and sends one transaction that checks it and moves the tokens, so the code is used the moment it lands.
- sell
- The same, with five transactions in one approval: three uploads, the check, and the sale into the curve. The 25%, 50%, 75% and max buttons fill in the amount from your balance.
- buy
- Never needs a code. One approval.
- renew
- 1,024 codes cover 1,023 sends or sells; the last one is kept for lifting or renewing. Renewing swaps in a fresh set while the account stays latched, and you back up the new set before anything is sent.
- lift
- Uses one more code to turn the latch off and retires your codes. Transfers are free again, and you can latch again later with fresh codes.
Each code works once, for that exact amount, that destination and that moment: an authorization expires after 750 slots, about five minutes. Codes are used in order, and one that was shown during a failed attempt is skipped, never reused.
backups and recovery
Your codes live in this browser's storage, sealed with your passphrase. Clearing the browser's data removes them, so the backup is what counts.
- 24 words
- Restore them in any browser with "restore from 24 words" in the app. They rebuild the same codes, which are checked against your latch on chain. They are not a wallet seed phrase: wallets refuse them, and the page refuses a wallet seed phrase typed in by mistake.
- backup file
- Restore it with "restore from a backup file" and its passphrase. You can download a fresh copy from the app at any time.
If your account is latched and you lose your 24 words and your backup file (or its passphrase), nobody can move those tokens or lift the latch, ever. Not you, not us. Keep the words on paper, somewhere private.
if your key leaks
- Send, don't sell. A sale pays SOL into your wallet, and whoever has your key can take it from there. Make a latched send to a fresh wallet you control instead: the send is bound to that wallet, so nobody can redirect it. Sell from the new wallet afterwards.
- Move your SOL too. The latch covers the coin, not SOL.
- Latch before it matters. The latch has to be on before anyone can forge your key. After that, someone with your key could turn on a latch of their own first.
launching a coin
On the launchpad, fill in a name (up to 32 characters), a ticker (up to 10 letters or digits), an image (PNG, JPEG, GIF or WebP, up to 512 KB) and a dev buy of 0.1 to 10 SOL. A description, website, X and Telegram link are optional.
- one approval
- One transaction creates the coin, sets up the latch, makes your dev buy and pays the 0.001 SOL upload fee for the image and metadata.
- you buy first
- The coin doesn't exist until that transaction runs, and your dev buy is inside it, so nobody can buy before you or get between the steps.
- the coin
- Its mint key is made in your browser, signs once and is thrown away. Mint and freeze authority are revoked, the name, ticker and image can never change, and there is no permanent delegate. There is no dev allocation: anything you hold, you bought.
- its image and metadata
- Stored permanently on Irys. Before you approve, the page checks the signed uploads against what you typed, byte for byte, so what gets published can only be what you saw. The image is published without its metadata (EXIF, comments, timestamps), so a photo never carries where or on what it was taken.
Launches open once $LATCH is live.
the curve
Every coin trades on a Meteora bonding curve: 1,000,000,000 tokens with 9 decimals, starting around a 42 SOL market cap.
- graduation
- At a 100,000,000 SOL market cap, about 64,770 SOL of net buying: permanent in practice. Until then the coin stays on the curve and the latch stays on.
- if it ever graduated
- The coin would move to a Meteora pool without the hook, and the latch would no longer apply to it.
- how the price moves
- About 64 SOL market cap after 10 SOL of net buying, 480 after 100, and about 25,800 after 1,000.
fees and payouts
Every buy and sell pays a 2% trading fee in SOL. Meteora, which runs the curve, takes its standard cut first, and the rest is split 50/50.
- holders
- Paid in SOL to everyone holding the coin, in proportion to how much they hold. Payouts run regularly, and small amounts add up until they are worth sending (0.001 SOL). The curve's own vault doesn't count as a holder, and each share follows the smaller of a holder's balances at two moments, so buying just before a payout gains nothing.
- latch
- Buybacks and burns.
- the launcher
- Gets no separate cut. A coin's creator earns the holders' share like everyone else, on what they hold.
security model
- what it stops
- Someone holding your wallet key, stolen, leaked or cracked, can't send or sell your latched tokens, can't lift the latch, and can't latch over it with codes of their own.
- why hashes
- Solana wallets sign with elliptic-curve keys, whose maths has the structure a quantum computer, or a shortcut found by AI, could run backwards. The latch's codes are hash-based one-time signatures over SHA-256, which has no such structure: the best known quantum attack only halves their security, leaving about 2128 work.
- its limits
- SOL isn't covered. A stolen backup gives away your codes. The latch has to be on before keys can be forged. A latched sell's authorization names the pool, not where the SOL goes, so it can be copied until it lands: if your key leaked, send, don't sell.
- the program
- It has no upgrade authority: nobody, including us, can change it. Every finding from its security reviews was replayed against it and refused.
- the site
- Your codes are made and used in your browser and never sent anywhere. The server only builds unsigned transactions, and before your wallet is asked, the page checks each one against what you typed and refuses anything else.
technical reference
technicals
a hash-based second factor, enforced by the token itself
Latch is a Token-2022 transfer-hook program. A holder opts in by committing, to a PDA seeded by their token account, the Merkle root of 2h Winternitz one-time public keys (W-OTS, w = 16, SHA-256, 67 chains; h = 10 by default). From then on, Token-2022's mid-transfer CPI into the hook requires a single-use authorization whose digest, SHA-256("qlh:xfer" ‖ mint ‖ source ‖ destination ‖ amount ‖ nonce), is recomputed from the live transfer and consumed on use. Authority over a latched balance therefore reduces to the one-wayness and second-preimage resistance of SHA-256, not to the discrete-log hardness of Ed25519. An ECDLP break, by Shor or by an undiscovered classical algorithm, yields signatures but not transfers.
- Authorization
- W-OTS signature, 2,144 B, staged in a scratch PDA and verified on chain against the committed root: at most 1,005 SHA-256 evaluations plus an h-level Merkle path, about 250k CU. Ed25519 remains a co-signer, so the scheme is hybrid, not a replacement.
- Binding
- Digest fixes mint, source, destination token account, amount and a monotonic per-account nonce. Authorizations are single use, valid only for the latest nonce, and expire after 750 slots.
- State discipline
- Leaves are consumed in strictly increasing order, with forward skips allowed so a leaf exposed by a failed attempt is never re-signed. The final leaf is reserved for Unlock and Rotate, the nonce survives re-registration, and re-registering a prior root is refused.
- Key lifecycle
- Rotate re-keys atomically under a signature over SHA-256("qlh:rotate" ‖ mint ‖ source ‖ root′ ‖ h′ ‖ nonce), with no unlatched interval. Unlock is itself W-OTS-authorized and refunds the scratch and auth rent.
- Robustness
- Every PDA is created with a top-up, allocate and assign path, so lamport pre-funding cannot block an account or a mint's extra-account-meta list. Execute rejects calls outside a live transfer via the source account's transferring flag.
- Margins and limits
- Grover's quadratic speed-up leaves about 2128 work against 256-bit preimages. Outside the model: a sell binds the pool vault, not the swap's output account, so the authorization is copyable until it lands (a latched send to a fresh wallet, then a plain sell, avoids this); the mint's hook authority sits with Meteora's DBC pool-authority PDA. The program itself has no upgrade authority.
how a latched transfer clears
- SeedGenerated on the holder's device and sealed there with a passphrase (AES-256-GCM). It never touches the chain.
- One-time keys1,024 of them derive from the seed, each a set of 67 hash chains. The holder registers only the Merkle root of their public ends, 32 bytes.
- SignatureMint, source account, destination, amount and the account's nonce are hashed into one digest. The next unused key signs it by walking its chains part way, which takes 2,144 bytes to write down. The client uploads that in three transactions.
- AuthorizeThe program walks each chain the rest of the way, hashes the ends, checks the Merkle path to the registered root, and stores the digest as a single-use authorization. At most 1,005 SHA-256 calls, about 250k compute units.
- TransferToken-2022 calls the hook in the middle of the transfer. The hook recomputes the digest from the real accounts and amount, compares it to the stored one, and burns the authorization. A different amount, a different destination, or a second use all fail. Unlatching goes through the same verification, so a forged wallet signature cannot simply lift the latch.
the signature scheme
- Scheme
- Winternitz one-time signature, w = 16, over SHA-256
- Chains
- 64 message chunks and 3 checksum chunks, 67 in all, each 15 steps long
- Signature size
- 2,144 bytes
- Keys per registration
- 1,024 by default, up to 65,536 at height 16
- Replay
- Keys are consumed strictly in order on chain, and each authorization is burned when the transfer uses it
accounts the program keeps
| Account | Seeded by | Holds |
|---|---|---|
| Latch | Token account | Owner, Merkle root, height, next leaf, nonce |
| Auth | Token account | One pending digest and nonce, single use |
| Scratch | Token account | Signature upload buffer |
| Extra metas | Mint | Tells Token-2022 to hand the latch and auth accounts to the hook |
instructions
- register
- Commits the Merkle root and height of a holder's one-time public keys to the latch account. Owner-signed; refused over an existing latch or for a key set used before.
- upload
- Writes part of a 2,144-byte one-time signature into the holder's scratch account; three uploads carry one signature.
- authorize
- Verifies the uploaded signature against the registered root for the digest of one transfer, and stores that digest as a single-use authorization.
- lift
- Removes the latch under a one-time signature, and returns the scratch and authorization rent.
- renew
- Replaces the key set under a one-time signature, with no unlatched moment in between.
- the hook
- Token-2022 calls it in the middle of every transfer. For a latched source it recomputes the digest from the live transfer, compares it to the stored authorization and uses it up; for anyone else it does nothing.
error codes
When the program refuses something, the transaction fails with one of these custom errors.
| code | name | what it means |
|---|---|---|
| 0x64 | NotAuthorized | A latched transfer without a valid authorization: no code, one already used, or a stale one. A sale or send of a latched balance from any other app fails with this. |
| 0x65 | DigestMismatch | The authorization is for a different transfer: the amount, destination or account changed. |
| 0x66 | BadHeight | The key set's size is out of range. |
| 0x67 | AlreadyLocked | The account is already latched. Lift or renew instead. |
| 0x68 | NotLocked | A lift, renew or authorization for an account that isn't latched. |
| 0x69 | WrongOwner | The signer doesn't own the token account. |
| 0x6a | WrongLeaf | That one-time key is already spent; the next one has to be used. |
| 0x6b | KeysExhausted | No codes left for a transfer: the last one is kept for lifting or renewing. |
| 0x6c | NoSignature | The uploaded signature isn't complete yet. The app waits and tries again on its own. |
| 0x6d | BadSignature | The one-time signature doesn't match the registered key set. |
| 0x6e | SameRoot | That key set was used before; register a fresh one. |
| 0x6f | AuthExpired | The authorization is older than 750 slots. |
| 0x70 | WrongMint | The token account belongs to a different coin. |
verify it yourself
You don't have to take our word for any of this. The verify section runs the published test vectors in your browser, the same file the program's tests and the client are checked against, and checks any latched transaction: your browser reads the signed bytes, rebuilds the signed message, walks the 67 hash chains and climbs the key tree to the registered root.
apps and wallets
- wallets
- Any Solana wallet that supports the Wallet Standard, such as Phantom, Backpack or Solflare. The site asks your wallet to sign only and sends the transaction itself. If the wallet's window disappears before you approve, the step offers "ask the wallet again".
- buying anywhere
- Works on any app that supports the coin. Buying never needs a code.
- selling elsewhere
- An unlatched balance sells anywhere. A latched balance only moves through the app here: on any other app the coin refuses the sale on chain (0x64), and the network fee for the attempt is still charged.
- extra warnings
- Some apps show a warning or an extra step for coins with a transfer hook. That comes from the app, not from the latch.
faq
- Does the latch change buying?
- No. Buying never needs a code, whether the latch is on or off.
- Can someone else latch or lift my tokens?
- No. Only the account's owner can turn the latch on, and turning it off takes one of your codes.
- What happens if I lose my codes?
- If you still have your 24 words or your backup file and its passphrase, restore them in the app. If you've lost both while latched, the tokens can't be moved again.
- Does it protect my SOL?
- No. Only the coin itself checks for the latch; protecting SOL would take a change to Solana.
- Why does a latched sell take five transactions?
- A one-time signature is 2,144 bytes, more than fits in one Solana transaction, so it's uploaded in three parts before the transaction that checks it and the sale itself. You still approve once.
- What if quantum computers never arrive?
- Then the latch is a seatbelt you never needed. While it's off the coin works like any other, and turning it on costs very little.
- Can I latch any token?
- Only coins that carry the Latch hook: every coin launched on the Latch launchpad.
- Has it been reviewed?
- It has been through security reviews, and every finding was fixed and replayed against the program, which refused it. The test vectors and the verify tool let you check the cryptography yourself.