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:
| Number | Definition |
|---|---|
| Raised | total_pledged |
| Early pledges left | early_cap - early_pledged, or 0 once now >= early_end |
| Bonus window ends | early_end |
| Your bonus if it fails | floor(pledge.eligible x bonus_bps / 10,000) |
| Bonus owed so far | bonus_owed |
| Fee | 2% 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.