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

# Quickstart: Bridge Tokens Across Blockchains

> Use App Kit to bridge tokens between blockchains with a browser wallet or Circle Wallets adapter

Bridge USDC between blockchains with the wallet model that matches your
application. Use a browser wallet when the end user signs in the client, or use
Circle Wallets when you manage developer-controlled wallets through Circle.

<Tabs>
  <Tab title="Browser wallet">
    Use this flow to bridge USDC from a browser wallet. The wallet runs in the
    browser, and the user signs transactions in the wallet extension, so connect the
    wallet first and call `kit.bridge()` only after the wallet is available.

    This example uses the
    [Viem adapter](https://www.npmjs.com/package/@circle-fin/adapter-viem-v2) to
    bridge between two EVM-compatible blockchains in an existing browser app. The
    sample configuration uses Ethereum Sepolia and Arc Testnet, but you can use any
    [supported EVM chains](/app-kit/references/supported-blockchains) as the source
    or destination.

    ## Prerequisites

    Before you begin, ensure that you have:

    * Installed [Node.js v22+](https://nodejs.org/).
    * Installed a browser wallet such as [MetaMask](https://metamask.io/) and added
      the [Ethereum Sepolia](https://chainlist.org/chain/11155111) and
      [Arc Testnet](https://docs.arc.network/arc/references/connect-to-arc#wallet-setup)
      networks.
    * Funded your wallet with testnet USDC from the
      [Circle Faucet](https://faucet.circle.com/).
    * Funded your wallet with ETH for Ethereum Sepolia from a
      [public faucet](https://www.alchemy.com/faucets/ethereum-sepolia).

    ## Step 1. Set up the project

    ### 1.1. Create the project and install dependencies

    Create a new directory, install the App Kit packages, and add local browser demo
    tooling:

    ```bash Shell theme={null}
    # Set up your directory and initialize a Node.js project
    mkdir app-kit-bridge-browser-wallet
    cd app-kit-bridge-browser-wallet
    npm init -y
    npm pkg set type=module

    # Install App Kit packages
    npm install @circle-fin/app-kit @circle-fin/adapter-viem-v2 viem

    # Install TypeScript and a local Vite dev server for the browser demo
    npm install --save-dev typescript vite
    ```

    <Tip>
      Only need to bridge and want a lighter install than the full App Kit SDK?
      Install the standalone Bridge Kit instead: `@circle-fin/bridge-kit`
    </Tip>

    ### 1.2. Configure TypeScript (optional)

    <Info>
      This step is optional. It helps prevent missing types in your IDE or editor.
    </Info>

    Create a `tsconfig.json` file:

    ```bash Shell theme={null}
    npx tsc --init
    ```

    Then, update the `tsconfig.json` file:

    ```bash Shell theme={null}
    cat <<'EOF' > tsconfig.json
    {
      "compilerOptions": {
        "target": "ESNext",
        "module": "ESNext",
        "moduleResolution": "bundler",
        "strict": true,
        "types": ["node"]
      }
    }
    EOF
    ```

    ## Step 2. Connect a browser wallet

    This step shows the core browser wallet integration flow: discover an
    [`EIP-6963`](https://eips.ethereum.org/EIPS/eip-6963) provider, create an App
    Kit adapter from the selected provider, and pass that adapter into an App Kit
    SDK method.

    The snippets below keep wallet discovery, wallet connection, and adapter setup
    in small helper functions for readability.

    ### 2.1. Discover a browser wallet with `EIP-6963`

    <Info>
      This pattern is standards-based. The example uses MetaMask as the selected
      wallet, but the discovery flow works with any wallet that announces an
      `EIP-6963` provider.
    </Info>

    ```typescript TypeScript theme={null}
    import type { EIP1193Provider } from "viem";

    type EIP6963ProviderInfo = {
      uuid: string;
      name: string;
      icon: string;
      rdns: string;
    };

    type EIP6963ProviderDetail = {
      info: EIP6963ProviderInfo;
      provider: EIP1193Provider;
    };

    declare global {
      interface WindowEventMap {
        "eip6963:announceProvider": CustomEvent<EIP6963ProviderDetail>;
      }
    }

    async function discoverBrowserWallets(): Promise<EIP6963ProviderDetail[]> {
      const providers = new Map<string, EIP6963ProviderDetail>();

      const handleProviderAnnouncement = (
        event: WindowEventMap["eip6963:announceProvider"],
      ) => {
        providers.set(event.detail.info.uuid, event.detail);
      };

      window.addEventListener(
        "eip6963:announceProvider",
        handleProviderAnnouncement,
      );
      window.dispatchEvent(new Event("eip6963:requestProvider"));

      await new Promise((resolve) => window.setTimeout(resolve, 250));
      window.removeEventListener(
        "eip6963:announceProvider",
        handleProviderAnnouncement,
      );

      return [...providers.values()];
    }
    ```

    ### 2.2. Connect the wallet and request account access

    After you select a provider, request account access before attempting to bridge.
    This should happen in a user-triggered action such as a `Connect wallet` button.

    ```typescript TypeScript theme={null}
    async function connectWallet(provider: EIP1193Provider) {
      await provider.request({
        method: "eth_requestAccounts",
        params: undefined, // Required by the provider type even though this method has no params.
      });

      const accounts = (await provider.request({
        method: "eth_accounts",
        params: undefined, // Required by the provider type even though this method has no params.
      })) as string[];

      return {
        connectedAddress: accounts[0] ?? null,
      };
    }
    ```

    <Tip>
      Keep wallet connection and bridging as separate user actions. This avoids
      overlapping wallet permission or chain-switch requests while a previous wallet
      prompt is still pending.
    </Tip>

    ### 2.3. Create a Viem adapter from the selected wallet provider

    Use the discovered provider to request account access, then create the App Kit
    adapter that signs bridge transactions in the browser:

    ```typescript TypeScript theme={null}
    import { createViemAdapterFromProvider } from "@circle-fin/adapter-viem-v2";

    async function connectBrowserWallet() {
      const providers = await discoverBrowserWallets();
      const selectedWallet =
        providers.find(
          ({ info }) => info.rdns === "io.metamask" || info.name === "MetaMask",
        ) ?? providers[0];

      if (!selectedWallet) {
        throw new Error("No EIP-6963 browser wallet found");
      }

      const { connectedAddress } = await connectWallet(selectedWallet.provider);

      const adapter = await createViemAdapterFromProvider({
        provider: selectedWallet.provider,
      });

      return {
        adapter,
        connectedAddress,
        walletName: selectedWallet.info.name,
      };
    }
    ```

    <Tip>
      If multiple EVM wallets are installed, explicitly choose the wallet you want to
      use instead of relying on the first announced provider. The browser demo used to
      validate this quickstart prefers MetaMask when it is available.
    </Tip>

    ## Step 3. Bridge USDC

    ### 3.1. Pass the browser wallet adapter into `kit.bridge()`

    This is the only App Kit-specific bridge call you need after the wallet is
    connected:

    ```typescript TypeScript theme={null}
    import { AppKit } from "@circle-fin/app-kit";

    const kit = new AppKit();

    async function bridgeUSDCWithBrowserWallet() {
      const { adapter, connectedAddress, walletName } =
        await connectBrowserWallet();

      let result = await kit.bridge({
        from: { adapter, chain: "Ethereum_Sepolia" },
        to: { adapter, chain: "Arc_Testnet" },
        amount: "1.00",
      });

      if (result.state === "error") {
        result = await kit.retryBridge(result, {
          from: adapter,
          to: adapter,
        });
      }

      console.log(`Submitted bridge with ${walletName}`, {
        connectedAddress,
        result,
      });
      return result;
    }
    ```

    Download the runnable
    [browser demo](https://github.com/circlefin/docs-examples/tree/master/app-kit-bridge-evm)
    to see the EVM-to-EVM bridge flow in action.

    ### 3.2. Observe bridge lifecycle events

    To inspect the bridge flow while it runs, subscribe to Bridge Kit events before
    you call `kit.bridge()`. This is useful for seeing the runtime step order and
    payload shape. The companion browser demos render these events into an on-page
    `<pre>` element, but logging them to the console is enough for the core
    integration.

    ```typescript TypeScript theme={null}
    kit.on("*", (payload) => {
      console.log("Action:", payload);
    });
    ```

    <Info>
      Using other EVM chains? Change the `chain` values in `kit.bridge()` and ensure
      the connected wallet holds USDC on the source chain and enough gas to complete
      the transfer flow.
    </Info>

    <Tip>
      You can customize your bridges to
      [collect a fee](/app-kit/tutorials/bridge/collect-bridge-fee), use the
      [Forwarding Service](/app-kit/tutorials/bridge/use-forwarding-service), or
      [estimate gas and provider fees](/app-kit/tutorials/bridge/estimate-costs)
      before bridging. Proceed only if the cost works for you.
    </Tip>

    ### 3.3. Verify the transaction

    After `kit.bridge()` resolves, inspect the returned `steps` array. Each
    transaction step includes an `explorerUrl`. Use those links to confirm the
    approve, burn, and mint steps for the amount you bridged.

    The following code is an example of how an `approve` event might look in the
    browser console after a successful bridge. The values are examples only and are
    not a real transaction:

    ```text Browser console theme={null}
    Event received: {
      protocol: "cctp",
      version: "v2",
      traceId: "550afd44ba4c6d1d1bf4880b9ded3840",
      values: {
        name: "approve",
        state: "success",
        txHash: "0xdeadbeefcafebabe1234567890abcdef1234567890abcdef1234567890abcd",
        data: {
          txHash:
            "0xdeadbeefcafebabe1234567890abcdef1234567890abcdef1234567890abcd",
          status: "success",
          cumulativeGasUsed: 17138643n,
          gasUsed: 38617n,
          blockNumber: 8778959n,
          blockHash:
            "0xbeadfacefeed1234567890abcdef1234567890abcdef1234567890abcdef12",
          transactionIndex: 173,
          effectiveGasPrice: 1037232n,
        },
        explorerUrl:
          "https://testnet.arcscan.app/tx/0xdeadbeefcafebabe1234567890abcdef1234567890abcdef1234567890abcd",
      },
      method: "approve",
    }
    ```

    ## Extend: Add a Solana source wallet

    If you want a Solana browser wallet as the source, keep the EVM destination
    adapter from the browser wallet flow above and add a Solana source adapter. The
    examples use Solana Devnet and Arc Testnet, but you can use Solana and any
    [supported EVM chain](/app-kit/references/supported-blockchains) as the
    destination.

    In this browser wallet flow, both wallets run in the browser and the user signs
    transactions in wallet extensions. Treat wallet connection and bridging as
    separate user actions: connect the destination EVM wallet first, connect the
    Solana source wallet second, then call `kit.bridge()` after both adapters are
    available.

    ### Additional prerequisites

    Before you begin, ensure that you have:

    * Worked through the EVM browser wallet flow above first. This Solana path adds
      a Solana source wallet to that same browser-wallet pattern.
    * Installed a Solana browser wallet that exposes `window.solana`.
    * Funded your Solana wallet with testnet USDC from the
      [Circle Faucet](https://faucet.circle.com/).
    * Funded your Solana wallet with SOL for Solana Devnet transaction fees from the
      [Solana Faucet](https://faucet.solana.com/).

    ### Add the Solana dependencies

    Add the Solana adapter dependency to the same project:

    ```bash Shell theme={null}
    npm install @circle-fin/app-kit @circle-fin/adapter-solana @circle-fin/adapter-viem-v2 viem
    ```

    ### Connect the Solana source wallet

    This step extends the EVM browser wallet flow by adding a Solana source wallet.
    You will connect the Solana wallet, create a Solana source adapter, keep the EVM
    destination adapter, and pass both adapters into `kit.bridge()`.

    The snippets below keep each part of the flow in small helper functions for
    readability. The companion browser demo wires this same sequence through
    `handleEvmConnect()`, `handleSolanaConnect()`, and `handleBridge()` in a
    runnable UI.

    #### Connect the Solana wallet and request account access

    <Info>
      This pattern assumes a Solana browser wallet that exposes `window.solana`. Keep
      wallet connection and bridging as separate user actions so the wallet is fully
      connected before you attempt the bridge. The destination EVM wallet should
      already be connected by the time you add the Solana source wallet.
    </Info>

    ```typescript TypeScript theme={null}
    import type { CreateSolanaAdapterFromProviderParams } from "@circle-fin/adapter-solana";

    type SolanaWalletProvider = CreateSolanaAdapterFromProviderParams["provider"];

    declare global {
      interface Window {
        solana?: SolanaWalletProvider;
      }
    }

    async function connectSolanaWallet(provider: SolanaWalletProvider) {
      const connection = await provider.connect();

      return {
        connectedAddress:
          connection.publicKey?.toString() ??
          provider.publicKey?.toString() ??
          null,
      };
    }
    ```

    #### Keep the EVM destination adapter and add a Solana source adapter

    This Solana path builds on the EVM browser wallet flow above. Reuse the
    connected EVM wallet provider from that flow, then add a Solana provider and
    create one adapter for each chain:

    ```typescript TypeScript theme={null}
    import { createViemAdapterFromProvider } from "@circle-fin/adapter-viem-v2";
    import { createSolanaAdapterFromProvider } from "@circle-fin/adapter-solana";
    import type { EIP1193Provider } from "viem";

    async function createBridgeAdapters(
      evmProvider: EIP1193Provider,
      solanaProvider: SolanaWalletProvider,
    ) {
      const evmAdapter = await createViemAdapterFromProvider({
        provider: evmProvider,
      });

      const solanaAdapter = await createSolanaAdapterFromProvider({
        provider: solanaProvider,
      });

      return {
        evmAdapter,
        solanaAdapter,
      };
    }
    ```

    #### Pass the browser wallet adapters into `kit.bridge()`

    After you have a connected EVM provider from the earlier browser-wallet flow and
    a connected Solana provider from `window.solana`, create both adapters and pass
    them into `kit.bridge()`:

    ```typescript TypeScript theme={null}
    import { AppKit } from "@circle-fin/app-kit";
    import type { EIP1193Provider } from "viem";

    const kit = new AppKit();

    async function bridgeUSDCWithSolanaBrowserWallet(
      evmProvider: EIP1193Provider,
      solanaProvider: SolanaWalletProvider,
    ) {
      const { evmAdapter, solanaAdapter } = await createBridgeAdapters(
        evmProvider,
        solanaProvider,
      );

      const result = await kit.bridge({
        from: { adapter: solanaAdapter, chain: "Solana_Devnet" },
        to: { adapter: evmAdapter, chain: "Arc_Testnet" },
        amount: "1.00",
      });

      console.log(
        "Submitted bridge from Solana browser wallet to EVM destination",
        {
          result,
        },
      );

      return result;
    }
    ```

    #### Retry a failed bridge attempt

    If the first bridge attempt returns `state: "error"`, retry it with the same
    freshly created adapters:

    ```typescript TypeScript theme={null}
    let result = await kit.bridge({
      from: { adapter: solanaAdapter, chain: "Solana_Devnet" },
      to: { adapter: evmAdapter, chain: "Arc_Testnet" },
      amount: "1.00",
    });

    if (result.state === "error") {
      result = await kit.retryBridge(result, {
        from: solanaAdapter,
        to: evmAdapter,
      });
    }
    ```

    Download the runnable
    [browser demo](https://github.com/circlefin/docs-examples/tree/master/app-kit-bridge-solana)
    to see the Solana-to-EVM bridge flow in action.

    #### Observe bridge lifecycle events

    If you added the `kit.on("*", (payload) => { ... })` listener in the previous
    step, it already captures Solana bridge events, and no additional subscription
    is needed.

    ```typescript TypeScript theme={null}
    kit.on("*", (payload) => {
      console.log("Action:", payload);
    });
    ```

    <Info>
      Using a different EVM chain as the destination? Change the `to.chain` value and
      ensure the connected Solana wallet holds USDC on the source chain and enough
      native gas to complete the transfer flow.
    </Info>

    <Tip>
      You can customize your bridges to
      [collect a fee](/app-kit/tutorials/bridge/collect-bridge-fee), use the
      [Forwarding Service](/app-kit/tutorials/bridge/use-forwarding-service), or
      [estimate gas and provider fees](/app-kit/tutorials/bridge/estimate-costs)
      before bridging. Proceed only if the cost works for you.
    </Tip>

    #### Verify the transaction

    After `kit.bridge()` resolves, inspect the returned `steps` array. Each
    transaction step includes an `explorerUrl`. Use those links to confirm the burn,
    attestation, and mint steps for the amount you bridged.

    The following code is an example of how a `burn` step might look in the browser
    console after a successful bridge. The values are examples only and are not a
    real transaction:

    ```text Browser console theme={null}
    steps: [
      {
        name: "burn",
        state: "success",
        txHash: "5UfgJ5vVZxUxefDGqzqkVLHzHxVTyYH9StYyHKSNc7WLyFTmgL5RFGujWNqEbUBdNKRkHmx7ZRQR3FVhdEwxKHm",
        data: {
          txHash:
            "5UfgJ5vVZxUxefDGqzqkVLHzHxVTyYH9StYyHKSNc7WLyFTmgL5RFGujWNqEbUBdNKRkHmx7ZRQR3FVhdEwxKHm",
          status: "success",
          blockNumber: 312456789n,
          blockHash: "HxVTyYH9StYyHKSNc7WLyFTmgL5RFGujWNqEbUBdNK",
          transactionIndex: 0,
          gasUsed: 25000n,
          cumulativeGasUsed: 0n,
          effectiveGasPrice: 5000n,
          explorerUrl:
            "https://solscan.io/tx/5UfgJ5vVZxUxefDGqzqkVLHzHxVTyYH9StYyHKSNc7WLyFTmgL5RFGujWNqEbUBdNKRkHmx7ZRQR3FVhdEwxKHm?cluster=devnet",
        },
      },
    ];
    ```
  </Tab>

  <Tab title="Circle Wallets">
    Bridge USDC between blockchains using the Circle Wallets adapter. The examples
    use Solana Devnet and Arc Testnet, but you can use any blockchain the Circle
    Wallets adapter [supports](/app-kit/references/supported-blockchains) as the
    source or destination.

    ## Prerequisites

    Before you begin, ensure that you have:

    * Installed [Node.js v22+](https://nodejs.org/).
    * Obtained a
      [Circle API Key](https://developers.circle.com/w3s/circle-developer-account#creating-an-api-key-for-developer-services)
      and
      [Entity Secret](https://developers.circle.com/wallets/dev-controlled/register-entity-secret)
      from the
      [Circle Console](https://developers.circle.com/w3s/circle-developer-account).
    * Created developer-controlled wallets on Arc Testnet and Solana Devnet using
      the Circle Console.
    * Funded your Arc Testnet wallet with testnet USDC from the
      [Circle Faucet](https://faucet.circle.com/).
    * Funded your Solana Devnet wallet with testnet USDC from the
      [Circle Faucet](https://faucet.circle.com/).
    * Funded your Solana Devnet wallet with SOL for transaction fees from the
      [Solana Faucet](https://faucet.solana.com/).

    ## Step 1. Set up the project

    ### 1.1. Create the project and install dependencies

    Create a new directory and install the App Kit SDK with the Circle Wallets
    adapter and supporting tools:

    ```bash theme={null}
    # Set up your directory and initialize a Node.js project
    mkdir app-kit-bridge-circle-wallets
    cd app-kit-bridge-circle-wallets
    npm init -y
    npm pkg set type=module

    # Set up module type and start command
    npm pkg set scripts.start="tsx --env-file=.env index.ts"

    # Install runtime dependencies
    npm install @circle-fin/app-kit @circle-fin/adapter-circle-wallets tsx

    # Install dev dependencies
    npm install --save-dev typescript @types/node
    ```

    <Tip>
      Only need to bridge and want a lighter install than the full App Kit SDK?
      Install the standalone Bridge Kit instead: `@circle-fin/bridge-kit`
    </Tip>

    ### 1.2. Configure TypeScript (optional)

    <Info>
      This step is optional. It helps prevent missing types in your IDE or editor.
    </Info>

    Create a `tsconfig.json` file:

    ```bash Shell theme={null}
    npx tsc --init
    ```

    Then, update the `tsconfig.json` file:

    ```bash Shell theme={null}
    cat <<'EOF' > tsconfig.json
    {
      "compilerOptions": {
        "target": "ESNext",
        "module": "ESNext",
        "moduleResolution": "bundler",
        "strict": true,
        "types": ["node"]
      }
    }
    EOF
    ```

    ### 1.3. Set environment variables

    Create an `.env` file in the project directory:

    ```bash Shell theme={null}
    touch .env
    ```

    Add your credentials. Replace `YOUR_API_KEY` with your Circle Developer API key,
    `YOUR_ENTITY_SECRET` with your entity secret (64 lowercase alphanumeric
    characters), and `YOUR_EVM_WALLET_ADDRESS` and `YOUR_SOLANA_WALLET_ADDRESS` with
    the wallet addresses you control through Circle Wallets. You can fetch the
    addresses from the
    [Circle Developer Console](https://developers.circle.com/w3s/circle-developer-account)
    or the
    [list wallets](https://developers.circle.com/api-reference/wallets/developer-controlled-wallets/get-wallets)
    endpoint:

    ```text .env theme={null}
    CIRCLE_API_KEY=YOUR_API_KEY
    CIRCLE_ENTITY_SECRET=YOUR_ENTITY_SECRET
    EVM_WALLET_ADDRESS=YOUR_EVM_WALLET_ADDRESS
    SOLANA_WALLET_ADDRESS=YOUR_SOLANA_WALLET_ADDRESS
    ```

    <Tip>
      Edit `.env` files in your IDE or editor so credentials are not leaked to your
      shell history.
    </Tip>

    ## Step 2. Bridge USDC

    ### 2.1. Create the script

    Create an `index.ts` file in the project directory and add the following code.
    This code sets up your script and bridges 1 USDC from Arc Testnet to Solana
    Devnet.

    <Info>
      Using a different blockchain as the source or destination? Change the `chain`
      values in `kit.bridge()` and ensure the source wallet has USDC. For this example
      that means keeping extra USDC on Arc Testnet for gas and SOL on Solana Devnet
      for Solana transaction fees.
    </Info>

    ```typescript TypeScript theme={null}
    // Import the App Kit SDK and the Circle Wallets adapter
    import { AppKit } from "@circle-fin/app-kit";
    import { createCircleWalletsAdapter } from "@circle-fin/adapter-circle-wallets";

    const kit = new AppKit();

    kit.on("*", (payload) => {
      console.log("Event received:", payload);
    });

    const adapter = createCircleWalletsAdapter({
      apiKey: process.env.CIRCLE_API_KEY!,
      entitySecret: process.env.CIRCLE_ENTITY_SECRET!,
    });

    console.log("---------------Starting Bridging---------------");

    const result = await kit.bridge({
      from: {
        adapter,
        chain: "Arc_Testnet",
        address: process.env.EVM_WALLET_ADDRESS!,
      },
      to: {
        adapter,
        chain: "Solana_Devnet",
        address: process.env.SOLANA_WALLET_ADDRESS!,
      },
      amount: "1",
    });

    console.dir(result, { depth: null, colors: true });
    ```

    <Tip>
      You can customize your bridges to
      [collect a fee](/app-kit/tutorials/bridge/collect-bridge-fee), use the
      [Forwarding Service](/app-kit/tutorials/bridge/use-forwarding-service), or
      [estimate gas and provider fees](/app-kit/tutorials/bridge/estimate-costs)
      before bridging. Proceed only if the cost works for you.
    </Tip>

    ### 2.2. Run the script

    Save the `index.ts` file and run the script in your terminal:

    ```bash Shell theme={null}
    npm run start
    ```

    ### 2.3. Verify the transaction

    As the bridge runs, the event listener logs `approve`, `burn`,
    `fetchAttestation`, and `mint` progress to the terminal. For transaction-backed
    steps, use `values.explorerUrl` from the event payload to open the Arc Testnet
    or Solana Devnet explorer and confirm the transfer.

    After the script finishes, inspect the final `result.steps` array. Each
    transaction step includes its own `explorerUrl`, which you can use to confirm
    the amount you bridged and the chain where that step executed.

    The following code is an example of how an `approve` event might look in the
    terminal output. The values are used in this example only and are not a real
    transaction:

    ```text Terminal output theme={null}
    Event received: {
      protocol: "cctp",
      version: "v2",
      traceId: "550afd44ba4c6d1d1bf4880b9ded3840",
      values: {
        name: "approve",
        state: "success",
        txHash: "0xb4a6efb91a3a714822185b9310e54d0806040d38ef1b5282a9279522f09e6ccd",
        data: {
          txHash: "0xb4a6efb91a3a714822185b9310e54d0806040d38ef1b5282a9279522f09e6ccd",
          status: "success",
          cumulativeGasUsed: 706909n,
          gasUsed: 38596n,
          blockNumber: 42852493n,
          blockHash: "0xdb5e8026f29ffd7d7cad14e7afcc04b3287981767bf406be2e21f3c559ced13d",
          transactionIndex: 6,
          effectiveGasPrice: 22000000000n,
        },
        explorerUrl:
          "https://testnet.arcscan.app/tx/0xb4a6efb91a3a714822185b9310e54d0806040d38ef1b5282a9279522f09e6ccd",
      },
      method: "approve",
    }
    ```
  </Tab>
</Tabs>
