Page cover

Accounts & Signers

Overview

All trading on Ethereal is done through subaccounts. Users can create multiple subaccounts to manage positions and balances separately.

How to Create a Subaccount

To start trading on Ethereal, you'll need to establish at least one subaccount. This process begins with selecting a unique bytes32 identifier for your subaccount, followed by making an initial deposit.

We recommend using the default subaccount name primary (encoded as bytes32).

To deposit, call deposit or depositUsd directly through the exchange smart contracts:

/// @notice Deposit `amount` of token from msg.sender to the `subaccount`.
/// @param subaccount bytes32 encoded string of the subaccount (unique per EOA)
/// @param depositToken Address of the token to deposit
/// @param amount The amount of tokens in native units to deposit (non-D9)
/// @param referralCode accepted only on the first deposit for an account, reference to credit for referral
function deposit(bytes32 subaccount, address depositToken, uint256 amount, bytes32 referralCode) external;

/// @notice Deposit the value amount of USD from msg.sender to the `subaccount`.
/// @param subaccount bytes32 encoded string of the subaccount (unique per EOA)
/// @param referralCode accepted only on the first deposit for an account, reference to credit for referral
function depositUsd(bytes32 subaccount, bytes32 referralCode) external payable;

Set referralCode to bytes32(0) if you don't have a ref code. Subsequent deposits to the same subaccount will not create a new subaccount and follow the same path.

Users can create an unlimited number of subaccounts on our exchange without any restrictions on the total quantity. While we don't charge fees for deposits at present, each deposit must meet a specified minimum amount to ensure account viability. Though deposits are currently free, be aware that we may implement a nominal fee structure for deposits in the future as part of our evolving service model and preventing spam.

Querying

Upon deposit, funds enter a pending state while our system processes the transaction. The smart contracts emit events that are captured by our offchain indexer and verified by the matching engine. This verification is then relayed back onchain to complete the process.

Once confirmation is complete, the funds become available as margin for trading. This entire sequence typically completes within seconds. The two-step confirmation process is essential for maintaining synchronization between onchain smart contracts and our offchain systems, ensuring transaction integrity throughout the platform.

You can query the trading API to retrieve the state of your subaccount:

curl -X 'GET' \
  'https://api.ethereal.trade/v1/subaccount?sender=0x5d9351C05fA2a6F71d3D1c1A1218C77f2D60919e' \
  -H 'accept: application/json'
{
  "hasNext": false,
  "data": [
    {
      "id": "45783bec-4675-4116-8829-f277afe063d7",
      "name": "0x7072696d61727900000000000000000000000000000000000000000000000000",
      "account": "0x5d9351C05fA2a6F71d3D1c1A1218C77f2D60919e",
      "blockNumber": "11205366",
      "createdAt": 1743745535947
    }
  ]
}

In this example, we are querying for subaccounts belonging to 0x5d9351C05fA2a6F71d3D1c1A1218C77f2D60919e and the API has returned one subaccount with the id of 45783bec-4675-4116-8829-f277afe063d7 and a bytes32 subaccount name of 0x7072696d61727900000000000000000000000000000000000000000000000000(i.e. primary ).

Once you have a subaccount id you can also query the subaccount directly:

curl -X 'GET' \
  'https://api.ethereal.trade/v1/subaccount/45783bec-4675-4116-8829-f277afe063d7' \
  -H 'accept: application/json'

You can also query for the subaccount's balance by:

curl -X 'GET' \
  'https://api.ethereal.trade/v1/subaccount/balance?subaccountId=45783bec-4675-4116-8829-f277afe063d7' \
  -H 'accept: application/json'
{
  "hasNext": false,
  "data": [
    {
      "subaccountId": "45783bec-4675-4116-8829-f277afe063d7",
      "tokenId": "ff761c8b-6248-4673-b63d-d1f980551959",
      "tokenAddress": "0xa1623E0AA40B142Cf755938b325321fB2c61Cf05",
      "tokenName": "USD",
      "amount": "35.644112906",
      "available": "12014.500177678",
      "totalUsed": "317.97964604",
      "updatedAt": 1743851518800
    }
  ]
}

Linked Signers

Subaccounts can be linked to specialized signers (known as "linked signers") to enhance the trading experience for users. These linked signers are client-generated private keys associated with your EOA (i.e. the msg.sender of the original depositor) that enable specific limited functions without requiring message signatures from your main wallet.

Purpose of Linked Signers?

Linked signers allow users to submit and cancel orders without needing to sign a message through your EOA. This allows the exchange application to enable one-click trading, an improved UX feature that does not require wallet providers to prompt on every exchange interaction.

If you are integrating directly with the API, linked signers do not provide any additional UX as presemubly your trading bot would already have access to private keys. It is largely in place to provide retail traders with an improved trading experienced through a UI.

However, it does provide an added layer of security if you choose to deposit funds with your primary account and delegate order submissions and cancelations to a linked signer.

To link a signer to your subaccount, first generate a secure private key using any popular cryptography library of your choice. Once you have your private key, create an EIP712 signature by signing a SigningKey message with your EOA wallet, including the necessary action details, derived signer address, subaccount ID, and expiration time.

Submit this information to our API endpoint with the required parameters, and upon successful verification, the system will establish the connection between your subaccount and the new signing key, enabling streamlined order management without repetitive wallet signatures.

curl -X 'POST' \
  'https://api.ethereal.trade/v1/linked-signer/link' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "signature": "string",
  "signerSignature": "string",
  "data": {
    "subaccountId": "<id_of_subaccount_linked_to>",
    "sender": "<address_of_subaccount_linked_to>",
    "subaccount": "<bytes32_subaccount_name_linked_to>",
    "signer": "<linked_signer_address>",
    "nonce": "<nonce_in_nanoseconds_as_string>",
    "signedAt": <timestamp_in_seconds>
  }
}'

You can view a subaccount's remaining linked signer quota by:

curl -X 'GET' \
  'https://api.ethereal.trade/v1/linked-signer/quota?subaccountId=45783bec-4675-4116-8829-f277afe063d7' \
  -H 'accept: application/json'
{
  "maxLinkedSignersPeriodDays": 7,
  "maxLinkedSignersInPeriod": 5,
  "linkedSignersUsedInPeriod": 1
}

Revoking Signers

You can unlink a previously linked signer through the revoke flow. Revoking is essential as a security feature for several reasons:

  1. If you suspect your device has been compromised or you've lost access then revoking allows you to immediately invalidate that signer.

  2. It's also useful for general opsec, rotating signers as part of regular security practices

Once revoked, a signer cannot be relinked, ensuring complete invalidation of the compromised credentials.

You can revoke a signer by calling:

curl -X 'DELETE' \
  'https://api.ethereal.trade/v1/linked-signer/revoke' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "signature": "string",
  "data": {
    "subaccountId": "<subaccount_of_linked>",
    "sender": "<subccount_address_of_linked>",
    "subaccount": "<bytes32_name_of_subaccount_linked>",
    "signer": "<address_of_signer_to_revoke>",
    "nonce": "<nonce_in_nanoseconds_as_string>",
    "signedAt": <timestamp_in_seconds>
  }
}'

Signer Expiry

Signers have a built-in expiration mechanism that automatically invalidates them after a period of inactivity. Currently, linked signers have a 90 day expiration period, after which they must be refreshed before they can be re-used otherwise they will remain as expired and cannot be used for order placement and cancelations.

Ethereal supports multiple linked signers. A subaccount can have many signers linked. This is often useful when users have many devices used to place orders.

Querying for Linked Signers

To query for a subaccount's linked signers:

curl -X 'GET' \
  'https://api.ethereal.trade/v1/linked-signer?subaccountId=45783bec-4675-4116-8829-f277afe063d7&active=true' \
  -H 'accept: application/json'
{
  "hasNext": false,
  "data": [
    {
      "id": "b406a408-0494-4e57-99e0-c4af28ff790c",
      "signer": "0x033Ec075B617D384688f51f0780a25C0d389A03F",
      "isActive": true,
      "blockNumber": "11206111",
      "linkedAt": 1743746279000,
      "expiresAt": 1744456485480,
      "createdAt": 1743746274425
    }
  ]
}

Last updated