Skip to content

Commit

Permalink
Fixing examples and modify orders
Browse files Browse the repository at this point in the history
  • Loading branch information
jordy25519 committed Dec 15, 2023
1 parent 791a78c commit b5f6661
Show file tree
Hide file tree
Showing 7 changed files with 260 additions and 156 deletions.
4 changes: 4 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
target/
.git/
.github/
README.md
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM rust:1.73.0 as builder
WORKDIR /build
COPY . .
RUN cargo build --release

FROM gcr.io/distroless/base-debian12
COPY --from=builder /lib/x86_64-linux-gnu/libgcc_s.so.1 /lib/x86_64-linux-gnu/libgcc_s.so.1
COPY --from=builder /build/target/release/drift-gateway /bin/drift-gateway
ENTRYPOINT ["/bin/drift-gateway"]
99 changes: 58 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,59 +41,69 @@ Options:
--help display usage information
```

## Examples
## API Examples

### Get Market Info
```bash
$> curl localhost:8080/v2/markets
$ curl localhost:8080/v2/markets
```

### Get Orderbook
gets a full snapshot of the current orderbook
```bash
$> curl localhost:8080/v2/orderbook -X GET -H 'content-type: application/json' -d '{"market":{"id":0,"type":"perp"}}'
$ curl localhost:8080/v2/orderbook -X GET -H 'content-type: application/json' -d '{"marketIndex":0,"marketType":"perp"}'
```
to stream orderbooks via websocket DLOB servers are available at:
devnet: `wss://master.dlob.drift.trade/ws`
mainnet: `wss://dlob.drift.trade/ws`

to stream orderbooks via websocket public DLOB servers are available at:
- devnet: `wss://master.dlob.drift.trade/ws`
- mainnet: `wss://dlob.drift.trade/ws`
see https://github.com/drift-labs/dlob-server/blob/master/example/wsClient.ts for usage example

### Get Orders
get all orders
```bash
$> curl localhost:8080/v2/orders
$ curl localhost:8080/v2/orders
```
get orders by market
```bash
$> curl localhost:8080/v2/orders -X GET -H 'content-type: application/json' -d '{"market":{"id":0,"type":"perp"}};
$ curl localhost:8080/v2/orders -X GET -H 'content-type: application/json' -d '{"marketIndex":1,"marketType":"spot"}'
```

### Get Positions
get all positions
```bash
$> curl localhost:8080/v2/positions
$ curl localhost:8080/v2/positions
```
get positions by market
```bash
$> curl localhost:8080/v2/positions -X GET -H 'content-type: application/json' -d '{"market":{"id":0,"type":"perp"}};
$ curl localhost:8080/v2/positions -X GET -H 'content-type: application/json' -d '{"marketIndex":0,"marketType":"perp"}'
```

### Place Orders

- use sub-zero `amount` to indicate sell/offer order
- `userOrderId` is a uint in the range 1 <= x <= 255 which can be assigned by the client to help distinguish orders
- `orderType` only "limit" and "market" options are fully supported by the gateway

```bash
$> curl localhost:8080/v2/orders -X POST -H 'content-type: application/json' -d '{
"orders": [{
"marketId": 1,
$ curl localhost:8080/v2/orders -X POST -H 'content-type: application/json' -d '{
"orders": [
{
"marketIndex": 1,
"marketType": "spot",
"amount": 1.23,
"price": 40.55,
"amount": -1.23,
"price": 80.0,
"postOnly": true,
"orderType": "limit",
"userOrderId": 101
"immediateOrCancel": false,
"reduce_only": false,
},
{
"marketId": 0,
"marketIndex": 0,
"marketType": "perp",
"amount": -1.05,
"price": 80,
"amount": 1.23,
"price": 60.0,
"postOnly": true,
"orderType": "limit",
"userOrderId": 102
Expand All @@ -102,38 +112,45 @@ $> curl localhost:8080/v2/orders -X POST -H 'content-type: application/json' -d
```

### Modify Orders
like place orders but specify either `orderId` or `userOrderId` to indicate which order to modify
like place orders but caller must specify either `orderId` or `userOrderId` to indicate which order to modify.

- `amount` can be modified to flip the order from long/short to bid/ask
- the order market cannot be modified.
```bash
$> curl localhost:8080/v2/orders -X PATCH -H 'content-type: application/json' -d '{
$ curl localhost:8080/v2/orders -X PATCH -H 'content-type: application/json' -d '{
"orders": [{
"marketId": 1,
"marketType": "spot",
"amount": 1.23,
"price": 40.55,
"postOnly": true,
"orderType": "limit",
"userOrderId": 5
"amount": -1.1,
"price": 80.5,
"userOrderId": 101
},
{
"orderId": 555,
"marketId": 0,
"marketType": "perp",
"amount": -1.05,
"price": 80,
"postOnly": true,
"orderType": "limit"
"amount": 1.05,
"price": 61.0,
"orderId": 32
}]
}'
```

### Cancelling Orders
### Cancel Orders
```bash
# cancel by market id
$> curl localhost:8080/v2/orders -X DELETE -H 'content-type: application/json' -d '{"market":{"id":1,"type":"perp"}}'
# cancel all by market id
$ curl localhost:8080/v2/orders -X DELETE -H 'content-type: application/json' -d '{"marketIndex":1,"marketType":"spot"}}'
# cancel by order ids
$> curl localhost:8080/v2/orders -X DELETE -H 'content-type: application/json' -d '{"ids":[1,2,3,4]}'
$ curl localhost:8080/v2/orders -X DELETE -H 'content-type: application/json' -d '{"ids":[1,2,3,4]}'
# cancel by user assigned order ids
$> curl localhost:8080/v2/orders -X DELETE -H 'content-type: application/json' -d '{"userIds":[1,2,3,4]}'
$ curl localhost:8080/v2/orders -X DELETE -H 'content-type: application/json' -d '{"userIds":[1,2,3,4]}'
# cancel all orders
$> curl localhost:8080/v2/orders -X DELETE
```
$ curl localhost:8080/v2/orders -X DELETE
```

### Errors
error responses have the following JSON structure:
```json
{
"code": "<http status code | program error code>",
"reason": "<explanation>"
}
```

Some endpoints send transactions to the drift program and can return program error codes.
The full list of drift program error codes is available in the [API docs](https://drift-labs.github.io/v2-teacher/#errors)
60 changes: 42 additions & 18 deletions src/controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::sync::Arc;

use drift_sdk::{
dlob::{DLOBClient, L2Orderbook},
types::{Context, MarketType, OrderParams, SdkError, SdkResult},
types::{Context, MarketType, ModifyOrderParams, SdkError, SdkResult},
DriftClient, Pubkey, TransactionBuilder, Wallet, WsAccountProvider,
};
use futures_util::{stream::FuturesUnordered, StreamExt};
Expand Down Expand Up @@ -67,6 +67,7 @@ impl AppState {
} else {
"https://dlob.drift.trade"
};

Self {
wallet,
client: Arc::new(client),
Expand All @@ -86,7 +87,7 @@ impl AppState {
let builder = TransactionBuilder::new(&self.wallet, &user_data);

let tx = if let Some(market) = req.market {
builder.cancel_orders((market.id, market.market_type), None)
builder.cancel_orders((market.market_index, market.market_type), None)
} else if !req.user_ids.is_empty() {
let order_ids = user_data
.orders
Expand All @@ -112,7 +113,7 @@ impl AppState {
/// Return orders by position if given, otherwise return all positions
pub async fn get_positions(
&self,
req: GetPositionsRequest,
req: Option<GetPositionsRequest>,
) -> GatewayResult<GetPositionsResponse> {
let (all_spot, all_perp) = self.client.all_positions(self.user()).await?;

Expand All @@ -122,8 +123,9 @@ impl AppState {
all_spot
.iter()
.filter(|p| {
if let Some(ref market) = req.market {
p.market_index == market.id && MarketType::Spot == market.market_type
if let Some(GetPositionsRequest { ref market }) = req {
p.market_index == market.market_index
&& MarketType::Spot == market.market_type
} else {
true
}
Expand All @@ -142,8 +144,9 @@ impl AppState {
perp: all_perp
.iter()
.filter(|p| {
if let Some(ref market) = req.market {
p.market_index == market.id && MarketType::Perp == market.market_type
if let Some(GetPositionsRequest { ref market }) = req {
p.market_index == market.market_index
&& MarketType::Perp == market.market_type
} else {
true
}
Expand All @@ -154,14 +157,17 @@ impl AppState {
}

/// Return orders by market if given, otherwise return all orders
pub async fn get_orders(&self, req: GetOrdersRequest) -> GatewayResult<GetOrdersResponse> {
pub async fn get_orders(
&self,
req: Option<GetOrdersRequest>,
) -> GatewayResult<GetOrdersResponse> {
let orders = self.client.all_orders(self.user()).await?;
Ok(GetOrdersResponse {
orders: orders
.into_iter()
.filter(|o| {
if let Some(ref market) = req.market {
o.market_index == market.id && o.market_type == market.market_type
if let Some(GetOrdersRequest { ref market }) = req {
o.market_index == market.market_index && o.market_type == market.market_type
} else {
true
}
Expand Down Expand Up @@ -203,25 +209,43 @@ impl AppState {

pub async fn modify_orders(&self, req: ModifyOrdersRequest) -> GatewayResult<String> {
let user_data = &self.client.get_user_account(self.user()).await?;

let mut params = Vec::<(u32, OrderParams)>::with_capacity(req.orders.len());
// NB: its possible to let the drift program sort the modifications by userOrderId
// sorting it client side for simplicity
let mut params = Vec::<(u32, ModifyOrderParams)>::with_capacity(req.orders.len());
for order in req.orders {
if let Some(id) = order.order_id {
params.push((id, order.to_order_params(self.context())));
} else if order.user_order_id > 0 {
if let Some(order_id) = order.order_id {
if let Some(onchain_order) =
user_data.orders.iter().find(|x| x.order_id == order_id)
{
params.push((
order_id,
order.to_order_params(
onchain_order.market_index,
onchain_order.market_type,
self.context(),
),
));
}
} else if let Some(user_order_id) = order.user_order_id {
if let Some(onchain_order) = user_data
.orders
.iter()
.find(|x| x.user_order_id == order.user_order_id)
.find(|x| x.user_order_id == user_order_id)
{
params.push((
onchain_order.order_id,
order.to_order_params(self.context()),
order.to_order_params(
onchain_order.market_index,
onchain_order.market_type,
self.context(),
),
));
}
} else {
return Err(ControllerError::UnknownOrderId(
order.order_id.unwrap_or(order.user_order_id as u32),
order
.order_id
.unwrap_or(order.user_order_id.unwrap_or(0) as u32),
));
}
}
Expand Down
Loading

0 comments on commit b5f6661

Please sign in to comment.