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. 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):
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:
#![allow(unused)]
fn main() {
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:
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 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.
#![allow(unused)]
fn main() {
// 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 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 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