POTLOCK Campaigns Contract: Escrow, Targets, and Donations
2025-09-22 · 8 min read

Campaigns on POTLOCK let you raise funds for a specific initiative with optional minimum targets and time windows. Donations can be held in escrow until the target is met; otherwise donors are refunded.
PotLock/core★ 11Fork 4
Campaigns contract lives under contracts/ (feat/revised-campaign branch). MIT licensed.
Use cases
- Targeted fundraising for events, projects, or community support.
- Campaigns on behalf of organizations.
- Community engagement with clear goals and refunds if target not met.
Types
type CampaignId = u64;
type DonationId = u64;
type TimestampMs = u64;
type ReferrerPayouts = HashMap<AccountId, Balance>;Campaign struct
pub struct Campaign {
pub owner: AccountId,
pub name: String,
pub description: Option<String>,
pub cover_image_url: Option<String>,
pub recipient: AccountId,
pub start_ms: TimestampMs,
pub end_ms: Option<TimestampMs>,
pub created_ms: TimestampMs,
pub ft_id: Option<AccountId>,
pub target_amount: Balance,
pub min_amount: Option<Balance>,
pub max_amount: Option<Balance>,
pub total_raised_amount: Balance,
pub net_raised_amount: Balance,
pub escrow_balance: Balance,
pub referral_fee_basis_points: u32,
pub creator_fee_basis_points: u32,
pub allow_fee_avoidance: bool,
}Write methods
#[payable]
pub fn create_campaign(
&mut self,
name: String,
description: Option<String>,
cover_image_url: Option<String>,
recipient: AccountId,
start_ms: TimestampMs,
end_ms: Option<TimestampMs>,
ft_id: Option<AccountId>,
target_amount: U128,
min_amount: Option<U128>,
max_amount: Option<U128>,
referral_fee_basis_points: Option<u32>,
creator_fee_basis_points: Option<u32>,
allow_fee_avoidance: Option<bool>,
) -> CampaignExternal
#[payable]
pub fn donate(
&mut self,
campaign_id: CampaignId,
message: Option<String>,
referrer_id: Option<AccountId>,
bypass_protocol_fee: Option<bool>,
bypass_creator_fee: Option<bool>,
) -> PromiseOrValue<DonationExternal>Read methods
pub fn get_config(&self) -> Config
pub fn get_campaign(&self, campaign_id: CampaignId) -> CampaignExternal
pub fn get_campaigns(&self, from_index: Option<u128>, limit: Option<u128>) -> Vec<CampaignExternal>
pub fn get_campaigns_by_owner(&self, owner_id: AccountId, ...) -> Vec<CampaignExternal>
pub fn get_campaigns_by_recipient(&self, recipient_id: AccountId, ...) -> Vec<CampaignExternal>
pub fn get_donations_for_campaign(&self, campaign_id: CampaignId, ...) -> Vec<DonationExternal>
pub fn get_donations_for_donor(&self, donor_id: AccountId, ...) -> Vec<DonationExternal>Events
{
"standard": "potlock",
"version": "1.0.0",
"event": "campaign_create",
"data": [{ "campaign": { ... } }]
}Mainnet: v1.campaigns.potlock.near. Staging: v1.campaigns.staging.potlock.near. Full contract docs: docs.potlock.org/contracts/campaigns-live.