# Falcon tips & transaction requirements (/falcon/tips)

> Exactly what Falcon accepts as a tip on a Solana transaction: instruction shape, allowed accounts, the 1,000,000 lamport minimum and the 1,232-byte cap.



Falcon checks every transaction before it forwards anything. Yours has to deserialize cleanly, carry as many signatures as its message header requires, fit in 1,232 bytes, and pay a tip that matches all four rules below.

## Tip selection

A tip only counts when **one top-level instruction** meets every condition at once:

| Condition   | Detail                                                                                                |
| ----------- | ----------------------------------------------------------------------------------------------------- |
| Program     | System Program                                                                                        |
| Instruction | `transfer`: the plain 8-byte-lamports transfer, not `transferWithSeed`                                |
| Recipient   | One of the [tip accounts](#amount-and-accounts), present in the transaction's **static account keys** |
| Amount      | At least 1,000,000 lamports, in one instruction                                                       |

That rules out several arrangements that look like they should work:

* **Amounts never add up.** Falcon walks the instructions in order and takes the first System transfer to an allowed tip account that already meets the minimum. Two half-sized transfers qualify as neither.
* **Address lookup tables don't work for the tip.** The recipient is matched against static account keys only.
* **A CPI tip doesn't count.** The transfer has to be an instruction in the transaction you submit, not something your program does internally.
* A tip declared in an HTTP field, a header or a client variable means nothing. Only the instruction is read.

## Amount and accounts

The minimum tip is **1,000,000 lamports (0.001 SOL)**, paid in one transfer to any of these accounts:

```text
Fa1con11xLjPddfzRwRUB16sbFZggp2JeJkCeWREyR8X
Fa1con11TM1RuAQzbQzYjTy4Ekfap9Lnc9fnEbQYEd6Q
Fa1con113Bvi76nS5AzUiRDC2fqjfzkNMUNRLgQybMYt
Fa1con1QGHJK232s8yZpzZZwqPexnAKcoyKj626LNsMv
Fa1con1zUzb6qJVFz5tNkPq1Ahm8H1qKW7Q48252QbkQ
Fa1con16d3MSwd3SAiwvr2LwgkpE7ot8zntbpuec8HAx
Fa1con1i7mpa7Qc6epYJ6r4P9AbU77DFFz173r59Df1x
Fa1con18nWn8TdAGL7JX8PertfMUGVSc899NawokJ4Bq
Fa1con1GKusK2EqsfzrDzGPaYZSxQtFGzJiRMMU9Zm2g
Fa1con1RDwVwM9VrJ53CwVefD3VU9c58EMpDawV7fLMi
```

Pick one at random per transaction: tipping the same account from everywhere makes every transaction compete for one write lock.

A JSON-RPC tip rejection comes back as `-32602 transaction does not include required tip` with `"data":{"minimumLamports":N}`. `N` is the required minimum; trust it over a hard-coded value.

## Every other requirement

| Requirement     | Rule                                                         | Failure                                                                                                   |
| --------------- | ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------- |
| Serialization   | Standard Solana transaction wire bytes, legacy or v0         | `could not deserialize transaction`                                                                       |
| Trailing bytes  | None; the buffer must end exactly where the transaction ends | `could not deserialize transaction`                                                                       |
| Size            | ≤ 1,232 serialized bytes                                     | `transaction exceeds maximum size of 1232 bytes`                                                          |
| Signatures      | At least one, and never more than 127                        | `transaction has no valid signature`                                                                      |
| Signature count | Must equal `num_required_signatures` in the message header   | `transaction signature count does not match required signatures`, with `"data":{"expected":n,"actual":n}` |

Falcon checks the signature **count**, not the signatures themselves. A partially signed transaction serialized with placeholder slots for the missing signers still carries the expected count, so Falcon forwards it and it fails on chain instead. Only a signature array that doesn't match `num_required_signatures` (or holds 0, or more than 127) is rejected here. Signatures are verified cryptographically in exactly one place: preflight simulation, which runs when you set `skipPreflight: false`.

## Add the tip in TypeScript

```typescript
import { PublicKey, SystemProgram, Transaction } from '@solana/web3.js';

const tipAccount = process.env.FALCON_TIP_ACCOUNT;
const tipLamports = Number(process.env.FALCON_MIN_TIP_LAMPORTS);

if (!tipAccount) {
  throw new Error('Set FALCON_TIP_ACCOUNT');
}
if (!Number.isSafeInteger(tipLamports) || tipLamports < 1_000_000) {
  throw new Error('FALCON_MIN_TIP_LAMPORTS must be at least 1000000');
}

const transaction = new Transaction();

// 1. Your application instructions.

// 2. The tip: a top-level System Program transfer.
transaction.add(
  SystemProgram.transfer({
    fromPubkey: payer.publicKey,
    toPubkey: new PublicKey(tipAccount),
    lamports: tipLamports,
  }),
);

// 3. Fee payer + fresh blockhash, then sign, then serialize.
```

The tip is an ordinary instruction, so the lamports only move if the transaction executes on chain.

## Symptom → cause → fix

| Symptom                                                                                                    | Cause                                                                                                                    | Fix                                                                                                    |
| ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ |
| `transaction does not include required tip` (or `SubmitError::MissingTip`) with a tip you believe is there | The transfer is below `minimumLamports`, the recipient is not one of the tip accounts, or the recipient came from an ALT | Use `data.minimumLamports`, an account from the list, and put the recipient in the static account keys |
| Tip rejected only on some transactions                                                                     | The tip was split across instructions, so no single transfer reaches the minimum                                         | Pay the whole tip in one transfer                                                                      |
| `transaction signature count does not match required signatures`                                           | A required signer is missing, or the message was edited after signing                                                    | Rebuild, sign with all signers, serialize once                                                         |
| `could not deserialize transaction: verify encoding and format`                                            | Wrong `encoding`, base64 sent as base58, or extra bytes appended                                                         | Match `encoding` to the string you send; submit the exact serialized bytes                             |
| `transaction exceeds maximum size of 1232 bytes` after adding the tip                                      | The tip pushed you over the cap                                                                                          | Drop an instruction, use an ALT for application accounts (not the tip), or split the work              |
| Nothing happens at all on UDP                                                                              | Any of the above                                                                                                         | Reproduce the same transaction over JSON-RPC to see the real reason                                    |

Per-transport response shapes are on [Falcon errors & retries](/falcon/errors).
