User Interaction Scenarios

Instant Withdrawal Flow

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.:

      {
        "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:

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

        {
          "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:

        {
          "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 – User logs in and initiates bridge transaction. – Backend captures the event; records bridge with bridge_type = no_policy.

  2. User Does Not Select a Policy – No withdrawal is scheduled; user receives no funds until they select a policy.

  3. User Retries Fee Options & Selects a Policy

    1. UI retrieves no-policy bridges via POST /v1/bridges/{account}/{start}/{size}.

    2. For each, UI sends POST /v1/fee-options?account=<account>&amount=<amount>.

    3. User chooses an option and calls POST /v1/select-fee-policy.

    4. Backend calls selectFeePolicyForBridge and, after cooldown (often zero), calls processWithdrawal(bridgeId).


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:

Code
Identifier
Message

1

unhandled_error

Internal server error

2

could_not_get_excepted_response

Could not get expected response

3

model_validation_error

Model validation error

4

not_found_error

Not found

5

already_has_pending

Already has pending withdrawal options—try again in ? seconds

6

not_enough_balance

Not enough user balance

7

invalid_bridge_transaction

Invalid bridge transaction

8

invalid_bridge_policy_option

Invalid Bridge Policy Option—please check and select options again

9

already_has_withdrawal_option_or_executed

You already selected an option for this bridge or it has executed

10

low_amount_to_bridge

Requested amount for bridge is very low

11

unauthorized_access

Unauthorized

12

invalid_signature

Invalid Signature

13

signature_mismatch

Signature mismatch

14

expired_nonce

Nonce expired or not found

15

not_authenticated

Not authenticated

16

contract_validation_failed

Contract validation failed

17

rpc_connection_failed

RPC endpoint connection failed

18

nonce_mismatch

Nonce mismatch

19

user_creation_in_progress

User creation in progress for this address. Please retry in a moment.

Last updated