> For the complete documentation index, see [llms.txt](https://docs.symm.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.symm.io/exchange-builder-documentation/frontend-builder-technical-guidance/instant-withdrawal-for-frontend-builders/instant-withdrawal-script.md).

# Instant Withdrawal Script

An instant withdrawal lets you withdraw funds without waiting the normal 12-hour cooldown. You select a fee option matching how fast you want it processed, and withdraw through a bridge. This guide shows how to do it without a frontend.

Instant withdrawals work in two steps:

1. **On-chain:** you transfer your allocated balance to a bridge.
2. **Off-chain:** you select a fee option, and the backend schedules the withdrawal for execution.

#### Before you start

You'll need:

* **Python 3.8** or newer
* A wallet private key (for signing and paying gas)
* An RPC URL for the chain you're withdrawing from
* The Python script from the reference repo

#### Setup

Create and activate a virtual environment, then install dependencies:

```bash
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
```

#### Configure .env

The script reads its configuration from a `.env` file. Use the private key for the wallet you want to withdraw from, and an RPC provider:

```dotenv
PRIVATE_KEY=0x...
RPC_URL=https://...
CHAIN_ID=8453
BASE_URL=https://instant-withdrawal-backend...
```

{% hint style="info" %}
Withdrawing 1 USDC means passing `1000000`, since USDC on Base has 6 decimals.
{% endhint %}

#### Running the script

From the project root:

```bash
python instant_withdrawal.py
```

Once started, the script walks through all the steps automatically.

#### What the script does, step by step

The flow below maps directly to the Python code.

**1. Sign in with your wallet (SIWE)**

The script proves wallet ownership with Sign-In With Ethereum and gets an access token, so it can talk to the Instant Withdrawal backend.

```python
nonce = requests.post(
    f"{BASE_URL}/v1/auth/nonce",
    json={"address": wallet_address}
).json()["nonce"]
```

```python
message = requests.get(
    f"{BASE_URL}/v1/auth/sign-in-message",
    params={"address": wallet_address, "domain": DOMAIN, "uri": ORIGIN}
).json()["message"]
```

```python
signed = account.sign_message(encode_defunct(text=message))
```

```python
token = requests.post(
    f"{BASE_URL}/v1/auth/login",
    json={"message": payload, "signature": signature}
).json()["accessToken"]
```

This token is required for all Instant Withdrawal API calls.

**2. Lock fee options for your withdrawal amount**

The script asks the backend for the fee options for a specific amount. This temporarily locks the options so rates can't change.

```python
options = requests.post(
    f"{BASE_URL}/v1/fee-options",
    params={"account": subaccount, "amount": AMOUNT},
    headers={"Authorization": f"Bearer {token}"}
).json()["options"]

```

**3. Deallocate funds from trading (on-chain)**

If your funds are currently allocated to trading, free them first. The script fetches a Muon uPNL signature, formats it for the contract, and sends the transaction.

```python
call_data = diamond.functions.deallocate(
    amount, upnl_sig
)._encode_transaction_data()
```

```python
tx = multi_account.functions._call(
    subaccount,
    [call_data]
)
```

This must complete on-chain before continuing.

**4. Transfer funds to the withdrawal bridge (on-chain)**

Once funds are free, they're transferred into the Instant Withdrawal bridge.

```python
call_data = diamond.functions.transferToBridge(
    amount, BRIDGE_ADDRESS
)._encode_transaction_data()
```

```python
tx = multi_account.functions._call(
    subaccount,
    [call_data]
)
```

After confirmation, the script extracts a `transactionId` from the emitted event. This ID is required for the next step.

**5. Fetch pending fee policies**

With the bridge transfer on-chain, the script fetches the valid fee options tied to that transfer.

```python
policies = requests.get(
    f"{BASE_URL}/v1/pending-fee-policy/{subaccount}",
    headers={"Authorization": f"Bearer {token}"}
).json()["policies"]
```

**6. Select a fee policy and schedule the withdrawal**

The script picks the fastest option and submits it.

```python
fastest = min(policies, key=lambda p: p["cooldown"])
```

```python
result = requests.post(
    f"{BASE_URL}/v1/select-fee-policy",
    json={
        "symmioBridgeId": bridge_id,
        "cooldown": fastest["cooldown"],
        "feeAmount": fastest["fee"],
    },
    headers={"Authorization": f"Bearer {token}"}
).json()
```

Once done, the withdrawal is scheduled and executes automatically.

### Reference implementation

[This repository](https://github.com/academy17/instant_withdrawal_reference) has a Python script showing the full Instant Withdrawal flow.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.symm.io/exchange-builder-documentation/frontend-builder-technical-guidance/instant-withdrawal-for-frontend-builders/instant-withdrawal-script.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
