├── .eslintrc.json
├── public
├── favicon.ico
├── images
│ ├── bg_tile.png
│ └── logo_commsaur.png
└── fonts
│ ├── SF-Pro-Rounded-Black.otf
│ ├── SF-Pro-Rounded-Bold.otf
│ ├── SF-Pro-Rounded-Heavy.otf
│ ├── SF-Pro-Rounded-Light.otf
│ ├── SF-Pro-Rounded-Thin.otf
│ ├── SF-Pro-Rounded-Medium.otf
│ ├── SF-Pro-Rounded-Regular.otf
│ ├── SF-Pro-Rounded-Semibold.otf
│ └── SF-Pro-Rounded-Ultralight.otf
├── postcss.config.js
├── next-env.d.ts
├── next.config.js
├── abis
├── commsaur.ts
├── commsaur_pfp_abi.json
└── commsaur_abi.json
├── tailwind.config.js
├── pages
├── api
│ └── hello.ts
├── _document.tsx
├── _app.tsx
└── index.tsx
├── .gitignore
├── tsconfig.json
├── hooks
├── useCommsaurData.ts
└── useContractBigNumber.ts
├── package.json
├── components
├── icons
│ └── DownloadIcon.tsx
├── LoadingSpinner.tsx
├── CommsaurRow.tsx
├── ToolContainer.tsx
├── UnwrapButton.tsx
├── CommsaurProvider.tsx
├── WrapButton.tsx
└── CommsaurComponent.tsx
├── styles
└── globals.css
└── README.md
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "next/core-web-vitals"
3 | }
4 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/exception/commsaur-tooling/master/public/favicon.ico
--------------------------------------------------------------------------------
/public/images/bg_tile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/exception/commsaur-tooling/master/public/images/bg_tile.png
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/public/images/logo_commsaur.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/exception/commsaur-tooling/master/public/images/logo_commsaur.png
--------------------------------------------------------------------------------
/public/fonts/SF-Pro-Rounded-Black.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/exception/commsaur-tooling/master/public/fonts/SF-Pro-Rounded-Black.otf
--------------------------------------------------------------------------------
/public/fonts/SF-Pro-Rounded-Bold.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/exception/commsaur-tooling/master/public/fonts/SF-Pro-Rounded-Bold.otf
--------------------------------------------------------------------------------
/public/fonts/SF-Pro-Rounded-Heavy.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/exception/commsaur-tooling/master/public/fonts/SF-Pro-Rounded-Heavy.otf
--------------------------------------------------------------------------------
/public/fonts/SF-Pro-Rounded-Light.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/exception/commsaur-tooling/master/public/fonts/SF-Pro-Rounded-Light.otf
--------------------------------------------------------------------------------
/public/fonts/SF-Pro-Rounded-Thin.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/exception/commsaur-tooling/master/public/fonts/SF-Pro-Rounded-Thin.otf
--------------------------------------------------------------------------------
/public/fonts/SF-Pro-Rounded-Medium.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/exception/commsaur-tooling/master/public/fonts/SF-Pro-Rounded-Medium.otf
--------------------------------------------------------------------------------
/public/fonts/SF-Pro-Rounded-Regular.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/exception/commsaur-tooling/master/public/fonts/SF-Pro-Rounded-Regular.otf
--------------------------------------------------------------------------------
/public/fonts/SF-Pro-Rounded-Semibold.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/exception/commsaur-tooling/master/public/fonts/SF-Pro-Rounded-Semibold.otf
--------------------------------------------------------------------------------
/public/fonts/SF-Pro-Rounded-Ultralight.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/exception/commsaur-tooling/master/public/fonts/SF-Pro-Rounded-Ultralight.otf
--------------------------------------------------------------------------------
/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
4 | // NOTE: This file should not be edited
5 | // see https://nextjs.org/docs/basic-features/typescript for more information.
6 |
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | reactStrictMode: true,
4 | images: {
5 | domains: ['commsaur.mypinata.cloud', 'd124myd65w4vuo.cloudfront.net'],
6 | },
7 | };
8 |
9 | module.exports = nextConfig;
10 |
--------------------------------------------------------------------------------
/abis/commsaur.ts:
--------------------------------------------------------------------------------
1 | export const commsaurAddress: string = process.env.NODE_ENV === 'production' ? '0xbacb34bcf94442dba033e9cf7216888b8170f0ce' : '0x5FbDB2315678afecb367f032d93F642f64180aa3';
2 | export const pfpAddress: string = process.env.NODE_ENV === 'production' ? '0x664dc1247848F1AddD2065009eBF9974b3BE7a81' : '0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512';
--------------------------------------------------------------------------------
/tailwind.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | content: [
3 | './pages/**/*.{js,ts,jsx,tsx}',
4 | './components/**/*.{js,ts,jsx,tsx}',
5 | ],
6 | theme: {
7 | extend: {
8 | fontFamily: {
9 | 'sf-rounded': '"SFRounded"',
10 | },
11 | },
12 | },
13 | plugins: [],
14 | };
15 |
--------------------------------------------------------------------------------
/pages/api/hello.ts:
--------------------------------------------------------------------------------
1 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
2 | import type { NextApiRequest, NextApiResponse } from 'next'
3 |
4 | type Data = {
5 | name: string
6 | }
7 |
8 | export default function handler(
9 | req: NextApiRequest,
10 | res: NextApiResponse
11 | ) {
12 | res.status(200).json({ name: 'John Doe' })
13 | }
14 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 | .pnpm-debug.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
34 | # typescript
35 | *.tsbuildinfo
36 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "forceConsistentCasingInFileNames": true,
9 | "noEmit": true,
10 | "esModuleInterop": true,
11 | "module": "esnext",
12 | "moduleResolution": "node",
13 | "resolveJsonModule": true,
14 | "isolatedModules": true,
15 | "jsx": "preserve",
16 | "incremental": true
17 | },
18 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
19 | "exclude": ["node_modules"]
20 | }
21 |
--------------------------------------------------------------------------------
/hooks/useCommsaurData.ts:
--------------------------------------------------------------------------------
1 | import { Commsaur } from "../components/CommsaurProvider";
2 | const rarities: RarityData[] = require('../rarity.json');
3 |
4 | interface RarityData {
5 | id: number;
6 | rank: number;
7 | rarity_score: number;
8 | traits: Trait[];
9 | }
10 |
11 | type Trait = {
12 | trait_type: string;
13 | trait_value: string;
14 | percent: number;
15 | count: number;
16 | }
17 |
18 | function useCommsaurData(dino: Commsaur): RarityData {
19 | const rarity = rarities.filter(saur => saur.id == dino.id)[0];
20 | return rarity;
21 | }
22 |
23 | export default useCommsaurData;
--------------------------------------------------------------------------------
/pages/_document.tsx:
--------------------------------------------------------------------------------
1 | import Document, {
2 | Html,
3 | Main,
4 | NextScript,
5 | DocumentContext,
6 | Head,
7 | } from 'next/document';
8 |
9 | class MyDocument extends Document {
10 | static async getInitialProps(ctx: DocumentContext) {
11 | const initialProps = await Document.getInitialProps(ctx);
12 | return { ...initialProps };
13 | }
14 |
15 | render() {
16 | return (
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | );
25 | }
26 | }
27 |
28 | export default MyDocument;
29 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "commsaur-utility",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "@headlessui/react": "^1.6.1",
13 | "@rainbow-me/rainbowkit": "^0.1.0",
14 | "ethers": "^5.6.5",
15 | "next": "12.1.6",
16 | "react": "18.1.0",
17 | "react-dom": "18.1.0",
18 | "wagmi": "^0.3.5"
19 | },
20 | "devDependencies": {
21 | "@types/node": "17.0.31",
22 | "@types/react": "18.0.9",
23 | "@types/react-dom": "18.0.3",
24 | "autoprefixer": "^10.4.7",
25 | "eslint": "8.15.0",
26 | "eslint-config-next": "12.1.6",
27 | "postcss": "^8.4.13",
28 | "tailwindcss": "^3.0.24",
29 | "typescript": "4.6.4"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/components/icons/DownloadIcon.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | type Props = {
4 | onClick: () => void;
5 | };
6 |
7 | function DownloadIcon({ onClick }: Props) {
8 | return (
9 |
24 | );
25 | }
26 |
27 | export default React.memo(DownloadIcon);
28 |
--------------------------------------------------------------------------------
/components/LoadingSpinner.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | function LoadingSpinner() {
4 | return (
5 |
25 | );
26 | }
27 |
28 | export default React.memo(LoadingSpinner);
29 |
--------------------------------------------------------------------------------
/hooks/useContractBigNumber.ts:
--------------------------------------------------------------------------------
1 | import { ReadContractConfig } from "@wagmi/core";
2 | import { BigNumber, ContractInterface } from "ethers";
3 | import { useState } from "react";
4 | import { useContractRead } from "wagmi";
5 |
6 | type CallData = {
7 | address: string;
8 | abi: ContractInterface;
9 | }
10 |
11 | type ContractNumberRead = {
12 | value: number;
13 | isLoading: boolean;
14 | error: Error | null;
15 | refetch: () => void;
16 | }
17 |
18 | function useContractBigNumber({ address, abi }: CallData, methodName: string, args: ReadContractConfig, enabled: boolean): ContractNumberRead {
19 | const [out, setOut] = useState(-1);
20 | const { isLoading, error, refetch } = useContractRead(
21 | {
22 | addressOrName: address,
23 | contractInterface: abi,
24 | },
25 | methodName,
26 | {
27 | ...args,
28 | enabled,
29 | watch: true,
30 | onSuccess (data) {
31 | if ('_hex' in data) {
32 | const num = data as unknown as BigNumber;
33 | const id = num.toNumber();
34 |
35 | setOut(id)
36 | }
37 | }
38 | },
39 | );
40 |
41 | return { value: out, isLoading, error, refetch };
42 | }
43 |
44 | export default useContractBigNumber;
--------------------------------------------------------------------------------
/components/CommsaurRow.tsx:
--------------------------------------------------------------------------------
1 | import Image from 'next/image';
2 | import React from 'react';
3 | import useCommsaurData from '../hooks/useCommsaurData';
4 | import { Commsaur, getDinoImage } from './CommsaurProvider';
5 |
6 | type Props = {
7 | dino: Commsaur;
8 | choose: (dino: number) => void;
9 | selected: boolean;
10 | };
11 |
12 | function CommsaurRow({ dino, choose, selected }: Props) {
13 | const rarity = useCommsaurData(dino);
14 |
15 | return (
16 | choose(dino.id)}
18 | className={`flex flex-row space-x-2 px-2 py-2 mb-1 items-center cursor-pointer hover:scale-[.98] transition-all duration-100 ease-in-out ${
19 | selected && 'bg-slate-900/60'
20 | } rounded-xl`}
21 | >
22 |
29 |
30 |
31 | {`Commsaur #${dino.id}`}
32 |
33 |
34 | Rank #{rarity.rank} {dino.wrapped && ' (wrapped)'}
35 |
36 |
37 |
38 | );
39 | }
40 |
41 | export default CommsaurRow;
42 |
--------------------------------------------------------------------------------
/pages/_app.tsx:
--------------------------------------------------------------------------------
1 | import '../styles/globals.css';
2 | import type { AppProps } from 'next/app';
3 | import '@rainbow-me/rainbowkit/styles.css';
4 | import {
5 | apiProvider,
6 | configureChains,
7 | connectorsForWallets,
8 | darkTheme,
9 | getDefaultWallets,
10 | RainbowKitProvider,
11 | wallet,
12 | } from '@rainbow-me/rainbowkit';
13 | import { chain, createClient, WagmiProvider } from 'wagmi';
14 |
15 | const { chains, provider } = configureChains(
16 | [process.env.NODE_ENV === 'production' ? chain.mainnet : chain.hardhat],
17 | [
18 | apiProvider.alchemy('nzLJjKrtgPGbidugKn5S6G8o9RFnsxnv'),
19 | apiProvider.jsonRpc((chain) => ({
20 | rpcUrl: chain.rpcUrls.default,
21 | })),
22 | ],
23 | );
24 |
25 | const { wallets } = getDefaultWallets({
26 | appName: 'Commsaur',
27 | chains,
28 | });
29 |
30 | const connectors = connectorsForWallets([
31 | ...wallets,
32 | {
33 | groupName: 'More',
34 | wallets: [wallet.ledger({ chains }), wallet.argent({ chains })],
35 | },
36 | ]);
37 |
38 | const wagmiClient = createClient({
39 | autoConnect: true,
40 | connectors,
41 | provider,
42 | });
43 |
44 | function MyApp({ Component, pageProps }: AppProps) {
45 | return (
46 |
47 |
48 |
49 |
50 |
51 | );
52 | }
53 |
54 | export default MyApp;
55 |
--------------------------------------------------------------------------------
/styles/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | @layer base {
6 | @font-face {
7 | font-family: 'SFRounded';
8 | src: url('/fonts/SF-Pro-Rounded-Regular.otf') format("opentype");
9 | font-weight: 400;
10 | }
11 |
12 | @font-face {
13 | font-family: 'SFRounded';
14 | src: url('/fonts/SF-Pro-Rounded-Thin.otf') format("opentype");
15 | font-weight: 100;
16 | }
17 |
18 | @font-face {
19 | font-family: 'SFRounded';
20 | src: url('/fonts/SF-Pro-Rounded-Ultralight.otf') format("opentype");
21 | font-weight: 200;
22 | }
23 |
24 | @font-face {
25 | font-family: 'SFRounded';
26 | src: url('/fonts/SF-Pro-Rounded-Light.otf') format("opentype");
27 | font-weight: 300;
28 | }
29 |
30 | @font-face {
31 | font-family: 'SFRounded';
32 | src: url('/fonts/SF-Pro-Rounded-Medium.otf') format("opentype");
33 | font-weight: 500;
34 | }
35 |
36 | @font-face {
37 | font-family: 'SFRounded';
38 | src: url('/fonts/SF-Pro-Rounded-Semibold.otf') format("opentype");
39 | font-weight: 600;
40 | }
41 |
42 | @font-face {
43 | font-family: 'SFRounded';
44 | src: url('/fonts/SF-Pro-Rounded-Bold.otf') format("opentype");
45 | font-weight: 700;
46 | }
47 |
48 | @font-face {
49 | font-family: 'SFRounded';
50 | src: url('/fonts/SF-Pro-Rounded-Heavy.otf') format("opentype");
51 | font-weight: 800;
52 | }
53 |
54 | @font-face {
55 | font-family: 'SFRounded';
56 | src: url('/fonts/SF-Pro-Rounded-Black.otf') format("opentype");
57 | font-weight: 900;
58 | }
59 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
2 |
3 | ## Getting Started
4 |
5 | First, run the development server:
6 |
7 | ```bash
8 | npm run dev
9 | # or
10 | yarn dev
11 | ```
12 |
13 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
14 |
15 | You can start editing the page by modifying `pages/index.tsx`. The page auto-updates as you edit the file.
16 |
17 | [API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`.
18 |
19 | The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
20 |
21 | ## Learn More
22 |
23 | To learn more about Next.js, take a look at the following resources:
24 |
25 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
26 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
27 |
28 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
29 |
30 | ## Deploy on Vercel
31 |
32 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
33 |
34 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
35 |
--------------------------------------------------------------------------------
/components/ToolContainer.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from 'react';
2 | import { useAccount } from 'wagmi';
3 | import CommsaurComponent from './CommsaurComponent';
4 | import { useCommsaurContext } from './CommsaurProvider';
5 | import CommsaurRow from './CommsaurRow';
6 |
7 | function ToolContainer() {
8 | const { data: account } = useAccount();
9 | const { originalSize: commsaurAmount, herd, reset } = useCommsaurContext();
10 | useEffect(() => {
11 | if (!account && herd.length > 0) {
12 | reset();
13 | }
14 | }, [account, herd, reset]);
15 | useEffect(() => {
16 | console.log(herd);
17 | }, [herd]);
18 | const [commsaur, setCommsaur] = useState(-1);
19 |
20 | return (
21 |
22 |
23 |
24 | Your Commsaurs{' '}
25 | ({commsaurAmount})
26 |
27 | {herd.length != commsaurAmount && (
28 |
29 | Herding {herd.length}/{commsaurAmount}...
30 |
31 | )}
32 |
33 | {herd.map((dino) => (
34 |
40 | ))}
41 |
42 |
43 |
44 | {commsaur == -1 && (
45 |
46 |
47 | Select one of your Commsaurs to access it's
48 | tools!
49 |
50 |
51 | )}
52 | {commsaur >= 0 && (
53 |
54 | saur.id == commsaur)!}
56 | />
57 |
58 | )}
59 |
60 |
61 | );
62 | }
63 |
64 | export default ToolContainer;
65 |
--------------------------------------------------------------------------------
/pages/index.tsx:
--------------------------------------------------------------------------------
1 | import { ConnectButton } from '@rainbow-me/rainbowkit';
2 | import type { NextPage } from 'next';
3 | import Head from 'next/head';
4 | import { useAccount } from 'wagmi';
5 | import { useEffect, useState } from 'react';
6 | import CommsaurProvider from '../components/CommsaurProvider';
7 | import ToolContainer from '../components/ToolContainer';
8 |
9 | const Home: NextPage = () => {
10 | const { data: account } = useAccount();
11 | const [hasAccount, setHasAccount] = useState(false);
12 | useEffect(() => {
13 | setHasAccount(!!account);
14 | }, [account]);
15 |
16 | return (
17 | <>
18 |
19 | Commsaur Tools
20 |
21 |
22 | {!hasAccount && (
23 |
24 |
25 | Commsaur Tools
26 |
27 |
28 | Connect your wallet to access the Commsaur tools,
29 | wrap your Commsaur into it's PFP version,
30 | download high-res JPEGs, and more!
31 |
32 |
33 |
34 | {({
35 | mounted,
36 | account,
37 | chain,
38 | openConnectModal,
39 | openChainModal,
40 | openAccountModal,
41 | }) => {
42 | if (!mounted || !account || !chain) {
43 | return (
44 |
52 | );
53 | }
54 |
55 | if (chain.unsupported) {
56 | return (
57 |
65 | );
66 | }
67 |
68 | return (
69 |
77 | );
78 | }}
79 |
80 |
81 | )}
82 | {hasAccount && (
83 |
84 |
85 |
86 | )}
87 |
88 | >
89 | );
90 | };
91 |
92 | export default Home;
93 |
--------------------------------------------------------------------------------
/components/UnwrapButton.tsx:
--------------------------------------------------------------------------------
1 | import React, { useCallback, useState } from 'react';
2 | import {
3 | useAccount,
4 | useContractRead,
5 | useContractWrite,
6 | useWaitForTransaction,
7 | } from 'wagmi';
8 | import { pfpAddress } from '../abis/commsaur';
9 | import { Commsaur, useCommsaurContext } from './CommsaurProvider';
10 | import pfpAbi from '../abis/commsaur_pfp_abi.json';
11 | import { useAddRecentTransaction } from '@rainbow-me/rainbowkit';
12 | import LoadingSpinner from './LoadingSpinner';
13 |
14 | type Props = {
15 | dino: Commsaur;
16 | setError: (error: string) => void;
17 | };
18 |
19 | function UnwrapButton({ dino, setError }: Props) {
20 | const { data: account } = useAccount();
21 | const [isApproved, setIsApproved] = useState(false);
22 | const addRecent = useAddRecentTransaction();
23 | const [transactionHash, setTransactionHash] = useState();
24 | const [wasUnwrapped, setWasUnwrapped] = useState(false);
25 | const [approveHash, setApproveHash] = useState();
26 | const { toggleWrapped } = useCommsaurContext();
27 |
28 | const { isLoading: useTransactionSending } = useWaitForTransaction({
29 | hash: transactionHash,
30 | enabled: !!transactionHash,
31 | onSuccess() {
32 | toggleWrapped(dino.id, false);
33 | setWasUnwrapped(true);
34 | },
35 | });
36 |
37 | const { isLoading: isApproving } = useWaitForTransaction({
38 | hash: approveHash,
39 | enabled: !!approveHash,
40 | onSuccess() {
41 | setIsApproved(true);
42 | },
43 | });
44 |
45 | const { isLoading: isApprovedLoading } = useContractRead(
46 | {
47 | addressOrName: pfpAddress,
48 | contractInterface: pfpAbi,
49 | },
50 | 'isApprovedForAll',
51 | {
52 | args: [account?.address, pfpAddress],
53 | enabled: !!account,
54 | onSuccess(data) {
55 | if (typeof data === 'boolean') {
56 | setIsApproved(data);
57 | }
58 | },
59 | onError(error) {
60 | setError(error.message);
61 | },
62 | },
63 | );
64 |
65 | const { isLoading: approvedWriting, write: approveContract } =
66 | useContractWrite(
67 | {
68 | addressOrName: pfpAddress,
69 | contractInterface: pfpAbi,
70 | },
71 | 'setApprovalForAll',
72 | {
73 | args: [pfpAddress, true],
74 | onSuccess(tx) {
75 | addRecent({
76 | hash: tx.hash,
77 | description: 'Approve Wrapped Commsaurs contract',
78 | });
79 |
80 | setApproveHash(tx.hash);
81 | },
82 | onError(error) {
83 | setError(error.message);
84 | },
85 | },
86 | );
87 |
88 | const { isLoading: unwrapping, write: unwrap } = useContractWrite(
89 | {
90 | addressOrName: pfpAddress,
91 | contractInterface: pfpAbi,
92 | },
93 | 'safeTransferFrom(address,address,uint256)',
94 | {
95 | args: [account?.address, pfpAddress, dino.id],
96 | onSuccess(tx) {
97 | addRecent({
98 | hash: tx.hash,
99 | description: `Wrap Commsaur ${dino.id}`,
100 | });
101 |
102 | setTransactionHash(tx.hash);
103 | },
104 | onError(error) {
105 | setError(error.message);
106 | },
107 | },
108 | );
109 |
110 | const doClick = useCallback(() => {
111 | if (!isApproved && !approvedWriting) {
112 | approveContract();
113 | }
114 |
115 | if (!useTransactionSending && isApproved) {
116 | unwrap();
117 | }
118 | }, [
119 | isApproved,
120 | approvedWriting,
121 | approveContract,
122 | useTransactionSending,
123 | unwrap,
124 | ]);
125 |
126 | return (
127 |
152 | );
153 | }
154 |
155 | export default UnwrapButton;
156 |
--------------------------------------------------------------------------------
/components/CommsaurProvider.tsx:
--------------------------------------------------------------------------------
1 | import { BigNumber } from 'ethers';
2 | import React, { ReactNode, useCallback, useContext, useState } from 'react';
3 | import { useAccount, useContractRead } from 'wagmi';
4 | import { commsaurAddress, pfpAddress } from '../abis/commsaur';
5 | import abi from '../abis/commsaur_abi.json';
6 | import pfpAbi from '../abis/commsaur_pfp_abi.json';
7 |
8 | export type Commsaur = {
9 | id: number;
10 | wrapped?: boolean;
11 | };
12 |
13 | type CommsaurContext = {
14 | herd: Commsaur[];
15 | originalSize: number;
16 | reset: () => void;
17 | error: Error | null;
18 | toggleWrapped: (id: number, state: boolean) => void;
19 | };
20 |
21 | export const getDinoImage = (saur: Commsaur): string => {
22 | if (saur.wrapped) {
23 | return `https://d124myd65w4vuo.cloudfront.net/pfps/${saur.id}.png`;
24 | }
25 |
26 | return `https://d124myd65w4vuo.cloudfront.net/fullBody/${saur.id}.jpeg`;
27 | };
28 |
29 | const CommsaurCtx = React.createContext(null);
30 |
31 | type Props = {
32 | children: ReactNode;
33 | };
34 |
35 | function CommsaurProvider({ children }: Props) {
36 | const { data: account } = useAccount();
37 | const [wrappedAmount, setWrappedAmount] = useState(0);
38 | const [saurAmount, setSaurAmount] = useState(0);
39 | const [error, setError] = useState(null);
40 | const [idx, setIdx] = useState(0);
41 | const [pfpIdx, setPfpIdx] = useState(0);
42 | const [herd, setHerd] = useState([]);
43 |
44 | useContractRead(
45 | {
46 | addressOrName: commsaurAddress,
47 | contractInterface: abi,
48 | },
49 | 'balanceOf',
50 | {
51 | args: account?.address,
52 | enabled: !!account,
53 | onSuccess(data) {
54 | const bId = data as unknown as BigNumber;
55 | const id = bId.toNumber();
56 | setSaurAmount(id);
57 | },
58 | onError(error) {
59 | setError(error);
60 | },
61 | },
62 | );
63 |
64 | useContractRead(
65 | {
66 | addressOrName: pfpAddress,
67 | contractInterface: pfpAbi,
68 | },
69 | 'balanceOf',
70 | {
71 | args: account?.address,
72 | enabled: !!account,
73 | onSuccess(data) {
74 | const bId = data as unknown as BigNumber;
75 | const id = bId.toNumber();
76 | setWrappedAmount(id);
77 | },
78 | onError(error) {
79 | setError(error);
80 | },
81 | },
82 | );
83 |
84 | const { refetch: refetchWrapped } = useContractRead(
85 | {
86 | addressOrName: pfpAddress,
87 | contractInterface: pfpAbi,
88 | },
89 | 'tokenOfOwnerByIndex',
90 | {
91 | args: [account?.address, pfpIdx],
92 | enabled: !!account && wrappedAmount > 0 && pfpIdx < wrappedAmount,
93 | onSuccess(data) {
94 | const bId = data as unknown as BigNumber;
95 | const id = bId.toNumber();
96 | setHerd((old) => [
97 | ...old,
98 | {
99 | id,
100 | wrapped: true,
101 | },
102 | ]);
103 | setPfpIdx((old) => old + 1);
104 | },
105 | onError(error) {
106 | setError(error);
107 | },
108 | },
109 | );
110 |
111 | const { refetch } = useContractRead(
112 | {
113 | addressOrName: commsaurAddress,
114 | contractInterface: abi,
115 | },
116 | 'tokenOfOwnerByIndex',
117 | {
118 | args: [account?.address, idx],
119 | enabled: !!account && saurAmount > 0 && idx < saurAmount,
120 | onSuccess(data) {
121 | const bId = data as unknown as BigNumber;
122 | const id = bId.toNumber();
123 | setHerd((old) => [
124 | ...old,
125 | {
126 | id: id,
127 | wrapped: false,
128 | },
129 | ]);
130 | setIdx((old) => old + 1);
131 | },
132 | onError(error) {
133 | setError(error);
134 | },
135 | },
136 | );
137 |
138 | const toggleWrapped = useCallback(
139 | (id: number, state: boolean) => {
140 | const idx = herd.findIndex((dino) => dino.id === id);
141 | const updated = { ...herd[idx], wrapped: state };
142 | const youngHerd = [
143 | ...herd.slice(0, idx),
144 | updated,
145 | ...herd.slice(idx + 1),
146 | ];
147 | setHerd(youngHerd);
148 | },
149 | [herd],
150 | );
151 |
152 | const reset = useCallback(() => {
153 | setError(null);
154 | refetch();
155 | refetchWrapped();
156 | setIdx(0);
157 | setPfpIdx(0);
158 | setHerd([]);
159 | }, [refetch, refetchWrapped]);
160 |
161 | const ctx: CommsaurContext = {
162 | herd: herd.sort((a, b) => a.id - b.id),
163 | originalSize: saurAmount + wrappedAmount,
164 | reset,
165 | error,
166 | toggleWrapped,
167 | };
168 |
169 | return {children};
170 | }
171 |
172 | export function useCommsaurContext() {
173 | const ctx = useContext(CommsaurCtx);
174 | if (ctx == null) {
175 | throw new Error(
176 | 'useCommsaurContext must be called within a CommsaurProvider',
177 | );
178 | }
179 |
180 | return ctx;
181 | }
182 |
183 | export default CommsaurProvider;
184 |
--------------------------------------------------------------------------------
/components/WrapButton.tsx:
--------------------------------------------------------------------------------
1 | import { useAddRecentTransaction } from '@rainbow-me/rainbowkit';
2 | import React, { useCallback, useState } from 'react';
3 | import {
4 | useAccount,
5 | useContractRead,
6 | useContractWrite,
7 | useWaitForTransaction,
8 | } from 'wagmi';
9 | import { commsaurAddress, pfpAddress } from '../abis/commsaur';
10 | import { Commsaur, useCommsaurContext } from './CommsaurProvider';
11 | import LoadingSpinner from './LoadingSpinner';
12 | import abi from '../abis/commsaur_abi.json';
13 | import pfpAbi from '../abis/commsaur_pfp_abi.json';
14 |
15 | type Props = {
16 | dino: Commsaur;
17 | acknowledged: boolean;
18 | setShowWarning: (shown: boolean) => void;
19 | setError: (error: string) => void;
20 | };
21 |
22 | function WrapButton({ acknowledged, dino, setShowWarning, setError }: Props) {
23 | const { data: account } = useAccount();
24 | const [isApproved, setIsApproved] = useState(false);
25 | const addRecent = useAddRecentTransaction();
26 | const [transactionHash, setTransactionHash] = useState();
27 | const [wasWrapped, setWasWrapped] = useState(false);
28 | const { toggleWrapped } = useCommsaurContext();
29 | const [approveHash, setApproveHash] = useState();
30 |
31 | const { isLoading: useTransactionSending } = useWaitForTransaction({
32 | hash: transactionHash,
33 | enabled: !!transactionHash,
34 | onSuccess() {
35 | setWasWrapped(true);
36 | toggleWrapped(dino.id, true);
37 | },
38 | });
39 |
40 | const { isLoading: isApproving } = useWaitForTransaction({
41 | hash: approveHash,
42 | enabled: !!approveHash,
43 | onSuccess() {
44 | setIsApproved(true);
45 | },
46 | });
47 |
48 | const { isLoading: isApprovedLoading } = useContractRead(
49 | {
50 | addressOrName: commsaurAddress,
51 | contractInterface: abi,
52 | },
53 | 'isApprovedForAll',
54 | {
55 | args: [account?.address, commsaurAddress],
56 | enabled: acknowledged,
57 | onSuccess(data) {
58 | if (typeof data === 'boolean') {
59 | setIsApproved(data);
60 | }
61 | },
62 | onError(error) {
63 | setError(error.message);
64 | },
65 | },
66 | );
67 |
68 | const { isLoading: approveWriting, write } = useContractWrite(
69 | {
70 | addressOrName: commsaurAddress,
71 | contractInterface: abi,
72 | },
73 | 'setApprovalForAll',
74 | {
75 | args: [commsaurAddress, true],
76 | onSuccess(tx) {
77 | addRecent({
78 | hash: tx.hash,
79 | description: 'Approve Wrapped Commsaurs contract',
80 | });
81 |
82 | setApproveHash(tx.hash);
83 | },
84 | onError(error) {
85 | setError(error.message);
86 | },
87 | },
88 | );
89 |
90 | const { isLoading: wrapLoading, write: wrapDinoCall } = useContractWrite(
91 | {
92 | addressOrName: commsaurAddress,
93 | contractInterface: pfpAbi,
94 | },
95 | 'safeTransferFrom(address,address,uint256)',
96 | {
97 | args: [account?.address, pfpAddress, dino.id],
98 | onSuccess(tx) {
99 | console.log('added', tx);
100 | addRecent({
101 | hash: tx.hash,
102 | description: `Wrap Commsaur ${dino.id}`,
103 | });
104 |
105 | setTransactionHash(tx.hash);
106 | },
107 | onError(error) {
108 | setError(error.message);
109 | },
110 | },
111 | );
112 |
113 | const doClick = useCallback(() => {
114 | if (!acknowledged) {
115 | setShowWarning(true);
116 | return;
117 | }
118 |
119 | setError('');
120 |
121 | if (!isApproved && !isApprovedLoading) {
122 | write();
123 | } else if (isApproved && !wrapLoading) {
124 | wrapDinoCall();
125 | }
126 | }, [
127 | acknowledged,
128 | isApproved,
129 | isApprovedLoading,
130 | write,
131 | wrapLoading,
132 | wrapDinoCall,
133 | setShowWarning,
134 | setError,
135 | ]);
136 |
137 | return (
138 |
177 | );
178 | }
179 |
180 | export default WrapButton;
181 |
--------------------------------------------------------------------------------
/components/CommsaurComponent.tsx:
--------------------------------------------------------------------------------
1 | /* eslint-disable @next/next/no-img-element */
2 | import { Dialog, Transition } from '@headlessui/react';
3 | import Link from 'next/link';
4 | import React, { Fragment, useCallback, useEffect, useState } from 'react';
5 | import { commsaurAddress, pfpAddress } from '../abis/commsaur';
6 | import useCommsaurData from '../hooks/useCommsaurData';
7 | import { Commsaur, getDinoImage } from './CommsaurProvider';
8 | import DownloadIcon from './icons/DownloadIcon';
9 | import UnwrapButton from './UnwrapButton';
10 | import WrapButton from './WrapButton';
11 |
12 | type Props = {
13 | dino: Commsaur;
14 | };
15 |
16 | function CommsaurComponent({ dino }: Props) {
17 | const rarity = useCommsaurData(dino);
18 | const [showWarning, setShowWarning] = useState(false);
19 | const [acknowledged, setAcknowledged] = useState(false);
20 | const [error, setError] = useState('');
21 |
22 | useEffect(() => {
23 | setShowWarning(false);
24 | setError('');
25 | setAcknowledged(false);
26 | }, [dino]);
27 |
28 | const download = useCallback(() => {
29 | window.open(
30 | dino.wrapped
31 | ? `https://d124myd65w4vuo.cloudfront.net/pfps/${dino.id}.png`
32 | : `https://d124myd65w4vuo.cloudfront.net/fullRes/${dino.id}.png`,
33 | '_blank',
34 | );
35 | }, [dino]);
36 |
37 | return (
38 | <>
39 |
40 |
41 | {dino.wrapped && 'Wrapped '}Commsaur #{dino.id}
42 |
43 |
44 |
45 |
46 |
47 |
})
52 | {error && (
53 |
54 | {error}
55 |
56 | )}
57 | {!dino.wrapped && (
58 |
64 | )}
65 | {dino.wrapped && (
66 |
67 | )}
68 |
98 |
99 |
100 | {rarity.traits.map((trait) => {
101 | if (trait.trait_value === 'None') return;
102 | return (
103 |
107 |
108 | {trait.trait_type} / {trait.trait_value}
109 |
110 | {' '}
111 | ({trait.percent}%)
112 |
113 |
114 |
120 |
121 | );
122 | })}
123 |
124 | This Commsaur is ranked #{rarity.rank} with a rarity
125 | score of {rarity.rarity_score}. Data provided by
126 | RaritySniper.
127 |
128 |
129 |
130 |
131 |
187 |
188 | >
189 | );
190 | }
191 |
192 | export default CommsaurComponent;
193 |
--------------------------------------------------------------------------------
/abis/commsaur_pfp_abi.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "inputs": [
4 | {
5 | "internalType": "address",
6 | "name": "_commsaurAddress",
7 | "type": "address"
8 | }
9 | ],
10 | "stateMutability": "nonpayable",
11 | "type": "constructor"
12 | },
13 | {
14 | "anonymous": false,
15 | "inputs": [
16 | {
17 | "indexed": true,
18 | "internalType": "address",
19 | "name": "owner",
20 | "type": "address"
21 | },
22 | {
23 | "indexed": true,
24 | "internalType": "address",
25 | "name": "approved",
26 | "type": "address"
27 | },
28 | {
29 | "indexed": true,
30 | "internalType": "uint256",
31 | "name": "tokenId",
32 | "type": "uint256"
33 | }
34 | ],
35 | "name": "Approval",
36 | "type": "event"
37 | },
38 | {
39 | "anonymous": false,
40 | "inputs": [
41 | {
42 | "indexed": true,
43 | "internalType": "address",
44 | "name": "owner",
45 | "type": "address"
46 | },
47 | {
48 | "indexed": true,
49 | "internalType": "address",
50 | "name": "operator",
51 | "type": "address"
52 | },
53 | {
54 | "indexed": false,
55 | "internalType": "bool",
56 | "name": "approved",
57 | "type": "bool"
58 | }
59 | ],
60 | "name": "ApprovalForAll",
61 | "type": "event"
62 | },
63 | {
64 | "anonymous": false,
65 | "inputs": [
66 | {
67 | "indexed": true,
68 | "internalType": "address",
69 | "name": "previousOwner",
70 | "type": "address"
71 | },
72 | {
73 | "indexed": true,
74 | "internalType": "address",
75 | "name": "newOwner",
76 | "type": "address"
77 | }
78 | ],
79 | "name": "OwnershipTransferred",
80 | "type": "event"
81 | },
82 | {
83 | "anonymous": false,
84 | "inputs": [
85 | {
86 | "indexed": true,
87 | "internalType": "address",
88 | "name": "from",
89 | "type": "address"
90 | },
91 | {
92 | "indexed": true,
93 | "internalType": "address",
94 | "name": "to",
95 | "type": "address"
96 | },
97 | {
98 | "indexed": true,
99 | "internalType": "uint256",
100 | "name": "tokenId",
101 | "type": "uint256"
102 | }
103 | ],
104 | "name": "Transfer",
105 | "type": "event"
106 | },
107 | {
108 | "inputs": [
109 | {
110 | "internalType": "address",
111 | "name": "to",
112 | "type": "address"
113 | },
114 | {
115 | "internalType": "uint256",
116 | "name": "tokenId",
117 | "type": "uint256"
118 | }
119 | ],
120 | "name": "approve",
121 | "outputs": [],
122 | "stateMutability": "nonpayable",
123 | "type": "function"
124 | },
125 | {
126 | "inputs": [
127 | {
128 | "internalType": "address",
129 | "name": "owner",
130 | "type": "address"
131 | }
132 | ],
133 | "name": "balanceOf",
134 | "outputs": [
135 | {
136 | "internalType": "uint256",
137 | "name": "",
138 | "type": "uint256"
139 | }
140 | ],
141 | "stateMutability": "view",
142 | "type": "function"
143 | },
144 | {
145 | "inputs": [],
146 | "name": "commsaurContract",
147 | "outputs": [
148 | {
149 | "internalType": "contract IERC721",
150 | "name": "",
151 | "type": "address"
152 | }
153 | ],
154 | "stateMutability": "view",
155 | "type": "function"
156 | },
157 | {
158 | "inputs": [
159 | {
160 | "internalType": "uint256",
161 | "name": "tokenId",
162 | "type": "uint256"
163 | }
164 | ],
165 | "name": "getApproved",
166 | "outputs": [
167 | {
168 | "internalType": "address",
169 | "name": "",
170 | "type": "address"
171 | }
172 | ],
173 | "stateMutability": "view",
174 | "type": "function"
175 | },
176 | {
177 | "inputs": [
178 | {
179 | "internalType": "address",
180 | "name": "owner",
181 | "type": "address"
182 | },
183 | {
184 | "internalType": "address",
185 | "name": "operator",
186 | "type": "address"
187 | }
188 | ],
189 | "name": "isApprovedForAll",
190 | "outputs": [
191 | {
192 | "internalType": "bool",
193 | "name": "",
194 | "type": "bool"
195 | }
196 | ],
197 | "stateMutability": "view",
198 | "type": "function"
199 | },
200 | {
201 | "inputs": [],
202 | "name": "name",
203 | "outputs": [
204 | {
205 | "internalType": "string",
206 | "name": "",
207 | "type": "string"
208 | }
209 | ],
210 | "stateMutability": "view",
211 | "type": "function"
212 | },
213 | {
214 | "inputs": [
215 | {
216 | "internalType": "address",
217 | "name": "",
218 | "type": "address"
219 | },
220 | {
221 | "internalType": "address",
222 | "name": "from",
223 | "type": "address"
224 | },
225 | {
226 | "internalType": "uint256",
227 | "name": "tokenId",
228 | "type": "uint256"
229 | },
230 | {
231 | "internalType": "bytes",
232 | "name": "",
233 | "type": "bytes"
234 | }
235 | ],
236 | "name": "onERC721Received",
237 | "outputs": [
238 | {
239 | "internalType": "bytes4",
240 | "name": "",
241 | "type": "bytes4"
242 | }
243 | ],
244 | "stateMutability": "nonpayable",
245 | "type": "function"
246 | },
247 | {
248 | "inputs": [],
249 | "name": "owner",
250 | "outputs": [
251 | {
252 | "internalType": "address",
253 | "name": "",
254 | "type": "address"
255 | }
256 | ],
257 | "stateMutability": "view",
258 | "type": "function"
259 | },
260 | {
261 | "inputs": [
262 | {
263 | "internalType": "uint256",
264 | "name": "tokenId",
265 | "type": "uint256"
266 | }
267 | ],
268 | "name": "ownerOf",
269 | "outputs": [
270 | {
271 | "internalType": "address",
272 | "name": "",
273 | "type": "address"
274 | }
275 | ],
276 | "stateMutability": "view",
277 | "type": "function"
278 | },
279 | {
280 | "inputs": [],
281 | "name": "renounceOwnership",
282 | "outputs": [],
283 | "stateMutability": "nonpayable",
284 | "type": "function"
285 | },
286 | {
287 | "inputs": [
288 | {
289 | "internalType": "address",
290 | "name": "to",
291 | "type": "address"
292 | },
293 | {
294 | "internalType": "uint256",
295 | "name": "tokenId",
296 | "type": "uint256"
297 | }
298 | ],
299 | "name": "rescue",
300 | "outputs": [],
301 | "stateMutability": "nonpayable",
302 | "type": "function"
303 | },
304 | {
305 | "inputs": [
306 | {
307 | "internalType": "address",
308 | "name": "from",
309 | "type": "address"
310 | },
311 | {
312 | "internalType": "address",
313 | "name": "to",
314 | "type": "address"
315 | },
316 | {
317 | "internalType": "uint256",
318 | "name": "tokenId",
319 | "type": "uint256"
320 | }
321 | ],
322 | "name": "safeTransferFrom",
323 | "outputs": [],
324 | "stateMutability": "nonpayable",
325 | "type": "function"
326 | },
327 | {
328 | "inputs": [
329 | {
330 | "internalType": "address",
331 | "name": "from",
332 | "type": "address"
333 | },
334 | {
335 | "internalType": "address",
336 | "name": "to",
337 | "type": "address"
338 | },
339 | {
340 | "internalType": "uint256",
341 | "name": "tokenId",
342 | "type": "uint256"
343 | },
344 | {
345 | "internalType": "bytes",
346 | "name": "_data",
347 | "type": "bytes"
348 | }
349 | ],
350 | "name": "safeTransferFrom",
351 | "outputs": [],
352 | "stateMutability": "nonpayable",
353 | "type": "function"
354 | },
355 | {
356 | "inputs": [
357 | {
358 | "internalType": "address",
359 | "name": "operator",
360 | "type": "address"
361 | },
362 | {
363 | "internalType": "bool",
364 | "name": "approved",
365 | "type": "bool"
366 | }
367 | ],
368 | "name": "setApprovalForAll",
369 | "outputs": [],
370 | "stateMutability": "nonpayable",
371 | "type": "function"
372 | },
373 | {
374 | "inputs": [
375 | {
376 | "internalType": "string",
377 | "name": "uri",
378 | "type": "string"
379 | }
380 | ],
381 | "name": "setBaseURI",
382 | "outputs": [],
383 | "stateMutability": "nonpayable",
384 | "type": "function"
385 | },
386 | {
387 | "inputs": [
388 | {
389 | "internalType": "bool",
390 | "name": "_enabled",
391 | "type": "bool"
392 | }
393 | ],
394 | "name": "setUnwrappingEnabled",
395 | "outputs": [],
396 | "stateMutability": "nonpayable",
397 | "type": "function"
398 | },
399 | {
400 | "inputs": [
401 | {
402 | "internalType": "bool",
403 | "name": "_enabled",
404 | "type": "bool"
405 | }
406 | ],
407 | "name": "setWrappingEnabled",
408 | "outputs": [],
409 | "stateMutability": "nonpayable",
410 | "type": "function"
411 | },
412 | {
413 | "inputs": [
414 | {
415 | "internalType": "bytes4",
416 | "name": "interfaceId",
417 | "type": "bytes4"
418 | }
419 | ],
420 | "name": "supportsInterface",
421 | "outputs": [
422 | {
423 | "internalType": "bool",
424 | "name": "",
425 | "type": "bool"
426 | }
427 | ],
428 | "stateMutability": "view",
429 | "type": "function"
430 | },
431 | {
432 | "inputs": [],
433 | "name": "symbol",
434 | "outputs": [
435 | {
436 | "internalType": "string",
437 | "name": "",
438 | "type": "string"
439 | }
440 | ],
441 | "stateMutability": "view",
442 | "type": "function"
443 | },
444 | {
445 | "inputs": [
446 | {
447 | "internalType": "uint256",
448 | "name": "index",
449 | "type": "uint256"
450 | }
451 | ],
452 | "name": "tokenByIndex",
453 | "outputs": [
454 | {
455 | "internalType": "uint256",
456 | "name": "",
457 | "type": "uint256"
458 | }
459 | ],
460 | "stateMutability": "view",
461 | "type": "function"
462 | },
463 | {
464 | "inputs": [
465 | {
466 | "internalType": "address",
467 | "name": "owner",
468 | "type": "address"
469 | },
470 | {
471 | "internalType": "uint256",
472 | "name": "index",
473 | "type": "uint256"
474 | }
475 | ],
476 | "name": "tokenOfOwnerByIndex",
477 | "outputs": [
478 | {
479 | "internalType": "uint256",
480 | "name": "",
481 | "type": "uint256"
482 | }
483 | ],
484 | "stateMutability": "view",
485 | "type": "function"
486 | },
487 | {
488 | "inputs": [
489 | {
490 | "internalType": "uint256",
491 | "name": "tokenId",
492 | "type": "uint256"
493 | }
494 | ],
495 | "name": "tokenURI",
496 | "outputs": [
497 | {
498 | "internalType": "string",
499 | "name": "",
500 | "type": "string"
501 | }
502 | ],
503 | "stateMutability": "view",
504 | "type": "function"
505 | },
506 | {
507 | "inputs": [],
508 | "name": "totalSupply",
509 | "outputs": [
510 | {
511 | "internalType": "uint256",
512 | "name": "",
513 | "type": "uint256"
514 | }
515 | ],
516 | "stateMutability": "view",
517 | "type": "function"
518 | },
519 | {
520 | "inputs": [
521 | {
522 | "internalType": "address",
523 | "name": "from",
524 | "type": "address"
525 | },
526 | {
527 | "internalType": "address",
528 | "name": "to",
529 | "type": "address"
530 | },
531 | {
532 | "internalType": "uint256",
533 | "name": "tokenId",
534 | "type": "uint256"
535 | }
536 | ],
537 | "name": "transferFrom",
538 | "outputs": [],
539 | "stateMutability": "nonpayable",
540 | "type": "function"
541 | },
542 | {
543 | "inputs": [
544 | {
545 | "internalType": "address",
546 | "name": "newOwner",
547 | "type": "address"
548 | }
549 | ],
550 | "name": "transferOwnership",
551 | "outputs": [],
552 | "stateMutability": "nonpayable",
553 | "type": "function"
554 | },
555 | {
556 | "inputs": [
557 | {
558 | "internalType": "uint256[]",
559 | "name": "tokenIds",
560 | "type": "uint256[]"
561 | }
562 | ],
563 | "name": "unwrapHerd",
564 | "outputs": [],
565 | "stateMutability": "nonpayable",
566 | "type": "function"
567 | },
568 | {
569 | "inputs": [
570 | {
571 | "internalType": "uint256[]",
572 | "name": "tokenIds",
573 | "type": "uint256[]"
574 | }
575 | ],
576 | "name": "wrapHerd",
577 | "outputs": [],
578 | "stateMutability": "nonpayable",
579 | "type": "function"
580 | },
581 | {
582 | "inputs": [],
583 | "name": "wrappingState",
584 | "outputs": [
585 | {
586 | "internalType": "bool",
587 | "name": "wrappingEnabled",
588 | "type": "bool"
589 | },
590 | {
591 | "internalType": "bool",
592 | "name": "unwrappingEnabled",
593 | "type": "bool"
594 | }
595 | ],
596 | "stateMutability": "view",
597 | "type": "function"
598 | }
599 | ]
--------------------------------------------------------------------------------
/abis/commsaur_abi.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "inputs": [],
4 | "stateMutability": "nonpayable",
5 | "type": "constructor"
6 | },
7 | {
8 | "inputs": [],
9 | "name": "ApprovalCallerNotOwnerNorApproved",
10 | "type": "error"
11 | },
12 | {
13 | "inputs": [],
14 | "name": "ApprovalQueryForNonexistentToken",
15 | "type": "error"
16 | },
17 | {
18 | "inputs": [],
19 | "name": "ApprovalToCurrentOwner",
20 | "type": "error"
21 | },
22 | {
23 | "inputs": [],
24 | "name": "ApproveToCaller",
25 | "type": "error"
26 | },
27 | {
28 | "inputs": [],
29 | "name": "BalanceQueryForZeroAddress",
30 | "type": "error"
31 | },
32 | {
33 | "inputs": [],
34 | "name": "MintToZeroAddress",
35 | "type": "error"
36 | },
37 | {
38 | "inputs": [],
39 | "name": "MintZeroQuantity",
40 | "type": "error"
41 | },
42 | {
43 | "inputs": [],
44 | "name": "OwnerIndexOutOfBounds",
45 | "type": "error"
46 | },
47 | {
48 | "inputs": [],
49 | "name": "OwnerQueryForNonexistentToken",
50 | "type": "error"
51 | },
52 | {
53 | "inputs": [],
54 | "name": "TokenIndexOutOfBounds",
55 | "type": "error"
56 | },
57 | {
58 | "inputs": [],
59 | "name": "TransferCallerNotOwnerNorApproved",
60 | "type": "error"
61 | },
62 | {
63 | "inputs": [],
64 | "name": "TransferFromIncorrectOwner",
65 | "type": "error"
66 | },
67 | {
68 | "inputs": [],
69 | "name": "TransferToNonERC721ReceiverImplementer",
70 | "type": "error"
71 | },
72 | {
73 | "inputs": [],
74 | "name": "TransferToZeroAddress",
75 | "type": "error"
76 | },
77 | {
78 | "inputs": [],
79 | "name": "URIQueryForNonexistentToken",
80 | "type": "error"
81 | },
82 | {
83 | "anonymous": false,
84 | "inputs": [
85 | {
86 | "indexed": true,
87 | "internalType": "address",
88 | "name": "owner",
89 | "type": "address"
90 | },
91 | {
92 | "indexed": true,
93 | "internalType": "address",
94 | "name": "approved",
95 | "type": "address"
96 | },
97 | {
98 | "indexed": true,
99 | "internalType": "uint256",
100 | "name": "tokenId",
101 | "type": "uint256"
102 | }
103 | ],
104 | "name": "Approval",
105 | "type": "event"
106 | },
107 | {
108 | "anonymous": false,
109 | "inputs": [
110 | {
111 | "indexed": true,
112 | "internalType": "address",
113 | "name": "owner",
114 | "type": "address"
115 | },
116 | {
117 | "indexed": true,
118 | "internalType": "address",
119 | "name": "operator",
120 | "type": "address"
121 | },
122 | {
123 | "indexed": false,
124 | "internalType": "bool",
125 | "name": "approved",
126 | "type": "bool"
127 | }
128 | ],
129 | "name": "ApprovalForAll",
130 | "type": "event"
131 | },
132 | {
133 | "anonymous": false,
134 | "inputs": [
135 | {
136 | "indexed": true,
137 | "internalType": "address",
138 | "name": "previousOwner",
139 | "type": "address"
140 | },
141 | {
142 | "indexed": true,
143 | "internalType": "address",
144 | "name": "newOwner",
145 | "type": "address"
146 | }
147 | ],
148 | "name": "OwnershipTransferred",
149 | "type": "event"
150 | },
151 | {
152 | "anonymous": false,
153 | "inputs": [
154 | {
155 | "indexed": true,
156 | "internalType": "address",
157 | "name": "from",
158 | "type": "address"
159 | },
160 | {
161 | "indexed": true,
162 | "internalType": "address",
163 | "name": "to",
164 | "type": "address"
165 | },
166 | {
167 | "indexed": true,
168 | "internalType": "uint256",
169 | "name": "tokenId",
170 | "type": "uint256"
171 | }
172 | ],
173 | "name": "Transfer",
174 | "type": "event"
175 | },
176 | {
177 | "inputs": [],
178 | "name": "MAX_SUPPLY",
179 | "outputs": [
180 | {
181 | "internalType": "uint16",
182 | "name": "",
183 | "type": "uint16"
184 | }
185 | ],
186 | "stateMutability": "view",
187 | "type": "function",
188 | "constant": true
189 | },
190 | {
191 | "inputs": [],
192 | "name": "MINT_PRICE",
193 | "outputs": [
194 | {
195 | "internalType": "uint256",
196 | "name": "",
197 | "type": "uint256"
198 | }
199 | ],
200 | "stateMutability": "view",
201 | "type": "function",
202 | "constant": true
203 | },
204 | {
205 | "inputs": [
206 | {
207 | "internalType": "address",
208 | "name": "to",
209 | "type": "address"
210 | },
211 | {
212 | "internalType": "uint256",
213 | "name": "tokenId",
214 | "type": "uint256"
215 | }
216 | ],
217 | "name": "approve",
218 | "outputs": [],
219 | "stateMutability": "nonpayable",
220 | "type": "function"
221 | },
222 | {
223 | "inputs": [
224 | {
225 | "internalType": "address",
226 | "name": "owner",
227 | "type": "address"
228 | }
229 | ],
230 | "name": "balanceOf",
231 | "outputs": [
232 | {
233 | "internalType": "uint256",
234 | "name": "",
235 | "type": "uint256"
236 | }
237 | ],
238 | "stateMutability": "view",
239 | "type": "function",
240 | "constant": true
241 | },
242 | {
243 | "inputs": [
244 | {
245 | "internalType": "uint256",
246 | "name": "tokenId",
247 | "type": "uint256"
248 | }
249 | ],
250 | "name": "getApproved",
251 | "outputs": [
252 | {
253 | "internalType": "address",
254 | "name": "",
255 | "type": "address"
256 | }
257 | ],
258 | "stateMutability": "view",
259 | "type": "function",
260 | "constant": true
261 | },
262 | {
263 | "inputs": [
264 | {
265 | "internalType": "address",
266 | "name": "owner",
267 | "type": "address"
268 | },
269 | {
270 | "internalType": "address",
271 | "name": "operator",
272 | "type": "address"
273 | }
274 | ],
275 | "name": "isApprovedForAll",
276 | "outputs": [
277 | {
278 | "internalType": "bool",
279 | "name": "",
280 | "type": "bool"
281 | }
282 | ],
283 | "stateMutability": "view",
284 | "type": "function",
285 | "constant": true
286 | },
287 | {
288 | "inputs": [],
289 | "name": "mintReserved",
290 | "outputs": [
291 | {
292 | "internalType": "bool",
293 | "name": "",
294 | "type": "bool"
295 | }
296 | ],
297 | "stateMutability": "view",
298 | "type": "function",
299 | "constant": true
300 | },
301 | {
302 | "inputs": [],
303 | "name": "mintStatus",
304 | "outputs": [
305 | {
306 | "internalType": "enum Commsaur.MintStatus",
307 | "name": "",
308 | "type": "uint8"
309 | }
310 | ],
311 | "stateMutability": "view",
312 | "type": "function",
313 | "constant": true
314 | },
315 | {
316 | "inputs": [],
317 | "name": "name",
318 | "outputs": [
319 | {
320 | "internalType": "string",
321 | "name": "",
322 | "type": "string"
323 | }
324 | ],
325 | "stateMutability": "view",
326 | "type": "function",
327 | "constant": true
328 | },
329 | {
330 | "inputs": [],
331 | "name": "owner",
332 | "outputs": [
333 | {
334 | "internalType": "address",
335 | "name": "",
336 | "type": "address"
337 | }
338 | ],
339 | "stateMutability": "view",
340 | "type": "function",
341 | "constant": true
342 | },
343 | {
344 | "inputs": [
345 | {
346 | "internalType": "uint256",
347 | "name": "tokenId",
348 | "type": "uint256"
349 | }
350 | ],
351 | "name": "ownerOf",
352 | "outputs": [
353 | {
354 | "internalType": "address",
355 | "name": "",
356 | "type": "address"
357 | }
358 | ],
359 | "stateMutability": "view",
360 | "type": "function",
361 | "constant": true
362 | },
363 | {
364 | "inputs": [],
365 | "name": "renounceOwnership",
366 | "outputs": [],
367 | "stateMutability": "nonpayable",
368 | "type": "function"
369 | },
370 | {
371 | "inputs": [
372 | {
373 | "internalType": "address",
374 | "name": "from",
375 | "type": "address"
376 | },
377 | {
378 | "internalType": "address",
379 | "name": "to",
380 | "type": "address"
381 | },
382 | {
383 | "internalType": "uint256",
384 | "name": "tokenId",
385 | "type": "uint256"
386 | }
387 | ],
388 | "name": "safeTransferFrom",
389 | "outputs": [],
390 | "stateMutability": "nonpayable",
391 | "type": "function"
392 | },
393 | {
394 | "inputs": [
395 | {
396 | "internalType": "address",
397 | "name": "from",
398 | "type": "address"
399 | },
400 | {
401 | "internalType": "address",
402 | "name": "to",
403 | "type": "address"
404 | },
405 | {
406 | "internalType": "uint256",
407 | "name": "tokenId",
408 | "type": "uint256"
409 | },
410 | {
411 | "internalType": "bytes",
412 | "name": "_data",
413 | "type": "bytes"
414 | }
415 | ],
416 | "name": "safeTransferFrom",
417 | "outputs": [],
418 | "stateMutability": "nonpayable",
419 | "type": "function"
420 | },
421 | {
422 | "inputs": [
423 | {
424 | "internalType": "address",
425 | "name": "operator",
426 | "type": "address"
427 | },
428 | {
429 | "internalType": "bool",
430 | "name": "approved",
431 | "type": "bool"
432 | }
433 | ],
434 | "name": "setApprovalForAll",
435 | "outputs": [],
436 | "stateMutability": "nonpayable",
437 | "type": "function"
438 | },
439 | {
440 | "inputs": [
441 | {
442 | "internalType": "bytes4",
443 | "name": "interfaceId",
444 | "type": "bytes4"
445 | }
446 | ],
447 | "name": "supportsInterface",
448 | "outputs": [
449 | {
450 | "internalType": "bool",
451 | "name": "",
452 | "type": "bool"
453 | }
454 | ],
455 | "stateMutability": "view",
456 | "type": "function",
457 | "constant": true
458 | },
459 | {
460 | "inputs": [],
461 | "name": "symbol",
462 | "outputs": [
463 | {
464 | "internalType": "string",
465 | "name": "",
466 | "type": "string"
467 | }
468 | ],
469 | "stateMutability": "view",
470 | "type": "function",
471 | "constant": true
472 | },
473 | {
474 | "inputs": [
475 | {
476 | "internalType": "uint256",
477 | "name": "index",
478 | "type": "uint256"
479 | }
480 | ],
481 | "name": "tokenByIndex",
482 | "outputs": [
483 | {
484 | "internalType": "uint256",
485 | "name": "",
486 | "type": "uint256"
487 | }
488 | ],
489 | "stateMutability": "view",
490 | "type": "function",
491 | "constant": true
492 | },
493 | {
494 | "inputs": [
495 | {
496 | "internalType": "address",
497 | "name": "owner",
498 | "type": "address"
499 | },
500 | {
501 | "internalType": "uint256",
502 | "name": "index",
503 | "type": "uint256"
504 | }
505 | ],
506 | "name": "tokenOfOwnerByIndex",
507 | "outputs": [
508 | {
509 | "internalType": "uint256",
510 | "name": "",
511 | "type": "uint256"
512 | }
513 | ],
514 | "stateMutability": "view",
515 | "type": "function",
516 | "constant": true
517 | },
518 | {
519 | "inputs": [
520 | {
521 | "internalType": "uint256",
522 | "name": "tokenId",
523 | "type": "uint256"
524 | }
525 | ],
526 | "name": "tokenURI",
527 | "outputs": [
528 | {
529 | "internalType": "string",
530 | "name": "",
531 | "type": "string"
532 | }
533 | ],
534 | "stateMutability": "view",
535 | "type": "function",
536 | "constant": true
537 | },
538 | {
539 | "inputs": [],
540 | "name": "totalSupply",
541 | "outputs": [
542 | {
543 | "internalType": "uint256",
544 | "name": "",
545 | "type": "uint256"
546 | }
547 | ],
548 | "stateMutability": "view",
549 | "type": "function",
550 | "constant": true
551 | },
552 | {
553 | "inputs": [
554 | {
555 | "internalType": "address",
556 | "name": "from",
557 | "type": "address"
558 | },
559 | {
560 | "internalType": "address",
561 | "name": "to",
562 | "type": "address"
563 | },
564 | {
565 | "internalType": "uint256",
566 | "name": "tokenId",
567 | "type": "uint256"
568 | }
569 | ],
570 | "name": "transferFrom",
571 | "outputs": [],
572 | "stateMutability": "nonpayable",
573 | "type": "function"
574 | },
575 | {
576 | "inputs": [
577 | {
578 | "internalType": "address",
579 | "name": "newOwner",
580 | "type": "address"
581 | }
582 | ],
583 | "name": "transferOwnership",
584 | "outputs": [],
585 | "stateMutability": "nonpayable",
586 | "type": "function"
587 | },
588 | {
589 | "inputs": [],
590 | "name": "withdrawalAddress",
591 | "outputs": [
592 | {
593 | "internalType": "address",
594 | "name": "",
595 | "type": "address"
596 | }
597 | ],
598 | "stateMutability": "view",
599 | "type": "function",
600 | "constant": true
601 | },
602 | {
603 | "inputs": [
604 | {
605 | "internalType": "uint256",
606 | "name": "commsaursToMint",
607 | "type": "uint256"
608 | }
609 | ],
610 | "name": "mintCommsaurs",
611 | "outputs": [],
612 | "stateMutability": "payable",
613 | "type": "function",
614 | "payable": true
615 | },
616 | {
617 | "inputs": [],
618 | "name": "mintAllowList",
619 | "outputs": [],
620 | "stateMutability": "payable",
621 | "type": "function",
622 | "payable": true
623 | },
624 | {
625 | "inputs": [
626 | {
627 | "internalType": "uint256",
628 | "name": "status",
629 | "type": "uint256"
630 | }
631 | ],
632 | "name": "setMintStatus",
633 | "outputs": [],
634 | "stateMutability": "nonpayable",
635 | "type": "function"
636 | },
637 | {
638 | "inputs": [
639 | {
640 | "internalType": "string",
641 | "name": "uri",
642 | "type": "string"
643 | }
644 | ],
645 | "name": "setBaseURI",
646 | "outputs": [],
647 | "stateMutability": "nonpayable",
648 | "type": "function"
649 | },
650 | {
651 | "inputs": [
652 | {
653 | "internalType": "address",
654 | "name": "_addr",
655 | "type": "address"
656 | }
657 | ],
658 | "name": "setWithdrawalAddress",
659 | "outputs": [],
660 | "stateMutability": "nonpayable",
661 | "type": "function"
662 | },
663 | {
664 | "inputs": [
665 | {
666 | "internalType": "address[]",
667 | "name": "addresses",
668 | "type": "address[]"
669 | }
670 | ],
671 | "name": "setAllowList",
672 | "outputs": [],
673 | "stateMutability": "nonpayable",
674 | "type": "function"
675 | },
676 | {
677 | "inputs": [],
678 | "name": "reserveTokens",
679 | "outputs": [],
680 | "stateMutability": "nonpayable",
681 | "type": "function"
682 | },
683 | {
684 | "inputs": [],
685 | "name": "withdraw",
686 | "outputs": [],
687 | "stateMutability": "nonpayable",
688 | "type": "function"
689 | },
690 | {
691 | "inputs": [
692 | {
693 | "internalType": "uint256",
694 | "name": "tokenId",
695 | "type": "uint256"
696 | }
697 | ],
698 | "name": "getOwnershipData",
699 | "outputs": [
700 | {
701 | "components": [
702 | {
703 | "internalType": "address",
704 | "name": "addr",
705 | "type": "address"
706 | },
707 | {
708 | "internalType": "uint64",
709 | "name": "startTimestamp",
710 | "type": "uint64"
711 | },
712 | {
713 | "internalType": "bool",
714 | "name": "burned",
715 | "type": "bool"
716 | }
717 | ],
718 | "internalType": "struct ERC721A.TokenOwnership",
719 | "name": "",
720 | "type": "tuple"
721 | }
722 | ],
723 | "stateMutability": "view",
724 | "type": "function",
725 | "constant": true
726 | }
727 | ]
--------------------------------------------------------------------------------