Integration

Everything PLEDGE does is public program state, so another app, a bot or a dashboard can read campaigns and run the permissionless steps.

Read campaigns

All campaigns are Campaign accounts owned by the program. Fetch them with getProgramAccounts and decode with the IDL (engine/target/idl/pledge.json).

import { Connection, PublicKey } from "@solana/web3.js"
import { BorshAccountsCoder } from "@coral-xyz/anchor"
import idl from "./pledge.json"

const PROGRAM = new PublicKey(idl.address)
const coder = new BorshAccountsCoder(idl as any)
const conn = new Connection(process.env.SOLANA_RPC_URL!)

const accounts = await conn.getProgramAccounts(PROGRAM, {
  filters: [{ memcmp: coder.memcmp("Campaign") }],
})
const campaigns = accounts.map((a) => ({ address: a.pubkey, ...coder.decode("Campaign", a.account.data) }))

Numbers to show

Use these definitions so every interface tells the same truth:

NumberDefinition
Raisedtotal_pledged
Early pledges leftearly_cap - early_pledged, or 0 once now >= early_end
Bonus window endsearly_end
Your bonus if it failsfloor(pledge.eligible x bonus_bps / 10,000)
Bonus owed so farbonus_owed
Fee2% of raised on success, 0 if waiver_locked > 0

Describe the bonus per dollar: every dollar pledged in the first half earns the bonus rate if the campaign fails, up to the bonus the creator locked. Never add USDC and SOL figures together.

Derive addresses

const campaign = PublicKey.findProgramAddressSync(
  [Buffer.from("campaign"), creator.toBuffer(), new BN(id).toArrayLike(Buffer, "le", 8)], PROGRAM)[0]
const vault = PublicKey.findProgramAddressSync([Buffer.from("vault"), campaign.toBuffer()], PROGRAM)[0]
const pledge = PublicKey.findProgramAddressSync([Buffer.from("pledge"), campaign.toBuffer(), backer.toBuffer()], PROGRAM)[0]
const feeVault = PublicKey.findProgramAddressSync([Buffer.from("fees"), mint.toBuffer()], PROGRAM)[0]

Run the permissionless steps

After a deadline, anyone can send settle, then claim_backer for each pledge and claim_creator, then close_campaign. The money always goes to the owner's own token account, so a keeper can do this for everyone without being trusted. The same goes for crank_burn: any wallet can spend accumulated fees on the burn, within the per-call limits.

Events

CampaignCreated, Pledged, Settled, BackerPaid, CreatorPaid and WaiverLocked are emitted as Anchor events in the transaction logs; see the API reference for their fields.