Backend skeleton for Cardano Web3 hybrid dApps. This backend uses Express as server and MongoDB as user database. It provides a basic API REST for authentication and authorization using CIP-0008 signing spec and CIP-0030 Cardano dApp-wallet web bridge.
MIT License
This is a basic API REST skeleton for Cardano dApp authentication and authorization written on JavaScript using async/await. This backend utilizes the standard CIP-0008 signing spec. The project has all necessary endpoints for athentication, authorization and user management. The authentication token is generated as a JWT web token, therefore it can be shared easily by other services.
The authentication process is driven by signed payloads with the CIP-0030 Cardano dApp-wallet web bridge. There are three actions that require the user's wallet signature, Signup, Login and Reset. Once the payload with the desired action is signed with the correct private key, a JWT web token is issued and takes control of the session.
This repository is self-contained and you can use ir and test it through the test suite and Postman. You can read more about the Postman examples in the usage section below. This is a good method for developing and debugging the code. But a front end is required to better understand how it works.
I've created another template for creating your web3 applications with ReactJS. You can clone it from the next repository jmagan/cardano-react-web3-skeleton.
cf-ipcountry
that CloudFlare creates when protecting your website).Authorization
header with value Bearer yourToken
where yourToken
is the signed and encrypted token given in the response from the login process.git clone https://github.com/jmagan/cardano-express-web3-skeleton.git ./myproject
cd myproject
npm install
npm update
.env.example
.env
.env
is already ignored, so you never commit your credentials..env
to your environment server(development or production)server
on your environment to the url of your server, for development mode use http://localhost:3000
IMPORTANT: By default token expires in 3 days (4320 minutes set in .env.example). You can refresh token at endpoint GET /token. If everything it´s ok you will get a new token.
To ensure the deliverability of emails sent by this API, Mailgun
is used for mailing users when they sign up, so if you want to use that feature go sign up at their website https://www.mailgun.com
If you want to try a different method it´s ok, I used https://nodemailer.com for this API and they have different transport methods like: smtp.
Language is automatically detected from Accept-Language
header on the request. So either you send locale manually on the request or your browser will send its default, if Accept-Language
header is not sent then it will use en
locale as default.
There are 3 available commands for this: fresh
, clean
and seed
.
npm run command
fresh
cleans and then seeds the database with dynamic data.clean
cleans the database.seed
seeds the database with dynamic data.npm run dev
You will know server is running by checking the output of the command npm run dev
****************************
* Starting Server
* Port: 3000
* NODE_ENV: development
* Database: MongoDB
* DB Connection: OK
****************************
It´s a good practice to do tests at your code, so a sample of how to do that in mocha/chai
is also included in the /test
directory
npm run test
Format your code with prettier by typing:
npm run format
Format all your markdown files with remark by typing:
npm run remark
Lint your code with ESLint by typing:
npm run lint
Once everything is set up to test API routes either use Postman or any other api testing application.
In order to use some endpoints, we need to sign payloads according to CIP-0008 signing spec. For this purpose, the project has a cli util for creating the keys and signatures. This can simulate 255 unique wallets selecting a number between 0 and 254. The cli util starts with the following command:
$ node mockWalletSignatures.js
In order to get the key and signature, we need to go through three steps.
In the next example, we can find how to create a login payload for the admin's account.
🤖 Please, select the action for the payload (S: Signup, R: Reset, L: Login)
Action: L
🤖 Creating login payload.
🤖 Choose a number between 0 and 254. Each number represents a unique address and private key. For example in the sample data, the number 0 is the wallet for admin and the number 1 for the simple user.
Wallet number: 0
🤖 Generating wallet address, key and signature.
📪 Address: stake1u89exkzjnh6898pjg632qv7tnqs6h073dhjg3qq9jp9tcsgq0wfzr
🔑 Key: a201012158203b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29
📝 Signature: 845828a16761646472657373581de1cb9358529df4729c3246a2a033cb9821abbfd16de4888005904abc41a166686173686564f4583a7b22686f7374223a22484f5354222c22616374696f6e223a224c6f67696e222c22656d61696c223a2261646d696e4061646d696e2e636f6d227d5840f93faf1473ad7ff9cdcbc4e2acbb4c24e90329c2ee77b04a8fcc8a716e04df9ae4094fb86f1ff3a88c85e892bf166d1b03bcf5c98cb821be40c285d9fea3e804
The address, key and signature will be used calling the endpoints. This login endpoint call is currently implemented in the postman-example.json
.
You can import the example collection to Postman. To import, click the import button located and select postman-example.json
located within the root directory.
Go to manage environments
to create environments for development, production, etc. On each of the environments you create you will need to:
Create a new key authToken
and within the /login
request this value is automatically updated after a successfull login through a script located in the tests
tab. Each time you make a request to the API it will send Authorization
header with the token
value in the request, you can check this on the headers of users or cities endpoints in the Postman example.
Create a second key server
with the url of your server, for development mode use http://localhost:3000
This is a REST API, so it works using the following HTTP methods:
If you need to add more models to the project just create a new file in /app/models/
and it will be loaded dynamically.
If you need to add more routes to the project just create a new file in /app/routes/
and it will be loaded dynamically.
When you create a new controller, try to also create another folder with validations and helpers. Ex. /countries
, /countries/validators
and /countries/helpers
. An example of this is included in the repository.
If you find it useful, please consider inviting me a coffee :)
You are welcome to report any bugs or improvements. Pull requests are always welcome.
This project is open-sourced software licensed under the MIT License. See the LICENSE file for more information.