Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 95 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,105 @@
# AgoraExpansion
Repository to house new validators and off-chain code for leveraging Agora with NFTs instead of FTs.

The repository now contains a multi-validator in `agora-expansion/validators/governance-token.ak`, the multivalidator contains both the capability of minting the token representing voting power, and also a 'locker' which contains the NFTs and FTs used to generate voting power. A user locks their tokens in order to mint an alternative token used for voting as described in the research in the `ResearchPhase` directory, in addition to the voting power token, a receipt is minted to allow for the users NFTs to be claimed when burning the correct amount of the voting power token.
Repository to house new validators and off-chain code for leveraging Agora with NFTs and FTs as governance voting power.

The repository also contains off-chain transaction building code in `agora-expansion/src/index.ts` and emulator testing code in `agora-expansion/src/test.ts`
The repository contains a multi-validator in `agora-expansion/validators/governance-token.ak`. The multi-validator supports minting the token that represents voting power, and a locker that holds the NFTs and FTs used to generate that voting power. A user locks their tokens to mint an alternative token used for voting as described in the research in the `ResearchPhase` directory. In addition to the voting power token, a receipt is minted so the user's NFTs and FTs can be claimed when burning the correct amount of voting power.

The user can verify the test suite by running
## Repository layout

- `agora-expansion`: validators, off-chain transaction building code, and emulator tests.
- `agora-expansion-fe`: public graphical user interface for the expansion lock/redeem flow.
- `ResearchPhase`: research notes and design references for using native assets as voting power.

## Public GUI

The public GUI is deployed at:

`https://adaocommunity.github.io/AgoraExpansion/`

This deployed interface is a static build of `agora-expansion-fe`. It requires Blockfrost configuration at build/deploy time so the app can read wallet assets and submit the normal lock/redeem flow.

## GUI local setup

Requirements:

- Node.js and npm.
- A Cardano browser wallet that exposes CIP-30.
- A Blockfrost project key for the network being tested.
- Testnet assets only when testing the preprod/testnet flow. Do not use real funds for test runs.

Run the frontend locally:

```bash
cd agora-expansion-fe
npm install
cp .env.example .env
npm start
```

PowerShell users can copy the environment file with:

```powershell
Copy-Item .env.example .env
```

The Create React App development server starts at `http://localhost:3000` by default.

## Blockfrost configuration

Create `agora-expansion-fe/.env` from `agora-expansion-fe/.env.example`, then add the Blockfrost key for the network you are testing.

```bash
REACT_APP_BLOCKFROST_MAINNET_URL=https://cardano-mainnet.blockfrost.io/api/v0
REACT_APP_BLOCKFROST_MAINNET_API_KEY=

REACT_APP_BLOCKFROST_TESTNET_URL=https://cardano-preprod.blockfrost.io/api/v0
REACT_APP_BLOCKFROST_TESTNET_API_KEY=
```

The `REACT_APP_` prefix is required because this frontend uses Create React App. Environment variables are read when `npm start` or `npm run build` starts. If the app shows `Blockfrost API key not configured`, add the matching `REACT_APP_BLOCKFROST_*_API_KEY` value and restart the dev server or rebuild the production bundle.

Do not commit real Blockfrost API keys. Use repository or deployment secrets for hosted builds.

## GUI user flow

Community or configuration flow:

1. Open the GUI and connect a Cardano wallet.
2. Configure the governance asset rules for the community, including the FT and/or NFT policy IDs, asset names when required, and voting weights.
3. Submit the configuration used by the expansion flow.

Voter lock/redeem flow:

1. Open the GUI and connect a Cardano wallet that holds eligible configured assets.
2. Review the detected FT/NFT assets and select the assets to use for voting power.
3. Submit the lock transaction. The selected assets are locked by the validator.
4. Receive voting power plus a receipt token.
5. Use the voting power in the Agora governance flow.
6. Redeem by burning the required voting power/receipt pair to reclaim the locked assets.

## Production build and deployment

Build the frontend:

```bash
cd agora-expansion-fe
npm install
npm run build
```

The frontend package uses `"homepage": "."` so asset paths are relative and can be served from GitHub Pages at `https://adaocommunity.github.io/AgoraExpansion/`.

For GitHub Pages or any hosted deployment, provide the `REACT_APP_BLOCKFROST_*` variables during the build. React embeds these values into the static bundle at build time.

## Contract test suite

The repository also contains off-chain transaction building code in `agora-expansion/src/index.ts` and emulator testing code in `agora-expansion/src/test.ts`.

The user can verify the test suite by running:

```bash
npm install
npm run test
```

in the `agora-expansion` directory. This assumes that the user has npm installed locally.
in the `agora-expansion` directory. This assumes that the user has npm installed locally.
10 changes: 10 additions & 0 deletions agora-expansion-fe/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Blockfrost configuration for the AgoraExpansion frontend.
# Copy this file to .env and fill in the API key for the network you are testing.
# Do not commit real API keys.

REACT_APP_BLOCKFROST_MAINNET_URL=https://cardano-mainnet.blockfrost.io/api/v0
REACT_APP_BLOCKFROST_MAINNET_API_KEY=

# The milestone test flow uses Cardano preprod/testnet assets.
REACT_APP_BLOCKFROST_TESTNET_URL=https://cardano-preprod.blockfrost.io/api/v0
REACT_APP_BLOCKFROST_TESTNET_API_KEY=
14 changes: 9 additions & 5 deletions agora-expansion-fe/src/services/lucidService.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Lucid, Blockfrost, Network, C } from 'lucid-cardano';
import { Asset } from './assetCache';

// You'll need to set your Blockfrost API keys
// Set Blockfrost API keys through .env / deployment secrets.
// For mainnet: https://cardano-mainnet.blockfrost.io/api/v0
// For testnet: https://cardano-testnet.blockfrost.io/api/v0
// For preprod/testnet: https://cardano-preprod.blockfrost.io/api/v0
const BLOCKFROST_MAINNET_URL = process.env.REACT_APP_BLOCKFROST_MAINNET_URL || 'https://cardano-mainnet.blockfrost.io/api/v0';
const BLOCKFROST_MAINNET_API_KEY = process.env.REACT_APP_BLOCKFROST_MAINNET_API_KEY || 'mainnet1awJnGhrtbecFGCc7eWIf2VnB82r4ZOd';
const BLOCKFROST_TESTNET_URL = process.env.REACT_APP_BLOCKFROST_TESTNET_URL || 'https://cardano-testnet.blockfrost.io/api/v0';
const BLOCKFROST_MAINNET_API_KEY = process.env.REACT_APP_BLOCKFROST_MAINNET_API_KEY || '';
const BLOCKFROST_TESTNET_URL = process.env.REACT_APP_BLOCKFROST_TESTNET_URL || 'https://cardano-preprod.blockfrost.io/api/v0';
const BLOCKFROST_TESTNET_API_KEY = process.env.REACT_APP_BLOCKFROST_TESTNET_API_KEY || '';

class LucidService {
Expand All @@ -28,8 +28,12 @@ class LucidService {
blockfrostApiKey = BLOCKFROST_TESTNET_API_KEY;
}

const apiKeyEnvName = network === 'Mainnet'
? 'REACT_APP_BLOCKFROST_MAINNET_API_KEY'
: 'REACT_APP_BLOCKFROST_TESTNET_API_KEY';

if (!blockfrostApiKey) {
throw new Error(`Blockfrost API key not configured for ${network}. Please set REACT_APP_BLOCKFROST_${network.toUpperCase()}_API_KEY environment variable.`);
throw new Error(`Blockfrost API key not configured for ${network}. Please set ${apiKeyEnvName} environment variable.`);
}

this.lucid = await Lucid.new(
Expand Down