apps/keeper/src/jobs/sweep.ts
Moves platform income to the treasury. Shown whole, as it was in the repository when this site was built. Line numbers link: add #L12 to the address.
apps/keeper/src/jobs/sweep.ts66 lines
1// sweep: move the platform slice (Σ coins.platform_lamports − Σ sweeps) from the vault to the treasury2// (NEXT_PUBLIC_SOLARY_TREASURY, cold) once it reaches sweep.min_lamports (0.05 SOL). Never touches what the vault3// owes holders or the buyback, and keeps vault.reserve_lamports for fees. The treasury may not exist on-chain yet:4// the first transfer to it must reach the rent-exempt minimum, which the threshold covers.5// Intents (kind 'sweep'); the sweeps row is written when the transfer confirms.6import { eq } from 'drizzle-orm';7import { intents, sweeps } from '@solary/db';8import { RENT_EXEMPT_WALLET } from '@solary/core';9import { event, sol, type JobCtx, type Stats } from '../ctx';10import { createIntent, holdReason, intentState, openIntents, setIntent } from '../intents';11import { words } from '../ledger/words';12import { settingBig, vaultObligations } from './common';13 14const KIND = 'sweep';15 16async function recordSweep(ctx: JobCtx, intentId: number, sig: string, lamports: bigint): Promise<void> {17 const inserted = await ctx.db.transaction(async (t) => {18 const [seen] = await t.select({ id: sweeps.id }).from(sweeps).where(eq(sweeps.tx, sig)).limit(1);19 await t.update(intents).set({ status: 'confirmed', updatedAt: new Date() }).where(eq(intents.id, intentId));20 if (seen) return false;21 await t.insert(sweeps).values({ lamports, tx: sig });22 return true;23 });24 if (inserted) await event(ctx.db, { action: 'sweep', message: words.swept(lamports), amounts: { lamports: lamports.toString() }, sig });25}26 27export async function sweepJob(ctx: JobCtx): Promise<Stats> {28 let reconciled = 0;29 for (const i of await openIntents(ctx, KIND)) {30 const st = await intentState(ctx, i);31 if (st === 'confirmed') {32 await recordSweep(ctx, i.id, i.sig, BigInt(String(i.payload.lamports ?? '0')));33 reconciled++;34 } else if (st !== 'unknown') await setIntent(ctx, i.id, st);35 }36 37 const treasury = ctx.sol.mode === 'fake' ? (ctx.env.treasury ?? 'FAKETreasury1111111111111111111111111111111') : ctx.env.treasury;38 if (!treasury) return { reconciled, skipped: 'NEXT_PUBLIC_SOLARY_TREASURY not set' };39 const min = await settingBig(ctx, 'sweep.min_lamports', 50_000_000n);40 const reserve = await settingBig(ctx, 'vault.reserve_lamports', 10_000_000n);41 const owed = await vaultObligations(ctx);42 if (owed.platform < min) return { reconciled, platform_lamports: owed.platform.toString(), skipped: 'under the sweep minimum' };43 const balance = await ctx.sol.vaultBalance();44 const free = balance - owed.holders - owed.buyback - reserve;45 const amount = owed.platform < free ? owed.platform : free;46 if (amount < min) return { reconciled, platform_lamports: owed.platform.toString(), vault_lamports: balance.toString(), skipped: 'vault holds too little above what it owes' };47 const exists = (await ctx.sol.walletsExist([treasury])).has(treasury);48 if (!exists && amount < BigInt(RENT_EXEMPT_WALLET)) return { reconciled, skipped: 'treasury does not exist yet and the amount is under rent' };49 50 const priority = await settingBig(ctx, 'tx.priority_micro_lamports', 50_000n);51 const prepared = await ctx.sol.prepareSweep(treasury, amount, priority);52 if (!prepared.ok) return { reconciled, failed: prepared.error ?? 'simulation failed' };53 const hold = holdReason(ctx);54 if (hold) {55 ctx.log(`${hold}: would sweep ${sol(amount)} to the treasury`);56 return { reconciled, would_sweep: amount.toString() };57 }58 const intentId = await createIntent(ctx, KIND, { to: treasury, lamports: amount });59 const res = await ctx.sol.send(prepared, (sig, lvbh) => setIntent(ctx, intentId, 'sent', { sig, payload: { lastValidBlockHeight: lvbh } }));60 if (res.status === 'confirmed') {61 await recordSweep(ctx, intentId, res.signature, amount);62 return { reconciled, swept: amount.toString() };63 }64 if (res.status !== 'pending') await setIntent(ctx, intentId, res.status, { payload: { error: res.error } });65 return { reconciled, status: res.status };66}