## Introduction

This guide shows how to use Intent Swap (Fusion mode) to perform a gasless swap from native SOL to JUP on Solana. You will use the 1inch Solana Fusion SDK to create orders and build escrow transactions. Native SOL swaps require no approval—the escrow instruction locks your SOL on-chain until the order is filled.

## Before You Start

- You must have a valid **1inch API Key**. You can get one from the [1inch Business](https://business.1inch.com/portal/applications).
- Your wallet must have:
  - SOL on Solana (swap amount plus ~0.01 SOL for transaction fees)

## Install Dependencies

Install the Solana Fusion SDK, Solana web3.js, and supporting libraries:

```bash
npm install @1inch/solana-fusion-sdk @solana/web3.js axios bs58 dotenv
```

## Set Up the Connection

Create a Solana connection using the 1inch Web3 node. Pass your API key in the `httpHeaders` for authenticated RPC access.

```typescript
import { Connection } from "@solana/web3.js";

const rpcUrl = "https://api.1inch.com/web3/501";
const connection = new Connection(rpcUrl, {
  commitment: "confirmed",
  httpHeaders: { Authorization: `Bearer ${API_KEY}` },
  wsEndpoint: `wss://api.1inch.com/web3/501?apiKey=${API_KEY}`
});
```

## Create the Wallet

Decode your private key (base58 or base64) and create a Keypair. The SDK supports both 32-byte seeds and 64-byte full keypairs.

```typescript
import { Keypair } from "@solana/web3.js";
import bs58 from "bs58";

let secretKey: Uint8Array;
try {
  secretKey = bs58.decode(PRIVATE_KEY);
} catch {
  secretKey = Buffer.from(PRIVATE_KEY, "base64");
}

let wallet: Keypair;
if (secretKey.length === 32) {
  wallet = Keypair.fromSeed(secretKey);
} else if (secretKey.length === 64) {
  wallet = Keypair.fromSecretKey(secretKey);
} else {
  throw new Error(`Invalid private key length: ${secretKey.length} bytes (expected 32 or 64)`);
}
```

## Initialize the Fusion SDK

Create the Solana Fusion SDK with an HTTP provider. The provider must implement `get` and `post` methods for API calls.

```typescript
import { Sdk } from "@1inch/solana-fusion-sdk";
import axios from "axios";

const sdk = new Sdk(
  {
    async get<T>(url: string, headers: Record<string, string>): Promise<T> {
      return (await axios.get<T>(url, { headers })).data;
    },
    async post<T>(url: string, data: unknown, headers: Record<string, string>): Promise<T> {
      return (await axios.post<T>(url, data, { headers })).data;
    }
  },
  { baseUrl: "https://api.1inch.com/fusion", authKey: API_KEY, version: "v2.0" }
);
```

## Create the Order

Call `createOrder` with the source token (`Address.NATIVE` for SOL), destination token address, amount in lamports, and maker address. The SDK returns an order object used to build the escrow transaction.

```typescript
import { Address } from "@1inch/solana-fusion-sdk";
import { LAMPORTS_PER_SOL } from "@solana/web3.js";

const JUP = "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN";

const amount = BigInt(0.01 * LAMPORTS_PER_SOL); // 0.01 SOL
const makerAddress = Address.fromPublicKey(wallet.publicKey);

const order = await sdk.createOrder(Address.NATIVE, new Address(JUP), amount, makerAddress);
```

## Build and Send the Escrow Transaction

Use `FusionSwapContract` to create the escrow instruction, add it to a Solana transaction, sign with your wallet, and broadcast. The escrow locks your SOL until a resolver fills the order.

```typescript
import { FusionSwapContract } from "@1inch/solana-fusion-sdk";
import { Transaction, PublicKey } from "@solana/web3.js";

const contract = FusionSwapContract.default();
const instruction = contract.create(order, {
  maker: makerAddress,
  srcTokenProgram: Address.TOKEN_PROGRAM_ID
});

const tx = new Transaction().add({
  programId: new PublicKey(instruction.programId.toBuffer()),
  keys: instruction.accounts.map((a) => ({
    pubkey: new PublicKey(a.pubkey.toBuffer()),
    isSigner: a.isSigner,
    isWritable: a.isWritable
  })),
  data: Buffer.from(instruction.data)
});

const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash();
tx.recentBlockhash = blockhash;
tx.lastValidBlockHeight = lastValidBlockHeight;
tx.feePayer = wallet.publicKey;
tx.sign(wallet);

// skipPreflight: true — 1inch Web3 can return "Invalid Request" on simulation
// while the transaction still broadcasts and confirms on-chain
const signature = await connection.sendRawTransaction(tx.serialize(), {
  skipPreflight: true,
  maxRetries: 3
});

const confirmation = await connection.confirmTransaction({ signature, blockhash, lastValidBlockHeight }, "confirmed");
if (confirmation.value.err) {
  throw new Error(`Transaction failed: ${JSON.stringify(confirmation.value.err)}`);
}
```

## Full Code Example

Explore the complete quick-start implementation (~120 lines) in StackBlitz:

<stackblitz example="intent-swap" file="src/solana/quick-start.ts" />

For a more comprehensive example with order tracking and error handling, see `src/solana/swap-sol-to-jup.ts` in the same project.
