> ## Documentation Index
> Fetch the complete documentation index at: https://garden-e60e7dd0-chore-update-preview.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

<Steps>
  <Step title="Prerequistes">
    This guide assumes that you have completed the [Setup](/developers/sdk/nodejs/setup) guide.
  </Step>

  <Step title="Initialize wallets and providers">
    <Tip>
      Initialize wallets and providers only for the chains you need.
    </Tip>

    ```ts
    import {
        BitcoinProvider,
        BitcoinNetwork,
        BitcoinWallet,
    } from '@catalogfi/wallets';
    import { createWalletClient, http } from 'viem';
    import { privateKeyToAccount } from 'viem/accounts';
    import { arbitrumSepolia } from 'viem/chains';
    import { RpcProvider, Account } from 'starknet';

    // Ethereum wallet setup
    const ethereumAccount = privateKeyToAccount('<YOUR_EVM_PRIVATE_KEY>');
    const ethereumWalletClient = createWalletClient({
    ethereumAccount,
    chain: arbitrumSepolia,
    transport: http(),
    });

    // Starknet wallet setup
    const starknetProvider = new RpcProvider(); // Using default RPC URL
    const starknetWallet = new Account(
        starknetProvider,
        '<YOUR_STARKNET_ADDRESS>',
        '<YOUR_STARKNET_PRIVATE_KEY>',
    );

    // Solana wallet setup
    const solanaPrivKeyBytes = new Uint8Array('<YOUR_SOLANA_PRIVATE_KEY_BYTES>');
    const solanaUser = web3.Keypair.fromSecretKey(solanaPrivKeyBytes);
    const solanaConnection = new web3.Connection(RPC_URL, { commitment: 'confirmed' });
    const solanaWallet = new anchor.Wallet(solanaUser);
    const solanaProvider = new anchor.AnchorProvider(solanaConnection, solanaWallet);
    ```
  </Step>

  <Step title="Configure Garden instance">
    <Tip>
      A digest key is a 32-byte key that serves as a unique identifier, used for generating secrets (preimages for HTLCs). It functions as a Garden account, but it is strictly non-custodial, with no funds ever being associated with it or moved through it.
    </Tip>

    <Tabs>
      <Tab title="Default wallet clients">
        ```js
        import { Garden } from '@gardenfi/core';
        import { Environment, DigestKey } from '@gardenfi/utils';

        const digestKey = DigestKey.from('<YOUR_DIGEST_KEY>');

        const garden = Garden.fromWallets({
            environment: Environment.TESTNET,
            digestKey: digestKey.val,
            wallets: {
                evm: ethereumWalletClient,
                starknet: starknetWallet,
                solana: solanaProvider,
            }
        });
        ```
      </Tab>

      <Tab title="Custom client configuration">
        <Note>
          You can initialize the Garden instance with your own HTLC client implementations. Check out the [IEVMHTLC](https://github.com/gardenfi/garden.js/blob/main/packages/core/src/lib/evm/htlc.types.ts), [IStarknetHTLC](https://github.com/gardenfi/garden.js/blob/main/packages/core/src/lib/starknet/starknetHTLC.types.ts), and [ISolanaHTLC](https://github.com/gardenfi/garden.js/blob/main/packages/core/src/lib/solana/htlc/ISolanaHTLC.ts) interfaces for more details.
        </Note>

        ```js
        import { Garden } from '@gardenfi/core';
        import { Environment } from '@gardenfi/utils';

        const garden = new Garden({
            environment: Environment.TESTNET,
            digestKey: digestKey.val,
            htlc: {
                evm: <IEVMHTLC>,
                starknet: <IStarknetHTLC>,
                solana: <ISolanaHTLC>,
            },
        });
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="Create a swap">
    ```js
    import { Quote, SwapParams } from '@gardenfi/core';
    import { Asset, SupportedAssets } from '@gardenfi/orderbook';

    const fromAsset = SupportedAssets.testnet.ethereum_sepolia_WBTC;
    const toAsset = SupportedAssets.testnet.bitcoin_testnet_BTC;

    const sendAmount = '1000000'; // 0.01 WBTC

    // Helper function to construct an order pair
    const constructOrderpair = (fromAsset: Asset, toAsset: Asset) =>
        `${fromAsset.chain}:${fromAsset.atomicSwapAddress}::${toAsset.chain}:${toAsset.atomicSwapAddress}`;

    const orderPair = constructOrderpair(
        fromAsset,
        toAsset,
    );

    // Get the quote for the send amount and order pair
    const quoteResult = await garden.quote.getQuote(
        orderPair,
        Number(sendAmount),
        false, // Set this to true if you wish to specify the output (receive) amount
    );

    if (!quoteResult.ok) {
        throw new Error(quoteResult.error);
    }

    // Choose a quote
    const [_strategyId, quoteAmount] = Object.entries(quoteResult.val.quotes)[0];

    const swapParams: SwapParams = {
        fromAsset,
        toAsset,
        sendAmount,
        receiveAmount: quoteAmount,
        additionalData: {
            strategyId: _strategyId,
            btcAddress?: '<YOUR_BITCOIN_ADDRESS>',
        },
    };

    // Create the swap
    const swapResult = await garden.swap(swapParams);

    if (!swapResult.ok) {
        throw new Error(swapResult.error);
    }

    const order = swapResult.val;
    console.log('✅ Order created:', order.create_order.create_id);
    ```
  </Step>

  <Step title="Initiate the swap">
    <Tabs>
      <Tab title="Swapping to Bitcoin">
        <Warning>
          The first swap requires gas for token approval. Subsequent swaps will be gasless.
        </Warning>

        ```js
        const order = swapResult.val;
        const initRes = await garden.evmHTLC.initiate(order); // `garden.starknetHTLC` for Starknet

        if (!initRes.ok) {
            throw new Error(initRes.error);
        }
        ```
      </Tab>

      <Tab title="Swapping from Bitcoin">
        <Tip>
          When swapping from Bitcoin, you must send funds to the deposit address.
        </Tip>

        ```js
            const order = swapResult.val;
            const depositAddress = order.source_swap.swap_id;
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="Settle the swap">
    Garden handles swap settlement automatically. The `execute` function continuously polls for the order status and calls `redeem` when the status becomes redeemable.

    ```js
    await garden.execute();

    // Subscribe to Garden events to track transaction statuses
    garden.on('error', (order, error) => {
        console.error(`Error occurred for order ID ${order.create_order.create_id}:`, error);
    });

    garden.on('success', (order, action, txHash) => {
        console.log(`${order} ${action} ${txHash}`);
    });
    ```

    <Note>
      It is important to keep the service running until completion of the swap. If the instance is stopped, restarting it will ensure Garden checks the status of the order and resubmits the redeem if necessary.
    </Note>
  </Step>
</Steps>
