This page describes the DCA integration contract. DCA execution and other background workers are currently disabled during the backend migration. Do not fund a DCA wallet or create a live schedule on the basis of these examples.
When enabled and independently qualified, SW4P DCA schedules recurring USDC swaps from a user's WaaS Solana wallet into a target Solana token such as 555 or wrapped SOL. The worker is designed to check funded USDC balance, execute the Jupiter swap, and record execution history.
User Flow
- Open DCA Scheduler in the SW4P app.
- Choose the funding chain, target token, USDC amount per execution, interval, and duration.
- Create the schedule. For EVM funding, SW4P returns the user's WaaS Solana deposit address and a helper deposit URL.
- Only after production execution is explicitly available and verified, fund the designated wallet for the planned executions. Do not send funds during maintenance.
- Monitor runs, pause/resume schedules, or cancel the schedule from the same UI.
If the worker sees repeated insufficient-balance failures, it auto-pauses the schedule with pauseReason: "insufficient_balance" so the user can top up before resuming.
Execution Semantics
The worker atomically claims due schedules by advancing nextExecutionAt before it checks balance or submits a swap. That prevents duplicate execution across backend replicas. It also means transient failures are retried at the next configured interval instead of immediately retrying in a tight loop.
After an on-chain swap is submitted successfully, terminal database persistence is retried three times before the worker emits a structured alert="dca_orphan_execution" log with the schedule ID, execution ID, and swap transaction signature. Operators should page on that alert and reconcile the execution row from the logged transaction signature.
SDK Usage
import { Sw4pClient } from "@sw4p/sdk";
const sw4p = new Sw4pClient({ apiKey: process.env.SW4P_API_KEY! });
const schedule = await sw4p.createDCA({
source_chain: "BASE",
token_out: "CQwwRomsuWsUCPYomZmRnwMns4ZCTASc31ExMvSysAF2",
token_out_symbol: "555",
amount_usdc: 25,
frequency_hours: 24,
max_executions: 12,
});
await sw4p.pauseDca(schedule.id);
await sw4p.resumeDca(schedule.id);
await sw4p.cancelDCA(schedule.id);
use sw4p_sdk::{CreateDcaParams, Sw4pClient};
let client = Sw4pClient::new(std::env::var("SW4P_API_KEY")?);
let schedule = client.create_dca(&CreateDcaParams {
source_chain: Some("BASE".to_string()),
token_out: "CQwwRomsuWsUCPYomZmRnwMns4ZCTASc31ExMvSysAF2".to_string(),
token_out_symbol: Some("555".to_string()),
amount_usdc: 25.0,
frequency_hours: 24,
max_executions: Some(12),
referrer_code: None,
}).await?;
client.pause_dca(&schedule.id).await?;
client.resume_dca(&schedule.id).await?;
client.cancel_dca(&schedule.id).await?;
Monitoring
Developer Console analytics includes a DCA Worker Health panel scoped to the connected wallet. It reports active schedules, due schedules, auto-pauses, 24-hour successes/failures, total executions, and the next scheduled run. A state of ATTENTION means at least one schedule is due, auto-paused, or has recent failures.
QA Gate
Before closing a production DCA ticket, capture devnet evidence for the flows that are supported by the configured devnet execution provider:
- Create: schedule returns
ACTIVE, source chain, target token, interval, and next execution time. - Execute: worker records a
SUCCESSexecution withswapTxHashonly when the configured swap provider supports the devnet input/output mints. - Complete: finite schedules move to
COMPLETEDoncemaxExecutionsis reached. - Controls: pause, resume, and cancel each return the updated schedule and are reflected in the UI.
- Critical failure: insufficient balance records failed executions and auto-pauses after the configured retry threshold.
Current provider note: SW4P's production DCA executor uses Jupiter for Solana swaps. Public Jupiter quote responses must be verified against the active devnet mints before claiming devnet swap-readiness; if Jupiter rejects a devnet mint as not tradable, keep the PR in draft and attach that blocker instead of fabricating a successful execution row.