> ## Documentation Index
> Fetch the complete documentation index at: https://docs.buckspay.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Gasless on Stellar

> How Stellar's native account-abstraction primitives make the payer's XLM balance irrelevant.

Stellar has two orthogonal mechanisms that together make a payment genuinely gasless for the
end user. Understanding them clarifies why Buckspay needs no fee-abstraction layer bolted on
from the outside - it uses what the protocol already provides.

## Sponsor fee-bump and sponsored reserves

Every Stellar transaction consumes a small XLM fee, and every account must maintain a minimum
XLM reserve to exist on-chain. Normally that burden falls on the account owner. Stellar's
**fee-bump** transaction wraps a signed inner transaction with an outer envelope that designates
a different account - the *sponsor* - as the fee source. The ledger debits the sponsor, not
the inner-transaction signer.

The same sponsor pattern applies to **reserves**: when an account or trustline is created
inside a `BEGIN_SPONSORING_FUTURE_RESERVES` / `END_SPONSORING_FUTURE_RESERVES` sandwich,
the reserve is charged to the sponsor's balance, not the new account's.

<Note>
  The payer needs zero XLM - not to send a payment, and not even to appear on-chain for the
  first time. Buckspay's facilitator is the sponsor for both the fee and the reserve.
</Note>

In Buckspay's sponsored mode the user signs **only** the `SorobanAuthorizationEntry` for their
payment. The facilitator wraps that authorization in a fee-bump transaction, sources the XLM
fee, and submits to the network. The user's account balance is never consulted for fees.

## `__check_auth` for contract accounts

Classic Stellar accounts (`G...`) authenticate via Ed25519 - the network verifies the signature
directly. Contract accounts (`C...`) follow a different path: the network calls the contract's
`__check_auth` entry point with the authorization payload and the signature(s), and the
contract decides whether to accept or reject.

This is Soroban's **custom authentication** hook. Buckspay uses an OpenZeppelin Smart Account
contract whose `__check_auth` implementation verifies a **secp256r1 (WebAuthn) signature**
on-chain. That is what makes passkey-based accounts possible on Stellar: the private key never
leaves the user's authenticator, and the secp256r1 check runs inside the contract, settled by
the ledger.

## Putting them together

For a passkey account payment:

1. The browser calls `prepare()`, which simulates the Soroban call and records the
   authorization entries.
2. The user's authenticator signs the authorization entry (secp256r1 via WebAuthn).
3. `send()` (via the BFF) hands the signed intent to the facilitator.
4. The facilitator wraps the transaction in a fee-bump and submits - the contract's
   `__check_auth` validates the passkey signature on-chain; the sponsor covers the fee.

The result: the user taps an authenticator prompt and the payment settles. No seed phrases,
no XLM balance, no transaction approval dialog.

```ts theme={null}
// Gasless modes - v1 ships exactly one: sponsored. The facilitator's sponsor account
// pays the XLM fee; the payer needs zero XLM.
import type { GasConfig } from "@buckspay/core";

export const sponsored: GasConfig = { mode: "sponsored" };

// Roadmap (NOT available in v1 - do not pass these):
//   { mode: "token", token: "USDC:GA5..." }  // pay gas in USDC via FeeForwarder
//   { mode: "self" }                          // payer pays their own fee
// The GasConfig type only admits `{ mode: "sponsored" }` today, so an unimplemented
// mode fails to type-check - the docs can't drift into an unsupported config.
```

## Next

<CardGroup cols={2}>
  <Card title="Account models" href="/concepts/account-models">
    Classic G-addresses vs. passkey smart-contract accounts.
  </Card>

  <Card title="Prepare -> Sign -> Send" href="/concepts/prepare-sign-send">
    The three-phase flow every Buckspay payment follows.
  </Card>
</CardGroup>
