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

# Quickstart

> Build your first cross-chain swap in five minutes.

Install the SDK, request a quote, sign one transaction, and track it to completion.

## Requirements

* Node 18 or later.
* A wallet holding the input token on the source chain, plus enough native gas for one transaction.
* An [ethers v6](https://docs.ethers.org/v6/)  signer connected to a provider when the source chain is EVM, or a `@solana/web3.js` connection and signing callback when it is Solana.

## Sample transaction

The steps below move **100 USDC on Arbitrum** into **SOL on Solana**. Any pair works, so substitute your own tokens and chains once the flow runs end to end.

<Steps>
  <Step title="Install the SDK">
    ```bash theme={null}
    npm install --save @mayanfinance/swap-sdk
    ```

    The SDK wraps the [Quote API](/integration/quote-api) and builds the transaction for you, which is why it is the shortest path to a working swap.
  </Step>

  <Step title="Get a quote">
    `fetchQuote` returns the routes available for the pair. By default it returns at most two, the quickest route first and the best-return route second, and when one route is both you get a single item.

    ```typescript theme={null}
    import { fetchQuote } from "@mayanfinance/swap-sdk";

    const quotes = await fetchQuote({
      amountIn64: "100000000",                                 // 100 USDC, 6 decimals
      fromChain: "arbitrum",
      fromToken: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", // USDC on Arbitrum
      toChain: "solana",
      toToken: "0x0000000000000000000000000000000000000000",   // native SOL
      slippageBps: "auto",
    });

    const quote = quotes[0];
    ```

    <Tip>
      `slippageBps: "auto"` lets Mayan set a safe level for the pair. Pass a number in basis points instead, such as `300` for 3%, when you want to control it yourself.
    </Tip>
  </Step>

  <Step title="Read the quote before you sign">
    Show the user what they are agreeing to. These are the fields that matter in a confirmation screen.

    | Field                      | What it tells you                                                   |
    | -------------------------- | ------------------------------------------------------------------- |
    | `expectedAmountOut`        | The amount the user should receive.                                 |
    | `minAmountOut`             | The floor on that amount.                                           |
    | `etaSeconds` / `clientEta` | Estimated settlement time, in seconds and as a display string.      |
    | `gasDrop`                  | Native gas delivered on the destination chain alongside the output. |
    | `type`                     | The route the order takes: `SWIFT`, `MCTP`, `FAST_MCTP`, or `WH`.   |

    <Note>
      On Swift quotes, `swiftAuctionMode` tells you how the output amount is determined. Mode `2` settles at or above `minAmountOut`, typically near `expectedAmountOut`. Mode `3` is exact-out, which means the user receives exactly `expectedAmountOut`. See [Guaranteed Price](/features/guaranteed-price) for which routes support it.
    </Note>
  </Step>

  <Step title="Execute the swap">
    The destination address belongs to the destination chain, so this example takes a Solana address even though the funds leave from Arbitrum.

    <Tabs>
      <Tab title="From EVM">
        ```typescript theme={null}
        import { swapFromEvm } from "@mayanfinance/swap-sdk";

        const tx = await swapFromEvm(
          quote,
          swapperAddress,      // wallet sending the funds; must equal signer's address
          destinationAddress,  // recipient on the destination chain
          null,                // referrerAddresses, null until you set up a referrer
          signer,              // ethers v6 Signer with a provider attached
          null,                // permit (EIP-2612), optional
          null,                // overrides (gas settings), optional
          null,                // payload, optional
        );
        ```
      </Tab>

      <Tab title="From Solana">
        ```typescript theme={null}
        import { swapFromSolana } from "@mayanfinance/swap-sdk";

        const tx = await swapFromSolana(
          quote,
          originWalletAddress,
          destinationAddress,    // recipient on the destination chain
          referrerAddresses,     // null until you set up a referrer
          signSolanaTransaction,
          connection,
        );
        ```
      </Tab>
    </Tabs>

    The user signs once on the source chain. Everything after that, including delivery on the destination chain, happens without further action from them.
  </Step>

  <Step title="Track it to completion">
    Pass the source transaction hash to the [Explorer API](/integration/explorer-api) and read `clientStatus`.

    ```typescript theme={null}
    const res = await fetch(
      `https://explorer-api.mayan.finance/v3/swap/trx/${txHash}`
    );
    const swap = await res.json();

    console.log(swap.clientStatus); // INPROGRESS, COMPLETED, or REFUNDED
    ```

    Poll until the status leaves `INPROGRESS`. Most swaps settle in seconds. `REFUNDED` means the order was not filled before its deadline and the input returned to the sender, which is covered in [Refunds](/how-mayan-works/refunds).
  </Step>
</Steps>

## Complete example

```typescript theme={null}
import { fetchQuote, swapFromEvm } from "@mayanfinance/swap-sdk";
import type { Signer, TransactionResponse } from "ethers";

const EXPLORER = "https://explorer-api.mayan.finance";

export async function swapUsdcToSol(
  signer: Signer,             // ethers v6 Signer connected to a provider
  destinationAddress: string, // a Solana address
) {
  const swapperAddress = await signer.getAddress();

  const quotes = await fetchQuote({
    amountIn64: "100000000",
    fromChain: "arbitrum",
    fromToken: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
    toChain: "solana",
    toToken: "0x0000000000000000000000000000000000000000",
    slippageBps: "auto",
  });

  const quote = quotes[0];
  if (!quote) throw new Error("No route available for this pair.");

  console.log(
    `Expecting ${quote.expectedAmountOut} SOL in about ${quote.clientEta} via ${quote.type}`
  );

  const tx = (await swapFromEvm(
    quote,
    swapperAddress,
    destinationAddress,
    null,   // referrerAddresses
    signer,
    null,   // permit
    null,   // overrides
    null,   // payload
  )) as TransactionResponse;

  // Poll until the swap reaches a terminal status.
  while (true) {
    const res = await fetch(`${EXPLORER}/v3/swap/trx/${tx.hash}`);
    const swap = await res.json();

    if (swap.clientStatus && swap.clientStatus !== "INPROGRESS") {
      return { status: swap.clientStatus, toAmount: swap.toAmount };
    }

    await new Promise((r) => setTimeout(r, 2000));
  }
}
```

## Next steps

<CardGroup cols={3}>
  <Card title="SDK" icon="cube" href="/build/sdk">
    Quotes, execution and every supported chain.
  </Card>

  <Card title="Track Transactions" icon="radar" href="/build/track-transactions">
    Status handling and what each state means for your interface.
  </Card>

  <Card title="Fees & Earning" icon="coins" href="/build/fees-earning">
    Set a referrer address and earn on every swap you route.
  </Card>
</CardGroup>
