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

# Withdraw to L1

export const Method = ({children, className = ""}) => {
  return <code className={`spark-method not-prose inline-block px-2 py-1 mt-12 text-sm font-mono font-semibold rounded-md border ${className}`}>
      {children}
    </code>;
};

Send Bitcoin to any on-chain Bitcoin address.

<Frame className="chill">
  <img className="block dark:hidden" src="https://mintcdn.com/lightspark/RCkJgy8FQAJRUhsh/images/wallets/withdraw-to-l1-light.png?fit=max&auto=format&n=RCkJgy8FQAJRUhsh&q=85&s=a851bf02252d0c992841ad75a2cf00de" alt="Withdraw to L1" width="3840" height="2160" data-path="images/wallets/withdraw-to-l1-light.png" />

  <img className="hidden dark:block" src="https://mintcdn.com/lightspark/RCkJgy8FQAJRUhsh/images/wallets/withdraw-to-l1.png?fit=max&auto=format&n=RCkJgy8FQAJRUhsh&q=85&s=da36f334325eac6c5f8799baf4c87379" alt="Withdraw to L1" width="3840" height="2160" data-path="images/wallets/withdraw-to-l1.png" />
</Frame>

***

## Withdrawal Flow

The complete process for sending Bitcoin to an on-chain Bitcoin address:

<Steps>
  <Step title="Get Fee Quote">
    Request a fee quote for your withdrawal with different speed options.

    ```typescript theme={null}
    const feeQuote = await wallet.getWithdrawalFeeQuote({
      amountSats: 50000,
      withdrawalAddress: "bc1p..." // Your Bitcoin address
    });
    console.log("Fee quote:", feeQuote);
    ```
  </Step>

  <Step title="Initiate Withdrawal">
    Start the withdrawal process using the fee quote.

    ```typescript theme={null}
    // Calculate fee based on exit speed
    import { ExitSpeed } from "@buildonspark/spark-sdk";

    if (!feeQuote) throw new Error("No fee quote available");

    const exitSpeed = ExitSpeed.FAST; // or ExitSpeed.MEDIUM, ExitSpeed.SLOW
    let feeAmountSats: number;
    switch (exitSpeed) {
      case ExitSpeed.FAST:
        feeAmountSats = (feeQuote.l1BroadcastFeeFast?.originalValue || 0) +
                        (feeQuote.userFeeFast?.originalValue || 0);
        break;
      case ExitSpeed.MEDIUM:
        feeAmountSats = (feeQuote.l1BroadcastFeeMedium?.originalValue || 0) +
                        (feeQuote.userFeeMedium?.originalValue || 0);
        break;
      case ExitSpeed.SLOW:
        feeAmountSats = (feeQuote.l1BroadcastFeeSlow?.originalValue || 0) +
                        (feeQuote.userFeeSlow?.originalValue || 0);
        break;
    }

    const withdrawal = await wallet.withdraw({
      onchainAddress: "bc1p...", // Your Bitcoin address
      exitSpeed,
      amountSats: 50000,
      feeQuoteId: feeQuote.id,
      feeAmountSats: feeAmountSats,
      deductFeeFromWithdrawalAmount: false
    });
    console.log("Withdrawal initiated:", withdrawal);
    ```
  </Step>

  <Step title="Monitor Status">
    Track the withdrawal status until completion.

    ```typescript theme={null}
    const exitRequest = await wallet.getCoopExitRequest(withdrawal.id);
    console.log("Withdrawal status:", exitRequest.status);
    console.log("Transaction ID:", exitRequest.coopExitTxid);
    ```
  </Step>
</Steps>

<Note>
  If you have custom L1 requirements like fee control, transaction chaining, or specific broadcast behavior, [talk to our team](https://www.spark.money/contact). We can expose lower-level controls to fit your infrastructure needs.
</Note>

***

## Get Withdrawal Fee Quote

Request fee quotes for different withdrawal speeds before initiating a withdrawal.

<Method>getWithdrawalFeeQuote(params)</Method>

Gets a fee quote for a cooperative exit (on-chain withdrawal). The quote includes options for different speeds and an expiry time and must be passed to `withdraw` before it expires.

```typescript theme={null}
const feeQuote = await wallet.getWithdrawalFeeQuote({
  amountSats: 100000,
  withdrawalAddress: "bc1p5d7rjq7g6rdk2yhzks9smtbqtedr4dekq08ge8ztwac72sfr9rusxg3297"
});

console.log("Fee quote:", feeQuote);
if (!feeQuote) throw new Error("No fee quote available");
console.log("Fast total fee (sats):", feeQuote.userFeeFast.originalValue + feeQuote.l1BroadcastFeeFast.originalValue);
console.log("Medium total fee (sats):", feeQuote.userFeeMedium.originalValue + feeQuote.l1BroadcastFeeMedium.originalValue);
console.log("Slow total fee (sats):", feeQuote.userFeeSlow.originalValue + feeQuote.l1BroadcastFeeSlow.originalValue);
```

<Expandable title="Parameters">
  <ResponseField name="amountSats" type="number" required>
    The amount in satoshis to withdraw
  </ResponseField>

  <ResponseField name="withdrawalAddress" type="string" required>
    The Bitcoin address where the funds should be sent
  </ResponseField>
</Expandable>

<Expandable title="Returns">
  <ResponseField name="feeQuote" type="CoopExitFeeQuote | null" required>
    A fee quote for the withdrawal, or null if not available
  </ResponseField>
</Expandable>

***

## Initiate Withdrawal

Start the withdrawal process using a fee quote.

<Method>withdraw(params)</Method>

Initiates a cooperative exit to withdraw Bitcoin from Spark to Layer 1.

```typescript theme={null}
// Calculate fee based on exit speed
import { ExitSpeed } from "@buildonspark/spark-sdk";

if (!feeQuote) throw new Error("No fee quote available");

const exitSpeed = ExitSpeed.FAST; // ExitSpeed.FAST, ExitSpeed.MEDIUM, or ExitSpeed.SLOW
let feeAmountSats: number;
switch (exitSpeed) {
  case ExitSpeed.FAST:
    feeAmountSats = (feeQuote.l1BroadcastFeeFast?.originalValue || 0) +
                    (feeQuote.userFeeFast?.originalValue || 0);
    break;
  case ExitSpeed.MEDIUM:
    feeAmountSats = (feeQuote.l1BroadcastFeeMedium?.originalValue || 0) +
                    (feeQuote.userFeeMedium?.originalValue || 0);
    break;
  case ExitSpeed.SLOW:
    feeAmountSats = (feeQuote.l1BroadcastFeeSlow?.originalValue || 0) +
                    (feeQuote.userFeeSlow?.originalValue || 0);
    break;
}

const withdrawal = await wallet.withdraw({
  onchainAddress: "bc1p5d7rjq7g6rdk2yhzks9smtbqtedr4dekq08ge8ztwac72sfr9rusxg3297",
  exitSpeed,
  amountSats: 100000,
  feeQuoteId: feeQuote.id,
  feeAmountSats: feeAmountSats,
  deductFeeFromWithdrawalAmount: false
});

if (!withdrawal) throw new Error("Withdrawal failed");

console.log("Withdrawal ID:", withdrawal.id);
console.log("Status:", withdrawal.status);
```

<Expandable title="Parameters">
  <ResponseField name="onchainAddress" type="string" required>
    The Bitcoin address to send the funds to
  </ResponseField>

  <ResponseField name="exitSpeed" type="ExitSpeed" required>
    The withdrawal speed: `ExitSpeed.FAST`, `ExitSpeed.MEDIUM`, or `ExitSpeed.SLOW`
  </ResponseField>

  <ResponseField name="amountSats" type="number">
    The amount in satoshis to withdraw (if not specified, withdraws all available funds)
  </ResponseField>

  <ResponseField name="feeQuoteId" type="string">
    The ID from the fee quote returned by getWithdrawalFeeQuote
  </ResponseField>

  <ResponseField name="feeAmountSats" type="number">
    The fee amount in satoshis based on the chosen exitSpeed
  </ResponseField>

  <ResponseField name="deductFeeFromWithdrawalAmount" type="boolean">
    Whether to deduct the fee from the withdrawal amount (default: true)
  </ResponseField>
</Expandable>

<Expandable title="Returns">
  <ResponseField name="withdrawal" type="CoopExitRequest" required>
    The withdrawal request details including ID and status
  </ResponseField>
</Expandable>

***

## Monitor Withdrawal Status

Track the status of your withdrawal request.

<Method>getCoopExitRequest(id)</Method>

Gets a cooperative exit request by ID to check withdrawal status.

```typescript theme={null}
const exitRequest = await wallet.getCoopExitRequest(withdrawalId);
console.log("Withdrawal status:", exitRequest.status);
console.log("Transaction ID:", exitRequest.coopExitTxid);
console.log("Fee:", exitRequest.fee.originalValue, exitRequest.fee.originalUnit);

// Check if withdrawal is complete
if (exitRequest.status === "SUCCEEDED") {
  console.log("Withdrawal completed successfully!");
}
```

<Expandable title="Parameters">
  <ResponseField name="id" type="string" required>
    The ID of the cooperative exit request
  </ResponseField>
</Expandable>

<Expandable title="Returns">
  <ResponseField name="exitRequest" type="CoopExitRequest | null" required>
    The cooperative exit request details or null if not found
  </ResponseField>
</Expandable>

***

## Real-time Withdrawal Monitoring

Monitor withdrawal status by polling `getCoopExitRequest()`.

<Info>
  Withdrawals don't emit events. Poll the status using `getCoopExitRequest()` with the withdrawal ID returned from `withdraw()`.
</Info>

```typescript theme={null}
// Check withdrawal status periodically
const checkWithdrawalStatus = async (withdrawalId) => {
  const exitRequest = await wallet.getCoopExitRequest(withdrawalId);
  
  switch (exitRequest.status) {
    case "SUCCEEDED":
      console.log("Withdrawal completed!");
      console.log("On-chain txid:", exitRequest.coopExitTxid);
      return true;
    case "FAILED":
      console.log("Withdrawal failed");
      return false;
    default:
      console.log("Withdrawal pending...");
      setTimeout(() => checkWithdrawalStatus(withdrawalId), 30000); // Check again in 30 seconds
      return false;
  }
};
```
