diff --git a/.babelrc b/.babelrc deleted file mode 100644 index 57a1399..0000000 --- a/.babelrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["next/babel"], - "plugins": ["babel-plugin-optimize-clsx"] -} diff --git a/.gitignore b/.gitignore index 74b7586..4e8d28e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,9 @@ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. +.turbo + # dependencies -/node_modules +node_modules /.pnp .pnp.js @@ -9,11 +11,11 @@ /coverage # next.js -/.next/ -/out/ +.next +out # production -/build +build # misc .DS_Store @@ -33,3 +35,6 @@ yarn-error.log* # vercel .vercel + +# ts +tsconfig.tsbuildinfo diff --git a/.husky/.gitignore b/.husky/.gitignore deleted file mode 100644 index 31354ec..0000000 --- a/.husky/.gitignore +++ /dev/null @@ -1 +0,0 @@ -_ diff --git a/.husky/pre-commit b/.husky/pre-commit deleted file mode 100755 index d2ae35e..0000000 --- a/.husky/pre-commit +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -. "$(dirname "$0")/_/husky.sh" - -yarn lint-staged diff --git a/.vscode/settings.json b/.vscode/settings.json index 51950c4..4f6524b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,7 +3,7 @@ "editor.formatOnSave": true, "editor.codeActionsOnSave": { "source.fixAll.eslint": true, - "source.fixAll.stylelint": true + "source.fixAll.stylelint": true, }, "css.validate": false, "less.validate": false, diff --git a/apps/hardhat/.env.example b/apps/hardhat/.env.example new file mode 100644 index 0000000..e8918da --- /dev/null +++ b/apps/hardhat/.env.example @@ -0,0 +1,2 @@ +INFURA_PROJECT_ID= +OWNER_WALLET_PRIVATE_KEY= \ No newline at end of file diff --git a/apps/hardhat/.gitignore b/apps/hardhat/.gitignore new file mode 100644 index 0000000..0f70b84 --- /dev/null +++ b/apps/hardhat/.gitignore @@ -0,0 +1,3 @@ +artifacts +cache +.secrets \ No newline at end of file diff --git a/apps/hardhat/README.md b/apps/hardhat/README.md new file mode 100644 index 0000000..e33cbeb --- /dev/null +++ b/apps/hardhat/README.md @@ -0,0 +1,11 @@ +### NFT metadata example +``` +{ + description: "BSMNT Grotesque Access Card", + external_url: "https://grotesque.basement.studio/" + image: "https://gateway.pinata.cloud/ipfs/" + name: "BSMNT Grotesque Access Card", + hash: "" + id: "" +} +``` \ No newline at end of file diff --git a/apps/hardhat/abis/GrotesqueAccessCard.json b/apps/hardhat/abis/GrotesqueAccessCard.json new file mode 100644 index 0000000..d0ea442 --- /dev/null +++ b/apps/hardhat/abis/GrotesqueAccessCard.json @@ -0,0 +1 @@ +{"address":"0xE36678d1Ea431F30e95ABEEb8cdDFaa43A0C8C12","abi":[{"type":"constructor","payable":false,"inputs":[{"type":"string","name":"_initBaseURI"},{"type":"string","name":"_initNotRevealedURI"}]},{"type":"event","anonymous":false,"name":"Approval","inputs":[{"type":"address","name":"owner","indexed":true},{"type":"address","name":"approved","indexed":true},{"type":"uint256","name":"tokenId","indexed":true}]},{"type":"event","anonymous":false,"name":"ApprovalForAll","inputs":[{"type":"address","name":"owner","indexed":true},{"type":"address","name":"operator","indexed":true},{"type":"bool","name":"approved","indexed":false}]},{"type":"event","anonymous":false,"name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","indexed":true},{"type":"address","name":"newOwner","indexed":true}]},{"type":"event","anonymous":false,"name":"Transfer","inputs":[{"type":"address","name":"from","indexed":true},{"type":"address","name":"to","indexed":true},{"type":"uint256","name":"tokenId","indexed":true}]},{"type":"function","name":"approve","constant":false,"payable":false,"gas":2000000,"inputs":[{"type":"address","name":"to"},{"type":"uint256","name":"tokenId"}],"outputs":[]},{"type":"function","name":"balanceOf","constant":true,"stateMutability":"view","payable":false,"gas":2000000,"inputs":[{"type":"address","name":"owner"}],"outputs":[{"type":"uint256"}]},{"type":"function","name":"cost","constant":true,"stateMutability":"view","payable":false,"gas":2000000,"inputs":[],"outputs":[{"type":"uint256"}]},{"type":"function","name":"getApproved","constant":true,"stateMutability":"view","payable":false,"gas":2000000,"inputs":[{"type":"uint256","name":"tokenId"}],"outputs":[{"type":"address"}]},{"type":"function","name":"isApprovedForAll","constant":true,"stateMutability":"view","payable":false,"gas":2000000,"inputs":[{"type":"address","name":"owner"},{"type":"address","name":"operator"}],"outputs":[{"type":"bool"}]},{"type":"function","name":"mint","constant":false,"stateMutability":"payable","payable":true,"gas":2000000,"inputs":[],"outputs":[{"type":"uint256"}]},{"type":"function","name":"name","constant":true,"stateMutability":"view","payable":false,"gas":2000000,"inputs":[],"outputs":[{"type":"string"}]},{"type":"function","name":"owner","constant":true,"stateMutability":"view","payable":false,"gas":2000000,"inputs":[],"outputs":[{"type":"address"}]},{"type":"function","name":"ownerOf","constant":true,"stateMutability":"view","payable":false,"gas":2000000,"inputs":[{"type":"uint256","name":"tokenId"}],"outputs":[{"type":"address"}]},{"type":"function","name":"renounceOwnership","constant":false,"payable":false,"gas":2000000,"inputs":[],"outputs":[]},{"type":"function","name":"reveal","constant":false,"payable":false,"gas":2000000,"inputs":[],"outputs":[]},{"type":"function","name":"revealed","constant":true,"stateMutability":"view","payable":false,"gas":2000000,"inputs":[],"outputs":[{"type":"bool"}]},{"type":"function","name":"safeTransferFrom","constant":false,"payable":false,"gas":2000000,"inputs":[{"type":"address","name":"from"},{"type":"address","name":"to"},{"type":"uint256","name":"tokenId"}],"outputs":[]},{"type":"function","name":"safeTransferFrom","constant":false,"payable":false,"gas":2000000,"inputs":[{"type":"address","name":"from"},{"type":"address","name":"to"},{"type":"uint256","name":"tokenId"},{"type":"bytes","name":"_data"}],"outputs":[]},{"type":"function","name":"setApprovalForAll","constant":false,"payable":false,"gas":2000000,"inputs":[{"type":"address","name":"operator"},{"type":"bool","name":"approved"}],"outputs":[]},{"type":"function","name":"setBaseURI","constant":false,"payable":false,"gas":2000000,"inputs":[{"type":"string","name":"_newBaseURI"}],"outputs":[]},{"type":"function","name":"setNotRevealedURI","constant":false,"payable":false,"gas":2000000,"inputs":[{"type":"string","name":"_notRevealedURI"}],"outputs":[]},{"type":"function","name":"supportsInterface","constant":true,"stateMutability":"view","payable":false,"gas":2000000,"inputs":[{"type":"bytes4","name":"interfaceId"}],"outputs":[{"type":"bool"}]},{"type":"function","name":"symbol","constant":true,"stateMutability":"view","payable":false,"gas":2000000,"inputs":[],"outputs":[{"type":"string"}]},{"type":"function","name":"tokenByIndex","constant":true,"stateMutability":"view","payable":false,"gas":2000000,"inputs":[{"type":"uint256","name":"index"}],"outputs":[{"type":"uint256"}]},{"type":"function","name":"tokenOfOwnerByIndex","constant":true,"stateMutability":"view","payable":false,"gas":2000000,"inputs":[{"type":"address","name":"owner"},{"type":"uint256","name":"index"}],"outputs":[{"type":"uint256"}]},{"type":"function","name":"tokenURI","constant":true,"stateMutability":"view","payable":false,"gas":2000000,"inputs":[{"type":"uint256","name":"_tokenId"}],"outputs":[{"type":"string"}]},{"type":"function","name":"totalSupply","constant":true,"stateMutability":"view","payable":false,"gas":2000000,"inputs":[],"outputs":[{"type":"uint256"}]},{"type":"function","name":"transferFrom","constant":false,"payable":false,"gas":2000000,"inputs":[{"type":"address","name":"from"},{"type":"address","name":"to"},{"type":"uint256","name":"tokenId"}],"outputs":[]},{"type":"function","name":"transferOwnership","constant":false,"payable":false,"gas":2000000,"inputs":[{"type":"address","name":"newOwner"}],"outputs":[]},{"type":"function","name":"withdrawEther","constant":false,"payable":false,"gas":2000000,"inputs":[],"outputs":[]}]} \ No newline at end of file diff --git a/apps/hardhat/contracts/GrotesqueAccessCard.sol b/apps/hardhat/contracts/GrotesqueAccessCard.sol new file mode 100644 index 0000000..d5a768c --- /dev/null +++ b/apps/hardhat/contracts/GrotesqueAccessCard.sol @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: MIT + +/* + ██╗ + ██║ + ██████╗ + ██╔══██╗ ██╗ + ██████╔╝ ██╝ + ╚═════╝ + + From the basement. https://basement.studio +*/ + +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; +import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; +import "@openzeppelin/contracts/utils/Counters.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; + +contract GrotesqueAccessCard is ERC721Enumerable, Ownable { + uint256 public cost = 0.02 ether; + + string private baseURI; + string private notRevealedURI; + bytes32 private baseExtension = ".json"; + bool public revealed = false; + + // Validation related variables + uint256 private maxSupply = 500; + uint256 private maxMintAmount = 1; + uint256 private maxNFTPerAddress = 5; + + constructor(string memory _initBaseURI, string memory _initNotRevealedURI) ERC721("BSMNT Grotesque Access Card", "BSMNT_NFT"){ + require(bytes(_initBaseURI).length > 0, "Base URI must be a non-empty string"); + require(bytes(_initNotRevealedURI).length > 0, "Not Revealed URI must be a non-empty string"); + + setBaseURI(_initBaseURI); + setNotRevealedURI(_initNotRevealedURI); + } + + function getNextTokenId() internal view returns (uint256) { + uint256 supply = totalSupply(); + return supply + 1; + } + + function mint() public payable returns (uint256) { + uint256 newTokenId = getNextTokenId(); + + require(newTokenId <= maxSupply, "Max NFT limit exceeded"); + require(msg.value >= cost, "Insufficient funds"); + + _safeMint(msg.sender, getNextTokenId()); + + return newTokenId; + } + + function withdrawEther() external onlyOwner { + payable(msg.sender).transfer(address(this).balance); + } + + function tokenURI(uint256 _tokenId) + public + view + virtual + override (ERC721) + returns (string memory) + { + require( + _exists(_tokenId), + "ERC721Metadata: URI query for nonexistent token" + ); + + // If the token is not revealed, return the notRevealedURI + if (revealed == false) { + return notRevealedURI; + } + + if (bytes(baseURI).length > 0) { + return string( + abi.encodePacked( + baseURI, + _tokenId.toString(), + baseExtension + ) + ); + } + + super.tokenURI(_tokenId); + } + + function setBaseURI(string memory _newBaseURI) public onlyOwner { + baseURI = _newBaseURI; + } + + function setNotRevealedURI(string memory _notRevealedURI) public onlyOwner { + notRevealedURI = _notRevealedURI; + } + + function reveal() public onlyOwner { + revealed = true; + } +} diff --git a/apps/hardhat/hardhat.config.ts b/apps/hardhat/hardhat.config.ts new file mode 100644 index 0000000..e0784e1 --- /dev/null +++ b/apps/hardhat/hardhat.config.ts @@ -0,0 +1,41 @@ +import '@nomiclabs/hardhat-ethers' +import dotenv from 'dotenv' + +import mintTask from './tasks/mint' +import holderInfoTask from './tasks/holder-info' +import getTotalSupplyTask from './tasks/get-total-supply' +import withdrawFunds from './tasks/withdraw-funds' +import getBalance from './tasks/get-balance' +import getTokenURI from './tasks/get-token-URI' +import revealNFTs from './tasks/reveal' + +dotenv.config() + +const INFURA_URL = `https://ropsten.infura.io/v3/${process.env.INFURA_PROJECT_ID}`; +const PRIVATE_KEY = process.env.OWNER_WALLET_PRIVATE_KEY; + +// @ts-ignore +task('mint', 'Mint an NFT').setAction(mintTask) +// @ts-ignore +task('holder-info', 'Get information about NFT holder').addParam('address', 'Holder wallet address').setAction(holderInfoTask) +// @ts-ignore +task('total-supply', 'Get NFT current total supply').setAction(getTotalSupplyTask) +// @ts-ignore +task('withdraw-funds', 'Withdraw contract funds').setAction(withdrawFunds) +// @ts-ignore +task('get-balance', 'Get contract\'s balance').setAction(getBalance) +// @ts-ignore +task('token-uri', 'Get token\'s URI information').addParam('tokenid', 'Token id').setAction(getTokenURI) +// @ts-ignore +task('reveal', 'WARNING! This reveals all the NFTs URIs').setAction(revealNFTs) + +export default { + solidity: "0.8.7", + networks: { + ropsten: { + url: INFURA_URL, + accounts: [`0x${PRIVATE_KEY}`], + gas: 3000000, + } + } +}; diff --git a/apps/hardhat/package-lock.json b/apps/hardhat/package-lock.json new file mode 100644 index 0000000..4338d80 --- /dev/null +++ b/apps/hardhat/package-lock.json @@ -0,0 +1,109 @@ +{ + "name": "grotesque-hardhat", + "version": "0.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "dev": true + }, + "@cspotcode/source-map-support": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", + "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "dev": true, + "requires": { + "@cspotcode/source-map-consumer": "0.8.0" + } + }, + "@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "dev": true + }, + "acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "dev": true + }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "ts-node": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz", + "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==", + "dev": true, + "requires": { + "@cspotcode/source-map-support": "0.7.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "yn": "3.1.1" + } + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true + } + } +} diff --git a/apps/hardhat/package.json b/apps/hardhat/package.json new file mode 100644 index 0000000..b739f2b --- /dev/null +++ b/apps/hardhat/package.json @@ -0,0 +1,19 @@ +{ + "name": "grotesque-hardhat", + "version": "0.0.1", + "main": "index.js", + "license": "MIT", + "scripts": { + "compile": "hardhat compile", + "deploy": "hardhat run scripts/deploy.ts --network ropsten" + }, + "dependencies": { + "@nomiclabs/hardhat-ethers": "^2.0.4", + "@openzeppelin/contracts": "^4.4.2", + "dotenv": "^16.0.0", + "ethers": "^5.5.4", + "hardhat": "^2.8.3", + "ts-node": "^10.4.0" + }, + "devDependencies": {} +} diff --git a/apps/hardhat/pinata-content/guardian.json b/apps/hardhat/pinata-content/guardian.json new file mode 100644 index 0000000..5517f66 --- /dev/null +++ b/apps/hardhat/pinata-content/guardian.json @@ -0,0 +1,6 @@ +{ + "description": "Grotesque Guardian", + "external_url": "https://grotesque.basement.studio/", + "name": "Grotesque Guardian", + "image": "https://ipfs.io/ipfs/QmTEF2k66mfr4nFf1ujfWcDwzu9ckKhQppxoiiMEYwCdfZ" +} \ No newline at end of file diff --git a/apps/hardhat/pinata-content/images/1.png b/apps/hardhat/pinata-content/images/1.png new file mode 100644 index 0000000..0001dac Binary files /dev/null and b/apps/hardhat/pinata-content/images/1.png differ diff --git a/apps/hardhat/pinata-content/metadata/1.json b/apps/hardhat/pinata-content/metadata/1.json new file mode 100644 index 0000000..c8337fe --- /dev/null +++ b/apps/hardhat/pinata-content/metadata/1.json @@ -0,0 +1,17 @@ +{ + "description": "BSMNT Grotesque Access Card", + "external_url": "https://grotesque.basement.studio/", + "image": "https://ipfs.io/ipfs/QmdffbPrPeRPp2iB9GewoXEdx5YGg2ppRpuqrg9wwHzgDL/1.png", + "name": "BSMNT Grotesque Access Card", + "tokenId": "1", + "attributes": [ + { + "name": "color", + "value": "silver" + }, + { + "name": "rarity", + "value": "common" + } + ] +} \ No newline at end of file diff --git a/apps/hardhat/scripts/deploy.ts b/apps/hardhat/scripts/deploy.ts new file mode 100644 index 0000000..af35d0d --- /dev/null +++ b/apps/hardhat/scripts/deploy.ts @@ -0,0 +1,33 @@ +import fs from 'fs'; +import { ethers } from 'hardhat'; + +const baseURI = 'https://gateway.pinata.cloud/ipfs/QmSVzZHDJ9upWSUPasESBBYK5aTr25MAXjjkEu6RbJM6Ag/' +const notRevealedURI = 'https://gateway.pinata.cloud/ipfs/QmVtxbcPzB2Nr2R3oEkzPz2AiQf6u9RNfZmaMjtcWRQXri' + +const main = async () => { + const [deployer] = await ethers.getSigners(); + console.log(`Deploying contracts with the account: ${deployer.address}`); + + const balance = await deployer.getBalance(); + console.log(`Account balance: ${ethers.utils.formatEther(balance)}`); + + const Contract = await ethers.getContractFactory('GrotesqueAccessCard'); + const deployedContract = await Contract.deploy(baseURI, notRevealedURI); + console.log(`Contract address: ${deployedContract.address}`); + + const contractAbi = deployedContract.interface.format('json') + + const data = { + address: deployedContract.address, + abi: JSON.parse(Array.isArray(contractAbi) ? contractAbi[0] : contractAbi) + }; + + fs.writeFileSync('abis/GrotesqueAccessCard.json', JSON.stringify(data)); +} + +main() + .then(() => process.exit(0)) + .catch(error => { + console.error(error); + process.exit(1); + }); diff --git a/apps/hardhat/tasks/get-balance.ts b/apps/hardhat/tasks/get-balance.ts new file mode 100644 index 0000000..a282f31 --- /dev/null +++ b/apps/hardhat/tasks/get-balance.ts @@ -0,0 +1,12 @@ +import grotesqueAccessCardContract from '../abis/GrotesqueAccessCard.json' +import { THardhat, getWalletAndProvider } from '../utils' + +const getBalance = async (_, hre: THardhat) => { + const { provider } = getWalletAndProvider(hre) + + const contractBalance = await provider.getBalance(grotesqueAccessCardContract.address) + + console.log(`Contract balance: ${hre.ethers.utils.formatEther(contractBalance)}`); +} + +export default getBalance \ No newline at end of file diff --git a/apps/hardhat/tasks/get-token-URI.ts b/apps/hardhat/tasks/get-token-URI.ts new file mode 100644 index 0000000..208555b --- /dev/null +++ b/apps/hardhat/tasks/get-token-URI.ts @@ -0,0 +1,23 @@ +import grotesqueAccessCardContract from '../abis/GrotesqueAccessCard.json' +import { THardhat, getWalletAndProvider } from '../utils' + +type Arguments = { + tokenid: string +} + +const getTokenURI = async ({ tokenid }: Arguments, hre: THardhat) => { + const { wallet } = getWalletAndProvider(hre) + + const ethersContract = new hre.ethers.Contract( + grotesqueAccessCardContract.address, + // @ts-ignore + grotesqueAccessCardContract.abi, + wallet + ).connect(wallet.address) + + const tokenURI: string = await ethersContract.tokenURI(tokenid.toString()) + + console.log('Token URI:', tokenURI) +} + +export default getTokenURI \ No newline at end of file diff --git a/apps/hardhat/tasks/get-total-supply.ts b/apps/hardhat/tasks/get-total-supply.ts new file mode 100644 index 0000000..5821c0a --- /dev/null +++ b/apps/hardhat/tasks/get-total-supply.ts @@ -0,0 +1,19 @@ +import grotesqueAccessCardContract from '../abis/GrotesqueAccessCard.json' +import { THardhat, getWalletAndProvider } from '../utils' + +const getTotalSupply = async (_, hre: THardhat) => { + const { wallet } = getWalletAndProvider(hre) + + const ethersContract = new hre.ethers.Contract( + grotesqueAccessCardContract.address, + // @ts-ignore + grotesqueAccessCardContract.abi, + wallet + ).connect(wallet.address) + + const totalSupply: THardhat['ethers']['BigNumber'] = await ethersContract.totalSupply() + + console.log('Total supply:', totalSupply.toString()) +} + +export default getTotalSupply \ No newline at end of file diff --git a/apps/hardhat/tasks/holder-info.ts b/apps/hardhat/tasks/holder-info.ts new file mode 100644 index 0000000..350b46d --- /dev/null +++ b/apps/hardhat/tasks/holder-info.ts @@ -0,0 +1,23 @@ +import grotesqueAccessCardContract from '../abis/GrotesqueAccessCard.json' +import { THardhat, getWalletAndProvider } from '../utils' + +type Arguments = { + address: string +} + +const holderInfo = async ({ address }: Arguments, hre: THardhat) => { + const { wallet } = getWalletAndProvider(hre) + + const ethersContract = new hre.ethers.Contract( + grotesqueAccessCardContract.address, + // @ts-ignore + grotesqueAccessCardContract.abi, + wallet + ).connect(wallet.address) + + const holderBalance: THardhat['ethers']['BigNumber'] = await ethersContract.balanceOf(address) + + console.log('Holder balance:', holderBalance.toString()) +} + +export default holderInfo \ No newline at end of file diff --git a/apps/hardhat/tasks/mint.ts b/apps/hardhat/tasks/mint.ts new file mode 100644 index 0000000..958d781 --- /dev/null +++ b/apps/hardhat/tasks/mint.ts @@ -0,0 +1,38 @@ +import grotesqueAccessCardContract from '../abis/GrotesqueAccessCard.json' +import { getWalletAndProvider, THardhat } from '../utils' + +const mint = async (_, hre: THardhat) => { + const overrides = { + value: hre.ethers.utils.parseEther('0.02'), + gasLimit: 3000000, + } + const { provider, wallet } = getWalletAndProvider(hre) + + const currentGasPrice = await provider.getGasPrice() + const balance = await wallet.getBalance(); + + console.log(`Current gas price: ${currentGasPrice}`) + console.log(`Account balance: ${hre.ethers.utils.formatEther(balance)}`); + + const ethersContract = new hre.ethers.Contract( + grotesqueAccessCardContract.address, + // @ts-ignore + grotesqueAccessCardContract.abi, + wallet + ).connect(wallet) + + const mintTransaction = await ethersContract.mint(overrides) + + console.log(`Transaction created: https://${ + hre.network.name !== 'mainnet' ? hre.network.name + '.' : '' + }etherscan.io/tx/${mintTransaction.hash}`) + + await mintTransaction.wait() + + console.log(`Transaction succeeded!`) + + const totalSupply = await ethersContract.totalSupply() + console.log(`Total supply: ${totalSupply}`) +} + +export default mint \ No newline at end of file diff --git a/apps/hardhat/tasks/reveal.ts b/apps/hardhat/tasks/reveal.ts new file mode 100644 index 0000000..d288612 --- /dev/null +++ b/apps/hardhat/tasks/reveal.ts @@ -0,0 +1,25 @@ +import grotesqueAccessCardContract from '../abis/GrotesqueAccessCard.json' +import { THardhat, getWalletAndProvider } from '../utils' + +const revealNFTs = async (_, hre: THardhat) => { + const { wallet } = getWalletAndProvider(hre) + + const ethersContract = new hre.ethers.Contract( + grotesqueAccessCardContract.address, + // @ts-ignore + grotesqueAccessCardContract.abi, + wallet + ).connect(wallet) + + const revealTransaction = await ethersContract.reveal() + + console.log(`Transaction created: https://${ + hre.network.name !== 'mainnet' ? hre.network.name + '.' : '' + }etherscan.io/tx/${revealTransaction.hash}`) + + await revealTransaction.wait() + + console.log('Reveal transaction succeeded!') +} + +export default revealNFTs \ No newline at end of file diff --git a/apps/hardhat/tasks/withdraw-funds.ts b/apps/hardhat/tasks/withdraw-funds.ts new file mode 100644 index 0000000..4a1e62c --- /dev/null +++ b/apps/hardhat/tasks/withdraw-funds.ts @@ -0,0 +1,29 @@ +import grotesqueAccessCardContract from '../abis/GrotesqueAccessCard.json' +import { THardhat, getWalletAndProvider } from '../utils' + +const withdrawFunds = async (_, hre: THardhat) => { + const { wallet, provider } = getWalletAndProvider(hre) + + const ethersContract = new hre.ethers.Contract( + grotesqueAccessCardContract.address, + // @ts-ignore + grotesqueAccessCardContract.abi, + wallet + ).connect(wallet) + + const contractBalance = await provider.getBalance(ethersContract.address) + + console.log(`Contract balance: ${hre.ethers.utils.formatEther(contractBalance)}`); + + const withrawTransaction = await ethersContract.withdrawEther() + + console.log(`Transaction created: https://${ + hre.network.name !== 'mainnet' ? hre.network.name + '.' : '' + }etherscan.io/tx/${withrawTransaction.hash}`) + + await withrawTransaction.wait() + + console.log(`Withdraw transaction succeeded!`) +} + +export default withdrawFunds \ No newline at end of file diff --git a/apps/hardhat/tsconfig.json b/apps/hardhat/tsconfig.json new file mode 100644 index 0000000..07062f2 --- /dev/null +++ b/apps/hardhat/tsconfig.json @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "resolveJsonModule": true, + "esModuleInterop": true + } +} diff --git a/apps/hardhat/utils.ts b/apps/hardhat/utils.ts new file mode 100644 index 0000000..866718a --- /dev/null +++ b/apps/hardhat/utils.ts @@ -0,0 +1,16 @@ +import type Hardhat from 'hardhat' +import config from './hardhat.config' + +export type THardhat = typeof Hardhat + +export const getWalletAndProvider = (hre: THardhat) => { + const ethersProvider = new hre.ethers.providers.JsonRpcProvider( + config.networks.ropsten.url + ) + const wallet = new hre.ethers.Wallet(config.networks.ropsten.accounts[0], ethersProvider) + + return { + provider: ethersProvider, + wallet, + } +} diff --git a/apps/web/.eslintrc.js b/apps/web/.eslintrc.js new file mode 100644 index 0000000..0b23a46 --- /dev/null +++ b/apps/web/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@basement-grotesque/config/eslint-preset') diff --git a/apps/web/.prettierrc.js b/apps/web/.prettierrc.js new file mode 100644 index 0000000..69ac97f --- /dev/null +++ b/apps/web/.prettierrc.js @@ -0,0 +1 @@ +module.exports = require('@basement-grotesque/config/prettier-preset') diff --git a/apps/web/.stylelintrc.js b/apps/web/.stylelintrc.js new file mode 100644 index 0000000..8b901c6 --- /dev/null +++ b/apps/web/.stylelintrc.js @@ -0,0 +1,27 @@ +module.exports = { + ignoreFiles: ['**/*.{ts,tsx,js,jsx}'], + extends: ['stylelint-config-standard'], + rules: { + 'at-rule-no-unknown': [ + true, + { + ignoreAtRules: ['tailwind', 'apply', 'variants', 'responsive', 'screen'] + } + ], + 'selector-pseudo-class-no-unknown': [ + true, + { + ignorePseudoClasses: ['global'] + } + ], + 'property-no-unknown': [ + true, + { + ignoreProperties: ['font-named-instance'] + } + ], + 'declaration-block-trailing-semicolon': null, + 'no-descending-specificity': null, + 'number-leading-zero': null + } +} diff --git a/jest.config.js b/apps/web/jest.config.js similarity index 100% rename from jest.config.js rename to apps/web/jest.config.js diff --git a/jest.setup.js b/apps/web/jest.setup.js similarity index 100% rename from jest.setup.js rename to apps/web/jest.setup.js diff --git a/apps/web/loco.d.ts b/apps/web/loco.d.ts new file mode 100644 index 0000000..bf4c24c --- /dev/null +++ b/apps/web/loco.d.ts @@ -0,0 +1,235 @@ +declare module '*.svg' { + const ReactComponent: React.FC> + const content: string + + export default ReactComponent +} + +declare module 'locomotive-scroll' { + export function getParents(elem: Element): Element[] + export function queryClosestParent( + elem: Element, + selector: string + ): Element | null + export function transform(el: Element, transformValue: string): void + export function getTranslate(el: Element): Vector2 + + export type Vector2 = { + x: number + y: number + } + + interface ScrollToOptions { + /** + * Defines an offset from your target. E.g. -100 if you want to scroll 100 pixels above your target. + */ + offset?: number | string + /** + * Defines the duration of the scroll animation in milliseconds. Defaults to 1000. + */ + duration?: number + /** + * An array of 4 floats between 0 and 1 defining the bezier curve for the animation's easing. + * + * Defaults to `[0.25, 0.00, 0.35, 1.00]` + * + * See http://greweb.me/bezier-easing-editor/example/ + * + * Keep in mind this will also be affected by the lerp unless you set `disableLerp` to `true`. + */ + easing?: [number, number, number, number] + /** + * Lerp effect won't be applied if set to true. + */ + disableLerp?: boolean + /** + * Called when scrollTo completes (note that it won't wait for lerp to stabilize). + */ + callback?: () => void + } + + export interface LocomotiveScrollOptions { + /** Scroll container element. */ + el?: Element + /** Data attribute prefix (data-scroll-xxxx). */ + name?: string + elMobile?: Element + /** + * Global in-view trigger offset : [bottom,top] + * Use a string with % to use a percentage of the viewport height. + * Use a numeric value for absolute pixels unit. + */ + offset?: [number, number] + /** + * Repeat in-view detection. + */ + repeat?: boolean + /** + * Smooth scrolling. + */ + smooth?: boolean + /** + * An object defining the initial scroll coordinates on a smooth instance. For example: { x: 0, y: 1000 } + */ + initPosition?: { x: number; y: number } + /** + * Scroll direction: vertical or horizontal. + */ + direction?: 'vertical' | 'horizontal' + /** + * Linear interpolation (lerp) intensity. Float between 0 and 1. + * This defines the "smoothness" intensity. The closer to 0, the smoother. + */ + lerp?: number + /** + * Add direction to scroll event. + */ + getDirection?: boolean + /** + * Add speed to scroll event. + */ + getSpeed?: boolean + /** + * Element in-view class. + */ + class?: string + /** + * Initialize class. + */ + initClass?: string + /** + * Is scrolling class. + */ + scrollingClass?: string + /** + * Is dragging class. + */ + draggingClass?: string + /** + * Has smooth scrolling class. + */ + smoothClass?: string + /** + * Scrollbar element class. + */ + scrollbarClass?: string + /** + * Specifies the container element for the scrollbar to be appended in. If false, scrollbar will be appended to the body. + */ + scrollbarContainer?: Element | false + /** + * Factor applied to the scroll delta, allowing to boost/reduce scrolling speed (regardless of the platform). + */ + multiplier?: number + /** + * Boost scrolling speed of Firefox on Windows. + */ + firefoxMultiplier?: number + /** + * Multiply touch action to scroll faster than finger movement. + */ + touchMultiplier?: number + /** + * By default locomotive-scroll listens for scroll events only on the scroll container (`el` option). With this option set to true, it listens on the whole document instead. + */ + scrollFromAnywhere?: boolean + /** + * Defines which gesture direction(s) scrolls in your instance. You can use: + * - `vertical` + * - `horizontal` + * - `both` + */ + gestureDirection?: 'vertical' | 'horizontal' | 'both' + /** + * Object allowing to override some options for a particular context. You can specify: + * - `smooth` + * - `direction` + * - `horizontalGesture` + * + * For tablet context you can also define breakpoint (integer, defaults to 1024) to set the max-width breakpoint for tablets. + */ + tablet?: { + smooth?: boolean + direction?: 'vertical' | 'horizontal' + horizontalGesture?: boolean + breakpoint?: number + } + /** + * Object allowing to override some options for a particular context. You can specify: + * - `smooth` + * - `direction` + * - `horizontalGesture` + * + * For tablet context you can also define breakpoint (integer, defaults to 1024) to set the max-width breakpoint for tablets. + */ + smartphone?: { + smooth?: boolean + direction?: 'vertical' | 'horizontal' + horizontalGesture?: boolean + } + /** + * Allows to reload the page when switching between `desktop`, `tablet` and `smartphone` contexts. It can be useful if your page changes a lot between contexts and you want to reset everything. + */ + reloadOnContextChange?: boolean + /** + * Sets `history.scrollRestoration = 'manual'` and calls `window.scrollTo(0, 0)` on locomotive-scroll init in Native Class. Useful if you use transitions with native scrolling, otherwise we advise to set it to `false` if you don't want to break History API's scroll restoration feature. + */ + resetNativeScroll?: boolean + } + + export type EventHandler = (data: { + currentElements: Record + delta: { x: number; y: number } + limit: { x: number; y: number } + scroll: { x: number; y: number } + speed: number + }) => void + + export default class LocomotiveScroll implements LocomotiveScrollOptions { + constructor(options?: LocomotiveScrollOptions) + + /** + * Reinitializes the scroll. + */ + init(): void + /** + * Scroller element. + */ + el: HTMLElement + /** + * Updates all element positions. + */ + update(): void + /** + * Destroys the scroll events. + */ + destroy(): void + /** + * Restarts the scroll events. + */ + start(): void + /** + * Stops the scroll events. + */ + stop(): void + /** + * Scroll to a target. + * @param target Defines where you want to scroll. + * @param options Settings object. + */ + scrollTo( + target: Node | string | 'top' | 'bottom' | number, + options?: ScrollToOptions + ): void + /** + * todo, type this + */ + on(event: 'scroll', handler: EventHandler): void + /** + * todo, type this + */ + off(event: 'scroll', handler: EventHandler): void + } + + export { LocomotiveScroll as Scroll } +} diff --git a/next-env.d.ts b/apps/web/next-env.d.ts similarity index 100% rename from next-env.d.ts rename to apps/web/next-env.d.ts diff --git a/next-sitemap.js b/apps/web/next-sitemap.js similarity index 100% rename from next-sitemap.js rename to apps/web/next-sitemap.js diff --git a/next.config.js b/apps/web/next.config.js similarity index 100% rename from next.config.js rename to apps/web/next.config.js diff --git a/apps/web/package.json b/apps/web/package.json new file mode 100644 index 0000000..5f26105 --- /dev/null +++ b/apps/web/package.json @@ -0,0 +1,84 @@ +{ + "name": "@basement-grotesque/web", + "version": "3.0.0", + "scripts": { + "dev": "next", + "build": "next build", + "build:analyze": "cross-env ANALYZE=true npm run build", + "start": "next start", + "type-check": "tsc --pretty --noEmit", + "postbuild": "next-sitemap", + "lint": "eslint . --ext ts --ext tsx --ext js", + "lint:fix": "yarn lint --fix", + "test": "jest --watch --env=jsdom" + }, + "dependencies": { + "@juggle/resize-observer": "^3.3.1", + "@radix-ui/react-polymorphic": "0.0.13", + "@react-three/drei": "^8.8.1", + "@react-three/fiber": "^7.0.26", + "@stitches/react": "^1.2.6", + "clsx": "^1.1.1", + "date-fns": "^2.23.0", + "eth-hooks": "^4.0.29", + "gsap": "https://basement.studio/gsap/bonus-0.0.12.tgz", + "locomotive-scroll": "^4.1.1", + "lodash.throttle": "^4.1.1", + "next": "^11.1.1", + "next-seo": "^4.26.0", + "next-svgr": "^0.0.2", + "p2": "^0.7.1", + "react": "^17.0.2", + "react-device-detect": "^1.17.0", + "react-dom": "^17.0.2", + "react-fast-marquee": "^1.2.1", + "react-hot-toast": "^2.1.0", + "react-intersection-observer": "^8.32.1", + "react-merge-refs": "^1.1.0", + "react-query": "^3.27.0", + "react-use-measure": "^2.0.4", + "sharp": "^0.29.0", + "three": "^0.137.5" + }, + "devDependencies": { + "@basement-grotesque/config": "*", + "@basement-grotesque/tsconfig": "*", + "@next/bundle-analyzer": "^11.1.0", + "@testing-library/jest-dom": "^5.14.1", + "@testing-library/react": "^12.0.0", + "@types/file-saver": "^2.0.3", + "@types/lodash.throttle": "^4.1.6", + "@types/node": "^16.7.2", + "@types/p2": "^0.7.39", + "@types/react": "^17.0.19", + "@types/react-dom": "^17.0.6", + "@types/three": "^0.137.0", + "@typescript-eslint/eslint-plugin": "^4.29.2", + "@typescript-eslint/parser": "^4.29.2", + "babel-jest": "^27.0.6", + "babel-plugin-optimize-clsx": "^2.6.2", + "cross-env": "^7.0.3", + "eslint": "^7.32.0", + "eslint-config-next": "^11.1.0", + "eslint-config-prettier": "^8.3.0", + "eslint-plugin-jsx-a11y": "^6.4.1", + "eslint-plugin-prettier": "^3.4.1", + "eslint-plugin-react": "^7.26.1", + "eslint-plugin-react-hooks": "^4.2.0", + "jest": "^27.3.1", + "next-compose-plugins": "^2.2.1", + "next-sitemap": "^1.6.162", + "next-transpile-modules": "^8.0.0", + "prettier": "^2.3.2", + "sass": "^1.38.0", + "stylelint": "^13.13.1", + "stylelint-config-standard": "^22.0.0", + "typescript": "^4.3.5" + }, + "browserslist": [ + ">0.2%", + "not dead", + "not ie <= 11", + "not op_mini all" + ] +} diff --git a/public/BasementGrotesque-Black_v1.202.zip b/apps/web/public/BasementGrotesque-Black_v1.202.zip similarity index 100% rename from public/BasementGrotesque-Black_v1.202.zip rename to apps/web/public/BasementGrotesque-Black_v1.202.zip diff --git a/public/KTYPE B- 1.mp4 b/apps/web/public/KTYPE B- 1.mp4 similarity index 100% rename from public/KTYPE B- 1.mp4 rename to apps/web/public/KTYPE B- 1.mp4 diff --git a/public/favicon-dark.svg b/apps/web/public/favicon-dark.svg similarity index 100% rename from public/favicon-dark.svg rename to apps/web/public/favicon-dark.svg diff --git a/public/favicon.svg b/apps/web/public/favicon.svg similarity index 100% rename from public/favicon.svg rename to apps/web/public/favicon.svg diff --git a/public/fonts/grotesque/BasementGrotesque-Black_v1.202.woff b/apps/web/public/fonts/grotesque/BasementGrotesque-Black_v1.202.woff similarity index 100% rename from public/fonts/grotesque/BasementGrotesque-Black_v1.202.woff rename to apps/web/public/fonts/grotesque/BasementGrotesque-Black_v1.202.woff diff --git a/public/fonts/grotesque/BasementGrotesque-Black_v1.202.woff2 b/apps/web/public/fonts/grotesque/BasementGrotesque-Black_v1.202.woff2 similarity index 100% rename from public/fonts/grotesque/BasementGrotesque-Black_v1.202.woff2 rename to apps/web/public/fonts/grotesque/BasementGrotesque-Black_v1.202.woff2 diff --git a/apps/web/public/fonts/grotesque/BasementGrotesqueDisplay-UltraBlackExtraExpanded.woff b/apps/web/public/fonts/grotesque/BasementGrotesqueDisplay-UltraBlackExtraExpanded.woff new file mode 100644 index 0000000..fd25293 Binary files /dev/null and b/apps/web/public/fonts/grotesque/BasementGrotesqueDisplay-UltraBlackExtraExpanded.woff differ diff --git a/apps/web/public/fonts/grotesque/BasementGrotesqueDisplay-UltraBlackExtraExpanded.woff2 b/apps/web/public/fonts/grotesque/BasementGrotesqueDisplay-UltraBlackExtraExpanded.woff2 new file mode 100644 index 0000000..a57094e Binary files /dev/null and b/apps/web/public/fonts/grotesque/BasementGrotesqueDisplay-UltraBlackExtraExpanded.woff2 differ diff --git a/public/fonts/inter/Inter-italic.var.woff2 b/apps/web/public/fonts/inter/Inter-italic.var.woff2 similarity index 100% rename from public/fonts/inter/Inter-italic.var.woff2 rename to apps/web/public/fonts/inter/Inter-italic.var.woff2 diff --git a/public/fonts/inter/Inter-roman.var.woff2 b/apps/web/public/fonts/inter/Inter-roman.var.woff2 similarity index 100% rename from public/fonts/inter/Inter-roman.var.woff2 rename to apps/web/public/fonts/inter/Inter-roman.var.woff2 diff --git a/public/images/labelhero.png b/apps/web/public/images/labelhero.png similarity index 100% rename from public/images/labelhero.png rename to apps/web/public/images/labelhero.png diff --git a/public/images/posters/arrow-down.png b/apps/web/public/images/posters/arrow-down.png similarity index 100% rename from public/images/posters/arrow-down.png rename to apps/web/public/images/posters/arrow-down.png diff --git a/public/images/posters/arrow-down.svg b/apps/web/public/images/posters/arrow-down.svg similarity index 100% rename from public/images/posters/arrow-down.svg rename to apps/web/public/images/posters/arrow-down.svg diff --git a/public/images/posters/magazine.png b/apps/web/public/images/posters/magazine.png similarity index 100% rename from public/images/posters/magazine.png rename to apps/web/public/images/posters/magazine.png diff --git a/public/images/posters/mar-del-plata.png b/apps/web/public/images/posters/mar-del-plata.png similarity index 100% rename from public/images/posters/mar-del-plata.png rename to apps/web/public/images/posters/mar-del-plata.png diff --git a/public/images/posters/street-mobile.png b/apps/web/public/images/posters/street-mobile.png similarity index 100% rename from public/images/posters/street-mobile.png rename to apps/web/public/images/posters/street-mobile.png diff --git a/public/images/posters/street.png b/apps/web/public/images/posters/street.png similarity index 100% rename from public/images/posters/street.png rename to apps/web/public/images/posters/street.png diff --git a/public/images/posters/subway.png b/apps/web/public/images/posters/subway.png similarity index 100% rename from public/images/posters/subway.png rename to apps/web/public/images/posters/subway.png diff --git a/public/images/posters/the-odyssey.png b/apps/web/public/images/posters/the-odyssey.png similarity index 100% rename from public/images/posters/the-odyssey.png rename to apps/web/public/images/posters/the-odyssey.png diff --git a/apps/web/public/models/bsmnt.glb b/apps/web/public/models/bsmnt.glb new file mode 100644 index 0000000..6413101 Binary files /dev/null and b/apps/web/public/models/bsmnt.glb differ diff --git a/public/og.png b/apps/web/public/og.png similarity index 100% rename from public/og.png rename to apps/web/public/og.png diff --git a/apps/web/public/robots.txt b/apps/web/public/robots.txt new file mode 100644 index 0000000..f246e0e --- /dev/null +++ b/apps/web/public/robots.txt @@ -0,0 +1,9 @@ +# * +User-agent: * +Allow: / + +# Host +Host: https://grotesque.basement.studio/ + +# Sitemaps +Sitemap: https://grotesque.basement.studio/sitemap.xml diff --git a/public/sitemap.xml b/apps/web/public/sitemap.xml similarity index 71% rename from public/sitemap.xml rename to apps/web/public/sitemap.xml index fc4c925..e801a41 100644 --- a/public/sitemap.xml +++ b/apps/web/public/sitemap.xml @@ -1,4 +1,4 @@ -https://next-typescript.basement.studiodaily0.72021-08-24T14:24:29.890Z +https://grotesque.basement.studiodaily0.72022-02-04T16:23:26.522Z \ No newline at end of file diff --git a/public/video.mp4 b/apps/web/public/video.mp4 similarity index 100% rename from public/video.mp4 rename to apps/web/public/video.mp4 diff --git a/src/components/common/README.md b/apps/web/src/components/common/README.md similarity index 100% rename from src/components/common/README.md rename to apps/web/src/components/common/README.md diff --git a/src/components/common/aspect-box.tsx b/apps/web/src/components/common/aspect-box.tsx similarity index 100% rename from src/components/common/aspect-box.tsx rename to apps/web/src/components/common/aspect-box.tsx diff --git a/src/components/common/box.tsx b/apps/web/src/components/common/box.tsx similarity index 100% rename from src/components/common/box.tsx rename to apps/web/src/components/common/box.tsx diff --git a/src/components/common/head.tsx b/apps/web/src/components/common/head.tsx similarity index 100% rename from src/components/common/head.tsx rename to apps/web/src/components/common/head.tsx diff --git a/src/components/common/native-scroll-container/index.tsx b/apps/web/src/components/common/native-scroll-container/index.tsx similarity index 100% rename from src/components/common/native-scroll-container/index.tsx rename to apps/web/src/components/common/native-scroll-container/index.tsx diff --git a/src/components/common/native-scroll-container/native-scroll-container.module.css b/apps/web/src/components/common/native-scroll-container/native-scroll-container.module.css similarity index 100% rename from src/components/common/native-scroll-container/native-scroll-container.module.css rename to apps/web/src/components/common/native-scroll-container/native-scroll-container.module.css diff --git a/src/components/common/section-heading.tsx b/apps/web/src/components/common/section-heading.tsx similarity index 100% rename from src/components/common/section-heading.tsx rename to apps/web/src/components/common/section-heading.tsx diff --git a/src/components/common/text.tsx b/apps/web/src/components/common/text.tsx similarity index 100% rename from src/components/common/text.tsx rename to apps/web/src/components/common/text.tsx diff --git a/src/components/layout/container.tsx b/apps/web/src/components/layout/container.tsx similarity index 100% rename from src/components/layout/container.tsx rename to apps/web/src/components/layout/container.tsx diff --git a/src/components/layout/footer/animation/index.tsx b/apps/web/src/components/layout/footer/animation/index.tsx similarity index 100% rename from src/components/layout/footer/animation/index.tsx rename to apps/web/src/components/layout/footer/animation/index.tsx diff --git a/src/components/layout/footer/animation/physics.js b/apps/web/src/components/layout/footer/animation/physics.js similarity index 100% rename from src/components/layout/footer/animation/physics.js rename to apps/web/src/components/layout/footer/animation/physics.js diff --git a/src/components/layout/footer/index.tsx b/apps/web/src/components/layout/footer/index.tsx similarity index 100% rename from src/components/layout/footer/index.tsx rename to apps/web/src/components/layout/footer/index.tsx diff --git a/src/components/layout/header/index.tsx b/apps/web/src/components/layout/header/index.tsx similarity index 100% rename from src/components/layout/header/index.tsx rename to apps/web/src/components/layout/header/index.tsx diff --git a/src/components/layout/header/mobile-menu/index.tsx b/apps/web/src/components/layout/header/mobile-menu/index.tsx similarity index 100% rename from src/components/layout/header/mobile-menu/index.tsx rename to apps/web/src/components/layout/header/mobile-menu/index.tsx diff --git a/src/components/layout/header/mobile-menu/mobile-menu.module.scss b/apps/web/src/components/layout/header/mobile-menu/mobile-menu.module.scss similarity index 100% rename from src/components/layout/header/mobile-menu/mobile-menu.module.scss rename to apps/web/src/components/layout/header/mobile-menu/mobile-menu.module.scss diff --git a/apps/web/src/components/layout/nft.tsx b/apps/web/src/components/layout/nft.tsx new file mode 100644 index 0000000..e22a0ef --- /dev/null +++ b/apps/web/src/components/layout/nft.tsx @@ -0,0 +1,165 @@ +import Box from 'components/common/box' +import Head, { HeadProps } from 'components/common/head' +import { NFTMarquee } from 'components/sections/nft/marquee' +import { toVw } from 'components/sections/posters' +import { range } from 'lib/utils' +import Footer from './footer' +import * as React from 'react' +import B from 'logos/b.svg' +import Link from 'components/primitives/link' +import { styled } from '../../../stitches.config' +import { R3fContextProvider } from 'lib/r3f/context' +import { R3fCanvas } from 'lib/r3f/canvas' +import { BsmnZipModel } from 'lib/r3f/components/bsmnt-zip-model' +import { R3fGroup } from 'lib/r3f/components/layout/group' + +type Props = { + children?: React.ReactNode + headProps?: HeadProps +} + +export const NFTLayout = ({ headProps, children }: Props) => { + return ( + + + + + + + + {range(0, 20).map( + () => `${new Date().getFullYear()} BASEMENT GROTESQUE NFT / ` + )} + + + +
+ + + + + About + + + The Grotesque + + + The Team + + +
+ + div': { + position: 'relative !important', + height: '100% !important', + borderRadius: '$$frameBorderRadius' + } + }} + /> + + + + + {/* JUST TESTING */} +
+ + + +
+
+ + + {children} + +