A Dollar Cost Averaging (DCA) plugin for the Vultisig ecosystem that enables automated, recurring cryptocurrency swaps across multiple chains.
Note: Uniswap V2 support has been removed. The plugin is being migrated to use 1inch as the DEX aggregator for EVM networks.
The DCA plugin operates as part of Vultisig's policy-based transaction verification system, allowing users to set up automated recurring swaps with configurable frequency, amounts, and assets. The system leverages distributed key signing (DKLS) for secure transaction execution.
- Ethereum
- Arbitrum
- Avalanche
- BNB Chain
- Base
- Blast
- Optimism
- Polygon
- Bitcoin
- Solana
- XRP
The system consists of four independently deployable services:
REST API server that handles policy management and provides the main plugin interface.
Key Features:
- Policy creation and validation
- Recipe specification management
- Multi-chain swap configuration
Background worker that schedules DCA transactions based on configured intervals.
Supported Frequencies:
minutely(60s)hourly(3600s)daily(86400s)weekly(604800s)bi-weekly(1209600s)monthly(2592000s)
Task consumer that executes DCA swaps and handles distributed key signing operations.
Key Features:
- Multi-chain network initialization
- Swap execution (migrating to 1inch for EVM chains)
- ERC20 approval management
- Distributed key signing integration
Blockchain transaction indexer for monitoring and verification.
internal/dca/- Core DCA logic, policy specs, and transaction consumptioninternal/evm/- EVM blockchain abstraction with multi-network supportinternal/graceful/- Graceful shutdown handling
- Policy Creation - User configures DCA parameters through the API
- Recipe Validation - System validates configuration against JSON schema
- Rule Generation - Creates swap operation rules with parameter constraints
- Scheduling - Scheduler queues transactions based on frequency settings, respecting endDate constraints
- Execution - Worker processes tasks, handling approvals and swaps
- Key Signing - Integrates with Vultisig's distributed key signing system
All services use environment-based configuration:
# Database
POSTGRES_DSN="postgres://user:pass@host:port/dbname?sslmode=disable"
# Redis (Task Queue)
REDIS_HOST="localhost"
REDIS_PORT="6379"
REDIS_PASSWORD="password"
# Block Storage
BLOCKSTORAGE_HOST="localhost:9100"
BLOCKSTORAGE_REGION="us-east-1"
BLOCKSTORAGE_ACCESSKEY="access-key"
BLOCKSTORAGE_SECRETKEY="secret-key"
BLOCKSTORAGE_BUCKET="bucket-name"
# DataDog
DATADOG_HOST="localhost"
DATADOG_PORT="8125"# Vault Service
VAULTSERVICE_RELAY_SERVER="https://api.vultisig.com/router"
VAULTSERVICE_LOCALPARTYPREFIX="vultisig-dca-0000"
VAULTSERVICE_ENCRYPTIONSECRET="encryption-secret"
# Verifier
VERIFIER_URL="http://localhost:8080"
VERIFIER_TOKEN="api-token"
VERIFIER_PARTYPREFIX="verifier"
# RPC URLs (per chain)
RPC_ETHEREUM_URL="https://ethereum-rpc.publicnode.com"
RPC_ARBITRUM_URL="https://arbitrum-rpc.publicnode.com"
RPC_AVALANCHE_URL="https://avalanche-c-chain-rpc.publicnode.com"
RPC_DASH_URL="https://dash-rpc.publicnode.com"
RPC_MAYACHAIN_URL="https://mayanode.mayachain.info"
# ... (other chains)# Build specific service
go build -o bin/server cmd/server/main.go
go build -o bin/worker cmd/worker/main.go
go build -o bin/scheduler cmd/scheduler/main.go
go build -o bin/tx_indexer cmd/tx_indexer/main.go
# Build all services
for service in server worker scheduler tx_indexer; do
go build -o bin/$service cmd/$service/main.go
done# Run all tests
go test ./...
# Run specific package tests
go test ./internal/dca/# Build Docker images
docker build --build-arg SERVICE=server -t dca-server .
docker build --build-arg SERVICE=worker -t dca-worker .
docker build --build-arg SERVICE=scheduler -t dca-scheduler .
docker build --build-arg SERVICE=tx_indexer -t dca-tx-indexer .Deploy using the provided manifests in the deploy/ directory:
# Apply all manifests
kubectl apply -f deploy/
# Or apply in order
kubectl apply -f deploy/00_ns.yaml
kubectl apply -f deploy/01_*.yaml
kubectl apply -f deploy/02_*.yaml
kubectl apply -f deploy/03_*.yamlPOST /api/policy
{
"fromChain": "Ethereum",
"fromAsset": "0xA0b86a33E6441439C01695E5481c061F0e6bB4F5",
"fromAmount": "100000000000000000000",
"toChain": "Ethereum",
"toAsset": "0x0000000000000000000000000000000000000000",
"toAddress": "0x742d35Cc6634C0532925a3b8D1B9b12a6B43B9a8",
"frequency": "daily",
"endDate": "2024-12-31T23:59:59Z"
}- fromChain/toChain: Must be same chain (cross-chain not supported)
- fromAsset/toAsset: Contract addresses (
0x0000...for native tokens) - fromAmount: Amount in wei (string)
- frequency:
minutely,hourly,daily,weekly,bi-weekly,monthly - toAddress: Recipient address
- endDate: ISO 8601 timestamp (optional) - scheduler stops scheduling new runs after this date
- Ethereum:
github.com/ethereum/go-ethereum- Blockchain interactions - Task Queue:
github.com/hibiken/asynqwith Redis - Background jobs - Database: PostgreSQL with
github.com/jackc/pgx/v5- Data persistence - Web Framework:
github.com/labstack/echo/v4- REST API - Configuration:
github.com/kelseyhightower/envconfig- Environment config
github.com/vultisig/recipes- Recipe system and blockchain abstractionsgithub.com/vultisig/verifier- Policy verification and plugin frameworkgithub.com/vultisig/go-wrappers- Native cryptographic library wrappers (DKLS)
- PostgreSQL - For policy and scheduler storage
- Redis - For task queuing
- Ethereum RPC - Mainnet or testnet endpoint
- Go 1.21+ - For building the services
- Copy environment variables from GoLand run configurations (
.run/*.xml) - Update database and Redis connection strings
- Configure RPC endpoints for desired chains
- Set up Vultisig vault and verifier integration
- DataDog Integration - Metrics and monitoring
- Structured Logging - Configurable log levels
- Health Checks - Available on
/healthzendpoint - Transaction Indexing - Audit trail and verification
- Distributed key signing (DKLS) for secure transaction execution
- Policy-based access control through Vultisig verifier
- Rate limiting: Maximum 2 transactions per frequency window
- Slippage protection and deadline management for DEX operations
- Follow existing code patterns and conventions
- Ensure all tests pass:
go test ./... - Update documentation for new features
- Use structured logging for observability