Author: Robert Keyan
(0) Technologies - React / Angular, Node.JS, Solidity
(1) There must be a file with the list of 5 addresses and the number of tokens in there.
You need to write:
(2) Small SmartContract where there will be addresses and the number of tokens attached to them
(3) On the front client must connect his metamask and:
(3.1) see the number of tokens on his balance
(3.2) claim any amount of tokens to his address from the smart contract address
(3.3) only the wallets among those five can claim tokens
For monorepo management I choose nx, this is great tool with own ecosystem and flexible configurations.
NOTE: this is my first experience to create the web app with Nx :)
Smart Contract
For the Smart contract development, I used Hardhat.
I was using the local node of hardhat instead of using Testnets, but it's easy to switch if you have Infura or Alchemy accounts.
The assignment requires to have "whitelist" addresses, so I prefer to walk with the MarkleTree cryptographic algorithm.
Backend The backend is responsible to provide the whitelisted wallets, managing them, and generating the MarkleTree hash with verification method
NOTE: The initial wallets list stored in
packages/app/src/app/wallets.json
Frontend
The Frontend is a basic React web page, to interact with a deployed contract with ether.js
.
Testing Sadly, I didn't have the time to write the tests for Smart contract :(
- React.js (packages/client)
- Nest.js (packages/app)
- Hardhat (packages/hardhat)
Node.js v16+, NPM, Metamask extension in chrome
- Just setup the dependencies with
npm install
- Run the local node of hardhat on your machine by
npm run hardhat:node
- Open other terminal window and run
npm run backend
- Once Backend is started, open another instance of the terminal and deploy the contract via
npm run deploy:contract
Note: Deployment script, request to the backend for whitelisted wallets and MarkleRoot, which is required arguments for contract deployment
- Copy the contract address from the output and go to
packages/client/src/environments/environment.ts
and replace thecontractAddress
value with the new copied address. - As all steps passed successfully, just run
npm run client
to open the React app - Take a breath..., we 1 step ahead of achieving our goal :)
- In the final step, you just need to take a few actions in Metamask to order to make the Metamask work with our local node. Just read this article, which properly shows how you can do it.
NOTE: Please take an attention to write custom "correct" nonce for everytime you run the local node, because everytime when you run it, the nonce is reset the value but Metamask keep old one.