decred.org/dcrdex@v1.0.5/spec/comm.mediawiki (about) 1 =Communication Protocols= 2 3 __TOC__ 4 5 ==WebSockets== 6 7 Trustless negotiation of trades requires considerable messaging. 8 Transaction details must be reported and relayed at appropriate times, sometimes 9 with substantial delays between subsequent actions. 10 Match notification via HTTP polling or other request interval-based methods are 11 thus not suitable for the DEX system. 12 Persistent, full-duplex communication is critical to minimizing communication 13 latencies and wasted bandwidth. 14 WebSockets ([https://tools.ietf.org/html/rfc6455 [3]]) are chosen as the 15 default and preferred communications protocol for 16 the DEX exchange API. 17 In addition to fulfilling the aforementioned needs, Websockets are now a 18 well-established technology with client software available for integration in 19 virtually all popular programming languages. 20 21 WebSocket messages are secured by encryption on Transport Layer 22 Security (TLS) [https://tools.ietf.org/html/rfc8446 [4]] connections. 23 24 ==Encoding== 25 26 ===Timestamps=== 27 28 In all client-server messages that include a timestamp or duration field, the 29 units of time are milliseconds unless otherwise specified. Location-independent 30 timestamps are encoded as milliseconds since the UNIX epoch (Jan 01 00:00:00 31 1970 UTC). 32 33 If a timestamp must be converted to seconds, e.g. for encoding as a locktime in 34 a swap contract, the timestamp should be rounded down. 35 36 ===Rate Encoding=== 37 38 Because the rate assigned to a limit order is a quotient, the value is naturally 39 expressed as a floating point number. 40 To avoid floating-point error, rates in API messages are encoded using a 41 custom unit, '''atoms quote asset per unit base asset'''. 42 This is called the '''message-rate format'''. 43 This can alternatively be viewed as conventional rate multiplied by 44 10<sup>8</sup> and floored to the nearest integer. 45 46 As an example of message-rate encoding, if someone wanted to purchase asset Z 47 using asset Y on the Z/Y market, and the user wanted to pay 0.001 Y for each 1 48 Z, the message-rate encoding would be 49 50 '''''r<sub>msg</sub> = 1 x 10<sup>8</sup> x 0.001 = 100000''''' 51 52 with unit ''atoms Y / unit Z''. 53 54 ===Coin ID=== 55 56 In order to demonstrate control of unspent value on the blockchain, a user must 57 provide its location. For Bitcoin-based blockchains, value is located by 58 pointing to an unspent transaction output (UTXO), identified by its transaction 59 ID and output index (vout). For account based assets, the coin id is different 60 in different situations. Pre-swap it is simply an account address. While swapping, 61 the value is transferred to a swap contract's address and can be found there in 62 a map keyed by the swap's secret hash. 63 64 In an effort to stay blockchain-protocol agnostic, the DEX accepts 65 and recognizes the locating information as a single byte-array called the 66 '''''coin ID''''', with the term '''''coin''''' being defined here as some 67 amount of spendable value that is verifiable on the blockchain. 68 It is up to backend and wallet developers to decide on how to properly encode the 69 identifier as a coin ID. As an example, Bitcoin implements 70 encoding as 36 bytes with the transaction hash being the first 32-bytes, and the 71 big-endian encoded output index as the last 4 bytes. 72 73 ==Message Protocol== 74 75 DEX messaging is JSON-formatted [https://tools.ietf.org/html/rfc8259 [5]]. 76 All messages, regardless of originating party, use a common top-level 77 structure called a '''Message'''. 78 79 '''JSON Message object''' 80 81 {| 82 ! field !! type !! description 83 |- 84 | type || int || message type 85 |- 86 | payload || any || the data being transmitted 87 |- 88 | route || string || the route identifier. requests and notifications only 89 |- 90 | id || int > 0 || the request ID. requests and responses only 91 |} 92 93 There are three anticipated message types. 94 95 '''Message types''' 96 97 {| 98 | type || id || description 99 |- 100 | request || 1 || a request is typically an uninitiated message that seeks a response 101 |- 102 | response || 2 || a response to a request 103 |- 104 | notification || 3 || usually part of a data feed. requires no response 105 |} 106 107 '''Example request''' 108 109 The payload for a request can be of any type. 110 111 <pre> 112 { 113 "type": 1, 114 "id": 123, 115 "route" "sendnum", 116 "payload": 5 117 } 118 </pre> 119 120 '''Response payload''' 121 122 The payload for a response has a structure that enables quick error checking. 123 124 {| 125 ! field !! type !! description 126 |- 127 | result || any || the result. field is missing or null if an error was encountered 128 |- 129 | error || string or null || the error. field is null or missing if no error was encountered 130 |} 131 132 '''Example response''' 133 134 <pre> 135 { 136 "type": 2, 137 "id": 123, 138 "payload": { "result": true } 139 } 140 </pre> 141 142 '''Example notification''' 143 144 <pre> 145 { 146 "type": 3, 147 "route": "notifynums" 148 "payload": [1, 5, 3, 9] 149 } 150 </pre> 151 152 ==Session Authentication== 153 154 Many DEX messages must be sent on an authenticated connection. Once a WebSocket 155 connection is established, the client will supply their account ID and signature. 156 157 '''Request route:''' <code>connect</code>, '''originator: ''' client 158 159 <code>payload</code> 160 {| 161 ! field !! type !! description 162 |- 163 | accountid || string || account ID 164 |- 165 | apiver || int || requested API version 166 |- 167 | timestamp || int || UNIX timestamp (milliseconds) 168 |- 169 | sig || string || hex-encoded signature of serialized connection data. serialization described below 170 |} 171 172 '''Connect serialization''' 173 174 {| 175 ! field !! size (bytes) !! description 176 |- 177 | account ID || 32 || client [[accounts.mediawiki/#Step_1_Registration|account ID]] 178 |- 179 | API version || 2 || requested API version 180 |- 181 | timestamp || 8 || the client's UNIX timestamp (milliseconds) 182 |} 183 184 '''Connect response''' 185 186 If a client unexpectedly disconnects with active orders, the orders may match in 187 the client's absence. A list of any pending matches is included in the response. 188 If the client has a broken rule, they will not be able to trade for the duration 189 of their penalization. 190 191 <code>result</code> 192 {| 193 ! field !! type !! description 194 |- 195 | activematches || <nowiki>[object]</nowiki> || list of active [[orders.mediawiki/#Match_negotiation|Match objects]] 196 |- 197 | activeorderstatuses || <nowiki>[object]</nowiki> || list of active <code>Order Status Object</code> 198 |- 199 | score || int || The user's score. The math behind this is currently being adjusted 200 |- 201 | tier || int || Bond tier. One or more indicates the account can trade. Legacy fee being paid gives a perpetual +1 to tier. Not set by legacy servers. 202 |- 203 | activeBonds || <nowiki>[object]</nowiki> || list of active <code>Bond Object</code> 204 |- 205 | legacyFeePaid || bool || Whether the legacy fee was paid. This currently has the internal value of one bond tier. Not set by legacy servers. 206 |- 207 | suspended || bool || DEPRECATED. For legacy servers true if suspended. Implies tier < 1, and means that the user cannot trade until posting more bond. 208 |- 209 | sig || string || hex-encoded server's signature of the serialized connection data 210 |} 211 212 '''Order Status Object''' 213 214 {| 215 ! field !! type !! description 216 |- 217 | ID || bytes || a unique order id 218 |- 219 | Status || int || the order status. See [[https://github.com/decred/dcrdex/blob/master/dex/order/status.go|status.go]] for statuses. 220 |} 221 222 '''Bond Object''' 223 224 {| 225 ! field !! type !! description 226 |- 227 | version || int || Bond version. 228 |- 229 | amount || int || Amount held in the bond in the lowest communicatable denomination of that coin. i.e. atoms for dcr, gwei for eth. 230 |- 231 | expiry || int || When the bond expires, NOT the bond locktime. 232 |- 233 | coinID || bytes || Coin ID that created the bond. 234 |- 235 | assetID || int || SLIP-0044 registered coin type of the bond asset. 236 |} 237 238 ==HTTP== 239 240 An API using HTTP for message transport may be provided for basic account 241 management and server status queries, however WebSocket connections are to be 242 the sole means for 243 [[orders.mediawiki/#Client_Order_Management|placing, monitoring, and executing orders]]. 244 The primary reason for limiting the scope of the HTTP API is to eliminate client 245 polling for rapidly changing resources, such as order status API endpoints.