Skip to content

Commit ba01179

Browse files
authored
Add delegated mode (#12)
1 parent f20c08d commit ba01179

File tree

4 files changed

+82
-42
lines changed

4 files changed

+82
-42
lines changed

Diff for: Cargo.lock

+28-28
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: README.md

+12-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Self hosted API gateway to easily interact with Drift V2 Protocol
88
# build
99
cargo build --release
1010

11-
# configure the gateway wallet key
11+
# configure the gateway signing key
1212
export DRIFT_GATEWAY_KEY=</PATH/TO/KEY.json | seedBase58>
1313

1414
# '--dev' to toggle devnet markets (default is mainnet)
@@ -27,7 +27,7 @@ docker run -e DRIFT_GATEWAY_KEY=<BASE58_SEED> -p 8080:8080 drift-gateway https:/
2727

2828
## Usage
2929
```bash
30-
Usage: drift-gateway <rpc_host> [--dev] [--host <host>] [--port <port>]
30+
Usage: drift-gateway <rpc_host> [--dev] [--host <host>] [--port <port>] [--delegate <delegate>]
3131

3232
Drift gateway server
3333

@@ -38,6 +38,8 @@ Options:
3838
--dev run in devnet mode
3939
--host gateway host address
4040
--port gateway port
41+
--delegate use delegated signing mode, provide the delegator's pubkey
42+
e.g. `--delegate <DELEGATOR_PUBKEY>`
4143
--help display usage information
4244
```
4345
@@ -178,7 +180,7 @@ get positions by market
178180
```bash
179181
$ curl -X GET \
180182
-H 'content-type: application/json' \
181-
-d '{"marketIndex":0,"marketType":"perp"} \
183+
-d '{"marketIndex":0,"marketType":"perp"}' \
182184
localhost:8080/v2/positions
183185
```
184186
@@ -301,6 +303,13 @@ $ curl localhost:8080/v2/orders/cancelAndPlace -X POST -H 'content-type: applica
301303
}'
302304
```
303305
306+
## Delegated Signing Mode
307+
Passing the `--delegate <DELEGATOR_PUBKEY>` flag will instruct the gateway to run in delegated signing mode.
308+
In this mode, the gateway will act for `DELEGATOR_PUBKEY` and sub-accounts while signing with the key provided via `DRIFT_GATEWAY_KEY`.
309+
310+
Use the drift UI or Ts/Python SDK to assign a delegator key.
311+
see [Delegated Accounts](https://docs.drift.trade/delegated-accounts) for more information.
312+
304313
## Sub-account Switching
305314
By default the gateway uses the drift sub-account (index 0)
306315
A `subAccountId` URL query parameter may be supplied to switch the sub-account per request basis.

Diff for: src/controller.rs

+16-4
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,32 @@ pub struct AppState {
3636
}
3737

3838
impl AppState {
39-
/// Configured drift signing address + fee payer
40-
pub fn authority(&self) -> Pubkey {
39+
/// Configured drift authority address
40+
pub fn authority(&self) -> &Pubkey {
4141
self.wallet.authority()
4242
}
43+
/// Configured drift signing address
44+
pub fn signer(&self) -> Pubkey {
45+
self.wallet.signer()
46+
}
4347
pub fn default_sub_account(&self) -> Pubkey {
4448
self.wallet.default_sub_account()
4549
}
46-
pub async fn new(secret_key: &str, endpoint: &str, devnet: bool) -> Self {
50+
pub async fn new(
51+
secret_key: &str,
52+
endpoint: &str,
53+
devnet: bool,
54+
delegate: Option<Pubkey>,
55+
) -> Self {
4756
let context = if devnet {
4857
Context::DevNet
4958
} else {
5059
Context::MainNet
5160
};
52-
let wallet = Wallet::try_from_str(secret_key).expect("valid key");
61+
let mut wallet = Wallet::try_from_str(secret_key).expect("valid key");
62+
if let Some(authority) = delegate {
63+
wallet.to_delegated(authority);
64+
}
5365
let account_provider = WsAccountProvider::new(endpoint).await.expect("ws connects");
5466
let client = DriftClient::new(endpoint, account_provider)
5567
.await

Diff for: src/main.rs

+26-7
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ use argh::FromArgs;
77
use log::{error, info};
88

99
use controller::{AppState, ControllerError};
10+
use drift_sdk::Pubkey;
1011
use serde_json::json;
12+
use std::str::FromStr;
1113
use types::{
1214
CancelAndPlaceRequest, CancelOrdersRequest, GetOrderbookRequest, ModifyOrdersRequest,
1315
PlaceOrdersRequest,
@@ -135,17 +137,30 @@ async fn main() -> std::io::Result<()> {
135137
.filter_level(log::LevelFilter::Info)
136138
.init();
137139
let secret_key = std::env::var("DRIFT_GATEWAY_KEY").expect("missing DRIFT_GATEWAY_KEY");
138-
let state = AppState::new(secret_key.as_str(), &config.rpc_host, config.dev).await;
140+
let delegate = config
141+
.delegate
142+
.map(|ref x| Pubkey::from_str(x).expect("valid pubkey"));
143+
let state = AppState::new(secret_key.as_str(), &config.rpc_host, config.dev, delegate).await;
139144

140145
info!(
141146
"🏛️ gateway listening at http://{}:{}",
142147
config.host, config.port
143148
);
144-
info!(
145-
"🪪: authority: {:?}, default sub-account: {:?}",
146-
state.authority(),
147-
state.default_sub_account()
148-
);
149+
150+
if delegate.is_some() {
151+
info!(
152+
"🪪: authority: {:?}, default sub-account: {:?}, 🔑 delegate: {:?}",
153+
state.authority(),
154+
state.default_sub_account(),
155+
state.signer(),
156+
);
157+
} else {
158+
info!(
159+
"🪪: authority: {:?}, default sub-account: {:?}",
160+
state.authority(),
161+
state.default_sub_account()
162+
);
163+
}
149164

150165
HttpServer::new(move || {
151166
App::new().app_data(web::Data::new(state.clone())).service(
@@ -180,6 +195,10 @@ struct GatewayConfig {
180195
/// gateway port
181196
#[argh(option, default = "8080")]
182197
port: u16,
198+
/// use delegated signing mode, provide the delegator's pubkey
199+
/// e.g. `--delegate <DELEGATOR_PUBKEY>`
200+
#[argh(option)]
201+
delegate: Option<String>,
183202
}
184203

185204
fn handle_result<T>(result: Result<T, ControllerError>) -> Either<HttpResponse, Json<T>> {
@@ -239,7 +258,7 @@ mod tests {
239258
}
240259

241260
async fn setup_controller() -> AppState {
242-
AppState::new(&get_seed(), TEST_ENDPOINT, true).await
261+
AppState::new(&get_seed(), TEST_ENDPOINT, true, None).await
243262
}
244263

245264
#[actix_web::test]

0 commit comments

Comments
 (0)