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

# Fee Abstraction: Pay Fees Without Native Gas Tokens

> Learn how SocketFi abstracts transaction fees so users can transact with USDC, USDT, or XLM — without needing to manage native gas balances.

One of the most common barriers to blockchain adoption is the requirement to hold a native gas token just to perform any action. A user who holds USDC but no XLM gets stuck before they can do anything useful. SocketFi's fee abstraction system removes this friction by allowing the smart wallet to evaluate fee requirements intelligently before each transaction — collecting fees in supported stablecoins, deferring them when the wallet has no balance, or blocking execution when the fee configuration makes it unsafe to proceed.

You don't need to implement any fee logic yourself. When you call `requestTransaction()`, the SDK automatically handles fee quoting, evaluation, and collection as part of the transaction lifecycle.

## How fee abstraction works

Before a transaction is submitted to the network, the smart wallet runs a fee evaluation pass:

```text theme={null}
Transaction ready
        │
        ▼
   Quote fee cost
        │
        ▼
 Evaluate fee preference
        │
        ▼
  Return FeeDecision
        │
   ┌────┴────────────────┐
   ▼                     ▼                     ▼
CollectNow             Defer             CannotProceed
(settle now)     (track as debt)         (blocked)
```

The outcome of this evaluation — the `FeeDecision` — determines how the transaction proceeds.

## Fee decisions

There are three possible fee decisions. SocketFi selects the appropriate one automatically based on the wallet's current state and the configured fee preference.

<CardGroup cols={1}>
  <Card title="CollectNow" icon="circle-check">
    The wallet has sufficient balance in a supported fee asset. The fee is collected immediately before execution, and the transaction proceeds normally.

    ```ts theme={null}
    {
      fee_asset: usdcAddress,
      previous_deferred_fee_in_base: 0,
      added_fee_in_base: 500000,
      total_in_base: 500000,
      total_fee_in_asset: 25
    }
    ```
  </Card>

  <Card title="Defer" icon="clock">
    The wallet has no balance in a supported fee asset, but fee deferral is allowed. The transaction proceeds and the fee obligation is recorded as a deferred balance against the wallet. The user can settle this balance in a future transaction.

    ```ts theme={null}
    {
      previous_deferred_fee: 100000,
      added_base_fee: 500000,
      updated_deferred_fee: 600000
    }
    ```

    Deferred fees accumulate over time. Once the deferred balance reaches the wallet's configured maximum, further deferral is blocked and the user must settle before transacting again.
  </Card>

  <Card title="CannotProceed" icon="circle-xmark">
    The transaction cannot proceed due to a fee configuration issue. This outcome blocks execution entirely and returns an error to your application. Common reasons include an unsupported fee asset, the calculated fee exceeding the user's configured maximum, or the deferred fee limit being reached.

    ```ts theme={null}
    {
      reason: "FeeExceedsMaximum",
      total_fee_in_asset: 250,
      max_total_fee: 100
    }
    ```
  </Card>
</CardGroup>

## FeePreference type

Users and applications can specify a fee preference to control which asset is used for fee payment and cap the maximum acceptable fee:

```ts theme={null}
interface FeePreference {
  asset: Address;         // The fee asset address (USDC, USDT, or XLM)
  max_total_fee: i128;    // Maximum fee the user is willing to pay, in the smallest unit of the asset
}
```

<Note>
  Setting `max_total_fee` protects users from unexpectedly high fees. If the calculated fee exceeds this value, the fee decision returns `CannotProceed` with reason `FeeExceedsMaximum` and the transaction is blocked. Encourage users to set a reasonable cap rather than leaving it unbounded.
</Note>

## Supported fee assets

SocketFi wallets support the following assets for fee payment:

| Asset    | Description                                        |
| -------- | -------------------------------------------------- |
| **USDC** | USD Coin — preferred stablecoin for fee settlement |
| **USDT** | Tether USD — alternative stablecoin                |
| **XLM**  | Stellar Lumens — native Stellar asset              |

If the wallet's configured fee asset isn't one of these, or the requested asset isn't supported by the wallet, the fee decision returns `CannotProceed` with reason `UnsupportedFeeAsset`.

## CannotProceed failure reasons

When a `CannotProceed` decision is returned, it includes a machine-readable reason code:

| Reason                   | Description                                                 |
| ------------------------ | ----------------------------------------------------------- |
| `UnsupportedFeeAsset`    | The requested fee asset is not supported by this wallet     |
| `FeeExceedsMaximum`      | The calculated fee exceeds the user's `max_total_fee` limit |
| `MaxDeferredFeeExceeded` | The wallet's accumulated deferred balance has hit its cap   |

## Developer guidance

For most integrations, you don't need to think about fee logic at all — `requestTransaction()` handles it automatically. However, there are a few situations where you may want to surface fee information to users:

**When a transaction is blocked by fees**, `requestTransaction()` will resolve with `success: false`. Your error handling should distinguish this from a user rejection or a contract error and provide actionable guidance (e.g., "Your wallet needs to settle a deferred fee balance before you can continue").

**When building settings UI**, you may want to expose fee asset selection and `max_total_fee` configuration so users can control their fee preferences. Surface this as a human-friendly "max fee" input rather than raw asset amounts.

**When monitoring deferred fee balances**, consider surfacing a banner or notification when a user's deferred balance is approaching its limit, so they can settle proactively rather than being blocked mid-action.

```ts theme={null}
// requestTransaction() handles all fee logic automatically
const result = await socketfi.requestTransaction({
  contractId,
  method,
  args,
});

if (!result.success) {
  // Fee failure is one possible reason — handle it alongside other failure types
  showError("Transaction could not be completed. Check your fee balance and try again.");
}
```

<Tip>
  Users don't need to understand what `CollectNow`, `Defer`, or `CannotProceed` mean. Translate fee outcomes into plain language: "Your fee of 0.025 USDC will be deducted" or "You need to settle your fee balance before continuing."
</Tip>
