API Endpoints

All endpoints are prefixed with /v1. Authentication uses JWT via an Authorization: Bearer <token> header, obtained through the SIWE login flow.

Base URL:

https://instant-withdrawal-base.symmio.foundation/

2.1. POST /v1/fee-options

Fetch available withdrawal policies (fee & cooldown) for a given account and amount.

  • Request (Query Parameters):

    • account (string; required; EVM address)

    • amount (integer; required; must be > 0; amount in wei)

  • Request Headers:

    • Authorization: Bearer <JWT>

  • Response Schema (200):

interface FeeOptionsResponseSchema {
  count: number;          // number of available options
  options: FeeOption[];
}
interface FeeOption {
  fee: number;           // total fee in wei
  cooldown: number;      // cooldown period in seconds
  user: string;          // checksumed ETH address
  amount: number;        // requested amount in wei
  validTime: number;     // Unix epoch (seconds) when this option expires
}
  • Behavior:

    • Validates JWT and wallet ownership of account.

    • Checks if an existing pending request exists. If yes, returns error code for locked options.

    • Computes policies to determine the fees.

  • Error Codes:

Code
Message
Condition

11

unauthorized

The owner_address from JWT does not match the owner for provided account.

5

Already has pending withdrawal options try in seconds

A pending request already exists.

6

not enough user balance

The user’s on-chain balance is less than amount.

10

requested amount for bridge is very low

The requested amount is less than or equal to OPERATOR_FEE.

2.2. POST /v1/unlock/{account}

Clear any existing lock on fee policies for the given account, allowing immediate re-fetch of options.

  • Request:

    • account (string; required; EVM address)

  • Request Headers:

    • Authorization: Bearer <JWT>

  • Response Schema (200):

interface UnlockAccountResponseSchema {
  message: string;  // "Account unlocked successfully."
}
  • Behavior:

    • Validates JWT and wallet ownership of account.

    • Removes pending fee options.

    • Returns { message: "Account <account> unlocked successfully." }.

  • Error Codes:

Code
Message
Condition

11

unauthorized

The owner_address from JWT does not match the owner for provided account.


2.3. GET /v1/pending-fee-policy/{account}

Retrieve currently locked fee policies for the given account, if any exist.

  • Request:

    • account (string; required; EVM address)

  • Request Headers:

    • Authorization: Bearer <JWT>

  • Response Schema (200):

interface FeeOptionsResponseSchema {
  count: number;          // number of available options
  options: FeeOption[];
}
interface FeeOption {
  fee: number;           // total fee in wei
  cooldown: number;      // cooldown period in seconds
  user: string;          // checksumed ETH address
  amount: number;        // requested amount in wei
  validTime: number;     // Unix epoch (seconds) when this option expires
}
  • Behavior:

    • Validates JWT and wallet ownership of account.

  • Error Codes:

Code
Message
Condition

11

unauthorized

The owner_address from JWT does not match the owner for provided account.


2.4. GET /v1/max-instant-value/{account}

Fetch the maximum amount (in wei) that the user can withdraw instantly at this moment.

  • Request (Path Parameter):

    • account (string; required; EVM address)

  • Request Headers:

    • Authorization: Bearer <JWT>

  • Response Schema (200):

interface MaxInstantWithdrawableAmountResponseSchema {
  amount: number; // maximum instant-withdrawable amount in wei
}
  • Behavior:

    • Validates JWT and wallet ownership of account.

    • Checks user balance and risk factor.

    • Returns { amount: <max_instant> }.

  • Error Codes:

Code
Message
Condition

11

unauthorized

The owner_address from JWT does not match the owner for provided account.


2.5. GET /v1/get-select-receiver-message?receiver={address}&bridgeId={bridgeId}

Construct an EIP‑712 typed-data payload that the user can sign to authorize selecting a different recipient (multi-account) for a given bridgeId.

  • Request (Query Parameters):

    • receiver (string; required; checksumed EVM address)

    • bridgeId (integer; required)

  • Request Headers:

    • No JWT required (open endpoint)

  • Response Schema (200):

interface GetSelectReceiverMessageResponse {
  payload: EIP712SelectReceiverMessage;
}
interface EIP712SelectReceiverMessage {
  types: EIP712Types;
  domain: EIP712DomainModel;
  primaryType: "SelectReceiver";
  message: {
    receiver: string; // address
    bridgeId: number;
  };
}
  • Behavior: Returns an on‑chain domain and typed data structure, according to EIP‑712.

2.6. POST /v1/select-fee-policy

Submit a signed fee policy selection for an existing bridge transaction.

  • Request Body Schema (application/json):

interface SelectFeePolicyRequestSchema {
  symmioBridgeId: number;        // bridge transaction ID
  cooldown: number;              // chosen cooldown
  feeAmount: number;             // chosen fee (wei)
  receiver?: SpecifiedReceiver | null; // optional new recipient object
}
interface SpecifiedReceiver {
  address: string;       // checksumed Ethereum address
  signature: string;     // EIP‑712 signature hex
}
  • Request Headers:

    • Authorization: Bearer <JWT>

  • Response Schema (200):

interface SelectFeePolicyResponseSchema {
  bridge_id: number;      // same as symmioBridgeId
  execution_time: number; // Unix epoch (seconds) when `processWithdrawal` will be called
  fee: number;            // fee in wei
}
  • Behavior:

    • Validates JWT and that the current user is the owner of the symmioBridgeId account.

    • Fetches BridgeTransaction from Symmio contract and validate data and status.

    • Calls select_fee_policy_for_bridge on-chain.

    • Returns { bridge_id, fee: feeAmount, execution_time }.

  • Error Codes:

Code
Message
Condition

11

unauthorized

The owner_address from JWT does not match the owner for provided account.

7

invalid bridge transaction

The provided bridgeId is not in RECEIVED status or does not point to the InstantWithdrawal contract.

8

invalid bridge policy option

No pending options exist for this user, or the selected fee/cooldown combination does not match any stored option.

9

You already selected a withdrawal option for bridge or it has executed.

A fee policy has already been selected for this bridge (bridge.bridge_type == instant).

2.7. POST /v1/bridges/{account}/{start}/{size}

Search and paginate historical bridge transactions for a given user account:

  • Request:

    • account (string; required; EVM address)

    • start (integer; required; offset index)

    • size (integer; required; page size)

  • Request Body Schema (application/json):

interface BridgeTransactionRequestModel {
  bridge_state?: "pending" | "executed" | "settled" | "suspend" | null;
  bridge_type?: "instant" | "after_cool_down" | "no_policy" | null;
}
  • Request Headers:

    • Authorization: Bearer <JWT>

  • Response Schema (200):

    interface BridgeTransactionSearchResponseSchema {
      count: number;
      bridges: BridgeTransactionResponseModel[] | null;
    }
    interface BridgeTransactionResponseModel {
      bridge_id: number;
      user_address: string;
      bridge_state: "pending" | "executed" | "settled" | "suspend";
      bridge_type: "instant" | "after_cool_down" | "no_policy";
      bridge_amount: number;        // in wei
      fee_amount: number;           // in wei
      bridge_transaction_time: number; // Unix epoch seconds
      execution_time?: number;      // Unix epoch seconds or null
    }
  • Behavior:

    • Validates JWT and wallet ownership of account.

    • Queries database, ordering by creation time descending.

    • If no records, returns { count: 0, bridges: null }.

    • Otherwise returns { count: <number_of_rows>, bridges: [ ... ] }.

  • Error Codes:

    Code
    Message
    Condition

    11

    unauthorized

    The owner_address from JWT does not match the owner for provided account.

2.8 GET /v1/withdrawal-config

Fetch the current withdrawal settings.

  • Request:

    • No Parameters

  • Request Headers:

    • Authorization: Bearer<JWT>

  • Response Schema (200):

interface WithdrawalSettingsResponseSchema {
 operatorFee: number;
 maxInstantAmount: number;
 instantFeeRate: number;
 policyValidTime: number;
 minWithdrawalCooldown: number;
}

2.9 Authentication Endpoints

2.9.1. POST /v1/auth/nonce

Request a one-time nonce for SIWE login:

  • Request Body (application/json):

    interface AddressSchema {
      address: string; // checksumed Ethereum address
    }
  • Response (200):

    { "nonce": "0x1234…abcd" }
  • Behavior:

    • Generates random nonce for the address.

  • Error Codes:

    • ValueError (missing or malformed address)

2.9.2. GET /v1/auth/sign-in-message

Returns a Sign‑In With Ethereum (SIWE/EIP-4361) message that the user must sign.

  • Request (Query):

    • address (string; required, EVM address)

    • domain (string; required)

    • uri (string; required)

    • statement (string; optional)

    • version (string; optional)

  • Response Schema (200):

    interface SignInMessageResponseSchema {
     message: string;
     params: SignInMessageParams;
    }
    interface SignInMessageParams {
     address: string; // Same as the `address` query param
     domain: string; // Same as the `domain` query param
     uri: string; // Same as the `uri` query param
     statement?: string; // Same as the `statement` query param
     version: string; // Same as the `version` query param
     chainId: number; // Backend’s configured chain ID
     nonce: string; // Newly generated 16-byte hex string
     issuedAt: string; // UTC timestamp in ISO 8601 format
    }
    
  • Behavior

    • Constructs a full EIP-4361-formatted message string comprising

    • Returns both the single message string and the underlying data object.

    • The UI shows message in the wallet’s signing modal and keeps the returned data for the subsequent POST /v1/auth/login call.

2.9.3. POST /v1/auth/login

Validate signed SIWE message and issue JWT:

  • Request Body:

    interface LoginRequest {
      message: CustomSiweMessage;   // full EIP‑4361 payload
      signature: string;            // hex signature
    }
    interface CustomSiweMessage {
      domain: string;
      address: string;
      uri: string;
      version: string;
      chainId: number;
      issuedAt: string;
      nonce: string;
      statement?: string;
      expirationTime?: string;
    }
  • Response Schema (200):

    interface Token {
      access_token: string; // JWT
      token_type: string;   // "bearer"
    }
  • Error Codes:

    Code
    Message
    Condition

    14

    expired_nonce

    No nonce found or expired.

    18

    nonce_mismatch

    Provided nonce differs from stored.

    12

    invalid_signature

    Signature verification failed.

2.8.4. GET /v1/auth/me

Retrieve the currently authenticated user address:

  • Request Headers:

    • Authorization: Bearer <JWT>

  • Response (200):

    interface AddressSchema {
      address: string; // checksumed Ethereum address
    }
  • Error Codes:

    Code
    Message
    Condition

    11

    unauthorized

    The owner_address from JWT does not match the owner for provided account.

Bridge Enums Overview

Bridge States:

Value
Meaning

pending

The bridge transaction is recorded but process withdrawal has not been called yet.

executed

A fee policy was selected, and the withdrawal has been executed on-chain.

settled

The funds have been withdrawn from Symmio to the bridge.

suspend

The bridge process is on hold (e.g., due to a suspension from Symmio).

Bridge Types:

Value
Meaning

instant

The user chose an instant-withdrawal policy with custom fee and cooldown.

after_cool_down

The user selected the default policy that requires waiting for Symmio cooldown before withdrawal.

no_policy

No fee policy has been chosen yet; the bridge is awaiting the user to request options and select one.

Last updated