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/nonce
with{ address }
.UI immediately calls
GET /v1/auth/sign-in-message
with the same address, domain, and URI; displays the returned message for signing.User signs; UI sends
POST /v1/auth/login
with{ message, signature }
.UI receives
access_token
and 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
FeeOption
items.
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
bridgeId
and 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_policy
state, 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-policy
with:{ "symmioBridgeId": <bridgeId>, "cooldown": <chosenCooldown>, "feeAmount": <chosenFee>, "receiver": { … } // optional }
Backend validates, records in DB, calls
selectFeePolicyForBridge
on-chain, and schedules withdrawal atexecution_time = now + cooldown
.Backend returns:
{ "bridge_id": <bridgeId>, "fee": <feeAmount>, "execution_time": <timestamp> }
Automated Withdrawal After
cooldown
seconds, 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-options
but 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)
Login & Bridge Funds – User logs in and initiates bridge transaction. – Backend captures the event; records bridge with
bridge_type = no_policy
.User Does Not Select a Policy – No withdrawal is scheduled; user receives no funds until they select a policy.
User Retries Fee Options & Selects a Policy
UI retrieves no-policy bridges via
POST /v1/bridges/{account}/{start}/{size}
.For each, UI sends
POST /v1/fee-options?account=<account>&amount=<amount>
.User chooses an option and calls
POST /v1/select-fee-policy
.Backend calls
selectFeePolicyForBridge
and, after cooldown (often zero), callsprocessWithdrawal(bridgeId)
.
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
BridgeTransactions
withno_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_time
has 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_time
has 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