POTLOCK Lists Contract: Curated Lists, Registrations, and Upvotes
2025-09-22 · 10 min read

Lists are like Spotify playlists for NEAR accounts. Anyone can create a list; accounts can register or be added by owner/admins. Lists are used as eligibility criteria in pots (e.g. POTLOCK public goods registry is list_id = 1).
PotLock/core★ 11Fork 4
Lists contract: github.com/PotLock/core/tree/main/contracts/lists. Example BOS SDK: PotLock/bos-app widget/SDK/lists.jsx.
Use cases
- Curated playlists of projects for quick donate flows.
- Membership and airdrop waitlists.
- Custom explore pages; community signal via upvotes.
- Donate-to-all flow for a basket of projects.
- RetroPGF and eligibility in quadratic funding pots.
Roles
- Owner: created the list; can add/remove admins, transfer ownership, update list, set default registration status, add/remove accounts in batches.
- Admin: same as owner except add/remove other admins.
- Registrant: can register/unregister if applications are open (no admin_only_registration).
- User: can upvote lists; can apply to list if applications open.
General types
type RegistrantId = AccountId;
type RegistrationId = u64;
type ListId = u64;
type TimestampMs = u64;ListInternal (stored)
pub struct ListInternal {
pub name: String, // max 64
pub description: Option<String>, // max 256
pub cover_img_url: Option<String>, // https://
pub owner: AccountId,
pub created_at: TimestampMs,
pub updated_at: TimestampMs,
pub default_registration_status: RegistrationStatus,
pub admin_only_registrations: bool,
}RegistrationStatus
pub enum RegistrationStatus {
Pending,
Approved,
Rejected,
Graylisted,
Blacklisted,
}Write methods
#[payable]
pub fn create_list(
&mut self,
name: String,
description: Option<String>,
cover_image_url: Option<String>,
admins: Option<Vec<AccountId>>,
default_registration_status: RegistrationStatus,
admin_only_registrations: Option<bool>,
) -> ListExternal
#[payable]
pub fn update_list(&mut self, list_id: ListId, name: Option<String>, ...) -> ListExternal
#[payable]
pub fn delete_list(&mut self, list_id: ListId)
#[payable]
pub fn upvote(&mut self, list_id: ListId)
#[payable]
pub fn remove_upvote(&mut self, list_id: ListId)
#[payable]
pub fn register_batch(&mut self, list_id: ListId, notes: Option<String>, registrations: Option<Vec<RegistrationInput>>) -> Vec<RegistrationExternal>
#[payable]
pub fn unregister(&mut self, list_id: Option<ListId>, registration_id: Option<RegistrationId>)
#[payable]
pub fn update_registration(&mut self, registration_id: RegistrationId, status: Option<RegistrationStatus>, notes: Option<String>) -> RegistrationExternalRead methods
pub fn get_list(&self, list_id: ListId) -> ListExternal
pub fn get_lists(&self, from_index: Option<u64>, limit: Option<u64>) -> Vec<ListExternal>
pub fn get_lists_for_owner(&self, owner_id: AccountId) -> Vec<ListExternal>
pub fn get_lists_for_registrant(&self, registrant_id: AccountId) -> Vec<ListExternal>
pub fn get_upvotes_for_list(&self, list_id: ListId, ...) -> Vec<AccountId>
pub fn get_registrations_for_list(&self, list_id: ListId, status: Option<RegistrationStatus>, ...) -> Vec<RegistrationExternal>
pub fn is_registered(&self, list_id: Option<ListId>, account_id: RegistrantId, required_status: Option<RegistrationStatus>) -> boolEvents
"event": "create_list" | "update_list" | "delete_list" | "upvote" | "remove_upvote" | "update_admins" | "owner_transfer" | "create_registration" | "update_registration" | "delete_registration" | "set_source_metadata"Mainnet: lists.potlock.near. Staging: lists.staging.potlock.near. Public goods registry: list_id = 1. Full docs: docs.potlock.org/contracts/lists-live.