Scheduled Transactions
Setting up and managing scheduled transactions
Scheduled Transactions Guide
This guide covers setting up scheduled transactions for automated payments, subscriptions, and recurring transfers.
Overview
Scheduled transactions allow you to automate one-time or recurring transactions. Supported patterns include:
- One-time: Execute a transaction at a specific future date/time
- Daily: Execute every day at a specified time
- Weekly: Execute weekly on a specific day
- Monthly: Execute monthly on a specific date
Basic Setup
One-Time Scheduled Transaction
import { create } from 'cilantro-sdk/scheduled-transactions';
// Schedule a transaction for next week
const scheduledDate = new Date();
scheduledDate.setDate(scheduledDate.getDate() + 7);
const scheduled = await create('wallet-id', {
transactionType: 'SEND_SOL',
recurrenceType: 'ONE_TIME',
scheduledAt: scheduledDate.toISOString(),
toAddress: 'DYw8jCTfwHNRJhhmFcbXvVDTqWMEVFBX6ZKUmG5CNSKK',
amount: 1000000000 // 1 SOL
});
console.log('Transaction scheduled:', scheduled.data.id);
Daily Recurring Transaction
// Schedule daily payments at 9 AM
const dailyPayment = await create('wallet-id', {
transactionType: 'SEND_SOL',
recurrenceType: 'DAILY',
scheduledAt: '2024-01-01T09:00:00Z', // First execution time
toAddress: 'recipient-address',
amount: 50000000, // 0.05 SOL per day
maxExecutions: 30 // Stop after 30 days
});
Weekly Recurring Transaction
// Schedule weekly subscription payment (every Monday)
const weeklySubscription = await create('wallet-id', {
transactionType: 'SEND_SOL',
recurrenceType: 'WEEKLY',
scheduledAt: '2024-01-01T10:00:00Z', // Every Monday at 10 AM
toAddress: 'subscription-recipient-address',
amount: 1000000000 // 1 SOL per week
});
Monthly Recurring Transaction
// Schedule monthly salary payment (1st of each month)
const monthlySalary = await create('wallet-id', {
transactionType: 'SEND_SOL',
recurrenceType: 'MONTHLY',
scheduledAt: '2024-01-01T00:00:00Z', // 1st of each month
toAddress: 'employee-address',
amount: 10000000000 // 10 SOL per month
});
Managing Scheduled Transactions
List All Scheduled Transactions
import { findAll } from 'cilantro-sdk/scheduled-transactions';
const scheduled = await findAll('wallet-id');
console.log('Total scheduled:', scheduled.data.length);
// Filter by status
const pending = scheduled.data.filter(tx => tx.status === 'pending');
const completed = scheduled.data.filter(tx => tx.status === 'completed');
const failed = scheduled.data.filter(tx => tx.status === 'failed');
Get Scheduled Transaction Details
import { findOne } from 'cilantro-sdk/scheduled-transactions';
const transaction = await findOne('wallet-id', 'scheduled-transaction-id');
console.log('Status:', transaction.data.status);
console.log('Next execution:', transaction.data.nextExecution);
console.log('Executions count:', transaction.data.executionCount);
Update Scheduled Transaction
import { update } from 'cilantro-sdk/scheduled-transactions';
// Update amount and schedule time
await update('wallet-id', 'scheduled-transaction-id', {
scheduledAt: '2025-01-01T00:00:00Z',
amount: 2000000000 // Increase to 2 SOL
});
Scheduled transactions cannot be updated once they enter 'processing' status. Make changes before the scheduled execution time.
Cancel Scheduled Transaction
import { cancel } from 'cilantro-sdk/scheduled-transactions';
// Cancel a pending scheduled transaction
await cancel('wallet-id', 'scheduled-transaction-id');
Use Cases
Subscription Payment System
async function setupSubscription(
walletId: string,
recipientAddress: string,
monthlyAmount: number
) {
// Create monthly subscription
const subscription = await create(walletId, {
transactionType: 'SEND_SOL',
recurrenceType: 'MONTHLY',
scheduledAt: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(),
toAddress: recipientAddress,
amount: monthlyAmount,
metadata: {
subscriptionId: 'sub-123',
plan: 'premium'
}
});
return subscription.data;
}
Automated Savings Plan
async function setupSavingsPlan(
walletId: string,
savingsWalletAddress: string,
dailyAmount: number,
durationDays: number
) {
const savingsPlan = await create(walletId, {
transactionType: 'SEND_SOL',
recurrenceType: 'DAILY',
scheduledAt: new Date().toISOString(),
toAddress: savingsWalletAddress,
amount: dailyAmount,
maxExecutions: durationDays
});
return savingsPlan.data;
}
Payroll System
async function setupPayroll(
walletId: string,
employeeAddresses: string[],
salaryAmount: number
) {
const payrollTransactions = [];
for (const address of employeeAddresses) {
const transaction = await create(walletId, {
transactionType: 'SEND_SOL',
recurrenceType: 'MONTHLY',
scheduledAt: '2024-01-01T00:00:00Z', // 1st of each month
toAddress: address,
amount: salaryAmount
});
payrollTransactions.push(transaction.data);
}
return payrollTransactions;
}
Monitoring and Status
Check Transaction Status
async function monitorScheduledTransactions(walletId: string) {
const scheduled = await findAll(walletId);
for (const tx of scheduled.data) {
const details = await findOne(walletId, tx.id);
console.log(`Transaction ${tx.id}:`);
console.log(`- Status: ${details.data.status}`);
console.log(`- Next execution: ${details.data.nextExecution}`);
console.log(`- Executions: ${details.data.executionCount}`);
if (details.data.status === 'failed') {
console.error(`- Error: ${details.data.error}`);
// Handle failed transaction
}
}
}
Handle Failed Transactions
async function handleFailedTransactions(walletId: string) {
const scheduled = await findAll(walletId);
const failed = scheduled.data.filter(tx => tx.status === 'failed');
for (const tx of failed) {
console.error(`Failed transaction: ${tx.id}`);
// Option 1: Retry by updating schedule
if (tx.recurrenceType !== 'ONE_TIME') {
await update(walletId, tx.id, {
scheduledAt: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString()
});
}
// Option 2: Cancel and notify
// await cancel(walletId, tx.id);
// notifyUser(tx.id, 'Transaction failed');
}
}
Best Practices
Verify Balance
Ensure wallet has sufficient balance before scheduling recurring transactions
Set Max Executions
Use maxExecutions to prevent infinite recurring transactions
Monitor Regularly
Regularly check transaction status to catch failures early
Handle Errors
Implement error handling for failed scheduled transactions