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

# Set up

> Add an app fee to a transaction and disclose it before the user signs

An app fee is a fee your application charges on top of transaction execution costs. Set a rate; the user sees the quoted fee before signing, in the embedded wallet's review or in your own UI with a custom signer. App fees remain user-paid even when you sponsor gas and bridging.

`appFees.feeBps` is an integer from `0` to `10000`, where `10000` is 100%. A rate of `25` requests a 0.25% fee. The charged amount comes from the quote, not the rate alone: collection depends on the route.

<Tabs>
  <Tab title="Embedded wallet">
    ## Configure the fee

    Start with the embedded-wallet example in [Send a transaction](/transactions/multichain/send-a-transaction#send-the-transaction). It defines `wallet`, the chains, tokens, `amount`, and transfer `calls` used here.

    Add `appFees` to that request. Keep the `source` and other options from the transaction guide when your flow needs them:

    ```ts {9} theme={null}
    const result = await wallet.sendIntent({
      source: { chain: base.id, token: usdcOnBase },
      destination: {
        chain: arbitrum.id,
        token: usdcOnArbitrum,
        amount,
        calls: [...calls],
      },
      appFees: { feeBps: 25 },
    });
    ```

    To apply a default to every intent, add this option to your existing [client initialization](/wallets/embedded-wallets/accounts#initialize-the-client):

    ```ts {3} theme={null}
    const wallet = new WalletClient({
      ...clientConfig,
      appFees: { feeBps: 25 },
    });
    ```

    `clientConfig` is the provider, client ID, and sponsorship configuration from the shared setup.

    Update your existing client rather than creating a second one. Its default applies to SDK intents, batch items, the EIP-1193 provider, and wagmi when they use that client.

    Override the default with `appFees` on an individual `sendIntent` request or `sendBatchIntent` item. Use `{ feeBps: 0 }` to disable the fee for that intent; omitting `appFees` inherits the default. With neither a default nor an override, no fee is requested. Non-integer or out-of-range rates are rejected before signing.

    Keep [application authentication](/transactions/sponsorship/set-up#application-authentication-is-not-sponsorship) configured even for user-paid intents. The app JWT identifies your Rhinestone project, which receives the fee; the rate is not configured in the developer portal.

    ## Display the fee

    The [review dialog](/wallets/embedded-wallets/clear-signing) shows **App fee** as a separate charged line and includes it in the total. It is never labeled sponsored. An intent signed with a [session key](/wallets/session-keys/create-a-session) shows no review, so disclose the fee in your own UI before the user grants the session.

    ## Validate the rate

    The browser chooses the rate. For sponsored intents, add an assertion to the signer from [Sponsorship setup](/transactions/sponsorship/set-up#embedded-wallets-backend):

    ```ts {5} theme={null}
    import { createSponsorshipSigner } from "@rhinestone/wallet/server";

    export const sponsorshipSigner = createSponsorshipSigner({
      shouldSponsor: {
        appFees: (fee) => fee?.feeBps === 25,
      },
    });
    ```

    Keep your other authorization checks alongside this filter. `extensionToken()` refuses to issue a grant if the requested rate differs from `25` or is missing. Use `sponsorshipMode: "required"` when sponsorship denial must stop the flow; `disabled` does not request a sponsorship grant.

    This check authorizes the requested rate, not the amount ultimately collected. It does not enforce a fee on self-funded transactions or guarantee that a route can carry one. See [Policies and security](/transactions/sponsorship/policies-and-security#current-enforcement-boundary) for the authorization boundary.
  </Tab>

  <Tab title="Custom signer">
    ## Configure the fee

    Pass `appFees` when you prepare the transaction. This example requests 100 USDC on Arbitrum and adds a 25 basis point (0.25%) app fee:

    ```ts {13} theme={null}
    import { arbitrum, base } from "viem/chains";

    const usdcOnBase = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
    const usdcOnArbitrum = "0xaf88d065e77c8cC2239327C5EDb3A432268e5831";

    const prepared = await account.prepareTransaction({
      source: { chain: base, token: usdcOnBase },
      destination: {
        chain: arbitrum,
        token: usdcOnArbitrum,
        amount: 100_000_000n,
      },
      appFees: { feeBps: 25 },
    });
    ```

    The same `appFees` object applies to supported Solana delivery requests; keep the [Solana transaction shape](/transactions/relaying/relay-a-transaction) and inspect the quoted fee. Solana instruction execution, authority changes, and deployment do not accept app fees.

    App fees are configured per transaction, at the top level of the SDK request. In the EVM example, fund the account with enough Base USDC for the delivery and user-paid fees. Keep the account initialization from your existing wallet setup rather than creating a separate client for monetization.

    ## Display the fee

    Read the app fee from the final selected quote:

    ```ts theme={null}
    const appFeeUsd = prepared.quotes.best.cost.fees.breakdown.app.usd;

    showFeeToUser({
      label: "App fee",
      amount: appFeeUsd,
      currency: "USD",
    });
    ```

    Display the fee before the user signs. If you select or prepare a different quote, update the displayed amount because costs can change with the route.

    The full fee breakdown is available at `prepared.quotes.best.cost.fees.breakdown`. Each category includes `usd` and `sponsored`; the app fee itself is not sponsorable.
  </Tab>
</Tabs>

Next, follow [Monetize the flow](./monetize-the-flow) to understand how the fee is calculated, collected, and withdrawn.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.