Sol.College

Full lesson

agora

On-chain debate-or-vote arbitration for multi-agent LLM systems. Agents deliberate. Quorum decides. Chain proves it.

What it does

From the project README:

This repo contains the backend, the Python SDK, the hosted dashboard, the benchmark runner, and the on-chain integration surface.
Original
zahemen9900/agora
SuperStack fork
Blockchains/agora @ 2f9078b
Stars
4
Last push (original)
2026-10-29
Languages
Python, TypeScript, Shell, CSS, Rust, JavaScript
Detected stack
Anchorsolana-py
Categories
AI & AgentsGovernance & DAOs
Licence
MIT
Homepage
https://agora-bay-seven.vercel.app

Architecture

282 source files. By extension: .py ×116, .tsx ×101, .ts ×55, .rs ×9, .js ×1.

Top-level directorySource files
agora-web155
agora43
tests38
api25
contract11
scripts4
sandbox_runner_service2
benchmarks2

On-chain programs: contract/programs/agora

Dapp: devnet deploy pending

⏳ Devnet deploy pending — goes live when the devnet wallet is topped up. This fork's own dapp is not deployed yet, so there is no program address or transaction to show. It is queued in dapp-queue.txt; once devnet SOL is available it is deployed, exercised with real devnet transactions, and this section switches to the live dapp at /dapps/agora/. Until then, the lesson and step-by-step guide below are complete, and you can run it locally with the commands below.

Key code, explained

Excerpts chosen automatically where the code uses the most Solana concepts, pinned to the fork's commit.

zahemen9900/agora · contract/programs/agora/src/instructions/release_payment.rs L13–36 @ 2f9078b · MIT · original
    )]    pub task_account: Account<'info, TaskAccount>,     #[account(        mut,        seeds = [b"vault", task_id.as_ref()],        bump = task_account.vault_bump,        close = authority    )]    pub vault: Account<'info, VaultAccount>,     #[account(mut)]    pub recipient: SystemAccount<'info>,     #[account(mut)]    pub authority: Signer<'info>,    pub system_program: Program<'info, System>,} pub fn handler(ctx: Context<ReleasePayment>, _task_id: [u8; 32]) -> Result<()> {    let task_account = &mut ctx.accounts.task_account;     require_keys_eq!(        ctx.accounts.authority.key(),
  1. Line 18 seeds = [b"vault", task_id.as_ref()],: Declares the PDA seeds. Anchor re-derives the address and rejects the account if it doesn't match.
  2. Line 19 bump = task_account.vault_bump,: Uses the bump seed, the extra byte that pushes the derived address off the ed25519 curve.
  3. Line 20 close = authority: Closes the account at the end of the instruction and refunds its lamports.
  4. Line 28 pub authority: Signer<'info>,: Requires this account to have signed the transaction.
  5. Line 35 require_keys_eq!(: An explicit validation that aborts the instruction with an error.
zahemen9900/agora · contract/programs/agora/src/instructions/record_switch.rs L13–36 @ 2f9078b · MIT · original
        seeds = [b"task", task_id.as_ref()],        bump = task_account.bump    )]    pub task_account: Account<'info, TaskAccount>,     #[account(        init,        payer = authority,        space = 8 + MechanismSwitchLog::LEN,        seeds = [b"switch", task_id.as_ref(), switch_index.to_le_bytes().as_ref()],        bump    )]    pub switch_log: Account<'info, MechanismSwitchLog>,     #[account(mut)]    pub authority: Signer<'info>,    pub system_program: Program<'info, System>,} pub fn handler(    ctx: Context<RecordMechanismSwitch>,    task_id: [u8; 32],    switch_index: u8,    from_mechanism: u8,
  1. Line 13 seeds = [b"task", task_id.as_ref()],: Declares the PDA seeds. Anchor re-derives the address and rejects the account if it doesn't match.
  2. Line 14 bump = task_account.bump: Uses the bump seed, the extra byte that pushes the derived address off the ed25519 curve.
  3. Line 19 init,: Creates and pays for a new account. Space and payer must be specified.
  4. Line 28 pub authority: Signer<'info>,: Requires this account to have signed the transaction.
zahemen9900/agora · contract/programs/agora/src/instructions/submit_receipt.rs L13–36 @ 2f9078b · MIT · original
        seeds = [b"task", task_id.as_ref()],        bump = task_account.bump    )]    pub task_account: Account<'info, TaskAccount>,    pub authority: Signer<'info>,} pub fn handler(    ctx: Context<SubmitReceipt>,    _task_id: [u8; 32],    transcript_merkle_root: [u8; 32],    decision_hash: [u8; 32],    quorum_reached: bool,    final_mechanism: u8,) -> Result<()> {    let task_account = &mut ctx.accounts.task_account;     require_keys_eq!(        ctx.accounts.authority.key(),        task_account.payer,        AgoraError::Unauthorized    );    require!(        matches!(task_account.status, TaskStatus::InProgress),
  1. Line 13 seeds = [b"task", task_id.as_ref()],: Declares the PDA seeds. Anchor re-derives the address and rejects the account if it doesn't match.
  2. Line 14 bump = task_account.bump: Uses the bump seed, the extra byte that pushes the derived address off the ed25519 curve.
  3. Line 17 pub authority: Signer<'info>,: Requires this account to have signed the transaction.
  4. Line 30 require_keys_eq!(: An explicit validation that aborts the instruction with an error.
zahemen9900/agora · contract/programs/agora/src/instructions/initialize_task.rs L13–36 @ 2f9078b · MIT · original
        init,        payer = payer,        space = 8 + TaskAccount::LEN,        seeds = [b"task", task_id.as_ref()],        bump    )]    pub task_account: Account<'info, TaskAccount>,     #[account(        init,        payer = payer,        space = 8 + VaultAccount::LEN,        seeds = [b"vault", task_id.as_ref()],        bump    )]    pub vault: Account<'info, VaultAccount>,     #[account(mut)]    pub payer: Signer<'info>,    pub system_program: Program<'info, System>,} pub fn handler(    ctx: Context<InitializeTask>,
  1. Line 13 init,: Creates and pays for a new account. Space and payer must be specified.
  2. Line 16 seeds = [b"task", task_id.as_ref()],: Declares the PDA seeds. Anchor re-derives the address and rejects the account if it doesn't match.
  3. Line 17 bump: Uses the bump seed, the extra byte that pushes the derived address off the ed25519 curve.
  4. Line 31 pub payer: Signer<'info>,: Requires this account to have signed the transaction.

How to run, build and test

These commands come from the repo's own manifests (package.json scripts, Anchor.toml, Cargo, go.mod, Makefile). Check the README for prerequisites and environment variables.

DirectoryCommandRuns
agora-webnpm run devvite
agora-webnpm run buildtsc -b && vite build
agora-webnpm run linteslint .
contractnpm run testanchor test
contractanchor buildcompile programs and generate IDLs
contractanchor testlocal validator + test suite
contractanchor run testnpx ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts

What you could build from it

Used in lessons