Reduce volatility exposure with automated recurring buy orders executed on-chain.
Recurring Buy is our implementation of Dollar-Cost Averaging (DCA) - a proven investment strategy that reduces timing risk by spreading purchases over regular intervals.
How It Works
Each recurring buy order is a dedicated smart contract that:
Is owned by your address
Is allowed to spend your sell token
Executes swaps at scheduled intervals, directly from your wallet
Can be canceled anytime
Sell tokens never leave your wallet, your dedicated DCA smart contract only execute trades directly on your account.
Use Cases
Long-term Accumulation Buy tokens weekly to average entry price
Treasury Management Systematic token accumulation for protocols
Volatility Smoothing Spread large purchases across multiple intervals
Consistent Investing Invest fixed amounts regardless of price
SDK Methods
Data Fetching
getDcaOrders(params) - Fetch user’s recurring buy orders
Simple Integration
executeCreateDca(params) - Create recurring buy order with automatic approvals
executeCancelDca(params) - Cancel active recurring buy order
Advanced Integration
createDcaToCalls(order) - Build recurring buy creation calls for custom execution
cancelDcaToCalls(orderAddress) - Build cancellation calls
// Simple integration
const result = await executeCreateDca ({
provider: account ,
order: {
sellTokenAddress: USDC_ADDRESS ,
buyTokenAddress: STRK_ADDRESS ,
sellAmount: parseUnits ( '1200' , 6 ). toString (),
sellAmountPerCycle: parseUnits ( '100' , 6 ). toString (),
frequency: moment . duration ( 1 , 'week' ),
traderAddress: account . address
}
});
// Advanced: compose with other operations
const dcaCalls = createDcaToCalls ( order );
const swapCalls = quoteToCalls ( quote , slippage , account . address );
await account . execute ([ ... swapCalls , ... dcaCalls ]);
Parameters
Create Recurring Buy Order
The recurring buy order configuration object. Token to spend (e.g., USDC address)
Token to accumulate (e.g., STRK address)
Total budget to spend (in smallest unit, e.g., wei)
Amount to spend per execution (in smallest unit)
Time between purchases (using moment Duration)
Optional price limits. If the price is outside these bounds, the trade is skipped. Minimum amount of buy tokens to receive per cycle (slippage protection)
Maximum amount of buy tokens to receive per cycle (limit price)
Address of the user creating the order
Execution Details
Automated execution:
avnu executors monitor all active orders
Trades execute within 5 minutes of scheduled time
Each trade uses solver routing for best price
Failed trades are retried automatically
Fully Gas Free:
avnu covers all gas fees for recurring buy execution. Users pay 0 gas for their automated purchases.
MEV Protection & Safety:
Randomized Execution: We introduce randomness in execution triggering to proactively avoid potential MEV attacks.
Price Impact Guard: There is a by-design 5% price impact safety limit . If a trade would cause >5% price impact, it will fail to protect the user.
Constraints:
Minimum interval: 1 hour
Maximum executions: 1000 per order
Examples
Weekly STRK Accumulation
$100 of STRK every week for 12 weeks:
import { executeCreateDca } from '@avnu/avnu-sdk' ;
import { parseUnits } from 'ethers' ;
import moment from 'moment' ;
const result = await executeCreateDca ({
provider: account , // Starknet AccountInterface
order: {
sellTokenAddress: USDC_ADDRESS ,
buyTokenAddress: STRK_ADDRESS ,
sellAmount: parseUnits ( '1200' , 6 ). toString (), // Total budget: 1200 USDC
sellAmountPerCycle: parseUnits ( '100' , 6 ). toString (), // $100 per buy
frequency: moment . duration ( 1 , 'week' ), // Frequency using moment
pricingStrategy: {
tokenToMinAmount: parseUnits ( '200' , 18 ). toString (), // Min 200 STRK per 100 USDC (Max price ~0.50 USDC/STRK)
tokenToMaxAmount: parseUnits ( '250' , 18 ). toString (), // Max 250 STRK per 100 USDC (Min price ~0.40 USDC/STRK)
},
traderAddress: account . address
}
});
console . log ( 'Recurring Buy Order Created:' , result . transactionHash );
Cancel an Order
import { executeCancelDca } from '@avnu/avnu-sdk' ;
const result = await executeCancelDca ({
provider: account ,
orderAddress: '0x...' // The address of the recurring buy order contract
});
console . log ( 'Recurring Buy Order Cancelled:' , result . transactionHash );
Fetch Active Orders
import { getDcaOrders , DcaOrderStatus } from '@avnu/avnu-sdk' ;
const orders = await getDcaOrders ({
traderAddress: account . address ,
status: DcaOrderStatus . ACTIVE ,
page: 0 ,
size: 10
});
console . log ( 'Active Orders:' , orders . content );
API Reference
REST API Documentation Complete HTTP endpoint reference and integration guide →
Advanced Features