Author: Patricio J Gerpe Onchain - Offchain Auction House to list NFT and trade them for ERC20 Tokens.
Express, Nodemon, NodeJs, Typescript, Hardhat, Ethers, Solidity, OpenZepellin, Typechain, Ropsten. Chai, Solhint, Prettier and Eslint are used for Quality Control.
Case outline:
NFT marketplaces often use techniques for reducing transaction fees. Some of these techniques require users to use these marketplaces with an off-chain sibling system that assist the on-chain pieces. This is a simple off-chain system and the on-chain smart-contract to enable cheap auctions. The goal is to enable trades between an ERC721 and a ERC20 with a single on-chain transaction.
npm i .
- Compile contracts
npm run compile
- Start a local node
npm run start:node
- Deploy contracts to local node
npm run deploy:dev
- Start Auctionfity app
- Use postman collection to communicate with Auctionfity application (./data/Auctionfity.postman_collection.json)
You can test with
npm run test
(TODO: Finish UT for settleTransaction function which can be tested via PostMan now)
- Copy .env.example file and paste with the name '.env'
- Create an Alchemy Account: https://www.alchemy.com/
- Create an App with network option as "Goerli"
- Press "View key" and the copy API KEY value to .env GI_API_KEY= value
- Create wallets
npx hardhat init
(this will initiate init task that will create bidder and nftowner wallets) - Copy both private keys and addresses and fill that data in our .env file (NFTOWNER_PRIVATE_KEY,BIDDER_PRIVATE_KEY,NFTOWNER_ADDR,BIDDER_ADDR)
- Make sure to write STAG after ENVIRONMENT property at .env
- Compile contracts
npm run compile
- Deploy contracts to Goerli
npm run deploy:stag
- Provide faucets for both Bidder and NFTOwner accounts at https://goerlifaucet.com/
- Start Auctionfity app
npm run start
- Use postman collection to communicate with Auctionfity application (./data/Auctionfity.postman_collection.json)
(You can import postmanCollection from ./data folder)
curl --location --request GET '127.0.0.1:3000/api/accounts'
curl --location --request POST '127.0.0.1:3000/api/init'
curl --location --request POST '127.0.0.1:3000/api/nfts/approve' \
--header 'Content-Type: application/json' \
--data-raw '{"nfts": [{"tokenId": 1, "price": 0.035}, {"tokenId": 2, "price": 0.035}]}'
curl --location --request GET '127.0.0.1:3000/api/nfts' \
--header 'Content-Type: application/json' \
--data-raw '{"nfts": [{"tokenId": 1, "price": 0.035}]}'
curl --location --request POST '127.0.0.1:3000/api/token/approve' \
--header 'Content-Type: application/json' \
--data-raw '{"quantity": 1000000000000000}'
curl --location --request POST '127.0.0.1:3000/api/nfts/list' \
--header 'Content-Type: application/json' \
--data-raw '{"nft": {"tokenId": 1}, "minPrice": 50}'
curl --location --request GET '127.0.0.1:3000/api/nfts/listings?startTime=2021-06-01&endTime=2022-09-09'
curl --location --request POST '127.0.0.1:3000/api/nfts/listings/bid-offer' \
--header 'Content-Type: application/json' \
--data-raw '{"price": 90, "tokenId": 1}'
curl --location --request GET '127.0.0.1:3000/api/nfts/listings/bids?startTime=2021-06-01&endTime=2022-09-09&tokenId=1'
curl --location --request POST '127.0.0.1:3000/api/nfts/listings/bid-accept' \
--header 'Content-Type: application/json' \
--data-raw '{"price": 50, "tokenId": 1}'
curl --location --request GET '127.0.0.1:3000/api/signatures?startTime=2021-06-01&endTime=2022-09-09'
curl --location --request POST '127.0.0.1:3000/api/nfts/settle' \
--header 'Content-Type: application/json' \
--data-raw '{"tokenId": 1, "bidderSignature": {
"r": "0x7f6e2a6fce8f54b25ef0f5dba37d6c4b1a063ce3c7afc0ee3ba6568619777fbb",
"s": "0x75c4cdc54ecedf68a43775742f3fe5b956098ca0ff8f95c824b47816a723d01c",
"_vs": "0xf5c4cdc54ecedf68a43775742f3fe5b956098ca0ff8f95c824b47816a723d01c",
"recoveryParam": 1,
"v": 28,
"yParityAndS": "0xf5c4cdc54ecedf68a43775742f3fe5b956098ca0ff8f95c824b47816a723d01c",
"compact": "0x7f6e2a6fce8f54b25ef0f5dba37d6c4b1a063ce3c7afc0ee3ba6568619777fbbf5c4cdc54ecedf68a43775742f3fe5b956098ca0ff8f95c824b47816a723d01c"
}, "nftOwnerSignature": {
"r": "0xca7a2a7760cf9670e3db308380fb886665adfcaa56f4d972c435e4178ee72fec",
"s": "0x69f1462599593d67eb842e26a27b92af966640a2bb335d07bca5946269243267",
"_vs": "0x69f1462599593d67eb842e26a27b92af966640a2bb335d07bca5946269243267",
"recoveryParam": 0,
"v": 27,
"yParityAndS": "0x69f1462599593d67eb842e26a27b92af966640a2bb335d07bca5946269243267",
"compact": "0xca7a2a7760cf9670e3db308380fb886665adfcaa56f4d972c435e4178ee72fec69f1462599593d67eb842e26a27b92af966640a2bb335d07bca5946269243267"
}
}'
npm run test
npm run lint:ts -- --fix
npm run lint:sol
npm run format
- handle ERC20 Token Transfers within MKT Contract Logic
- work with listings fees
- finish ut for settleTransaction function (it can be tested via postman though)
- add test coverage
- add full coverage smart contract ut
- refactor controllers and services to reduce code lines per file and avoid cases of repeated code
- integrate Mongoose for more convenient data quering
- update software architecture diagram with Alchemy and Goerli (replacing Ropsten)