ChainX is a full-stack project for building, testing, and deploying Cardano validators using Aiken, and providing a robust backend API with Node.js/Express. It integrates with MeshJS, Blockfrost, Koios, and supports modern API documentation via Swagger.
- Introduction
- Project Structure
- Prerequisites
- Installation
- Environment Variables
- Development Workflow
- Aiken: Build & Test
- API Backend Usage
- Swagger & API Documentation
- References
ChainX enables you to:
- Write Cardano validators in the
validators/folder using Aiken. - Add supporting functions in the
lib/folder with.akextension. - Build a backend API with Node.js/Express, integrating MeshJS, Blockfrost, Koios, and more.
- Easily test, document, and deploy your Cardano smart contracts and related services.
├── api/ # Express/Node.js backend source code
│ ├── routes/ # API route definitions (e.g. cip68.route.ts)
│ ├── utils/ # Utilities (Swagger, ...)
│ └── index.ts # Server entry point
├── validators/ # Aiken validators (.ak)
├── lib/ # Aiken libraries (.ak)
├── env/ # Aiken environment configs
├── src/ # TypeScript source code (if separated)
├── .env # Backend environment variables
├── package.json # Node.js project config
├── tsconfig.json # TypeScript config
├── aiken.toml # Aiken config
└── README.md
- Node.js (v20 recommended for best compatibility)
- npm (comes with Node.js)
- Aiken (for smart contract development)
- Clone the repository:
git clone https://github.com/independenceee/ChainX.git cd ChainX - Install Node.js dependencies:
npm install
- Install Aiken (if not already):
# See https://aiken-lang.org/getting-started/ for platform-specific instructions aiken --version
Create a .env file in the project root with the following (example):
USER_MEMONIC="..."
PLATFORM_MEMONIC="..."
PLATFORM_ADDRESS="..."
PLATFORM_TOKEN="..."
BLOCKFROST_API_KEY="..."
KOIOS_TOKEN="..."
VERCEL_URL="..." # Optional, for deployment- These are used for wallet, API, and blockchain integration.
npm run dev- Server runs at: http://localhost:3000
- Swagger UI: http://localhost:3000/documents
- Hot reload enabled via
nodemon.
npm run build
npm start- Compiles TypeScript to JavaScript and runs the server from
dist/.
aiken build- Compiles all
.akfiles invalidators/andlib/.
aiken check- Run all tests:
aiken check - Run specific test:
aiken check -m <test_name> - Example test in Aiken:
use config test foo() { config.network_id + 1 == 42 }
Edit aiken.toml:
[config.default]
network_id = 41Or add environment modules under env/.
The backend is built with Node.js and Express, providing RESTful APIs to interact with Cardano smart contracts and blockchain data. Below are detailed instructions for extending and using the API backend:
-
All route files are located in
api/routes/. -
Each route file should export an Express router.
-
Example: Create a new file
api/routes/cip68.route.ts:import { Router } from "express"; const router = Router(); /** * @openapi * /api/v1/mint: * post: * summary: Mint a new token * requestBody: * required: true * content: * application/json: * schema: * type: object * properties: * assetName: * type: string * quantity: * type: integer * responses: * 200: * description: Minted successfully */ router.post("/mint", async (req, res) => { // Your mint logic here res.json({ success: true }); }); export default router;
- In
api/index.ts, import and register your route:import cip68 from "@/api/routes/cip68.route"; app.use("/api/v1/mint", cip68);
- This exposes your endpoint at
POST /api/v1/mint/mint(or adjust as needed).
- Store sensitive data and API keys in
.env. - Access them in your code via
process.env.VARIABLE_NAME. - Example:
const apiKey = process.env.BLOCKFROST_API_KEY;
- Use MeshJS, Blockfrost, or Koios SDKs to interact with the Cardano blockchain.
- Example (using MeshJS):
import { MeshWallet } from "@meshsdk/core"; const wallet = new MeshWallet({ networkId: 0, fetcher: blockfrostProvider, submitter: blockfrostProvider, key: { type: "mnemonic", words: process.env.PLATFORM_MEMONIC?.split(" ") || [] }, });
- Use Express's error handling middleware for consistent API responses.
- Always return JSON responses for API endpoints.
- Example:
app.use((err, req, res, next) => { res.status(500).json({ error: err.message }); });
- Use tools like Postman or curl to test your endpoints.
- Example curl request:
curl -X POST http://localhost:3000/api/v1/mint/mint \ -H "Content-Type: application/json" \ -d '{"assetName": "ChainX", "quantity": 1000}'
- Add more route files in
api/routes/for new features. - Document each endpoint with OpenAPI (Swagger) comments for automatic documentation.
- API documentation is auto-generated and available at: http://localhost:3000/documents
- Swagger configuration is in
api/utils/swagger.util.ts. - To add documentation for a route, use JSDoc comments in your route files. Example:
/** * @openapi * /api/v1/mint: * post: * summary: Mint a new token * requestBody: * ... */ router.post("/mint", ...)