Fees
A payment can carry three fees, the protocol fee, Solana's network fee and the relayer's tip. Here is who pays each.
Every Solana transaction pays a network fee in SOL. A Nimbus payment can carry two more: a protocol fee, and a tip for the relayer that sends it.
The three fees
- The protocol fee is a share of the amount, paid in the token being moved. Governance sets the rates for each kind of payment and token. The SDK reads them when it prepares the payment.
- The Solana network fee is paid in SOL by whoever sends the transaction.
- The relayer's tip pays the relayer that sends a Private Send or a withdrawal. It is paid in the token being moved, and anyone can see it.
Change that comes back to your user pays no protocol fee. Neither does a merge, which only moves value between your user's own notes.
Who pays what
| Payment | Protocol fee | Network fee | Relayer's tip |
|---|---|---|---|
| Register | None | Your user's wallet | None |
| Deposit | From the amount, or on top | Your user's wallet | None by default |
| Private Send | From the amount, or on top | The relayer | The relayer's minimum |
| Withdraw | From the amount, or on top | The relayer | The relayer's minimum |
The relayer's minimum is zero while it sponsors payments. Otherwise it is the minimum its published
policy asks for. A withdrawal to a token account that does not exist yet also pays the relayer's
creation fee, unless the relayer creates it for free. You can offer more with the submitterFee
option.
Deducted or added
By default, fees are deducted: they come out of amount. Pass fees: "added" to pay them on top
instead. Here is how that plays out for Alice, in USDC:
| Alice asks to | With fees: "deducted" | With fees: "added" |
|---|---|---|
| Deposit 25 USDC | 25 USDC leaves her wallet. Her private balance grows by 25 USDC less the protocol fee. | 25 USDC leaves her wallet, and her new note holds all 25. The fee comes from USDC already in her private balance. |
| Send Bob 10 USDC | Her balance drops by 10 USDC. Bob receives 10 USDC less the fees. | Bob receives exactly 10 USDC. Her balance drops by 10 USDC plus the fees. |
| Withdraw 10 USDC | Her balance drops by 10 USDC. The address receives 10 USDC less the fees. | The address receives exactly 10 USDC. Her balance drops by 10 USDC plus the fees. |
With added, the private balance must cover the fees. If it cannot, a deposit throws
amount-unfundable. A Private Send or withdrawal returns refused with insufficient. Nothing is
sent either way.
The prepared progress stage carries the exact fees. You can show them while the proof runs.
A Token-2022 token may also keep a transfer fee of its own on the way into the pool. The protocol fee applies to what arrives.
Priority fees
When Solana is busy, a priority fee helps a transaction land sooner. Pass priorityFeeLamports to
register, deposit or refundStrandedDeposit. It is in lamports for the whole transaction, 0n
by default, and your user's wallet pays it.
A Private Send or withdrawal takes no priority fee. The relayer sends it, so the relayer decides.
Rent
Your user's first deposit of a token creates a token account for their platform wallet. Their wallet pays that account's rent.
If a deposit ever needs a refund, refundStrandedDeposit can return that rent too. Pass
closeTokenAccount: true to close the emptied account.
What this means for your app
- Show the fee before your user commits, or as soon as the
preparedstage reports it. - Pick one fee mode and say which in your UI. "You send 10, Bob gets 10" reads differently from "You send 10, Bob gets a little less".
- Expect the tip to change. It follows the relayer's policy, which can change.
Last updated