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.
Any valid bytes32 can be used as an identifier but we suggest you to avoid unicode characters.
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;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.
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>
}
}'Signers are restricted to a configurable number per specified time period (in days). This value is applied across all subaccounts. See System Limits to read more about linked signer limits.
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:
If you suspect your device has been compromised or you've lost access then revoking allows you to immediately invalidate that signer.
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>
}
}'All resting orders signed by this signer must be canceled before the signer can be revoked. Linked signers are settled and used for verified onchain. If an order is traded offchain, signed by a linked signer that is revoked onchain, then the trade cannot be relayed.
Linked signers cannot withdraw funds. This restriction is intentional. Linked signers enable delegated trading and access to non-public subaccount information but the primary wallet retains exclusive control over fund withdrawals.
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.
Expiration enforcement happens at the offchain level through the trading API, which will reject requests from expired signers, rather than through on-chain verification. To completely clear out expired signers, it is recommended to revoke them.
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
