Developer and User Documentation

Agora Expansion documentation

Clone the repository, configure and run the React frontend, build and test the Aiken and off-chain packages, then follow the complete configure, lock, receipt, and redeem flow.

Overview

From repository clone to working interface

This documentation is for developers evaluating or extending Agora Expansion and for users who need the practical wallet and Blockfrost workflow. Commands and source paths below follow the public GitHub repository.

1. Clone And Inspect

Clone the repository and understand the validator, off-chain TypeScript, React frontend, research, and automation directories before changing code.

2. Build And Configure

Install each package, configure Blockfrost for the connected wallet network, build the contracts and TypeScript, and run the repository test commands.

3. Follow The User Flow

Walk through configure, lock, receipt, and redeem using the illustrated interface states.

Developer Start

Clone the repository and choose the package you need

Agora Expansion is a multi-package repository. The on-chain validator and off-chain transaction code live separately from the browser interface, while the research directory records the design behind using native assets as governance voting power.

Git: clone the public repository and inspect its history. Node.js and npm: install frontend and off-chain dependencies. Aiken: build and check the validator package. CIP-30 wallet: use Eternl, Lace, or Yoroi for browser testing. Blockfrost: create a project ID for the wallet's Cardano network.
The repository test workflow uses Node.js 18 and Aiken v1.0.26-alpha. The Pages deployment workflow uses Node.js 20.
git clone https://github.com/ADAOcommunity/AgoraExpansion.git
cd AgoraExpansion

# Inspect the main packages
git status
Get-ChildItem

# Open either package
cd agora-expansion
# or: cd agora-expansion-fe
Use a feature branch for changes. Never commit wallet credentials, seed phrases, private keys, or real Blockfrost project IDs.

agora-expansion/

Aiken validators, off-chain transaction builders, generated Plutus data, and emulator tests.

Browse contract package

agora-expansion-fe/

Create React App frontend for wallet connection, asset configuration, locking, receipts, and redemption.

Browse frontend package

ResearchPhase/

Research notes, logic explanations, and CDDL specifications behind the governance-token design.

Browse research

Setup

Get the wallet, network, and Blockfrost project lined up

The frontend is a static React app. A wallet can connect before Blockfrost is configured, but asset lookup and the full transaction flow require a Blockfrost project key for the same network as the connected wallet.

Wallet: Eternl, Lace, or Yoroi with dApp connection enabled. Network: Preprod for testing, or Mainnet for production use. Blockfrost: project ID created for that same network. Assets: eligible FT or NFT assets under the configured policy.

Network matching rule

Preprod testing

addr_test... wallet address

REACT_APP_BLOCKFROST_TESTNET_API_KEY

cardano-preprod.blockfrost.io

Mainnet production

addr1... wallet address

REACT_APP_BLOCKFROST_MAINNET_API_KEY

cardano-mainnet.blockfrost.io

git clone https://github.com/ADAOcommunity/AgoraExpansion.git
cd AgoraExpansion/agora-expansion-fe
npm install
Copy-Item .env.example .env

# Preprod testing example
REACT_APP_BLOCKFROST_TESTNET_URL=https://cardano-preprod.blockfrost.io/api/v0
REACT_APP_BLOCKFROST_TESTNET_API_KEY=preprod_project_id_here

# Mainnet uses separate production values
REACT_APP_BLOCKFROST_MAINNET_URL=https://cardano-mainnet.blockfrost.io/api/v0
REACT_APP_BLOCKFROST_MAINNET_API_KEY=mainnet_project_id_here

npm start
Keep real project IDs out of commits. Frontend demo IDs are visible after build, so use intentionally limited keys or a backend-controlled setup for production.

Contracts And Tests

Build the validator and verify the off-chain package

The contract package combines an Aiken multi-validator with TypeScript transaction helpers. Build the TypeScript before running npm test because the test script executes the compiled dist/src/test.js file.

cd agora-expansion
npm install
npm run build
npm run test

# Validator checks used by repository CI
aiken fmt --check
aiken check -D
aiken build
Run these commands from agora-expansion/. A successful run verifies the TypeScript build, emulator flow, Aiken formatting, checks, and validator build.
Locker validator: holds eligible NFTs and FTs until redemption. Minter policy: validates voting-power and receipt-token minting or burning. Off-chain builders: construct lock and retrieve transactions with Lucid. Emulator test: exercises the compiled transaction flow in src/test.ts.
Use testnet assets for development. Do not use real funds while validating local or preproduction changes.

Validator entry point

validators/governance-token.ak contains the parameterized locker and minter handlers.

Open validator source

Off-chain API

src/index.ts exports validator helpers, voting-power calculation, lock, and retrieve functions.

Open transaction source

Emulator test

src/test.ts contains the package test entry point invoked after TypeScript compilation.

Open test source

Source Map

Where to make each kind of change

Start at the ownership boundary closest to the behavior you need. The validator enforces on-chain rules, services prepare chain access and transactions, and React components own the browser workflow.

lib/agora/types.ak

Contract configuration, datum, redeemer, and voting-power data types.

Open file

lib/agora/utils.ak

Token naming, inline datum access, and voting-power calculation helpers.

Open file

src/App.tsx

Top-level frontend state and transitions between connection, configuration, lock, and redeem screens.

Open file

components/WalletConnect.tsx

CIP-30 wallet discovery, permission, address selection, and network identification.

Open file

components/TokenConfig.tsx

FT/NFT rule selection, asset search, weighting mode, and voting-power configuration.

Open file

services/lucidService.ts

Blockfrost initialization, network selection, address conversion, and wallet asset queries.

Open file

services/lockTokensService.ts

Frontend transaction assembly for voting power, locker addresses, locking, and retrieval.

Open file

components/TokenSelection.tsx

Eligible asset loading and the user path that selects and locks configured tokens.

Open file

components/NFTSelection.tsx

Receipt NFT discovery and redemption workflow for recovering locked assets.

Open file

Build And Deploy

Create the static frontend and understand repository automation

The frontend uses Create React App with a relative homepage setting. The production command writes static files to agora-expansion-fe/build/ for GitHub Pages or another static host.

cd agora-expansion-fe
npm install
Copy-Item .env.example .env

# Add the required Blockfrost project IDs to .env
npm run build

# Static output
Get-ChildItem build
REACT_APP_* values are embedded when the build starts. Set deployment values before building; a deployed static site cannot read your later local .env changes.

Tests workflow

.github/workflows/tests.yml installs the contract package, builds TypeScript, runs the emulator test, and executes Aiken format, check, and build commands.

Inspect tests workflow

Pages workflow

.github/workflows/deploy.yml installs the frontend with Node.js 20, builds it, uploads build/, and deploys the artifact to GitHub Pages.

Inspect deployment workflow

Concepts

Cardano terms in plain English

These are the terms that matter for this tutorial. The definitions are scoped to how Agora Expansion uses them, so you can understand the interface without reading the full protocol specifications first.

CIP-30 wallet bridge

CIP-30 is the browser wallet standard used by Cardano dApps. It lets the page request wallet access, read wallet state after consent, and ask the wallet to sign or submit transactions.

CIP-0030 reference

Blockfrost project ID

Blockfrost is the API layer the frontend uses to look up chain data. Each project ID belongs to a specific network, so a Preprod key will not work for a Mainnet wallet.

Blockfrost setup

Preprod vs Mainnet

Preprod is the safer testing network. Mainnet is production. Cardano address prefixes make the difference visible: test addresses begin with addr_test, while Mainnet addresses begin with addr1.

Blockfrost Cardano guide

Policy ID and asset name

Cardano native assets are identified by the pair of policy ID and asset name. Agora Expansion uses this to decide which FTs or NFTs count toward configured voting power.

Native tokens

UTxOs and token bundles

Wallet assets live in transaction outputs. A single output can contain ada plus native tokens, so the app reads wallet UTxOs before it can list eligible assets for locking.

Token bundles

Receipt NFT

In this flow, the receipt NFT is the user's handle for redemption. The generate path locks selected assets and mints voting power plus a receipt; the redeem path spends the receipt to recover the locked assets.

Agora UI tutorial
The screenshots illustrate the interface flow. To perform live transactions, connect a funded wallet and configure Blockfrost for the wallet's network.

Troubleshooting

When the wallet connects but the flow stalls

Most setup issues come from three separate systems being out of sync: the browser wallet, the Blockfrost project, and the configured Cardano asset identifiers. Use this guide before assuming the interface is broken.

Message

Blockfrost APIs are not configured

  • Add the matching REACT_APP_BLOCKFROST_*_URL and REACT_APP_BLOCKFROST_*_API_KEY values.
  • Use a Preprod project ID with cardano-preprod.blockfrost.io and a Mainnet project ID with cardano-mainnet.blockfrost.io.
  • Restart the React dev server after changing .env values.
Symptom

Wallet connects but no assets appear

  • Confirm the wallet network matches the Blockfrost URL and project ID.
  • Confirm the wallet actually holds eligible assets in spendable UTxOs.
  • Check that the policy ID and asset name match the configured FT or NFT rule.
Concept

CIP-30 consent is only the first gate

  • The wallet permission popup lets the dApp read wallet state after user approval.
  • It does not prove Blockfrost is configured or that a transaction can be built.
  • Signing and submission still require the wallet, network, assets, and app config to line up.
Usage

Tutorial media and live transactions

  • Use this site, screenshots, and the MP4 to learn the interface flow.
  • Use Cardano explorer URLs to inspect real Preprod or Mainnet transactions.
  • Example transaction hashes in tutorial media are not live-chain transactions.

Tutorial

Connect, configure, lock, and redeem

Start with the setup checklist, then follow these illustrated steps. Select any screenshot to inspect the interface state in detail, or open the separate video walkthrough for the complete animated flow.

1

Connect a Cardano wallet

Open the GUI and choose a supported CIP-30 wallet. The wallet extension asks the user for permission before the app can read wallet state.

2

Configure voting-power rules

Choose the weighting mode, define the FT/NFT policy information, and set the voting-power values that the community will use. The policy ID and asset name are how the app recognizes eligible native assets.

3

Choose the action

After configuration, choose whether to generate voting power by locking assets or redeem a receipt NFT to retrieve previously locked assets.

4

Lock selected assets

Select eligible wallet assets. The live app builds a transaction from wallet UTxOs, then asks the connected wallet to sign and submit it.

5

Open the Redeem path

Return to the action chooser and select Redeem Governance Tokens. This opens the wallet's list of receipt NFTs from earlier lock transactions.

6

Select the receipt NFT

Choose the receipt that represents the assets you want to recover. The Redeem Selected NFT button becomes available only after a receipt is selected.

7

Redeem locked assets

Submit the selected receipt to recover the locked assets. For a live transaction, the wallet requests a signature and the submitted hash should be confirmed in a Cardano explorer.

Screenshot Reference

Browse the interface flow

Browse each interface state at your own pace, from wallet connection and voting-power configuration through locking, receipt confirmation, and redemption.

Expanded screenshot