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
Login via wallet (SIWE flow)
UI calls
POST /v1/auth/noncewith{ address }.UI immediately calls
GET /v1/auth/sign-in-messagewith the same address, domain, and URI; displays the returned message for signing.User signs; UI sends
POST /v1/auth/loginwith{ message, signature }.UI receives
access_tokenand setsAuthorization: Bearer <token>on subsequent requests.
Fetch Fee Options
User enters their wallet account address and desired amount in UI.
UI calls
POST /v1/fee-options?account=<account>&amount=<amount>.Backend validates, computes instant and fallback options, and locks them for
POLICY_VALID_TIME(e.g., 30 s).UI displays the returned array of one or more
FeeOptionitems.
Bridge Funds
UI invokes on-chain call
symmio_contract.bridge(amount)(or_call(deallocate, bridge)if bridging from a multi-account).Once on-chain transaction is mined, UI displays the
bridgeIdand instructs user to select a fee policy.
Select Fee Policy
UI calls
POST /v1/bridges/{account}/{start}/{size}to fetch the user’s bridges inno_policystate, e.g.:{ "bridge_state": "pending", "bridge_type": "no_policy" }For each bridge:
UI calls
GET /v1/pending-fee-policy/{account}and displays locked fee policies.User chooses one of the displayed
FeeOption.(Optional) To specify a different receiver:
UI calls
GET /v1/get-select-receiver-message?receiver=<newReceiver>&bridgeId=<bridgeId>UI has user sign the returned EIP-712 payload and includes:
"receiver": { "address": "<newReceiver>", "signature": "<sig>" }
UI calls
POST /v1/select-fee-policywith:{ "symmioBridgeId": <bridgeId>, "cooldown": <chosenCooldown>, "feeAmount": <chosenFee>, "receiver": { … } // optional }Backend validates, records in DB, calls
selectFeePolicyForBridgeon-chain, and schedules withdrawal atexecution_time = now + cooldown.Backend returns:
{ "bridge_id": <bridgeId>, "fee": <feeAmount>, "execution_time": <timestamp> }
Automated Withdrawal After
cooldownseconds, the backend bot automatically callsprocessWithdrawal(bridgeId)on-chain.
Scenario 2: Fee Options Expire and Retry
Login via wallet (as in Scenario 1).
Initial Fee Options UI calls
POST /v1/fee-optionsbut user waits beyondPOLICY_VALID_TIME(e.g., 30 s).Bridge funds and obtain
bridgeId.Lock expires (options TTL passed).
UI retrieves no-policy bridges via
POST /v1/bridges/{account}/{start}/{size}.Retry Fee Options UI calls
POST /v1/fee-options?account=<account>&amount=<amount>again; backend regenerates options and locks for another 30 s.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_policyandstatus = 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 wherebridge_type = no_policy.For each pending bridge, request a new set of fee options using
POST /v1/fee-options?account=<account>&amount=<amount>.
4. Selecting a Policy and Processing the Withdrawal
Once the user selects a fee option:
The frontend calls
POST /v1/select-fee-policywith the chosen policy .The backend calls
selectFeePolicyForBridgeon-chain.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
Bot Down During Bridge – User bridges on-chain while event poller is offline → no record created.
Bot Reactivation & Catch-Up – Bot scans missed events, creates
BridgeTransactionswithno_policy.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
Follow Scenario 1 through fee-policy selection.
Bot goes down before scheduled withdrawal executes.
Manual Withdrawal
UI displays “Withdraw After Cooldown” button next to bridges where
execution_timehas passed but state is stillpending.When clicked, UI calls
processWithdrawal(bridgeId)on-chain.Tokens arrive in user’s wallet.
Scenario 5: Reset Locked Fee Options
Login via wallet.
UI calls
POST /v1/fee-options?account=<account>&amount=<amount>, receives options.UI calls
POST /v1/unlock/{account}to clear locks.UI calls
POST /v1/fee-options?account=<account>&amount=<amount>again to fetch fresh options.
4. Additional UI Actions and Buttons
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.
Refresh Fee Options Button
Combined Actions:
POST /v1/unlock/{account}POST /v1/fee-options?account=<account>&amount=<amount>
Purpose: Clear existing lock and fetch fresh fee/cooldown options in one click.
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_timehas passed but state is stillpending.
5. Error Codes
All endpoints return structured error codes via the shared ErrorInfoContainer:
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
