|
| 1 | +# Websocket API Reference |
| 2 | + |
| 3 | +You can connect to the server via websocket in order to reduce latency and subscribe to various events. The websocket endpoint relies at `/v1/ws`(e.g `wss://pyth-express-relay-mainnet.asymmetric.re/v1/ws`) |
| 4 | + |
| 5 | +## General format |
| 6 | + |
| 7 | +Each request sent to the server via websocket should be in the following json format: |
| 8 | + |
| 9 | +```json |
| 10 | +{ |
| 11 | + "id": "...", // used for uniquely identifying the responses to requests |
| 12 | + "method": "...", // name of the server method to invoke |
| 13 | + "params": {...} // parameters necessary for the method |
| 14 | +} |
| 15 | +``` |
| 16 | + |
| 17 | +The server responds using the same `id` specified in the request: |
| 18 | + |
| 19 | +```json |
| 20 | +{ |
| 21 | + "id": "...", |
| 22 | + "status": "success", |
| 23 | + "result": {} |
| 24 | +} |
| 25 | +``` |
| 26 | + |
| 27 | +In case of error, `status` field will be `error` and the error message will be available in the `result` field as a string: |
| 28 | + |
| 29 | +```json |
| 30 | +{ |
| 31 | + "id": "...", |
| 32 | + "status": "error", |
| 33 | + "result": "..." |
| 34 | +} |
| 35 | +``` |
| 36 | + |
| 37 | +## Subscribing to opportunities |
| 38 | + |
| 39 | +To subscribe to opportunities you can send a request with the `chain_ids` parameter which specifies the chains as an array. |
| 40 | + |
| 41 | +```json |
| 42 | +{ |
| 43 | + "id": "1", |
| 44 | + "method": "subscribe", |
| 45 | + "params": { |
| 46 | + "chain_ids": ["op_sepolia"] |
| 47 | + } |
| 48 | +} |
| 49 | +``` |
| 50 | + |
| 51 | +After a successful subscription you will receive the new opportunities for the selected chains via the websocket in the following format: |
| 52 | + |
| 53 | +```json |
| 54 | +{ |
| 55 | + "type": "new_opportunity", |
| 56 | + "opportunity": {...} |
| 57 | +} |
| 58 | +``` |
| 59 | + |
| 60 | +The schema for the opportunity is similar to what’s returned in the [http requests](https://pyth-express-relay-mainnet.asymmetric.re/docs/#/liquidation/get_opportunities) |
| 61 | + |
| 62 | +In order to unsubscribe from a list of chains you can send the following message: |
| 63 | + |
| 64 | +```json |
| 65 | +{ |
| 66 | + "id": "1", |
| 67 | + "method": "unsubscribe", |
| 68 | + "params": { |
| 69 | + "chain_ids": ["op_sepolia"] |
| 70 | + } |
| 71 | +} |
| 72 | +``` |
| 73 | + |
| 74 | +## Submitting bids |
| 75 | + |
| 76 | +In addition to the http methods, you can submit your bids via websocket in order to avoid additional network round-trips and get notified about changes to your bid status. Here is an example json payload for submitting a new bid |
| 77 | + |
| 78 | +```json |
| 79 | +{ |
| 80 | + "id": "1", |
| 81 | + "method": "post_bid", |
| 82 | + "params": { |
| 83 | + "bid": { |
| 84 | + "amount": "10", |
| 85 | + "calldata": "0xdeadbeef", |
| 86 | + "chain_id": "sepolia", |
| 87 | + "contract": "0xcA11bde05977b3631167028862bE2a173976CA11", |
| 88 | + "permission_key": "0xdeadbeefcafe" |
| 89 | + } |
| 90 | + } |
| 91 | +} |
| 92 | +``` |
| 93 | + |
| 94 | +A successful response to bid submission has the following schema: |
| 95 | + |
| 96 | +```json |
| 97 | +{ |
| 98 | + "id": "1", // websocket request id |
| 99 | + "status": "success", |
| 100 | + "result": { |
| 101 | + "id": "beedbeed-b346-4fa1-8fab-2541a9e1872d", //bid id |
| 102 | + "status": "OK" |
| 103 | + } |
| 104 | +} |
| 105 | +``` |
| 106 | + |
| 107 | +From this point you will receive notifications about the bid status updates in JSON format. We share four examples below, one for each of the status options (”pending”, “submitted”, “lost”, “won”): |
| 108 | + |
| 109 | +```json |
| 110 | +// pending |
| 111 | +// The temporary state which means the auction for this bid is pending |
| 112 | +{ |
| 113 | + "type": "bid_status_update", |
| 114 | + "status": { |
| 115 | + "id": "1eaee2a4-01bf-4f6c-8a76-21fadb2c43b1", |
| 116 | + "bid_status": { |
| 117 | + "type": "pending" |
| 118 | + } |
| 119 | + } |
| 120 | +} |
| 121 | + |
| 122 | +// submitted |
| 123 | +// The bid is submitted to the chain, which is placed at the given index of the transaction with the given hash |
| 124 | +// This state is temporary and will be updated to either lost or won after conclusion of the auction |
| 125 | +{ |
| 126 | + "type": "bid_status_update", |
| 127 | + "status": { |
| 128 | + "id": "beedbeed-0e42-400f-a8ef-d78aa5422252", |
| 129 | + "bid_status": { |
| 130 | + // the enum for the bid_status |
| 131 | + "type": "submitted", |
| 132 | + // the hash of the transaction that the bid's calldata was included in |
| 133 | + "result": "0xabc393b634fdf3eb45be8350fd16cd1b4add47b96059beacc1d8c20e51d75ec3", |
| 134 | + // the index of the bid calldata within the multicall bundle for the above transaction |
| 135 | + "index": 0 |
| 136 | + } |
| 137 | + } |
| 138 | +} |
| 139 | + |
| 140 | +// lost |
| 141 | +// The bid lost the auction, which is concluded with the transaction with the given hash and index |
| 142 | +// The result will be None if the auction was concluded off-chain and no auction was submitted to the chain |
| 143 | +// The index will be None if the bid was not submitted to the chain and lost the auction by off-chain calculation |
| 144 | +// There are cases where the result is not none and the index is none. |
| 145 | +// It is because other bids were selected for submission to the chain, but not this one. |
| 146 | +{ |
| 147 | + "type": "bid_status_update", |
| 148 | + "status": { |
| 149 | + "id": "1eaee2a4-01bf-4f6c-8a76-21fadb2c43b1", |
| 150 | + "bid_status": { |
| 151 | + "type": "lost", |
| 152 | + "result": "0x99c2bf411330ae997632f88abe8f86c0d1f4c448f7d5061319d23814a0fb1135" |
| 153 | + } |
| 154 | + } |
| 155 | +} |
| 156 | + |
| 157 | +// won |
| 158 | +// The bid won the auction, which is concluded with the transaction with the given hash and index |
| 159 | +{ |
| 160 | + "type": "bid_status_update", |
| 161 | + "status": { |
| 162 | + "id": "beedbeed-0e42-400f-a8ef-d78aa5422252", |
| 163 | + "bid_status": { |
| 164 | + // the enum for the bid_status |
| 165 | + "type": "won", |
| 166 | + // the hash of the transaction that the bid's calldata was included in |
| 167 | + "result": "0xabc393b634fdf3eb45be8350fd16cd1b4add47b96059beacc1d8c20e51d75ec3", |
| 168 | + // the index of the bid calldata within the multicall bundle for the above transaction |
| 169 | + "index": 0 |
| 170 | + } |
| 171 | + } |
| 172 | +} |
| 173 | +``` |
| 174 | + |
| 175 | +## Connection Persistence |
| 176 | + |
| 177 | +The websocket server responds to ping messages according to websocket standards. |
| 178 | + |
| 179 | +Additionally, the server periodically sends a ping message to the client to ensure the connection is still active and expects a pong in return. |
0 commit comments