Stork Documentation
Search…
⌃K

Hybrid Oracle Documentation

Interested in our upcoming Near, Aptos, or Sui integrations? get in touch at [email protected] to participate in our early access program.
Stork's Websocket is an implementation of Stork's hybrid Oracle. The intended use for this API is for the dApp to consume the data off-chain, and submit to compatible chains, such as StarkEx, Arbitrum, and others, where the data can be verified.

Configuration

  • Each asset's price feed will update instantaneously either:
    • if the price has moved by 0.1% (10bp), or
    • if it has been 5 seconds since the previous update.
  • Ensure you obtained an API key and URL information from Stork prior to proceeding ([email protected])

StarkEx Configuration

If using Stork on StarkEx, you must confirm that your StarkEx configuration is properly configured with the public addresses of oracles (“List of public keys that are allowed to sign on this asset”) as well as list of external asset prices (“List of possible names to identify this asset, that will be signed by different Oracle companies”). Note that updating this configuration can take a significant amount of time, so we advise you to perform this well in advance of the time when you need to receive price updates.

Connecting to the Websocket

From an allowlisted IP or with an appropriate API key, you can connect to the client via cli using wscat:
wscat -c [WEBSOCKET URL] --header "Authorization: [YOUR KEY]"
Additionally, you can connect to the websocket using any standard websocket library. For example, in Python, libraries websocket and websocket-client both work.

Subscribing to Price Feeds

To receive live price updates, send a subscribe request:
{"action":"subscribe","assets":["BTCUSD","ETHUSD"]}
Price feeds also have unsubscribe functionality:
{"action":"unsubscribe","assets":["ETHUSD"]}
To toggle the signature from STARK (default) to EVM:
{"action":"set_signature", "type":"EVM"}
Price updates will arrive in a format similar to the StarkEx transaction format, in particular the signed_prices map can be directly passed into StarkEx; however is your responsibility to calculate the aggregate and properly quantize the median price for each asset, and provide the appropriate encoding for the asset ID to match your configuration.

Response Schemas

StarkNet / StarkEx

{
"oracle_prices":
ASSET_PAIR:{ // e.g. "BTCUSD"
"price": MEDIAN_PRICE, // e.g. "16029.1014" * 10^18
"evm_signed_prices":{
ORACLE_KEY: {
"external_asset_id": EXTERNAL_ASSET_ID,
"price": PRICE,
"timestamped_signature":{
"signature":{
"r": R,
"s": S,
},
"timestamp": ORACLE_TIMESTAMP,
"msg_hash": PEDERSEN_HASH
}
}
},
}
}

EVM (Ethereum, Avalanche, Arbitrum, and others)

{
"oracle_prices":
ASSET_PAIR:{ // e.g. "BTCUSD"
"price": MEDIAN_PRICE, // e.g. "16029.1014" * 10^18
"evm_signed_prices": {
ORACLE_ADDRESS: {
"external_asset_id": EXTERNAL_ASSET_ID,
"price": PRICE,
"timestamped_signature":{
"signature":{
"r": R,
"v": V,
"s": S
},
"timestamp": ORACLE_TIMESTAMP
}
},
"type": "ORACLES_PRICE_TICK",
"timestamp": TIMESTAMP,
}
}
}
The StarkEx function verify can be used to validate the authenticity of each Orace's update using the Pedersen Hash of the Oracle's message. As a deviation from the StarkEx transaction format, we have temporarily provided the parameter msg_hash so that the client can verify their calculation of the Pedersen Hash.

EVM Signature

The signature is calculated based on the keccak hash of the components of the price, which is then encoded for EVM-compatible chains and StarkEx and signed by each publisher.

Signature for EVM-compatible Chains (Python Sample)

concat_hash = keccak(encode_abi_packed(['string','string','uint256','uint256'],[oracle_name, asset_pair,timestamp,price]))
evm_packed_message_hash = encode_defunct(text=concat_hash.hex())
w3.eth.account.sign_message(evm_packed_message_hash)

Sample Python Code

Listening to price updates using the websocket-client library:
from websocket import create_connection import json
stork = create_connection([WEBSOCKET URL])
message = {"action": "subscribe", "assets": ["BTCUSD", "ETHUSD"]}
stork.send(json.dumps(message))
while True:
print(stork.recv())

Pinging and disconnects

The Websocket will kick an idle connection after 20 minutes. In order to sustain a longer connection, send a message to the Websocket every <20 minutes. Many websocket implementations, such as the Python websockets library, have built-in behavior to do this.
At any point you can send a ping command and you will automatically receive a response.
> {"action":"ping"}
< {"message": "pong"}
The maximal lifespan for a connection is 120 minutes, after which you will need to reconnect to the websocket client.

Getting Whitelisted

If you would like production access, or for your IP to be whitelisted, contact Stork at [email protected]