> 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/user-interaction-scenarios.md).

# User Interaction Scenarios

Below are typical user flows. Each scenario assumes the user has a Web3 wallet connected and has retrieved a valid JWT via the SIWE login flow.

## Scenario 1: Normal Flow and Successful Instant Withdrawal

1. **Login via wallet (SIWE flow)**
   1. UI calls `POST /v1/auth/nonce` with `{ address }`.
   2. UI immediately calls `GET /v1/auth/sign-in-message` with the same address, domain, and URI; displays the returned message for signing.
   3. User signs; UI sends `POST /v1/auth/login` with `{ message, signature }`.
   4. UI receives `access_token` and sets `Authorization: Bearer <token>` on subsequent requests.
2. **Fetch Fee Options**
   1. User enters their wallet account address and desired amount in UI.
   2. UI calls `POST /v1/fee-options?account=<account>&amount=<amount>`.
   3. Backend validates, computes instant and fallback options, and locks them for `POLICY_VALID_TIME` (e.g., 30 s).
   4. UI displays the returned array of one or more `FeeOption` items.
3. **Bridge Funds**
   1. UI invokes on-chain call `symmio_contract.bridge(amount)` (or `_call(deallocate, bridge)` if bridging from a multi-account).
   2. Once on-chain transaction is mined, UI displays the `bridgeId` and instructs user to select a fee policy.
4. **Select Fee Policy**
   1. UI calls `POST /v1/bridges/{account}/{start}/{size}` to fetch the user’s bridges in `no_policy` state, e.g.:

      ```json
      {
        "bridge_state": "pending",
        "bridge_type": "no_policy"
      }
      ```
   2. For each bridge:
      1. UI calls `GET /v1/pending-fee-policy/{account}` and displays locked fee policies.
      2. User chooses one of the displayed `FeeOption`.
      3. *(Optional)* To specify a different receiver:
         1. UI calls

            ```
            GET /v1/get-select-receiver-message?receiver=<newReceiver>&bridgeId=<bridgeId>
            ```
         2. UI has user sign the returned EIP-712 payload and includes:

            ```json
            "receiver": {
              "address": "<newReceiver>",
              "signature": "<sig>"
            }
            ```
      4. UI calls `POST /v1/select-fee-policy` with:

         ```json
         {
           "symmioBridgeId": <bridgeId>,
           "cooldown": <chosenCooldown>,
           "feeAmount": <chosenFee>,
           "receiver": { … }      // optional
         }
         ```
      5. Backend validates, records in DB, calls `selectFeePolicyForBridge` on-chain, and schedules withdrawal at `execution_time = now + cooldown`.
      6. Backend returns:

         ```json
         {
           "bridge_id": <bridgeId>,
           "fee": <feeAmount>,
           "execution_time": <timestamp>
         }
         ```
5. **Automated Withdrawal**\
   After `cooldown` seconds, the backend bot automatically calls `processWithdrawal(bridgeId)` on-chain.

***

## Scenario 2: Fee Options Expire and Retry

1. Login via wallet (as in Scenario 1).
2. **Initial Fee Options**\
   UI calls `POST /v1/fee-options` but user waits beyond `POLICY_VALID_TIME` (e.g., 30 s).
3. Bridge funds and obtain `bridgeId`.
4. Lock expires (options TTL passed).
5. UI retrieves no-policy bridges via `POST /v1/bridges/{account}/{start}/{size}`.
6. **Retry Fee Options**\
   UI calls `POST /v1/fee-options?account=<account>&amount=<amount>` again; backend regenerates options and locks for another 30 s.
7. **Select & Withdraw**\
   User picks a new option, signs payload, calls `POST /v1/select-fee-policy`, and flow continues as in Scenario 1.

***

## Scenario 3: No Policy Selected (Withdrawal Pending)

#### **1. Login & Bridge Funds**

* The user logs in and initiates a bridge transaction through the frontend.
* The backend captures the bridge event and records it with\
  `bridge_type = no_policy` and `status = RECEIVED`.
* The funds are deducted from the user’s Symmio balance and reserved in the bridge contract — **no payout occurs yet.**

#### **2. User Does Not Select a Policy**

* If the user leaves or closes the UI before selecting a fee policy:
  * No withdrawal is scheduled.
  * The bridge transaction remains **pending** indefinitely.
  * The user’s reserved funds **cannot be used elsewhere**, but **can still be withdrawn later** once a policy is chosen.

#### **3. User Returns Later to Complete the Withdrawal**

* When the user logs back in, the UI must:
* Retrieve all pending bridges with\
  `POST /v1/bridges/{account}/{start}/{size}`\
  and look for entries where `bridge_type = no_policy`.
* For each pending bridge, request a **new set of fee options** using\
  `POST /v1/fee-options?account=<account>&amount=<amount>`.

{% hint style="info" %}
Previously shown fee options may have expired past their `POLICY_VALID_TIME,`in which case a new set of fee options must be fetched.
{% endhint %}

#### **4. Selecting a Policy and Processing the Withdrawal**

* Once the user selects a fee option:
  1. The frontend calls `POST /v1/select-fee-policy` with the chosen policy .
  2. The backend calls `selectFeePolicyForBridge` on-chain.
  3. After the configured cooldown period (usually 0), the backend or bot executes\
     `processWithdrawal(bridgeId)` to finalize the payout to the user.
* The transaction is then marked as **completed**, and the user receives the bridged funds.

***

## Scenario 4a: Bot Inactive, Then Reactivated

1. **Bot Down During Bridge**\
   – User bridges on-chain while event poller is offline → no record created.
2. **Bot Reactivation & Catch-Up**\
   – Bot scans missed events, creates `BridgeTransactions` with `no_policy`.
3. **User Resumes Normal Flow**\
   – UI requests fee options and follows Scenario 1 steps to select and execute withdrawal.

***

## Scenario 4b: Bot Inactive after Policy Selected, Manual Withdrawal

1. Follow Scenario 1 through fee-policy selection.
2. Bot goes down before scheduled withdrawal executes.
3. **Manual Withdrawal**
   1. UI displays “Withdraw After Cooldown” button next to bridges where `execution_time` has passed but state is still `pending`.
   2. When clicked, UI calls `processWithdrawal(bridgeId)` on-chain.
   3. Tokens arrive in user’s wallet.

***

## Scenario 5: Reset Locked Fee Options

1. Login via wallet.
2. UI calls `POST /v1/fee-options?account=<account>&amount=<amount>`, receives options.
3. UI calls `POST /v1/unlock/{account}` to clear locks.
4. UI calls `POST /v1/fee-options?account=<account>&amount=<amount>` again to fetch fresh options.

***

### 4. Additional UI Actions and Buttons

1. **Get Max Instant Value Button**
   * **Endpoint:** `GET /v1/max-instant-value/{account}`
   * **Purpose:** Show the maximum amount the user can withdraw instantly; guide the user to not bridge more than this.
2. **Refresh Fee Options Button**
   * **Combined Actions:**
     1. `POST /v1/unlock/{account}`
     2. `POST /v1/fee-options?account=<account>&amount=<amount>`
   * **Purpose:** Clear existing lock and fetch fresh fee/cooldown options in one click.
3. **Manual Process Withdrawal Button**
   * **Action:** Calls the contract’s `processWithdrawal(bridgeId)` method directly.
   * **Purpose:** Allow users to trigger on-chain withdrawal if scheduled withdrawal failed or bot is down.
   * **When to Show:** After fetching user’s bridge list, display “Withdraw Now” next to any entry where `execution_time` has passed but state is still `pending`.

***

### 5. Error Codes

All endpoints return structured error codes via the shared `ErrorInfoContainer`:

<table><thead><tr><th width="101">Code</th><th>Identifier</th><th>Message</th></tr></thead><tbody><tr><td>1</td><td><code>unhandled_error</code></td><td>Internal server error</td></tr><tr><td>2</td><td><code>could_not_get_excepted_response</code></td><td>Could not get expected response</td></tr><tr><td>3</td><td><code>model_validation_error</code></td><td>Model validation error</td></tr><tr><td>4</td><td><code>not_found_error</code></td><td>Not found</td></tr><tr><td>5</td><td><code>already_has_pending</code></td><td>Already has pending withdrawal options—try again in ? seconds</td></tr><tr><td>6</td><td><code>not_enough_balance</code></td><td>Not enough user balance</td></tr><tr><td>7</td><td><code>invalid_bridge_transaction</code></td><td>Invalid bridge transaction</td></tr><tr><td>8</td><td><code>invalid_bridge_policy_option</code></td><td>Invalid Bridge Policy Option—please check and select options again</td></tr><tr><td>9</td><td><code>already_has_withdrawal_option_or_executed</code></td><td>You already selected an option for this bridge or it has executed</td></tr><tr><td>10</td><td><code>low_amount_to_bridge</code></td><td>Requested amount for bridge is very low</td></tr><tr><td>11</td><td><code>unauthorized_access</code></td><td>Unauthorized</td></tr><tr><td>12</td><td><code>invalid_signature</code></td><td>Invalid Signature</td></tr><tr><td>13</td><td><code>signature_mismatch</code></td><td>Signature mismatch</td></tr><tr><td>14</td><td><code>expired_nonce</code></td><td>Nonce expired or not found</td></tr><tr><td>15</td><td><code>not_authenticated</code></td><td>Not authenticated</td></tr><tr><td>16</td><td><code>contract_validation_failed</code></td><td>Contract validation failed</td></tr><tr><td>17</td><td><code>rpc_connection_failed</code></td><td>RPC endpoint connection failed</td></tr><tr><td>18</td><td><code>nonce_mismatch</code></td><td>Nonce mismatch</td></tr><tr><td>19</td><td><code>user_creation_in_progress</code></td><td>User creation in progress for this address. Please retry in a moment.</td></tr></tbody></table>


---

# 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/user-interaction-scenarios.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.
