# Delegate Accounts

A delegate is a separate keypair authorized to trade on behalf of your main account. Orders placed by a delegate are
attributed to the delegator's account — they share the same balances, positions, and margin.

For full setup instructions, see the
[delegate account setup guide](https://docs.bullet.xyz/bulletx-exchange/how-to-guide/delegate-account-setup).
This page covers API-specific usage.

## Why use delegates

- **Security**: your main wallet key stays in your wallet; the delegate key is the only secret you handle - if the
  delegate key is compromised, your main wallet remains untouched
- **Scoped access**: delegates can only trade — they cannot deposit or withdraw
- **Revocable**: delegate access can be removed anytime by your main account
- **Visibility**: all trades made by delegates appear in the webapp UI under your account

## Setup

### 1. Generate a keypair

Generate an ed25519 keypair locally. This will be your delegate key.

**Solana CLI** (easiest):

```bash
solana-keygen new --outfile delegate-key.json --no-bip39-passphrase
solana-keygen pubkey delegate-key.json
```

The generated file contains the 64-byte secret key (first 32 bytes are the private key, last 32 are the public key).
The printed public key (base58) is what you register in the webapp.

**Rust:**

```rust
use ed25519_dalek::SigningKey;

let keypair = SigningKey::generate( & mut rand::thread_rng());
let public_key = hex::encode(keypair.verifying_key().to_bytes());
let private_key = hex::encode(keypair.to_bytes());

println!("public key:  {public_key}");   // register this in the webapp
println!("private key: {private_key}");   // use this to sign API transactions
```

**Python:**

```python
from nacl.signing import SigningKey

keypair = SigningKey.generate()
public_key = keypair.verify_key.encode().hex()
private_key = keypair.encode().hex()

print(f"public key:  {public_key}")   # register this in the webapp
print(f"private key: {private_key}")   # use this to sign API transactions
```

Store the private key securely. You will need the public key for the next step.

### 2. Register the delegate

Register your delegate's public key via the webapp. See the
[Bullet UI guide](https://docs.bullet.xyz/bulletx-exchange/how-to-guide/delegate-account-setup) for full instructions
including Ledger and cold wallet setup.

### 3. Trade with the delegate key

Sign transactions with the delegate's private key. The exchange resolves the delegate to your main account
automatically — no special fields or flags needed.

```rust
// sign with the delegate keypair — order executes on the main account
let order_bytes = create_place_order_bytes(
& delegate_keypair,
chain_id,
& chain_hash,
market_id,
orders,
);
```

See [Transaction Signing](./tx-signing.md) for the full signing flow.

> **Note:** For read endpoints (account info, balances, positions, open orders), always use your **main account's**
> address — not the delegate's. All state lives on the main account.

## Capabilities

| Operation             | Delegate | Main wallet |
|-----------------------|----------|-------------|
| Place / cancel orders | Yes      | Yes         |
| Deposit               | No       | Yes         |
| Withdraw              | No       | Yes         |

## Revoking a delegate

Revoke a delegate from the webapp at any time - revocation is immediate and the delegate key can no longer submit
transactions for your account. See
the [Bullet UI guide](https://docs.bullet.xyz/bulletx-exchange/how-to-guide/delegate-account-setup) for details.

## Limits

- Up to **10** delegates per account
- Delegate names are max **20** characters
- A delegate address cannot already have its own account
- A delegate cannot be registered to multiple accounts
