Rasa Instant Trading Implementation

Implementing Instant Actions

For Frontends:

To enable instant actions on the frontend, users must delegate specific functions to solvers so they can perform actions on the user's behalf without requiring signatures for each request.

Front-ends should ensure that the following functions are delegated to the respective solver addresses through the delegateAccess() method on the MultiAccount contract:

  • sendQuote: 0x7f2755b2

  • sendQuoteWithAffiliate: 0x40f1310c

  • requestToClosePosition: 0x501e891f

  • requestToCancelQuote: 0xa8ffc7ab

  • requestToCancelCloseRequest: 0xa63b9363

  • allocate: 0x90ca796b

The delegation should be initiated by calling delegateAccesses() on the MultiAccount contract, specifying the user’s sub-account, the target (solver) address, and the function selectors that need to be delegated.

For Solvers:

Overview

This document outlines how to implement Instant Trading for Solvers. Instant trading involves creating sessions for users allowing solvers to open and close positions on traders' behalf without requiring signatures for each action.

Users must first delegate certain functions to the solver to manage positions on behalf of them (sendQuote, sendQuoteWithAffiliate, requestToClosePosition)

The frontend then prompts to authenticate the user for instant actions and generates a message to sign. This message includes the following details:

  • Wallet Address (address): The multiaccount address to be used with instant trading.

  • Nonce (nonce): The nonce related to the request.

  • Domain (domain): The domain of the application.

  • URI (uri): The specific endpoint the request is associated with (e.g., the login endpoint).

  • Issued At (issuedAt): The timestamp when the message was created.

  • Expiration Time (expirationTime): The time after which the signature is no longer valid.

Once the message is signed, the frontend sends this signed message along with other necessary data (such as the nonce, expiration time, and wallet address) to the solver API via a request (e.g., to the /login endpoint).

The solver should issue an access token which the frontend stores and includes it in the headers of future requests until the token expires. Solvers should validate the stored access token before proceeding with any API request. The expiration time can be set by the frontend and should be checked before every API call.

This section covers the API endpoints and request/response structures needed for instant trading.

Authentication and Session Management

Before executing any trading actions, solvers must authenticate the user and manage sessions via the following endpoints.

Nonce Retrieval

Endpoint: GET /nonce/{activeAddress}

  • Description: Retrieve a nonce for signing the login message.

Parameters:

  • activeAddress (string): The user's active multiaccount wallet address.

Response:

{
 "nonce": "string"
}

User Login

Endpoint: POST /login

  • Description: Authenticates the user and retrieves an access token. The nonce is obtained in the previous API call. The access token is saved to the browser locally, meaning the user won't have to log in again after closing and reopening the browser.

Request Body:

{
 "account_address": "string",
 "expiration_time": "ISO8601 datetime string",
 "issued_at": "ISO8601 datetime string",
 "signature": "string",
 "nonce": "string"
}

Response:

{
 "access_token": "string"
}

Get Pending Instant Open Requests

Endpoint: GET /instant_open/{account_address}

Description: This endpoint retrieves a statement for all pending instant open requests for a given account.

Parameters:

  • account_address (string): The user's multi-account wallet address.

Response: A list of pending instant open requests for the given account. Each object in the list contains details of the requested positions.

Response Schema:

[
  {
    "position_type": 0 // 0 for long, 1 for short,
    "temp_quote_id": "string",
    "symbol_id": "string",
    "requested_open_price": "string",
    "quantity": "string",
    "party_a_address": "string",
    "cva": "string",
    "partyAmm": "string",
    "partyBmm": "string",
    "lf": "string",
    "order_type": 0 // 0 for limit, one for market
  }
]

Instant Actions

These endpoints allow solvers to execute instant open and close actions on the user's behalf.

Instant Open Position

Endpoint: POST /instant_open

Opens a position instantly on behalf of the user. The user’s account balance is checked, including allocated balance, unrealized PnL, and locked amounts (cva, lf, partyAmm). If the user has too many pending instant RFQs, or if their available balance does not cover the new RFQ's requirements, the request should be rejected.

A temporary quote ID is generated, and the necessary request data is emitted and stored in Redis. The request is registered as a pending instant open action (stored in the InstantRFQs table).

Response:

Upon successful registration, the details of the newly created instant RFQ are returned, including position type, symbol ID, quote ID, and other relevant data.

Request Body:

{
 "symbolId": "string",
 "positionType": 0, // 0 for long, 1 for short
 "orderType": 0,    // 0 for limit, 1 for market
 "price": "string",
 "quantity": "string",
 "cva": "string",
 "lf": "string",
 "partyAmm": "string",
 "partyBmm": "string",
 "maxFundingRate": "string",
 "deadline": 1625234523 // Unix timestamp
}

Headers:

headers: {
   "Content-Type": "application/json",
   Authorization: `Bearer ${token}`,
},

Response:

[
  {
    "position_type": 0 // 0 for long, 1 for short,
    "temp_quote_id": "string",
    "symbol_id": "string",
    "requested_open_price": "string",
    "quantity": "string",
    "party_a_address": "string",
    "cva": "string",
    "partyAmm": "string",
    "partyBmm": "string",
    "lf": "string",
    "order_type": 0 // 0 for limit, one for market
  }
]

This response includes the temporary temp_quote_id which allows the system to track the quote before it is confirmed on-chain. Once confirmed, the real quote_id will be resolved and stored.

How Temporary Quote IDs Work:

  • A temporary quote ID is generated as a negative decremental integer when the instant open request is made.

  • The temporary quote ID is used to track the status of the position until the actual on-chain quote_id is confirmed.

  • Once the on-chain transaction is confirmed, the real quote_id replaces the temporary one.

  • The position state endpoint will provide the real quote_id after the resolution, allowing the user to track the final status.

Instant Close Position

Endpoint: POST /instant_close

  • Description: Closes an open position instantly on behalf of the user. The API checks the validity of the request based on the user's access, the state of the position, and available balance The close is always processed as a MARKET order.

Request Body:

{
 "quote_id": number,
 "quantity_to_close": "string",
 "close_price": "string"
}

Headers:

headers: {
   "Content-Type": "application/json",
   Authorization: `Bearer ${token}`,
},

Response:

{
 "successful": "boolean",
 "message": "string"
}

Get Instant Close Requests

Endpoint: GET /instant_close/{account_address}

Description: Retrieves all pending instant close requests for the provided user's account (account_address). The system returns a list of pending close requests for both instant close requests and any regular close requests that are still being processed.

Headers:

{
  "Authorization": `Bearer ${token}`   // Access token obtained during login
}

Response:

[
  {
    "quote_id": number,             
    "quantity_to_close": "string",  
    "close_price": "string"           },
  {
    "quote_id": number,
    "quantity_to_close": "string",
    "close_price": "string"
  }
]

Cancel Instant Action

Endpoints:

  • DELETE /instant_close/{quoteId}

  • DELETE /instant_open/{quoteId}

Description: Cancel an open or close request.

Parameters:

  • quoteId (integer): The temporary ID of the instant quote to be canceled.

Headers:

headers: {
   "Content-Type": "application/json",
   Authorization: `Bearer ${token}`,
},

Response:

{
 "successful": "boolean",
 "message": "string"
}

Contract Calls for Instant Trading

In order to implement instant actions it’s necessary for the user to call delegateAccess() on the MultiAccount contract for the respective sub-account to the partyB address, which performs actions on behalf of the user. This transaction should include the function signatures which partyB needs access to for instant trading.

To execute functions on behalf of partyA, the partyB should use the _call() function on the MultiAccount contract and pass the partyA address as a parameter with the _callDatas.

After this step the user should then sign the message from the solver.

Instant Open

For Instant Opens, delegateAccess() should be called from the trader’s wallet with the following parameters:

  • account (address): The User’s sub-account

  • target (address) : The address of the PartyB

  • selector (bytes4[]): 0x7f2755b2 (Function selector for sendQuote) AND 0x40f1310c (Function selector for sendQuoteWithAffiliate)

  • state (bool): true

Instant Close

For Instant Close, delegateAccess() should be called from the trader’s wallet with the following parameters:

  • account(address): The User’s sub-account

  • target(address) : The address of the PartyB

  • selector(bytes4[]): 0x501e891f (Function selector for requestToClosePosition)

  • state (bool): true

Last updated

Logo

All rights to the people (c) 2023 Symmetry Labs A.G.