Ithaca Python SDK Reference
Version: 0.2.30
Description: A Python library to interact with the Ithaca Protocol (for both on-chain and off-chain operations).
Table of Contents
- Authentication & Session Handling
- Market & Orders
- Client: Positions & History
- Fundlock: Deposits & Withdrawals
- Calculation & Fees
- Analytics
- Protocol & Misc
- Common HTTP Status Codes
- Socket and Real-Time Updates
Authentication & Session Handling
Auth.login()
Description
Performs an Ethereum signature-based login, generating an authToken that is stored in the internal session. This allows subsequent API calls without needing extra credentials.
Endpoints Invoked
- POST /v1/auth/requestAuth (requests nonce)
- POST /v1/auth/validateAuth (validates signature)
No direct user parameters—uses your private_key from IthacaSDK(...).
Example
sdk = IthacaSDK(private_key="0xabc123...", env_name="CANARY")
login_ok = sdk.auth.login()
print("Logged in:", login_ok)
Example Response (typical success):
{
"result": "OK",
"details": "",
"payload": {
"authToken": "ec798c76-8032-45fd-af44-4eb7cc1f2b01",
"clientId": 12345,
"ethAddress": "0x123abc...",
"riskScoreValidationStatus": "PENDING",
"accountInfos": {}
}
}
Potential Errors
- 401 if signature fails or session is invalid.
- 500 on unexpected server error.
Auth.logout()
Description
Invalidates the current authToken and ends the server-side session.
Endpoint
- POST /v1/auth/logout
Example
sdk.auth.logout()
Example Response:
{"result": "OK"}
If the user was never logged in, a 401 may occur.
Auth.link_address(address)
Description
Links a secondary (managed) wallet to the currently authenticated user’s main wallet.
Endpoints
- POST /v1/linked_wallets/request_link
- POST /v1/linked_wallets/confirm_link
Parameters
- address (str): The address to link
Example
resp = sdk.auth.link_address("0xManagerAccount123")
Typical Response:
{
"result": "OK",
"details": "",
"payload": "some success message or object"
}
Errors
- 401 if not logged in.
- 412 if already linked or address invalid.
Market & Orders
Orders.new_order(legs, price, client_order_id=None, time_in_force="GOOD_TILL_CANCEL", ...)
Description
Places a new “conditional” order with one or more legs. Requires an authenticated session.
Endpoint
- POST /v1/clientapi/newOrder
Key Parameters
- legs (list of tuples): Each (contractId, side, quantity)
- side is "BUY" or "SELL".
- price (float): The limit/conditional price.
- time_in_force (str): e.g. "GOOD_TILL_CANCEL".
Example
legs = [(5559, "SELL", 1.0), (5563, "BUY", 1.0)]
response = sdk.orders.new_order(legs, price=99.5)
Example Request Body
{
"clientOrderId": 1742473240341423,
"totalNetPrice": "99.5000",
"legs": [
{"contractId": 5559, "side": "SELL", "quantity": "1.0000"},
{"contractId": 5563, "side": "BUY", "quantity": "1.0000"}
],
"signature": "<EIP712-signature>",
"orderGenesis": "CLIENT_PREDEFINED",
"orderDescr": "",
"requestSinglePrice": true
}
Example Response
{
"result": "OK",
"details": "",
"payload": {},
"clientOrderId": 1742473240341423
}
Errors
- 401 if not authenticated.
- 412 for insufficient collateral or invalid input.
- 500 if internal server error.
Orders.open_orders()
Description
Returns current open orders.
Endpoint
- POST /v1/clientapi/clientOpenOrders
Example
resp = sdk.orders.open_orders()
Truncated Example Response:
{'result': 'OK',
'details': '',
'payload': [{'revDate': 1738360260010,
'orderId': 1780080905569458,
'clientId': 1759288230128641,
'orderStatus': 'NEW',
'netPrice': -0.0111,
'orderGenesis': 'CLIENT_PREDEFINED',
'orderDescr': 'Quoter - Call 3',
'collateral': {'currencyPair': 'WETH/USDC',
'underlierAmount': 0.0007,
'numeraireAmount': 0.0},
'timeInForce': 'GOOD_TILL_CANCEL',
'orderClass': 'ConditionalOrder',
'requestSinglePrice': True,
'iocAuctionTime': 0,
'details': [{'contractId': 36875,
'contractDto': {'contractId': 36875,
'payoff': 'Call',
'economics': {'currencyPair': 'WETH/USDC',
'expiry': 250205080,
'strike': 3600.0,
'priceCurrency': 'USDC',
'qtyCurrency': 'WETH'},
'tradeable': True},
'side': 'SELL',
'originalQty': 0.0007,
'remainingQty': 0.0007,
'cancelledQty': 0.0,
'avgPrice': 0.0,
'totalCost': 0.0,
'currencyPair': 'WETH/USDC',
'expiry': 250205080}],
'insertionDate': 1738360264223,
'spotPriceAtCreation': 3315.14},
{'revDate': 1738360260010,
'orderId': 1780080904649219,
'clientId': 1759288230128641,
'orderStatus': 'NEW',
'netPrice': 0.0184,
'orderGenesis': 'CLIENT_PREDEFINED',
'orderDescr': 'Quoter - Call 3',
'collateral': {'currencyPair': 'WETH/USDC',
'underlierAmount': 0.0,
'numeraireAmount': 0.0},
'timeInForce': 'GOOD_TILL_CANCEL',
'orderClass': 'ConditionalOrder',
'requestSinglePrice': True,
'iocAuctionTime': 0,
'details': [{'contractId': 30927,
'contractDto': {'contractId': 30927,
'payoff': 'Call',
'economics': {'currencyPair': 'WETH/USDC',
'expiry': 250207080,
'strike': 3600.0,
'priceCurrency': 'USDC',
'qtyCurrency': 'WETH'},
'tradeable': True},
'side': 'BUY',
'originalQty': 0.0008,
'remainingQty': 0.0008,
'cancelledQty': 0.0,
'avgPrice': 0.0,
'totalCost': 0.0,
'currencyPair': 'WETH/USDC',
'expiry': 250207080}],
'insertionDate': 1738360264223,
'spotPriceAtCreation': 3315.14},
{'revDate': 1738360260010,
'orderId': 1780080904991230,
'clientId': 1759288230128641,
'orderStatus': 'NEW',
'netPrice': 0.0016,
'orderGenesis': 'CLIENT_PREDEFINED',
'orderDescr': 'Quoter - Call 2',
'collateral': {'currencyPair': 'WETH/USDC',
'underlierAmount': 0.0,
'numeraireAmount': 0.0},
'timeInForce': 'GOOD_TILL_CANCEL',
'orderClass': 'ConditionalOrder',
'requestSinglePrice': True,
'iocAuctionTime': 0,
'details': [{'contractId': 36273,
'contractDto': {'contractId': 36273,
'payoff': 'Call',
'economics': {'currencyPair': 'WETH/USDC',
'expiry': 250203080,
'strike': 3500.0,
'priceCurrency': 'USDC',
'qtyCurrency': 'WETH'},
'tradeable': True},
'side': 'BUY',
'originalQty': 0.0005,
'remainingQty': 0.0005,
'cancelledQty': 0.0,
'avgPrice': 0.0,
'totalCost': 0.0,
'currencyPair': 'WETH/USDC',
'expiry': 250203080}],
'insertionDate': 1738360264223,
'spotPriceAtCreation': 3315.14},
{'revDate': 1738360260010,
'orderId': 1780080904616646,
'clientId': 1759288230128641,
'orderStatus': 'NEW',
'netPrice': -0.0567,
'orderGenesis': 'CLIENT_PREDEFINED',
'orderDescr': 'Quoter - Call 2',
'collateral': {'currencyPair': 'WETH/USDC',
'underlierAmount': 0.0012,
'numeraireAmount': 0.0},
'timeInForce': 'GOOD_TILL_CANCEL',
'orderClass': 'ConditionalOrder',
'requestSinglePrice': True,
'iocAuctionTime': 0,
'details': [{'contractId': 30919,
'contractDto': {'contractId': 30919,
'payoff': 'Call',
'economics': {'currencyPair': 'WETH/USDC',
'expiry': 250207080,
'strike': 3500.0,
'priceCurrency': 'USDC',
'qtyCurrency': 'WETH'},
'tradeable': True},
'side': 'SELL',
'originalQty': 0.0012,
'remainingQty': 0.0012,
'cancelledQty': 0.0,
'avgPrice': 0.0,
'totalCost': 0.0,
'currencyPair': 'WETH/USDC',
'expiry': 250207080}],
'insertionDate': 1738360264223,
'spotPriceAtCreation': 3315.14},
{'revDate': 1738360260010,
'orderId': 1780080904843514,
'clientId': 1759288230128641,
'orderStatus': 'NEW',
'netPrice': -0.0153,
'orderGenesis': 'CLIENT_PREDEFINED',
'orderDescr': 'Quoter - Put 3',
'collateral': {'currencyPair': 'WETH/USDC',
'underlierAmount': 0.0,
'numeraireAmount': 2.4},
'timeInForce': 'GOOD_TILL_CANCEL',
'orderClass': 'ConditionalOrder',
'requestSinglePrice': True,
'iocAuctionTime': 0,
'details': [{'contractId': 30925,
'contractDto': {'contractId': 30925,
'payoff': 'Put',
'economics': {'currencyPair': 'WETH/USDC',
'expiry': 250207080,
'strike': 3000.0,
'priceCurrency': 'USDC',
'qtyCurrency': 'WETH'},
'tradeable': True},
'side': 'SELL',
'originalQty': 0.0008,
'remainingQty': 0.0008,
'cancelledQty': 0.0,
'avgPrice': 0.0,
'totalCost': 0.0,
'currencyPair': 'WETH/USDC',
'expiry': 250207080}],
'insertionDate': 1738360264223,
'spotPriceAtCreation': 3315.14},
...
]
}
Errors
- 401 if session is invalid.
- 500 server error.
Orders.open_orders_with_lock_info()
Description
Returns open orders including collateral lock info.
Endpoint
- POST /v1/clientapi/clientOpenOrdersWithLockInfo
Example
resp = sdk.orders.open_orders_with_lock_info()
Truncated Example Response:
{
"result": "OK",
"details": "",
"payload": {
"openOrders": [
{
"orderId": 1779794543802527,
"netPrice": 1.4431,
"details": [
{ "contractId": 30919, "side": "SELL", ... },
...
],
"insertionDate": 1738080609604,
"spotPriceAtCreation": 3171.06
}
],
"softLock": {
"currencyPair": "WETH/USDC",
"numeraireAmount": 7.5906
},
"postExecutionLock": {
"currencyPair": "WETH/USDC",
"numeraireAmount": 7.4431
}
}
}
Orders.order_cancel(client_order_id)
Description
Cancel a single open order by its client_order_id.
Endpoint
- POST /v1/clientapi/orderCancel
Parameters
- client_order_id (int)
Example
sdk.orders.order_cancel(1742473240341423)
Example Response
{"result": "OK","details": ""}
Orders.order_cancel_all(contains=None)
Description
Cancels all orders, optionally filtered by a substring.
Endpoint
- POST /v1/clientapi/allOrdersCancel?contains=...
Example
resp = sdk.orders.order_cancel_all()
Truncated Example Response:
{
"result": "OK",
"details": "",
"payload": [
{
"clientId": 1755725897769985,
"clientOrderId": 1779794543802527
}
]
}
Orders.order_status(client_order_id)
Description
Get status for a specific order.
Endpoint
- POST /v1/clientapi/orderStatus
Example
sdk.orders.order_status(1780080905569458)
Example Response (if invalid):
{'result': 'OK',
'details': '',
'payload': {'revDate': 1738360275010,
'orderId': 1780080905569458,
'clientId': 1759288230128641,
'orderStatus': 'CANCELED',
'ordRejReason': 'CANCELLED_BY_USER',
'netPrice': -0.0111,
'orderGenesis': 'CLIENT_PREDEFINED',
'orderDescr': 'Quoter - Call 3',
'timeInForce': 'GOOD_TILL_CANCEL',
'orderClass': 'ConditionalOrder',
'requestSinglePrice': True,
'iocAuctionTime': 0,
'details': [{'contractId': 36875,
'contractDto': {'contractId': 36875,
'payoff': 'Call',
'economics': {'currencyPair': 'WETH/USDC',
'expiry': 250205080,
'strike': 3600.0,
'priceCurrency': 'USDC',
'qtyCurrency': 'WETH'},
'tradeable': True},
'side': 'SELL',
'originalQty': 0.0007,
'remainingQty': 0.0,
'cancelledQty': 0.0007,
'avgPrice': 0.0,
'totalCost': 0.0,
'currencyPair': 'WETH/USDC',
'expiry': 250205080}],
'insertionDate': 1738360281627,
'spotPriceAtCreation': 3315.14}}
Client: Positions & History
Client.current_positions(_filter=None, details=False)
Description
Fetch the user’s current open positions.
Endpoint
- POST /v1/clientapi/clientCurrentPositions
Parameters
- _filter (str): "COMBINE_STRATEGIES", "SHOW_ORDERS", etc.
- details (bool): If True, returns a pandas DataFrame with contract info (when used in Python).
Example
positions = sdk.client.current_positions(_filter="SHOW_ORDERS", details=True)
Truncated Response:
{
"result":"OK",
"payload":[
{
"contractId":30913,
"positionsAvgPrice":133.0,
"positionsQty":-0.0002
},
...
]
}
Client.fundlock_state()
Description
Retrieve the client’s fundlock state (locked deposit info).
Endpoint
- POST /v1/clientapi/clientFundLockState
Example
sdk.client.fundlock_state()
Example Response:
{
"result": "OK",
"details": "",
"payload": [
{
"currency": "WETH",
"orderValue": 0.0,
"fundLockValue": 10.0,
"settleValue": -4.39e-05
},
{
"currency": "USDC",
"orderValue": 0.0,
"fundLockValue": 10.0,
"settleValue": 0.3953
}
]
}
Client.historical_positions(expiry, _filter="NO_DETAILS")
Description
Return historical (closed) positions at a specific expiry.
Endpoint
- POST /v1/clientapi/clientHistoricalPositions
Parameters
- expiry (int): e.g. 250207080
- _filter (str): "NO_DETAILS", "SHOW_ORDERS", etc.
Example
resp = sdk.client.historical_positions(250207080, _filter="NO_DETAILS")
Example Response (If error):
{'result': 'OK',
'details': '',
'payload': {'240915080': {'totalCollateral': {'WETH/USDC': {'currencyPair': 'WETH/USDC',
'underlierAmount': 0.0008,
'numeraireAmount': 0.1583}},
'expiryPrices': {'WETH/USDC': 2423.1799},
'payoff': {'WETH/USDC': {'currencyPair': 'WETH/USDC',
'underlierAmount': 0.0007243,
'numeraireAmount': 0.0794}},
'positions': [{'contractId': 6663,
'positionsAvgPrice': 2182.0667,
'positionsQty': -0.0015},
{'contractId': 6571, 'positionsAvgPrice': 58.5, 'positionsQty': 0.0004},
{'contractId': 6573,
'positionsAvgPrice': 198.969,
'positionsQty': -0.0012997},
{'contractId': 6578, 'positionsAvgPrice': 1.0, 'positionsQty': 0.03},
(Might indicate the given expiry doesn’t exist or a server issue.)
Client.historical_positions_by_date(_from, to)
Description
Return historical positions for a date range in milliseconds since 1970.
Endpoint
- POST /v1/clientapi/clientHistoricalPositionsByDatePeriod
Parameters
- _from (int): e.g. 1690000000
- to (int): e.g. 1695000000
Example
resp = sdk.client.historical_positions_by_date(1690000000, 1695000000)
Shortened Example Response:
{
"result":"OK",
"payload":{
"240915080":{
"totalCollateral":{"WETH/USDC":{"currencyPair":"WETH/USDC","underlierAmount":0.0008,"numeraireAmount":0.1583}},
"expiryPrices":{"WETH/USDC":2423.1799},
"payoff":{"WETH/USDC":{"underlierAmount":0.0007243,"numeraireAmount":0.0794}},
"positions":[
{"contractId":6663,"positionsAvgPrice":2182.0667,"positionsQty":-0.0015},
...
]
},
...
}
}
Client.positions_lock_state()
Description
Retrieve client’s locked positions collateral by expiry.
Endpoint
- POST /v1/clientapi/getLockedCollateral
Example
sdk.client.positions_lock_state()
Truncated Example Response:
{
"result":"OK",
"payload":{
"1738569600000":[
{
"clientId":1759288230128641,
"expiry":250203080,
"locked":{
"currencyPair":"WETH/USDC",
"underlierAmount":5e-07,
"numeraireAmount":1.057
},
"feesPaid":3.0576
}
],
...
}
}
Client.trade_history(date_from=None, date_to=None, offset=None, limit=None, status=None)
Description
Fetch user’s trade history.
Endpoint
- POST /v1/clientapi/tradeHistory
Example
resp = sdk.client.trade_history(date_from=1690000000, date_to=1695000000, limit=10)
Truncated Example Response:
{
"result": "OK",
"details": "",
"payload": []
}
Fundlock: Deposits & Withdrawals
Fundlock.deposit(symbol, amount)
Description
Approves (if needed) and deposits tokens from your wallet to the Ithaca FundLock contract on-chain.
Endpoint
(On-chain transaction; no direct Ithaca REST endpoint is used. The SDK calls Web3.)
Parameters
- symbol (str): e.g. "USDC", "WETH".
- amount (int or float): The amount (scaled by token decimals).
Example
sdk.fundlock.deposit("USDC", 100000000) # If USDC has 6 decimals => 100 USDC
On success, returns a web3 tx receipt:
{
"transactionHash": "0xf4de...",
"status": 1,
...
}
Errors
- “Invalid token” if symbol is unrecognized.
- On-chain revert if insufficient balance.
Fundlock.withdraw(symbol, amount)
Description
Requests a withdrawal from the Ithaca FundLock contract. The user can then “release” after a lock period.
Endpoint
(On-chain transaction via Web3.)
Parameters
- symbol (str)
- amount (int or float)
Example
sdk.fundlock.withdraw("USDC", 50000000) # withdraw 50 USDC if 6 decimals
Returns a web3 receipt or None on error.
Fundlock.release(symbol, withdrawal_slot)
Description
Releases funds previously withdrawn after the lock period.
Endpoint
(On-chain transaction)
Parameters
- symbol (str)
- withdrawal_slot (int)
Example
sdk.fundlock.release("USDC", withdrawal_slot=1)
Returns a web3 tx receipt or None.
Fundlock.history()
Description
Fetch all deposit/withdrawal history from the subgraph.
Endpoint
(GraphQL request to self.parent.subgraph_url)
Example
sdk.fundlock.history()
Truncated Example Response:
{
"errors": "...",
"data": {
"account": {
"deposits": [...],
"withdrawalRequests": [...],
"releases": [...]
}
}
}
If your subgraph URL is None, you might get an error.
Calculation & Fees
Calculation.calc_portfolio_collateral()
Description
Calculate portfolio collateral usage given your current positions (session-based).
Endpoint
- POST /v1/clientapi/calcPortfolioCollateral
Example
sdk.calculation.calc_portfolio_collateral()
Example Response:
{
"result": "OK",
"details": "",
"payload": {
"actual": {
"currencyPair":"WETH/USDC",
"underlierAmount":0.0,
"numeraireAmount":0.0
},
"potential": {
"currencyPair":"WETH/USDC",
"underlierAmount":0.0,
"numeraireAmount":0.0
}
}
}
Calculation.estimate_order_lock(...)
Description
Estimates how much collateral would be locked by a hypothetical order.
Endpoint
- POST /v1/clientapi/estimateOrderLock
Example
sdk.calculation.estimate_order_lock(legs=..., price=..., order_type="LIMIT")
Typical Errors
- Will fail if legs is empty or if user is not logged in.
Calculation.estimate_order_fees(...)
Description
Estimate the fees for a proposed order.
Endpoint
- POST /v1/clientapi/estimateOrderFees
or
- POST /v1/clientapi/estimateOrderFeesExtended
Example
sdk.calculation.estimate_order_fees(legs=..., price=..., order_type="LIMIT")
Errors
- Same as above, e.g. NoneType if invalid parameters.
Analytics
Below, we demonstrate typical calls for the "WETH/USDC" pair. Each method is configured similarly for other pairs.
Analytics.total_trading_volume()
Description
Returns total trading volume for the specified underlier/numeraire.
Endpoint
- GET /v1/analytics/{underlier}/{numeraire}/totalTradingVolume
Example
resp = sdk.analytics.total_trading_volume()
Shortened Response:
{
"response": {
"num": 847.50825,
"totalInNum": 279198.91263458,
"totalInUnd": 95.6624274,
"und": 95.3386274
}
}
Analytics.total_open_interest()
Description
Fetch total open interest (OI).
Endpoint
- GET /v1/analytics/{underlier}/{numeraire}/totalOpenInterest
Example
resp = sdk.analytics.total_open_interest()
If no OI => server returns 204 NO_CONTENT.
If error => possibly "<Response [500]>".
Analytics.total_value_locked()
Description
Get total value locked (TVL).
Endpoint
- GET /v1/analytics/{underlier}/{numeraire}/totalValueLocked
Example
resp = sdk.analytics.total_value_locked()
Example:
{
"response": 715298652.1484877
}
(Large numeric means 715M in USDC, for instance.)
Analytics.trades(date_range=...)
Description
Returns aggregated trades data over a date range.
Endpoint
- POST /v1/analytics/{underlier}/{numeraire}/trades
Example
resp = sdk.analytics.trades(since=someDate, to=someDate)
Truncated Example:
{
"response": {
"2025-01-01T00:00": 169040,
"2025-01-02T00:00": 157875,
...
}
}
If no data: 204.
Analytics.open_interest_by_product(date_range=...)
Description
Open interest grouped by product type (Call, Put, BinaryCall, etc.).
Endpoint
- POST /v1/analytics/{underlier}/{numeraire}/openInterestByProduct
Truncated Example:
{
"response": {
"Binary Call": {
"num": 25.4212,
"totalInNum": 25.4212,
...
},
"Call": {...},
"Forward": {...},
"Put": {...}
}
}
Analytics.open_interest_by_strike(date_range=..., strike_range=...)
Description
Open interest grouped by strike prices.
Endpoint
- POST /v1/analytics/{underlier}/{numeraire}/openInterestByStrike
Truncated Example:
{
"response": {
"2700.0": {
"Put": {...}
},
"3000.0": {
"Call": {...},
"Put": {...}
},
"3500.0": {
"Binary Call": {...},
"Call": {...}
}
}
}
Analytics.daily_volume(date_range=...)
Description
Aggregated daily volume.
Endpoint
- POST /v1/analytics/{underlier}/{numeraire}/dailyVolume
Truncated Example:
{
"response": {
"2025-01-01T00:00": {
"num": 0,
"totalInNum": 670.95531,
"totalInUnd": 0.2001,
"und": 0.2001
},
...
}
}
Analytics.best_prices()
Description
Returns best bid/ask for each contract (estimated or from real orders).
Endpoints
- POST /clientapi/bestBidAsk
- POST /clientapi/bestBidAskPrecise
Truncated Example:
{
"result": "OK",
"details": "",
"payload": {
"30903": {
"bestAsk": 120.5833,
"bestBid": 115.0,
"askVolume": 0.0024,
"bidVolume": 0.0016
},
...
}
}
If none found, can return empty object.
Protocol & Misc
Protocol.system_info()
Description
Retrieves system parameters: fundlock address, token addresses, etc.
Endpoint
- POST /v1/clientapi/systemInfo
Example
info = sdk.protocol.system_info()
Truncated Example:
{
"result": "OK",
"payload": {
"fundlockAddress": "0xabc123...",
"tokenAddress": {
"USDC": "0xTokenUsdcAddr",
"WETH": "0xTokenWethAddr"
},
...
}
}
Common HTTP Status Codes
- 200 OK
Request succeeded; typically returns JSON of the form{"result": "OK", "payload": ...}. - 204 NO_CONTENT
Request succeeded but no data is available (empty response). - 400 BAD_REQUEST
The request’s JSON or input is malformed. - 401 UNAUTHORIZED
No valid session; you must login. - 404 NOT_FOUND
The resource or item ID was not found. - 412 PRECONDITION_FAILED
Validation or logical failure. E.g. insufficient collateral, invalid address, etc. - 500 INTERNAL_SERVER_ERROR
Unexpected server-side error.
Socket and Real-Time Updates
The SDK provides a WebSocket-based interface for streaming real-time events such as:
- Execution reports (updates about order fills or cancellations)
- Auction notifications (e.g.
AUCTION_STARTED,AUCTION_FINISHED) - Orderbook updates (
ORDERBOOK,MM_ORDERBOOK_UPDATED, etc.) - Trade reports (
TRADE_REPORT) - Fundlock updates (
FUNDLOCK_UPDATED) - Other server-pushed notifications
Once you connect and authenticate, the server begins pushing messages to your provided callback function.
Overview
- Connect: Call
sdk.socket.connect(on_message=..., on_open=...). - Authenticate: Upon connection, the SDK automatically logs in (via Ethereum private key or RSA) and sends a
VALIDATE_AUTH_TOKENaction so the server knows who you are. - Receive Messages: The server sends JSON objects containing a
responseTypeandpayload, among other fields. - Process: In your
on_messagecallback, parse the JSON and handle theresponseType(e.g.EXEC_REPORT,ORDERBOOK,AUCTION_STARTED, etc.). - Close: If needed, call
sdk.socket.close()to stop streaming and reconnect attempts.
Important: The SDK will auto-reconnect if the connection drops or if the server instructs you to reconnect.
Socket.connect(on_message=None, on_open=None)
Description
Starts a background thread to connect to the WebSocket endpoint specified in your IthacaSDK constructor (ws_endpoint). The method also ensures you are authenticated using your existing credentials (private_key or RSA). If authentication fails, the SDK retries with exponential backoff.
- Parameters
on_message (function): Your callback to handle server messages.- Signature should be
on_message(ws, message). wsis the raw WebSocket object fromwebsocket-client.messageis a string containing JSON from the server.
- Signature should be
on_open (function, optional): Callback invoked once the socket is fully open (post-auth).- Signature:
on_open(ws). - Useful if you want to immediately send subscription messages to the server.
- Signature:
Example
import json
def my_on_message(ws, message):
data = json.loads(message)
response_type = data.get("responseType")
if response_type == "VALIDATE_AUTH_TOKEN_RESPONSE":
print("Socket authenticated successfully!", data)
elif response_type == "AUCTION_STARTED":
print("Auction started:", data["payload"])
elif response_type == "EXEC_REPORT":
print("Execution report:", data["payload"])
else:
print("Other socket response:", data)
# Connect
sdk.socket.connect(on_message=my_on_message)
Typical responseType Values
-
VALIDATE_AUTH_TOKEN_RESPONSE
Confirmation you’re authenticated -
EXEC_REPORT
Real-time updates about orders (canceled, partially/fully filled) -
AUCTION_STARTED / AUCTION_FINISHED
Auction cycle events -
ORDERBOOK, ORDERBOOK_DELTA, MM_ORDERBOOK_UPDATED
Orderbook updates -
TRADE_REPORT
Trade notifications -
FUNDLOCK_UPDATED
Fundlock/collateral changes -
HEARTBEAT_RESPONSE
Response to keep-alive requests -
UNKNOWN
Unexpected action or error
Note
If youron_messageoron_opencallback raises exceptions, the SDK logs them but continues running.
Handling Disconnections & Inactivity
The SDK automatically handles:
-
Network Disconnects
If the WebSocket closes unexpectedly, the SDK waits a few seconds and retries the connection, with an exponential backoff up to a maximum delay. -
Inactivity
By default, if no messages arrive withininactivity_thresholdseconds, the SDK closes and re-establishes the connection. This keeps the stream alive if the server times out idle connections.
Socket.close()
Description
Closes the current WebSocket connection and stops the automatic reconnect loop. After close() is called, the socket thread shuts down, and no more real-time messages will be received.
sdk.socket.close()
Complete Example
Below is a short snippet demonstrating how to:
- Initialize
IthacaSDK - Connect to the WebSocket
- Handle real-time messages (auctions, execution reports, etc.)
- Optionally send your own subscription commands in
on_open
import json
from ithaca import IthacaSDK
sdk = IthacaSDK(
private_key="0xabc123...",
api_endpoint="https://app.canary.ithacanoemon.tech/api/v1",
ws_endpoint="wss://app.canary.ithacanoemon.tech/wss"
)
def on_socket_open(ws):
# Subscribe to an linked accounts, to receive notifications of managed accounts.
subscribe_linked_accounts = {
"action": "subscribe_linked_accounts"
}
ws.send(json.dumps(subscribe_linked_accounts))
def on_socket_message(ws, message):
data = json.loads(message)
rtype = data.get("responseType")
if rtype == "VALIDATE_AUTH_TOKEN_RESPONSE":
print("WebSocket Authenticated:", data)
elif rtype == "EXEC_REPORT":
print("Exec report:", data["payload"])
elif rtype == "AUCTION_STARTED":
print("Auction started:", data["payload"])
else:
print("Received message:", rtype, data)
# Connect with your callbacks:
sdk.socket.connect(on_message=on_socket_message, on_open=on_socket_open)
This allows you to maintain real-time awareness of events happening in the Ithaca Protocol without constantly polling HTTP endpoints.