Schedule Operations
Create and manage payment schedules.
Create Schedule (Simple)
Use createScheduleFromRecipients for automatic merkle tree generation.
import { PublicKey } from "@solana/web3.js";
import { BN } from "@coral-xyz/anchor";
const recipients = [
{ address: new PublicKey("recipient1..."), amount: 100_000n },
{ address: new PublicKey("recipient2..."), amount: 200_000n },
{ address: new PublicKey("recipient3..."), amount: 200_000n },
];
const { signature, scheduleId, merkleRoot } =
await client.createScheduleFromRecipients({
recipients,
intervalSecs: 86400, // Daily (24 hours)
reservedAmount: new BN(10_000_000), // Total reserved: 10 USDC
perExecutionAmount: new BN(500_000), // Per cycle: 0.5 USDC
});
console.log("Schedule created:", signature);
console.log("Schedule ID:", scheduleId);
console.log("Merkle Root:", merkleRoot);Parameters:
recipients- Array of{ address: PublicKey, amount: bigint }intervalSecs- Seconds between executionsreservedAmount- Total amount to reserve (BN)perExecutionAmount- Amount paid per execution cycle (BN)
Returns:
signature- Transaction signaturescheduleId- Schedule ID (number[])merkleRoot- Merkle root (number[])
Create Schedule (Advanced)
For manual control over schedule parameters.
import { generateScheduleId, buildMerkleTree } from "@veil-dev/sdk";
// Generate IDs
const scheduleId = generateScheduleId();
const erJobId = generateScheduleId();
// Build merkle tree manually
const recipients = [
{ address: pubkey1, amount: 100_000n },
{ address: pubkey2, amount: 200_000n },
];
const { root, proofs } = buildMerkleTree(recipients);
// Create schedule
const signature = await client.createSchedule({
scheduleId,
intervalSecs: 86400,
reservedAmount: new BN(10_000_000),
perExecutionAmount: new BN(500_000),
merkleRoot: Array.from(root),
totalRecipients: recipients.length,
erJobId,
});Pause Schedule
Pause or resume a schedule.
import { getVaultPda, getSchedulePda } from "@veil-dev/sdk";
const [vaultPda] = getVaultPda(wallet.publicKey);
const [schedulePda] = getSchedulePda(vaultPda, scheduleId);
// Pause
await client.pauseSchedule(schedulePda, true);
// Resume
await client.pauseSchedule(schedulePda, false);Cancel Schedule
Cancelling returns reserved funds to available balance.
await client.cancelSchedule(schedulePda);Note: Cancelled schedules cannot be resumed.
Get Schedule State
const schedule = await client.getSchedule(schedulePda);
if (schedule) {
console.log("Status:", schedule.status);
console.log("Next Execution:", schedule.nextExecution.toString());
console.log("Reserved:", schedule.reservedAmount.toString());
console.log("Recipients:", schedule.totalRecipients);
console.log("Last Executed Batch:", schedule.lastExecutedBatch.toString());
}Returns: ScheduleAccount | null
ScheduleAccount Fields:
employer- Vault ownervault- Vault PDAscheduleId- Schedule identifierstatus- Active | Paused | CancelledintervalSecs- Seconds between executionsreservedAmount- Reserved funds (BN)perExecutionAmount- Amount per cycle (BN)merkleRoot- Merkle root (number[])totalRecipients- Number of recipientsnextExecution- Next execution timestamp (BN)lastExecutedBatch- Last batch number (BN)
PDA Helpers
Derive program addresses without making RPC calls.
import {
getVaultPda,
getSchedulePda,
} from "@veil-dev/sdk";
// Vault for an employer
const [vaultPda, vaultBump] = getVaultPda(employerPubkey);
// Schedule
const [schedulePda] = getSchedulePda(vaultPda, scheduleId);Example: Complete Schedule Flow
// 1. Create schedule
const { scheduleId, merkleRoot } = await client.createScheduleFromRecipients({
recipients: [
{ address: recipient1, amount: 100_000n },
{ address: recipient2, amount: 200_000n },
],
intervalSecs: 86400,
reservedAmount: new BN(2_000_000),
perExecutionAmount: new BN(300_000),
});
// 2. Get schedule PDA
const [vaultPda] = getVaultPda(wallet.publicKey);
const [schedulePda] = getSchedulePda(vaultPda, scheduleId);
// 3. Check status
const schedule = await client.getSchedule(schedulePda);
console.log("Status:", schedule?.status);
// 4. Pause if needed
await client.pauseSchedule(schedulePda, true);
// 5. Resume
await client.pauseSchedule(schedulePda, false);