@velox-movement/solver
v1.0.0
Published
TypeScript SDK for running Velox solvers on Movement Network
Downloads
6
Maintainers
Readme
Velox Solver SDK
TypeScript SDK for running intent solvers on the Velox DEX on Movement Network.
Overview
Velox is the first intent-based DEX on Movement, leveraging Move 2.0's enum types for type-safe order expression. Solvers compete to fulfill user intents (swaps, limit orders, TWAP, DCA) with optimal execution.
This SDK allows anyone to run a solver instance by:
- Registering as a solver on the Velox UI (stake required)
- Configuring the SDK with your wallet's private key
- Running the solver to automatically listen for and fill intents
Quick Start
Installation
npm install @velox-movement/solver1. Register as a Solver
Before running the SDK, you must register your wallet as a solver:
- Go to Velox UI
- Connect your wallet
- Navigate to "Become a Solver"
- Stake the minimum required amount (1,000,000 units)
- Your wallet is now registered!
2. Generate Configuration
npx velox-solver initThis creates a .env file with all available configuration options.
3. Configure Your Solver
Edit the .env file:
# Required
RPC_URL=https://testnet.movementnetwork.xyz/v1
VELOX_ADDRESS=0x951cb360d9b1d4cb4834cf76e4fca0f63a85237874d8b2d45b3056439b91cbb7
SOLVER_PRIVATE_KEY=your_registered_wallet_private_key
# Optional - customize solver behavior
MIN_PROFIT_BPS=10
SPREAD_BPS=10
ENABLE_SWAP=true
ENABLE_LIMIT_ORDER=true
ENABLE_TWAP=true
ENABLE_DCA=true4. Start Your Solver
npx velox-solver startCLI Commands
# Start the solver
npx velox-solver start
# Start with options
npx velox-solver start --dry-run # Simulate without transactions
npx velox-solver start --skip-registration-check
npx velox-solver start -v # Verbose logging
npx velox-solver start -c ./config/.env.prod # Custom config file
# Check solver status and stats
npx velox-solver status
# Validate configuration
npx velox-solver check-config
# Generate config template
npx velox-solver init
npx velox-solver init -o .env.productionConfiguration Reference
Required Variables
| Variable | Description |
|----------|-------------|
| RPC_URL | Movement RPC endpoint |
| VELOX_ADDRESS | Velox contract address |
| SOLVER_PRIVATE_KEY | Your registered solver wallet private key |
Network Options
| Variable | Default | Description |
|----------|---------|-------------|
| GRAPHQL_URL | - | GraphQL endpoint for faster queries |
| SHINAMI_KEY | - | Shinami Node Service API key |
Solver Behavior
| Variable | Default | Description |
|----------|---------|-------------|
| POLLING_INTERVAL | 5000 | Intent polling interval (ms) |
| SKIP_EXISTING | true | Skip existing intents on startup |
| MAX_CONCURRENT | 5 | Max concurrent intent processing |
| DRY_RUN | false | Simulate without submitting transactions |
Intent Types
| Variable | Default | Description |
|----------|---------|-------------|
| ENABLE_SWAP | true | Handle swap intents |
| ENABLE_LIMIT_ORDER | true | Handle limit orders |
| ENABLE_TWAP | true | Handle TWAP intents |
| ENABLE_DCA | true | Handle DCA intents |
| ENABLE_SEALED_BID_AUCTION | true | Participate in sealed-bid auctions |
| ENABLE_DUTCH_AUCTION | true | Participate in Dutch auctions |
Intent Filtering
| Variable | Default | Description |
|----------|---------|-------------|
| MIN_INPUT_AMOUNT | 0 | Minimum input amount to consider |
| MAX_INPUT_AMOUNT | u64 max | Maximum input amount to consider |
| INPUT_TOKEN_WHITELIST | - | Comma-separated input token addresses |
| OUTPUT_TOKEN_WHITELIST | - | Comma-separated output token addresses |
Profitability
| Variable | Default | Description |
|----------|---------|-------------|
| MIN_PROFIT_BPS | 10 | Minimum profit margin (basis points) |
| SPREAD_BPS | 10 | Spread for solver margin (basis points) |
| MAX_GAS_PRICE | 1000 | Maximum gas price (octas) |
| MIN_DEADLINE_SECONDS | 30 | Skip intents with less time to deadline |
Limit Orders
| Variable | Default | Description |
|----------|---------|-------------|
| LIMIT_ORDER_CHECK_INTERVAL | 15000 | Price check interval (ms) |
| ENABLE_PARTIAL_FILLS | true | Enable partial fills |
Scheduled Intents (DCA/TWAP)
| Variable | Default | Description |
|----------|---------|-------------|
| MONITOR_SCHEDULED | true | Monitor scheduled intents |
| SCHEDULED_CHECK_INTERVAL | 5000 | Check interval for scheduled readiness (ms) |
Auction Strategies
| Variable | Default | Description |
|----------|---------|-------------|
| DUTCH_AUCTION_STRATEGY | moderate | conservative, moderate, or aggressive |
| DUTCH_MAX_PRICE_PERCENT | 102 | Max price as % of market price |
| SEALED_BID_STRATEGY | moderate | conservative, moderate, or aggressive |
Logging & Monitoring
| Variable | Default | Description |
|----------|---------|-------------|
| LOG_LEVEL | info | debug, info, warn, or error |
| COLORED_OUTPUT | true | Enable colored console output |
| WEBHOOK_URL | - | Notification webhook URL |
| ENABLE_METRICS | false | Enable Prometheus metrics |
| METRICS_PORT | 9090 | Metrics endpoint port |
Programmatic Usage
You can also use the SDK programmatically in your own applications:
import { VeloxSolver, SolverConfig, Intent, IntentType } from '@velox-movement/solver';
// Create config from environment or manually
const config = SolverConfig.fromEnv();
// OR
const config = new SolverConfig({
rpcUrl: 'https://testnet.movementnetwork.xyz/v1',
veloxAddress: '0x...',
privateKey: process.env.SOLVER_PRIVATE_KEY!,
minProfitBps: 10,
spreadBps: 10,
});
// Create solver instance
const solver = new VeloxSolver({
rpcUrl: config.rpcUrl,
veloxAddress: config.veloxAddress,
privateKey: config.privateKey,
pollingInterval: config.pollingInterval,
skipExistingOnStartup: config.skipExistingOnStartup,
});
// Listen for new intents
solver.startIntentStream(async (intent: Intent) => {
console.log(`New intent: ${intent.id} (${IntentType[intent.type]})`);
// Calculate optimal solution
const solution = await solver.calculateOptimalSolution(intent);
// Check if profitable
if (intent.minOutputAmount && solution.outputAmount < intent.minOutputAmount) {
console.log('Cannot meet minimum output');
return;
}
// Fill the intent
const result = await solver.solveSwap(intent.id, solution.outputAmount);
if (result.success) {
console.log(`Filled! TX: ${result.txHash}`);
}
});
// Graceful shutdown
process.on('SIGINT', () => {
solver.stopIntentStream();
process.exit(0);
});Intent Types
Swap
Basic token swap with minimum output protection.
await solver.solveSwap(intentId, outputAmount);Limit Order
Execute at specified price or better, supports partial fills.
const { canFill, outputAmount } = await solver.canFillLimitOrder(intent);
if (canFill) {
await solver.solveLimitOrder(intentId, fillAmount, outputAmount);
}TWAP (Time-Weighted Average Price)
Large orders split into chunks over time.
const isReady = await solver.isTWAPChunkReady(intentId);
if (isReady) {
await solver.solveTWAPChunk(intentId, outputAmount);
}DCA (Dollar-Cost Averaging)
Periodic buys over time.
const isReady = await solver.isDCAPeriodReady(intentId);
if (isReady) {
await solver.solveDCAPeriod(intentId, outputAmount);
}Auction Mechanisms
Sealed-Bid Auction
Multiple solvers submit bids, best wins.
// Submit bid
await solver.submitBid(intentId, outputAmount, executionPrice);
// Monitor and settle if won
const result = await solver.monitorAndSettleAuction(intentId);Dutch Auction
Price descends until a solver accepts.
// Check current price
const price = await solver.getDutchPrice(intentId);
// Accept at current price
await solver.acceptDutchAuction(intentId);
// Settle
await solver.settleDutchAuction(intentId);Custom Strategies
Extend BaseStrategy to create custom solving strategies:
import { BaseStrategy, Intent, Solution, VeloxSolver, IntentType } from '@velox-movement/solver';
class MyStrategy extends BaseStrategy {
name = 'MyCustomStrategy';
canHandle(intent: Intent): boolean {
// Only handle swaps above 1000 units
return intent.type === IntentType.SWAP && intent.inputAmount > BigInt(1000);
}
async calculateSolution(intent: Intent, solver: VeloxSolver): Promise<Solution | null> {
// Your custom logic here
const route = await solver.findBestRoute(
intent.inputToken.address,
intent.outputToken.address,
intent.inputAmount
);
// Apply custom spread
const outputWithSpread = route.expectedOutput * BigInt(9990) / BigInt(10000);
return {
intentId: intent.id,
outputAmount: outputWithSpread,
executionPrice: this.calculatePrice(intent, outputWithSpread),
route,
expiresAt: new Date(Date.now() + 60000),
};
}
}Solver Economics
Fees
- Protocol Fee: 3 bps (collected from input tokens)
- Solver Margin: Determined by spread (difference between market price and offered price)
Reputation System
- Starting Reputation: 5000/10000 (50%)
- Minimum to Participate: 2000/10000 (20%)
- Success Bonus: +100 per fill
- Failure Penalty: -200 per fail
- Fast Execution Bonus: +50 (fills < 5 seconds)
- Better-than-expected Bonus: +25
Staking
- Minimum Stake: 1,000,000 units
- Unstaking Cooldown: 7 days
Development
# Clone and install
git clone https://github.com/velox-protocol/solver-sdk
cd solver-sdk
npm install
# Run in development mode
npm run dev
# Run with custom config
npm run solver:start
# Check status
npm run solver:status
# Build for production
npm run buildSupport
- Documentation: https://docs.velox.movementlabs.xyz
- Discord: Join our Discord
- Issues: GitHub Issues
License
MIT
