- About
- Standards
- Architecture
- Project Structure
- Run as Containers
- Run Services Locally
- Run Services on Cloud
- User Onboarding
- Web Frontend
- Localization
- API
- Status Page
- Governance & Support
The National Carbon Registry enables carbon credit trading in order to reduce greenhouse gas emissions.
As an online database, the National Carbon Registry uses national and international standards for quantifying and verifying greenhouse gas emissions reductions by programmes, tracking issued carbon credits and enabling credit transfers in an efficient and transparent manner. The Registry functions by receiving, processing, recording and storing data on mitigations projects, the issuance, holding, transfer, acquisition, cancellation, and retirement of emission reduction credits. This information is publicly accessible to increase public confidence in the emissions reduction agenda.
The National Carbon Registry enables carbon credit tracking transactions from mitigation activities, as the digital implementation of the Paris Agreement. Any country can customize and deploy a local version of the registry then connect it to other national & international registries, MRV systems, and more.
The system has 3 key features:
- Analytics Dashboard: Enabling governments, companies, and certification bodies to operate transparently and function on an immutable blockchain.
- Carbon Credit Calculator: Standardized system According to the UNFCCC - CDM (Clean Development Mechanism) methodologies, across defined sectors.
- Serial Number Generator: Standardizing the technical format to allow for easy cross-border collaboration between carbon trading systems.
This codebase aims to fullfill the digital public goods standard: https://digitalpublicgoods.net/standard/ It is built according to the Principles for Digital Development: https://digitalprinciples.org/
UNDP Carbon Registry is based on service oriented architecture (SOA). Following diagram visualize the basic components in the system.
Authenticate, Validate and Accept user (Government, Programme Developer/Certifier) API requests related to the following functionalities,
- User and company CRUD operations.
- User authentication.
- Programme life cycle management.
- Credit life cycle management.
Service is horizontally scalable and state maintained in the following locations,
- File storage.
- Operational Database.
- Ledger Database.
Uses the Carbon Credit Calculator and Serial Number Generator node modules to estimate the programme carbon credit amount and issue a serial number. Uses Ledger interface to persist programme and credit life cycles.
Serve all the system analytics. Generate all the statistics using the operational database. Horizontally scalable.
Asynchronously replicate ledger database events in to the operational database. During the replication process it injects additional information to the data for query purposes (Eg: Location information).
Currently implemented for QLDB and PostgresSQL ledgers. By implementing replicator interface can support more ledger replicators.
Replicator select based on the LEDGER_TYPE environment variable. Support types QLDB, PGSQL(Default).
System services can deploy in 2 ways.
- As a Container - Each service boundary containerized in to a docker container and can deploy on any container orchestration service. Please refer Docker Compose file
- As a Function - Each service boundary packaged as a function (Serverless) and host on any Function As A Service (FaaS) stack. Please refer Serverless configuration file
All the external services access through a generic interface. It will decouple the system implementation from the external services and enable extendability to multiple services.
Geo Location Service
Currently implemented for 2 options.
- File based approach. User has to manually add the regions with the geo coordinates. Sample File. To apply new file changes, replicator service needs to restart.
- Mapbox. Dynamically query geo coordinates from the Mapbox API.
Can add more options by implementing location interface
Change by environment variable LOCATION_SERVICE. Supported types MAPBOX, FILE(Default)
File Service
Implemented 2 options for static file hosting.
- NestJS static file hosting using the local storage and container volumes.
- AWS S3 file storage.
Can add more options by implementing file handler interface
Change by environment variable FILE_SERVICE. Supported types S3, LOCAL(Default)
Primary/secondary database architecture used to store carbon programme and account balances. Ledger database is the primary database. Add/update programmes and update account balances in a single transaction. Currently implemented only for AWS QLDB
Operational Database is the secondary database. Eventually replicated to this from primary database via data stream. Implemented based on PostgresSQL
Why Two Database Approach?
- Cost and Query capabilities - Ledger database (blockchain) read capabilities can be limited and costly. To support rich statistics and minimize the cost, data is replicated in to a cheap query database.
- Disaster recovery
- Scalability - Primary/secondary database architecture is scalable since additional secondary databases can be added as needed to handle more read operations.
Why Ledger Database?
- Immutable and Transparent - Track and maintain a sequenced history of every carbon programme and credit change.
- Data Integrity (Cryptographic verification by third party).
- Reconcile carbon credits and company account balance.
Ledger Database Interface
This enables the capability to add any blockchain or ledger database support to the carbon registry without functionality module changes. Currently implemented for PostgresSQL and AWS QLDB.
PostgresSQL Ledger Implementation storage all the carbon programme and credit events in a separate event database with the sequence number. Support all the ledger functionalities except immutability.
Single database approach used for user and company management.
Carbon Registry contains 3 ledger tables.
- Programme ledger - Contains all the programme and credit transactions.
- Company Account Ledger (Credit) - Contains company accounts credit transactions.
- Country Account Ledger (Credit) - Contains country credit transactions.
The below diagram demonstrates the the ledger behavior of programme create, authorise, issue and transfer processes. Blue color document icon denotes a single data block in a ledger.
- JWT Authentication - All endpoints based on role permissions.
- API Key Authentication - MRV System connectivity.
.
├── .github # CI/CD [Github Actions files]
├── deployment # Declarative configuration files for initial resource creation and setup [AWS Cloudformation]
├── backend # System service implementation
├── services # Services implementation [NestJS application]
├── src
├── national-api # National API [NestJS module]
├── stats-api # Statistics API [NestJS module]
├── ledger-replicator # Blockchain Database data replicator [QLDB to Postgres]
├── shared # Shared resources [NestJS module]
├── serverless.yml # Service deployment scripts [Serverless + AWS Lambda]
├── libs
├── carbon-credit-calculator # Implementation for the Carbon credit calculation library [Node module + Typescript]
├── serial-number-gen # Implementation for the carbon programme serial number calculation [Node module + Typescript]
├── web # System web frontend implementation [ReactJS]
├── .gitignore
├── docker-compose.yml # Docker container definitions
└── README.md
- Update docker compose file env variables as required.
- Run
docker-compose up -d. This will build and start containers for following services,- PostgresDB container
- National service
- Analytics service
- Replicator service
- React web server with Nginx.
- Setup postgreSQL locally and create a new database.
- Update following DB configurations in the .env.local file (If the file does not exist please create a new .env.local)
- DB_HOST (Default localhost)
- DB_PORT (Default 5432)
- DB_USER (Default root)
- DB_PASSWORD
- DB_NAME (Default carbondbdev)
- Move to folder
cd backend/service - Run
yarn run sls:install - Initial user data setup
serverless invoke local --stage=local --function setup --data '{"rootEmail": "<Root user email>","systemCountryCode": "<System country Alpha 2 code>", "name": "<System country name>", "logoBase64": "<System country logo base64>"}' - Start all the services by executing
sls offline --stage=local - Now all the system services are up and running. Swagger documentation will be available on
http://localhost:3000/local/national
- Execute to create all the required resources on the AWS.
aws cloudformation deploy --template-file ./deployment/aws-formation.yml --stack-name carbon-registry-basic --parameter-overrides EnvironmentName=<stage> DBPassword=<password> --capabilities CAPABILITY_NAMED_IAM - Setup following Github Secrets to enable CI/CD
- AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY
- Run it manually to deploy all the lambda services immediately. It will create 2 lambda layers and following lambda functions,
- national-api: Handle all carbon registry user and program creation. Trigger by external http request.
- replicator: Replicate Ledger database entries in to Postgres database for analytics. Trigger by new record on the Kinesis stream.
- setup: Function to add initial system user data.
- Create initial user data in the system by invoking setup lambda function by executing
aws lambda invoke \ --function-name carbon-registry-services-dev-setup --cli-binary-format raw-in-base64-out\ --payload '{"rootEmail": "<Root user email>","systemCountryCode": "<System country Alpha 2 code>", "name": "<System country name>", "logoBase64": "<System country logo base64>"}' \ response.json
Carbon credit calculation implemented in a separate node module. Please refer this for more information.
Serial Number generation implemented in a separate node module. Please refer this for more information.
System pre-defined user roles are as follows,
- Root
- Company Level (National Government, Programme and Certification Company come under this level)
- Admin
- Manager
- View Only
- After the system setup, the system have a Root User for the setup email (one Root User for the system)
- Root User is responsible for creating the Government entity and the Admin of the Government
- The Government Admin is responsible for creating the other companies and Admins of each company.
- Admin of the company has the authority to add the remaining users (Admin, Managers, View Only Users) to the company.
- When a user is added to the system, a confirmation email should be sent to users including the login password.
All the CRUD operations can be performed as per the following table,
| Company Role | New User Role | Authorized User Roles (Company) |
|---|---|---|
| Government | Root | Cannot create new one other than the default system user and Can manage all the users in the system |
| Government | Admin Manager View Only |
Root Admin(Government) |
| All other Company Roles | Admin Manager View Only |
Root Admin(Government) Admin(Company) |
- All users can edit own user account except Role and Email.
- Users are not allowed to delete the own account from the system.
Web frontend implemented using ReactJS framework. Please refer getting started with react app for more information.
- Languages (Current): English
- Languages (In Progress): French. Spanish For updating translations or adding new ones, reference https://github.com/undp/carbon-registry/tree/main/web/public/Assets/i18n
For integration, reference RESTful Web API Documentation documentation via Swagger. To access
- National API: api.APP_URL/national
- Status API: api.APP_URL/stats
For transparent uptime monitoring go to status.APP_URL Open source code available at https://github.com/undp/carbon-registry-status
With funding, coordination and support from United Nations Development Programme
UNDP is responsible for managing the application.
Availability problems, failures of platform components, capacity requirements, performances degradation, database indexing, backup and monitoring are all in the responsibility of UNDP.
UNDP is also responsible for performing the user support.
By performing such support UNDP may require assistance from Xeptagon.