A collection of Python scripts demonstrating integration with GRVT's Builder Codes system and Trading API.
This repository contains example scripts for:
- Builder Authorization - Generate API keys through EIP-712 signature authorization
- Wallet Login - Authenticate using an EIP-712 wallet signature (no API key required)
- Order Creation - Create and submit authenticated orders to the GRVT Trading API
These examples demonstrate the complete flow from user authorization to order execution, following GRVT's official API documentation.
builder-examples/
βββ authorize.py # Builder authorization & API key generation
βββ wallet_login.py # EIP-712 wallet login (main signing wallet)
βββ grvt_create_order_api.py # Order creation with API key authentication
βββ create_order_data.json # Sample order data
βββ docs/
β βββ AUTHORIZE_README.md # Detailed authorize.py documentation
β βββ WALLET_LOGIN_README.md # Detailed wallet_login.py documentation
β βββ CREATE_ORDER_README.md # Detailed order creation documentation
βββ README.md # This file
- Python 3.7+
- Install required packages:
pip install requests eth-accountLogin with the user's main wallet to obtain their funding_account_address (used as main_account_id in the next step):
python wallet_login.py \
--env testnet \
--wallet-privkey 0xYOUR_USER_WALLET_PRIVATE_KEY \
--no-verify
# Output includes:
# Funding account address: 0xabc123... β use this as --main-account-id belowπ See docs/WALLET_LOGIN_README.md for complete documentation
Authorize a builder to generate an API key (use this when the builder needs to trade on behalf of the user):
python authorize.py \
--env testnet \
--authorize \
--user-privkey 0xYOUR_USER_WALLET_PRIVATE_KEY \
--main-account-id 0xFUNDING_ACCOUNT_ADDRESS \
--builder-account-id 0xBUILDER_ACCOUNT_ADDRESS \
--builder-api-signer-privkey 0xFRESH_SIGNER_PRIVATE_KEYThis will output an API key (e.g., grvt_api_...) that you'll use for authenticated requests.
Alternatively, to authorize a builder's fee rates without creating an API key:
python authorize.py \
--env testnet \
--authorize-only \
--user-privkey 0xYOUR_USER_WALLET_PRIVATE_KEY \
--main-account-id 0xFUNDING_ACCOUNT_ADDRESS \
--builder-account-id 0xBUILDER_ACCOUNT_ADDRESSπ See docs/AUTHORIZE_README.md for complete documentation
Use the generated API key to create and submit orders:
python grvt_create_order_api.py \
--env testnet \
--api-key YOUR_API_KEY \
--private-key YOUR_PRIVATE_KEY \
--order-file create_order_data.jsonπ See docs/CREATE_ORDER_README.md for complete documentation
Purpose: Authenticate with the user's main wallet using EIP-712. Returns a session cookie and off-chain account ID for API access, and funding_account_address which is used as --main-account-id in the authorize step.
Key Features:
- EIP-712
WalletLoginsignature (primary type:WalletLogin(address signer, uint32 nonce, int64 expiration)) - Returns
funding_account_addressin response body β use asmain_account_idinauthorize.py - Replay prevention via server-side nonce consumption (Redis SETNX)
- Short-lived signatures (max 5 minutes, server-enforced)
Quick Example:
# Login and get funding_account_address (= main_account_id for authorize step)
python wallet_login.py --env testnet \
--wallet-privkey 0xYOUR_WALLET_PRIVATE_KEY \
--no-verify
# Output includes:
# Funding account address: 0xabc123... β pass as --main-account-id to authorize.pyChain ID Configuration:
- dev/staging: 327
- testnet: 326
- prod: 325
π Full Documentation: docs/WALLET_LOGIN_README.md
Purpose: Authorize a builder to act on behalf of a user's account. Uses funding_account_address from wallet login as --main-account-id.
Key Features:
- EIP-712 signature-based authorization (two paths: with or without API key creation)
- Multi-environment support (dev, staging, testnet, prod)
- Automatic chain ID configuration per environment
- Session cookie and account ID extraction
- Test API access with authenticated endpoints
Quick Example:
# Authorize and create API key (AddAccountSignerWithBuilder)
# --main-account-id = funding_account_address from wallet_login
python authorize.py --env testnet --authorize \
--user-privkey 0x... \
--main-account-id 0xFUNDING_ACCOUNT_ADDRESS \
--builder-account-id 0x... \
--builder-api-signer-privkey 0x...
# Authorize builder without API key (AuthorizeBuilder)
python authorize.py --env testnet --authorize-only \
--user-privkey 0x... \
--main-account-id 0xFUNDING_ACCOUNT_ADDRESS \
--builder-account-id 0x...Chain ID Configuration:
- dev/staging: 327
- testnet: 326
- prod: 325
π Full Documentation: docs/AUTHORIZE_README.md
Purpose: Create and submit signed orders to the GRVT Trading API using API key authentication.
Key Features:
- API key authentication flow
- EIP-712 order signing
- Multi-leg order support
- Automatic expiration and nonce updates
- Instrument metadata fetching
- Comprehensive error handling
Quick Example:
# Basic order creation
python grvt_create_order_api.py \
--env testnet \
--api-key YOUR_API_KEY \
--private-key YOUR_PRIVATE_KEY \
--order-file create_order_data.json
# With auto-updated expiration
python grvt_create_order_api.py \
--env testnet \
--api-key YOUR_API_KEY \
--private-key YOUR_PRIVATE_KEY \
--order-file create_order_data.json \
--update-expiration \
--expiration-hours 24π Full Documentation: docs/CREATE_ORDER_README.md
All scripts support multiple GRVT environments:
| Environment | Chain ID | Edge API | Trading API | Market Data API |
|---|---|---|---|---|
| dev | 327 | edge.dev.gravitymarkets.io | trades.dev.gravitymarkets.io | market-data.dev.gravitymarkets.io |
| staging | 327 | edge.staging.gravitymarkets.io | trades.staging.gravitymarkets.io | market-data.staging.gravitymarkets.io |
| testnet | 326 | edge.testnet.grvt.io | trades.testnet.grvt.io | market-data.testnet.grvt.io |
| prod | 325 | edge.grvt.io | trades.grvt.io | market-data.grvt.io |
Use --env flag to select the environment (default: testnet).
Here's the recommended end-to-end flow from wallet login through to order creation:
export USER_WALLET_PRIVKEY="0x..." # User's main signing wallet private key
python wallet_login.py --env testnet \
--wallet-privkey "$USER_WALLET_PRIVKEY" \
--no-verify
# Output includes:
# Funding account address: 0xabc123... β this is your main_account_id
#
# Set it for the next step:
export MAIN_ACCOUNT="0xabc123..." # funding_account_address from step 1 outputexport BUILDER_ACCOUNT="0x..." # Builder's funding account address
export BUILDER_SIGNER_PRIVKEY="0x..." # Fresh keypair for the API key (auto-generated if omitted)
# --main-account-id is the funding_account_address returned by wallet_login above
python authorize.py --env testnet \
--authorize \
--user-privkey "$USER_WALLET_PRIVKEY" \
--main-account-id "$MAIN_ACCOUNT" \
--builder-account-id "$BUILDER_ACCOUNT" \
--builder-api-signer-privkey "$BUILDER_SIGNER_PRIVKEY"
# Save the output API key
export GRVT_API_KEY="grvt_api_..."Edit create_order_data.json:
{
"order": {
"sub_account_id": "YOUR_SUB_ACCOUNT_ID",
"is_market": true,
"time_in_force": "GOOD_TILL_TIME",
"post_only": false,
"reduce_only": false,
"legs": [
{
"instrument": "BTC_USDT_Perp",
"size": "0.1",
"limit_price": "0",
"is_buying_asset": true
}
],
"signature": {
"expiration": "1767672926708000000",
"nonce": 1234562
},
"metadata": {
"client_order_id": "23043"
},
"builder": "0xYOUR_BUILDER_ADDRESS",
"builder_fee": "0.1"
}
}export ORDER_SIGNING_KEY="0x..." # Private key for signing orders
python grvt_create_order_api.py \
--env testnet \
--api-key "$GRVT_API_KEY" \
--private-key "$ORDER_SIGNING_KEY" \
--order-file create_order_data.json \
--update-expiration \
--expiration-hours 24- Never commit private keys or API keys to version control
- Use environment variables for sensitive data
- Test on testnet first before using production
- Rotate API keys regularly (keys can expire up to 30 days)
- Use secure key management systems in production
- Validate order parameters before submission
- Monitor your orders and positions after submission
- Builder Codes Integration: https://api-docs.grvt.io/builder_codes/
- Authentication: https://api-docs.grvt.io/auth/
- Trading API: https://api-docs.grvt.io/trading_api/
- Market Data API: https://api-docs.grvt.io/market_data/
- Ensure all four required arguments are provided when using
--authorize - See docs/AUTHORIZE_README.md
- API key may be invalid or expired
- Check you're using the correct environment
- See docs/AUTHORIZE_README.md
- Verify instrument name is correct and case-sensitive
- Check instrument is active in your environment
- See docs/CREATE_ORDER_README.md
- Ensure private key matches the signer address
- Check expiration timestamp is in the future
- Verify nonce is unique
- See docs/CREATE_ORDER_README.md
- Check the detailed documentation for each script in the
docs/folder - Review GRVT's official API documentation
- Verify your environment configuration and credentials
- Test with smaller values on testnet first
# Test authorization (without actual keys)
python authorize.py --help
# Test order creation (without actual keys)
python grvt_create_order_api.py --help- requests - HTTP client for API calls
- eth-account - Ethereum key management and EIP-712 signing
Install with:
pip install requests eth-accountWhen modifying these scripts:
- Test on testnet before committing changes
- Update documentation if you add new features or arguments
- Follow security best practices for key handling
- Validate against all environments (dev, staging, testnet)
- Add error handling for new edge cases
These examples are provided as-is for testing and integration purposes with GRVT's Builder Codes system.
- GRVT Website: https://grvt.io/
- API Documentation: https://api-docs.grvt.io/
- Discord Community: Join GRVT Discord
# Get help
python wallet_login.py --help
# Login and get funding_account_address (= main_account_id for authorize step)
python wallet_login.py --env testnet \
--wallet-privkey 0xYOUR_WALLET_PRIVATE_KEY \
--no-verify# Get help
python authorize.py --help
# Authorize and create API key (--main-account-id = funding_account_address from wallet_login)
python authorize.py --env testnet --authorize \
--user-privkey 0x... \
--main-account-id 0xFUNDING_ACCOUNT_ADDRESS \
--builder-account-id 0x... \
--builder-api-signer-privkey 0x...
# Authorize builder without API key
python authorize.py --env testnet --authorize-only \
--user-privkey 0x... \
--main-account-id 0xFUNDING_ACCOUNT_ADDRESS \
--builder-account-id 0x...# Get help
python grvt_create_order_api.py --help
# Create order
python grvt_create_order_api.py \
--env testnet \
--api-key YOUR_API_KEY \
--private-key YOUR_PRIVATE_KEY \
--order-file create_order_data.json
# Create order with auto-expiration
python grvt_create_order_api.py \
--env testnet \
--api-key YOUR_API_KEY \
--private-key YOUR_PRIVATE_KEY \
--order-file create_order_data.json \
--update-expiration \
--expiration-hours 24Ready to get started? Check out the detailed documentation:
- π Authorization Guide
- π Order Creation Guide