├── .DS_Store
├── client
├── .DS_Store
├── .next
│ ├── react-loadable-manifest.json
│ ├── server
│ │ ├── middleware-manifest.json
│ │ └── webpack-runtime.js
│ └── static
│ │ └── development
│ │ ├── _middlewareManifest.js
│ │ └── _ssgManifest.js
├── README.md
├── assets
│ ├── check.png
│ ├── cp.png
│ ├── error.png
│ └── metamask.png
├── components
│ ├── Post.tsx
│ ├── Sidebar.tsx
│ ├── SidebarOption.tsx
│ ├── Widgets.tsx
│ ├── home
│ │ ├── Feed.tsx
│ │ └── TweetBox.tsx
│ └── profile
│ │ ├── ProfileHeader.tsx
│ │ ├── ProfileTweets.tsx
│ │ └── mintingModal
│ │ ├── FinishedState.tsx
│ │ ├── InitialState.tsx
│ │ ├── LoadingState.tsx
│ │ └── ProfileImageMinter.tsx
├── context
│ └── TwitterContext.js
├── lib
│ ├── ProfileImageNfts.json
│ ├── client.js
│ ├── constants.js
│ ├── hexStyles.css
│ ├── pinata.js
│ └── static.js
├── next-env.d.ts
├── next.config.js
├── package.json
├── pages
│ ├── _app.tsx
│ ├── api
│ │ └── hello.ts
│ ├── index.tsx
│ └── profile.tsx
├── postcss.config.js
├── public
│ ├── favicon.ico
│ └── vercel.svg
├── styles
│ ├── Home.module.css
│ └── globals.css
├── tailwind.config.js
├── tsconfig.json
└── yarn.lock
├── smart_contract
├── .DS_Store
├── .gitignore
├── README.md
├── contracts
│ └── MintProfileImage.sol
├── hardhat.config.js
├── package-lock.json
├── package.json
├── scripts
│ └── deploy.js
├── test
│ └── sample-test.js
└── yarn.lock
└── studio
├── .DS_Store
├── .eslintrc
├── README.md
├── config
├── .checksums
└── @sanity
│ ├── data-aspects.json
│ ├── default-layout.json
│ ├── default-login.json
│ └── form-builder.json
├── package.json
├── plugins
└── .gitkeep
├── sanity.json
├── schemas
├── schema.js
├── tweetSchema.js
└── userSchema.js
├── static
├── .gitkeep
└── favicon.ico
├── tsconfig.json
└── yarn.lock
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CleverProgrammers/twitter-blockchain-youtube/a352cdb72195cf0d918277ebff3e1bbec7ccf878/.DS_Store
--------------------------------------------------------------------------------
/client/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CleverProgrammers/twitter-blockchain-youtube/a352cdb72195cf0d918277ebff3e1bbec7ccf878/client/.DS_Store
--------------------------------------------------------------------------------
/client/.next/react-loadable-manifest.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/client/.next/server/middleware-manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "sortedMiddleware": [],
3 | "clientInfo": [],
4 | "middleware": {},
5 | "version": 1
6 | }
--------------------------------------------------------------------------------
/client/.next/server/webpack-runtime.js:
--------------------------------------------------------------------------------
1 | /*
2 | * ATTENTION: An "eval-source-map" devtool has been used.
3 | * This devtool is neither made for production nor for readable output files.
4 | * It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
5 | * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
6 | * or disable the default devtool with "devtool: false".
7 | * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
8 | */
9 | /******/ (() => { // webpackBootstrap
10 | /******/ "use strict";
11 | /******/ var __webpack_modules__ = ({});
12 | /************************************************************************/
13 | /******/ // The module cache
14 | /******/ var __webpack_module_cache__ = {};
15 | /******/
16 | /******/ // The require function
17 | /******/ function __webpack_require__(moduleId) {
18 | /******/ // Check if module is in cache
19 | /******/ var cachedModule = __webpack_module_cache__[moduleId];
20 | /******/ if (cachedModule !== undefined) {
21 | /******/ return cachedModule.exports;
22 | /******/ }
23 | /******/ // Create a new module (and put it into the cache)
24 | /******/ var module = __webpack_module_cache__[moduleId] = {
25 | /******/ // no module.id needed
26 | /******/ // no module.loaded needed
27 | /******/ exports: {}
28 | /******/ };
29 | /******/
30 | /******/ // Execute the module function
31 | /******/ var threw = true;
32 | /******/ try {
33 | /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
34 | /******/ threw = false;
35 | /******/ } finally {
36 | /******/ if(threw) delete __webpack_module_cache__[moduleId];
37 | /******/ }
38 | /******/
39 | /******/ // Return the exports of the module
40 | /******/ return module.exports;
41 | /******/ }
42 | /******/
43 | /******/ // expose the modules object (__webpack_modules__)
44 | /******/ __webpack_require__.m = __webpack_modules__;
45 | /******/
46 | /************************************************************************/
47 | /******/ /* webpack/runtime/compat get default export */
48 | /******/ (() => {
49 | /******/ // getDefaultExport function for compatibility with non-harmony modules
50 | /******/ __webpack_require__.n = (module) => {
51 | /******/ var getter = module && module.__esModule ?
52 | /******/ () => (module['default']) :
53 | /******/ () => (module);
54 | /******/ __webpack_require__.d(getter, { a: getter });
55 | /******/ return getter;
56 | /******/ };
57 | /******/ })();
58 | /******/
59 | /******/ /* webpack/runtime/define property getters */
60 | /******/ (() => {
61 | /******/ // define getter functions for harmony exports
62 | /******/ __webpack_require__.d = (exports, definition) => {
63 | /******/ for(var key in definition) {
64 | /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
65 | /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
66 | /******/ }
67 | /******/ }
68 | /******/ };
69 | /******/ })();
70 | /******/
71 | /******/ /* webpack/runtime/ensure chunk */
72 | /******/ (() => {
73 | /******/ __webpack_require__.f = {};
74 | /******/ // This file contains only the entry chunk.
75 | /******/ // The chunk loading function for additional chunks
76 | /******/ __webpack_require__.e = (chunkId) => {
77 | /******/ return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {
78 | /******/ __webpack_require__.f[key](chunkId, promises);
79 | /******/ return promises;
80 | /******/ }, []));
81 | /******/ };
82 | /******/ })();
83 | /******/
84 | /******/ /* webpack/runtime/get javascript chunk filename */
85 | /******/ (() => {
86 | /******/ // This function allow to reference async chunks and sibling chunks for the entrypoint
87 | /******/ __webpack_require__.u = (chunkId) => {
88 | /******/ // return url for filenames based on template
89 | /******/ return undefined;
90 | /******/ };
91 | /******/ })();
92 | /******/
93 | /******/ /* webpack/runtime/hasOwnProperty shorthand */
94 | /******/ (() => {
95 | /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
96 | /******/ })();
97 | /******/
98 | /******/ /* webpack/runtime/make namespace object */
99 | /******/ (() => {
100 | /******/ // define __esModule on exports
101 | /******/ __webpack_require__.r = (exports) => {
102 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
103 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
104 | /******/ }
105 | /******/ Object.defineProperty(exports, '__esModule', { value: true });
106 | /******/ };
107 | /******/ })();
108 | /******/
109 | /******/ /* webpack/runtime/startup entrypoint */
110 | /******/ (() => {
111 | /******/ __webpack_require__.X = (result, chunkIds, fn) => {
112 | /******/ // arguments: chunkIds, moduleId are deprecated
113 | /******/ var moduleId = chunkIds;
114 | /******/ if(!fn) chunkIds = result, fn = () => (__webpack_require__(__webpack_require__.s = moduleId));
115 | /******/ chunkIds.map(__webpack_require__.e, __webpack_require__)
116 | /******/ var r = fn();
117 | /******/ return r === undefined ? result : r;
118 | /******/ }
119 | /******/ })();
120 | /******/
121 | /******/ /* webpack/runtime/require chunk loading */
122 | /******/ (() => {
123 | /******/ // no baseURI
124 | /******/
125 | /******/ // object to store loaded chunks
126 | /******/ // "1" means "loaded", otherwise not loaded yet
127 | /******/ var installedChunks = {
128 | /******/ "webpack-runtime": 1
129 | /******/ };
130 | /******/
131 | /******/ // no on chunks loaded
132 | /******/
133 | /******/ var installChunk = (chunk) => {
134 | /******/ var moreModules = chunk.modules, chunkIds = chunk.ids, runtime = chunk.runtime;
135 | /******/ for(var moduleId in moreModules) {
136 | /******/ if(__webpack_require__.o(moreModules, moduleId)) {
137 | /******/ __webpack_require__.m[moduleId] = moreModules[moduleId];
138 | /******/ }
139 | /******/ }
140 | /******/ if(runtime) runtime(__webpack_require__);
141 | /******/ for(var i = 0; i < chunkIds.length; i++)
142 | /******/ installedChunks[chunkIds[i]] = 1;
143 | /******/
144 | /******/ };
145 | /******/
146 | /******/ // require() chunk loading for javascript
147 | /******/ __webpack_require__.f.require = (chunkId, promises) => {
148 | /******/ // "1" is the signal for "already loaded"
149 | /******/ if(!installedChunks[chunkId]) {
150 | /******/ if("webpack-runtime" != chunkId) {
151 | /******/ installChunk(require("./" + __webpack_require__.u(chunkId)));
152 | /******/ } else installedChunks[chunkId] = 1;
153 | /******/ }
154 | /******/ };
155 | /******/
156 | /******/ module.exports = __webpack_require__;
157 | /******/ __webpack_require__.C = installChunk;
158 | /******/
159 | /******/ // no HMR
160 | /******/
161 | /******/ // no HMR manifest
162 | /******/ })();
163 | /******/
164 | /************************************************************************/
165 | /******/
166 | /******/
167 | /******/ })()
168 | ;
--------------------------------------------------------------------------------
/client/.next/static/development/_middlewareManifest.js:
--------------------------------------------------------------------------------
1 | self.__MIDDLEWARE_MANIFEST=[];self.__MIDDLEWARE_MANIFEST_CB&&self.__MIDDLEWARE_MANIFEST_CB()
--------------------------------------------------------------------------------
/client/.next/static/development/_ssgManifest.js:
--------------------------------------------------------------------------------
1 | self.__SSG_MANIFEST=new Set;self.__SSG_MANIFEST_CB&&self.__SSG_MANIFEST_CB()
--------------------------------------------------------------------------------
/client/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 |
--------------------------------------------------------------------------------
/client/assets/check.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CleverProgrammers/twitter-blockchain-youtube/a352cdb72195cf0d918277ebff3e1bbec7ccf878/client/assets/check.png
--------------------------------------------------------------------------------
/client/assets/cp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CleverProgrammers/twitter-blockchain-youtube/a352cdb72195cf0d918277ebff3e1bbec7ccf878/client/assets/cp.png
--------------------------------------------------------------------------------
/client/assets/error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CleverProgrammers/twitter-blockchain-youtube/a352cdb72195cf0d918277ebff3e1bbec7ccf878/client/assets/error.png
--------------------------------------------------------------------------------
/client/assets/metamask.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CleverProgrammers/twitter-blockchain-youtube/a352cdb72195cf0d918277ebff3e1bbec7ccf878/client/assets/metamask.png
--------------------------------------------------------------------------------
/client/components/Post.tsx:
--------------------------------------------------------------------------------
1 | import { BsFillPatchCheckFill } from 'react-icons/bs'
2 | import { FaRegComment, FaRetweet } from 'react-icons/fa'
3 | import { AiOutlineHeart } from 'react-icons/ai'
4 | import { FiShare } from 'react-icons/fi'
5 | import { format } from 'timeago.js'
6 | import { useState } from 'react'
7 |
8 | const style = {
9 | wrapper: `flex p-3 border-b border-[#38444d]`,
10 | profileImage: `rounded-full h-[40px] w-[40px] object-cover`,
11 | postMain: `flex-1 px-4`,
12 | headerDetails: `flex items-center`,
13 | name: `font-bold mr-1`,
14 | verified: `text-[0.8rem]`,
15 | handleAndTimeAgo: `text-[#8899a6] ml-1`,
16 | tweet: `my-2`,
17 | image: `rounded-3xl`,
18 | footer: `flex justify-between mr-28 mt-4 text-[#8899a6]`,
19 | footerIcon: `rounded-full text-lg p-2`,
20 | }
21 |
22 | interface PostProps {
23 | displayName: string
24 | userName: string
25 | text: string
26 | avatar: string
27 | timestamp: string
28 | isProfileImageNft: Boolean | undefined
29 | }
30 |
31 | const Post = ({
32 | displayName,
33 | userName,
34 | text,
35 | avatar,
36 | timestamp,
37 | isProfileImageNft,
38 | }: PostProps) => {
39 | const [profileImageLink] = useState(avatar)
40 |
41 | return (
42 |
43 |
44 |

53 |
54 |
55 |
56 |
57 | {displayName}
58 | {isProfileImageNft && (
59 |
60 |
61 |
62 | )}
63 |
64 | @{userName} • {format(new Date(timestamp).getTime())}
65 |
66 |
67 |
{text}
68 |
69 |
70 |
73 |
74 |
75 |
78 |
79 |
80 |
85 |
88 |
89 |
90 |
91 |
92 |
93 | )
94 | }
95 |
96 | export default Post
97 |
--------------------------------------------------------------------------------
/client/components/Sidebar.tsx:
--------------------------------------------------------------------------------
1 | import { useState, useContext } from 'react'
2 | import { useRouter } from 'next/router'
3 | import { TwitterContext } from '../context/TwitterContext'
4 | import SidebarOption from './SidebarOption'
5 | import { RiHome7Line, RiHome7Fill, RiFileList2Fill } from 'react-icons/ri'
6 | import { BiHash } from 'react-icons/bi'
7 | import { FiBell, FiMoreHorizontal } from 'react-icons/fi'
8 | import { HiOutlineMail, HiMail } from 'react-icons/hi'
9 | import { FaRegListAlt, FaHashtag, FaBell } from 'react-icons/fa'
10 | import { CgMoreO } from 'react-icons/cg'
11 | import { VscTwitter } from 'react-icons/vsc'
12 | import Modal from 'react-modal'
13 | import { customStyles } from '../lib/constants'
14 | import ProfileImageMinter from './profile/mintingModal/ProfileImageMinter'
15 | import {
16 | BsBookmark,
17 | BsBookmarkFill,
18 | BsPerson,
19 | BsPersonFill,
20 | } from 'react-icons/bs'
21 |
22 | const style = {
23 | wrapper: `flex-[0.7] px-8 flex flex-col`,
24 | twitterIconContainer: `text-3xl m-4`,
25 | tweetButton: `bg-[#1d9bf0] hover:bg-[#1b8cd8] flex items-center justify-center font-bold rounded-3xl h-[50px] mt-[20px] cursor-pointer`,
26 | navContainer: `flex-1`,
27 | profileButton: `flex items-center mb-6 cursor-pointer hover:bg-[#333c45] rounded-[100px] p-2`,
28 | profileLeft: `flex item-center justify-center mr-4`,
29 | profileImage: `height-12 w-12 rounded-full`,
30 | profileRight: `flex-1 flex`,
31 | details: `flex-1`,
32 | name: `text-lg`,
33 | handle: `text-[#8899a6]`,
34 | moreContainer: `flex items-center mr-2`,
35 | }
36 |
37 | interface SidebarProps {
38 | initialSelectedIcon: string
39 | }
40 |
41 | function Sidebar({ initialSelectedIcon }: SidebarProps) {
42 | const [selected, setSelected] = useState(initialSelectedIcon)
43 | const { currentAccount, currentUser } = useContext(TwitterContext)
44 | const router = useRouter()
45 |
46 | return (
47 |
48 |
49 |
50 |
51 |
52 |
59 |
65 |
71 |
77 |
83 |
89 |
96 |
97 |
99 | router.push(`${router.pathname}/?mint=${currentAccount}`)
100 | }
101 | className={style.tweetButton}
102 | >
103 | Mint
104 |
105 |
106 |
107 |
108 |

117 |
118 |
119 |
120 |
{currentUser.name}
121 |
122 | @{currentAccount.slice(0, 6)}...{currentAccount.slice(39)}
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
router.back()}
134 | style={customStyles}
135 | >
136 |
137 |
138 |
139 | )
140 | }
141 |
142 | export default Sidebar
143 |
--------------------------------------------------------------------------------
/client/components/SidebarOption.tsx:
--------------------------------------------------------------------------------
1 | import { Dispatch, SetStateAction } from 'react'
2 | import { IconType } from 'react-icons'
3 | import { useRouter } from 'next/router'
4 |
5 | const style = {
6 | wrapper: `w-min flex items-center rounded-[100px] p-4 cursor-pointer hover:bg-[#333c45] transition-all hover:duration-200 hover:ease-in-out`,
7 | iconContainer: `text-xl mr-4`,
8 | textGeneral: `font-medium`,
9 | textActive: `font-bold`,
10 | }
11 |
12 | interface SidebarOptionProps {
13 | text: String
14 | Icon: IconType
15 | isActive?: Boolean
16 | setSelected?: Dispatch>
17 | redirect?: URL | string
18 | }
19 |
20 | function SidebarOption({
21 | text,
22 | Icon,
23 | isActive,
24 | setSelected,
25 | redirect,
26 | }: SidebarOptionProps) {
27 | const router = useRouter()
28 |
29 | const handleClick = (buttonText = text) => {
30 | if (buttonText !== 'More' && setSelected) {
31 | setSelected(buttonText)
32 | } else return
33 | }
34 |
35 | return (
36 | {
39 | handleClick(text)
40 | if (redirect) {
41 | router.push(redirect)
42 | } else return
43 | }}
44 | >
45 |
46 |
47 |
48 |
49 | {text}
50 |
51 |
52 | )
53 | }
54 |
55 | export default SidebarOption
56 |
--------------------------------------------------------------------------------
/client/components/Widgets.tsx:
--------------------------------------------------------------------------------
1 | import { news, whoToFollow } from '../lib/static'
2 | import { BiSearch } from 'react-icons/bi'
3 |
4 | const style = {
5 | wrapper: `flex-[1] p-4`,
6 | searchBar: `flex items-center bg-[#243340] p-2 rounded-3xl`,
7 | searchIcon: `text-[#8899a6] mr-2`,
8 | inputBox: `bg-transparent outline-none`,
9 | section: `bg-[#192734] my-6 rounded-xl overflow-hidden`,
10 | title: `p-2 font-bold text-lg`,
11 | showMore: `p-2 text-[#1d9bf0] text-sm cursor-pointer hover:bg-[#22303c]`,
12 | item: `flex items-center p-3 my-2 hover:bg-[#22303c] cursor-pointer`,
13 | newsItemLeft: `flex-1`,
14 | newsItemCategory: `text-[#8899a6] text-xs font-semibold`,
15 | newsItemTitle: `text-sm font-bold`,
16 | newsItemRight: `w-1/5 ml-3`,
17 | newsItemImage: `rounded-xl h-14 w-14 object-cover`,
18 | followAvatarContainer: `w-1/6`,
19 | followAvatar: `rounded-full h-[40px] w-[40px]`,
20 | profileDetails: `flex-1`,
21 | name: `font-bold`,
22 | handle: `text-[#8899a6]`,
23 | followButton: `bg-white text-black px-3 py-1 rounded-full text-xs font-bold`,
24 | }
25 |
26 | function Widgets() {
27 | return (
28 |
29 |
30 |
31 |
36 |
37 |
38 |
What's happening
39 | {news.map((item, index) => (
40 |
41 |
42 |
{item.category}
43 |
{item.title}
44 |
45 |
46 |

51 |
52 |
53 | ))}
54 |
Show more
55 |
56 |
57 |
Who to follow
58 | {whoToFollow.map((item, index) => (
59 |
60 |
61 |

66 |
67 |
68 |
{item.name}
69 |
{item.handle}
70 |
71 |
Follow
72 |
73 | ))}
74 |
Show more
75 |
76 |
77 | )
78 | }
79 |
80 | export default Widgets
81 |
--------------------------------------------------------------------------------
/client/components/home/Feed.tsx:
--------------------------------------------------------------------------------
1 | import { useContext, useEffect } from 'react'
2 | import { TwitterContext } from '../../context/TwitterContext'
3 | import TweetBox from './TweetBox'
4 | import Post from '../Post'
5 | import { BsStars } from 'react-icons/bs'
6 |
7 | const style = {
8 | wrapper: `flex-[2] border-r border-l border-[#38444d] overflow-y-scroll`,
9 | header: `sticky top-0 bg-[#15202b] z-10 p-4 flex justify-between items-center`,
10 | headerTitle: `text-xl font-bold`,
11 | }
12 |
13 | interface Tweet {
14 | author: TweetAuthor
15 | tweet: string
16 | timestamp: string
17 | }
18 |
19 | interface TweetAuthor {
20 | name: string
21 | walletAddress: string
22 | profileImage: string
23 | isProfileImageNft: boolean
24 | }
25 |
26 | function Feed() {
27 | const { tweets } = useContext(TwitterContext)
28 |
29 | return (
30 |
31 |
35 |
36 | {tweets.map((tweet: Tweet, index: number) => (
37 |
56 | ))}
57 |
58 | )
59 | }
60 |
61 | export default Feed
62 |
--------------------------------------------------------------------------------
/client/components/home/TweetBox.tsx:
--------------------------------------------------------------------------------
1 | import { useState, useContext } from 'react'
2 | import { TwitterContext } from '../../context/TwitterContext'
3 | import { BsCardImage, BsEmojiSmile } from 'react-icons/bs'
4 | import { RiFileGifLine, RiBarChartHorizontalFill } from 'react-icons/ri'
5 | import { IoMdCalendar } from 'react-icons/io'
6 | import { MdOutlineLocationOn } from 'react-icons/md'
7 | import { client } from '../../lib/client'
8 |
9 | const style = {
10 | wrapper: `px-4 flex flex-row border-b border-[#38444d] pb-4`,
11 | tweetBoxLeft: `mr-4`,
12 | tweetBoxRight: `flex-1`,
13 | profileImage: `height-12 w-12 rounded-full`,
14 | inputField: `w-full h-full outline-none bg-transparent text-lg`,
15 | formLowerContainer: `flex`,
16 | iconsContainer: `text-[#1d9bf0] flex flex-1 items-center`,
17 | icon: `mr-2`,
18 | submitGeneral: `px-6 py-2 rounded-3xl font-bold`,
19 | inactiveSubmit: `bg-[#196195] text-[#95999e]`,
20 | activeSubmit: `bg-[#1d9bf0] text-white`,
21 | }
22 |
23 | function TweetBox() {
24 | const [tweetMessage, setTweetMessage] = useState('')
25 | const { currentAccount, fetchTweets, currentUser } =
26 | useContext(TwitterContext)
27 |
28 | const submitTweet = async (event: any) => {
29 | event.preventDefault()
30 |
31 | if (!tweetMessage) return
32 | const tweetId = `${currentAccount}_${Date.now()}`
33 |
34 | const tweetDoc = {
35 | _type: 'tweets',
36 | _id: tweetId,
37 | tweet: tweetMessage,
38 | timestamp: new Date(Date.now()).toISOString(),
39 | author: {
40 | _key: tweetId,
41 | _ref: currentAccount,
42 | _type: 'reference',
43 | },
44 | }
45 |
46 | await client.createIfNotExists(tweetDoc)
47 |
48 | await client
49 | .patch(currentAccount)
50 | .setIfMissing({ tweets: [] })
51 | .insert('after', 'tweets[-1]', [
52 | {
53 | _key: tweetId,
54 | _ref: tweetId,
55 | _type: 'reference',
56 | },
57 | ])
58 | .commit()
59 |
60 | await fetchTweets()
61 | setTweetMessage('')
62 | }
63 |
64 | return (
65 |
66 |
67 |

75 |
76 |
106 |
107 | )
108 | }
109 |
110 | export default TweetBox
111 |
--------------------------------------------------------------------------------
/client/components/profile/ProfileHeader.tsx:
--------------------------------------------------------------------------------
1 | import { useContext, useEffect, useState } from 'react'
2 | import { TwitterContext } from '../../context/TwitterContext'
3 | import { BsArrowLeftShort } from 'react-icons/bs'
4 | import { useRouter } from 'next/router'
5 | import Modal from 'react-modal'
6 | import ProfileImageMinter from './mintingModal/ProfileImageMinter'
7 | import { customStyles } from '../../lib/constants'
8 |
9 | Modal.setAppElement('#__next')
10 |
11 | const style = {
12 | wrapper: `border-[#38444d] border-b`,
13 | header: `py-1 px-3 mt-2 flex items-center`,
14 | primary: `bg-transparent outline-none font-bold`,
15 | secondary: `text-[#8899a6] text-xs`,
16 | backButton: `text-3xl cursor-pointer mr-2 rounded-full hover:bg-[#313b44] p-1`,
17 | coverPhotoContainer: `flex items-center justify-center h-[15vh] overflow-hidden`,
18 | coverPhoto: `object-cover h-full w-full`,
19 | profileImageContainer: `w-full h-[6rem] rounded-full mt-[-3rem] mb-2 flex justify-start items-center px-3 flex justify-between`,
20 | profileImage: `object-cover rounded-full h-full`,
21 | profileImageNft: `object-cover h-full`,
22 | profileImageMint: `bg-white text-black px-3 py-1 rounded-full hover:bg-[#8899a6] cursor-pointer`,
23 | details: `px-3`,
24 | nav: `flex justify-around mt-4 mb-2 text-xs font-semibold text-[#8899a6]`,
25 | activeNav: `text-white`,
26 | }
27 |
28 | interface Tweets {
29 | tweet: string
30 | timestamp: string
31 | }
32 |
33 | interface UserData {
34 | name: string
35 | profileImage: string
36 | coverImage: string
37 | walletAddress: string
38 | tweets: Array
39 | isProfileImageNft: Boolean | undefined
40 | }
41 |
42 | const ProfileHeader = () => {
43 | const { currentAccount, currentUser } = useContext(TwitterContext)
44 | const router = useRouter()
45 | const [userData, setUserData] = useState({
46 | name: '',
47 | profileImage: '',
48 | coverImage: '',
49 | walletAddress: '',
50 | tweets: [],
51 | isProfileImageNft: undefined,
52 | })
53 |
54 | useEffect(() => {
55 | if (!currentUser) return
56 |
57 | setUserData({
58 | name: currentUser.name,
59 | profileImage: currentUser.profileImage,
60 | walletAddress: currentUser.walletAddress,
61 | coverImage: currentUser.coverImage,
62 | tweets: currentUser.tweets,
63 | isProfileImageNft: currentUser.isProfileImageNft,
64 | })
65 | }, [currentUser])
66 |
67 | return (
68 |
69 |
70 |
router.push('/')} className={style.backButton}>
71 |
72 |
73 |
74 |
{userData.name}
75 |
76 | {userData.tweets?.length} Tweets
77 |
78 |
79 |
80 |
81 |

86 |
87 |
88 |
93 |

102 |
103 |
104 |
105 |
106 |
{currentUser.name}
107 |
108 |
109 | {currentAccount && (
110 | <>
111 | @{currentAccount.slice(0, 8)}...{currentAccount.slice(37)}
112 | >
113 | )}
114 |
115 |
116 |
117 |
Tweets
118 |
Tweets & Replies
119 |
Media
120 |
Likes
121 |
122 |
123 | )
124 | }
125 |
126 | export default ProfileHeader
127 |
--------------------------------------------------------------------------------
/client/components/profile/ProfileTweets.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useContext, useState } from 'react'
2 | import { TwitterContext } from '../../context/TwitterContext'
3 | import Post from '../Post'
4 |
5 | const style = {
6 | wrapper: `no-scrollbar`,
7 | header: `sticky top-0 bg-[#15202b] z-10 p-4 flex justify-between items-center`,
8 | headerTitle: `text-xl font-bold`,
9 | }
10 |
11 | interface Tweet {
12 | timestamp: string
13 | tweet: string
14 | }
15 |
16 | interface Tweets extends Array {}
17 |
18 | interface Author {
19 | name: string
20 | profileImage: string
21 | walletAddress: string
22 | isProfileImageNft: Boolean | undefined
23 | }
24 |
25 | const ProfileTweets = () => {
26 | const { currentUser } = useContext(TwitterContext)
27 | const [tweets, setTweets] = useState([
28 | {
29 | timestamp: '',
30 | tweet: '',
31 | },
32 | ])
33 | const [author, setAuthor] = useState({
34 | name: '',
35 | profileImage: '',
36 | walletAddress: '',
37 | isProfileImageNft: undefined,
38 | })
39 |
40 | useEffect(() => {
41 | if (!currentUser) return
42 |
43 | setTweets(currentUser.tweets)
44 | setAuthor({
45 | name: currentUser.name,
46 | profileImage: currentUser.profileImage,
47 | walletAddress: currentUser.walletAddress,
48 | isProfileImageNft: currentUser.isProfileImageNft,
49 | })
50 | }, [currentUser])
51 |
52 | return (
53 |
54 | {tweets?.map((tweet: Tweet, index: number) => (
55 |
74 | ))}
75 |
76 | )
77 | }
78 |
79 | export default ProfileTweets
80 |
--------------------------------------------------------------------------------
/client/components/profile/mintingModal/FinishedState.tsx:
--------------------------------------------------------------------------------
1 | import { useContext, useEffect } from 'react'
2 | import { TwitterContext } from '../../../context/TwitterContext'
3 | import Image from 'next/image'
4 | import checkMark from '../../../assets/check.png'
5 | import { useRouter } from 'next/router'
6 |
7 | const style = {
8 | wrapper: `h-[20rem] w-[35rem] text-white bg-[#15202b] rounded-3xl p-10 flex flex-col items-center justify-center`,
9 | title: `font-semibold text-xl mb-6`,
10 | closeButton: `mt-6 bg-white text-black px-3 py-1 rounded-full hover:bg-[#8899a6] cursor-pointer`,
11 | }
12 |
13 | const FinishedState = () => {
14 | const router = useRouter()
15 | const { getCurrentUserDetails } = useContext(TwitterContext)
16 |
17 | useEffect(() => {
18 | getCurrentUserDetails()
19 | })
20 |
21 | return (
22 |
23 |
Minting Successful!
24 |
25 |
router.push('/')} className={style.closeButton}>
26 | Close
27 |
28 |
29 | )
30 | }
31 |
32 | export default FinishedState
33 |
--------------------------------------------------------------------------------
/client/components/profile/mintingModal/InitialState.tsx:
--------------------------------------------------------------------------------
1 | import { Dispatch, SetStateAction } from 'react'
2 | import { GiEarthAmerica } from 'react-icons/gi'
3 |
4 | const style = {
5 | wrapper: `h-[20rem] w-[35rem] text-white bg-[#15202b] rounded-3xl p-10 flex flex-col`,
6 | inputFieldsContainer: `flex-1`,
7 | inputContainer: `mb-4`,
8 | fileInput: `hidden`,
9 | input: `bg-transparent outline-none text-xl w-full`,
10 | customInput: `bg-white text-black px-3 py-1 rounded-full hover:bg-[#8899a6] cursor-pointer`,
11 | fileSelected: `bg-[#2b6127] text-white px-3 py-1 rounded-full hover:bg-[#8899a6] cursor-pointer`,
12 | lower: `flex justify-between items-center`,
13 | visibility: `flex items-center text-[#1d9bf0] text-sm font-bold`,
14 | visibilityText: `ml-2`,
15 | mintButton: `bg-white text-black px-3 py-1 rounded-full hover:bg-[#8899a6] cursor-pointer`,
16 | inactiveMintButton: `text-black px-3 py-1 rounded-full bg-[#8899a6]`,
17 | }
18 |
19 | interface InitialStateProps {
20 | profileImage: File
21 | setProfileImage: Dispatch>
22 | name: string
23 | setName: Dispatch>
24 | description: string
25 | setDescription: Dispatch>
26 | mint: Function
27 | }
28 |
29 | const InitialState = ({
30 | profileImage,
31 | setProfileImage,
32 | name,
33 | setName,
34 | description,
35 | setDescription,
36 | mint,
37 | }: InitialStateProps) => {
38 | console.log(profileImage)
39 |
40 | return (
41 |
42 |
78 |
79 |
80 |
81 | Everyone can see this
82 |
83 |
{
90 | if (name && description && profileImage) {
91 | mint()
92 | }
93 | }}
94 | >
95 | Mint
96 |
97 |
98 |
99 | )
100 | }
101 |
102 | export default InitialState
103 |
--------------------------------------------------------------------------------
/client/components/profile/mintingModal/LoadingState.tsx:
--------------------------------------------------------------------------------
1 | import { GridLoader } from 'react-spinners'
2 | import { css } from '@emotion/react'
3 |
4 | const style = {
5 | wrapper: `h-[20rem] w-[35rem] text-white bg-[#15202b] rounded-3xl p-10 flex flex-col items-center justify-center`,
6 | title: `font-semibold text-xl mb-6`,
7 | }
8 |
9 | const cssOverride = css`
10 | display: block;
11 | margin: 0 auto;
12 | border-color: white;
13 | `
14 |
15 | const LoadingState = () => {
16 | return (
17 |
18 |
Minting in progress...
19 |
20 |
21 | )
22 | }
23 |
24 | export default LoadingState
25 |
--------------------------------------------------------------------------------
/client/components/profile/mintingModal/ProfileImageMinter.tsx:
--------------------------------------------------------------------------------
1 | import { useState, useContext } from 'react'
2 | import { TwitterContext } from '../../../context/TwitterContext'
3 | import { useRouter } from 'next/router'
4 | import { client } from '../../../lib/client'
5 | import { contractABI, contractAddress } from '../../../lib/constants'
6 | import { ethers } from 'ethers'
7 | import InitialState from './InitialState'
8 | import LoadingState from './LoadingState'
9 | import FinishedState from './FinishedState'
10 | import { pinJSONToIPFS, pinFileToIPFS } from '../../../lib/pinata'
11 |
12 | declare let window: any
13 |
14 | let metamask: any
15 |
16 | if (typeof window !== 'undefined') {
17 | metamask = window.ethereum
18 | }
19 |
20 | interface Metadata {
21 | name: string
22 | description: string
23 | image: string
24 | }
25 |
26 | interface HeaderObject {
27 | key: string | undefined
28 | value: string | undefined
29 | }
30 |
31 | const getEthereumContract = () => {
32 | const provider = new ethers.providers.Web3Provider(metamask)
33 | const signer = provider.getSigner()
34 | const transactionContract = new ethers.Contract(
35 | contractAddress,
36 | contractABI,
37 | signer,
38 | )
39 |
40 | return transactionContract
41 | }
42 |
43 | const createPinataRequestHeaders = (headers: Array) => {
44 | const requestHeaders: HeadersInit = new Headers()
45 |
46 | headers.forEach((header: any) => {
47 | requestHeaders.append(header.key, header.value)
48 | })
49 |
50 | return requestHeaders
51 | }
52 |
53 | const ProfileImageMinter = () => {
54 | const { currentAccount, setAppStatus } = useContext(TwitterContext)
55 | const router = useRouter()
56 |
57 | const [name, setName] = useState('')
58 | const [description, setDescription] = useState('')
59 | const [status, setStatus] = useState('initial')
60 | const [profileImage, setProfileImage] = useState()
61 |
62 | const mint = async () => {
63 | if (!name || !description || !profileImage) return
64 | setStatus('loading')
65 |
66 | const pinataMetaData = {
67 | name: `${name} - ${description}`,
68 | }
69 |
70 | const ipfsImageHash = await pinFileToIPFS(profileImage, pinataMetaData)
71 |
72 | await client
73 | .patch(currentAccount)
74 | .set({ profileImage: ipfsImageHash })
75 | .set({ isProfileImageNft: true })
76 | .commit()
77 |
78 | const imageMetaData: Metadata = {
79 | name: name,
80 | description: description,
81 | image: `ipfs://${ipfsImageHash}`,
82 | }
83 |
84 | const ipfsJsonHash = await pinJSONToIPFS(imageMetaData)
85 |
86 | const contract = await getEthereumContract()
87 |
88 | const transactionParameters = {
89 | to: contractAddress,
90 | from: currentAccount,
91 | data: await contract.mint(currentAccount, `ipfs://${ipfsJsonHash}`),
92 | }
93 |
94 | try {
95 | await metamask.request({
96 | method: 'eth_sendTransaction',
97 | params: [transactionParameters],
98 | })
99 |
100 | setStatus('finished')
101 | } catch (error: any) {
102 | console.log(error)
103 | setStatus('finished')
104 | }
105 | }
106 |
107 | const renderLogic = (modalStatus = status) => {
108 | switch (modalStatus) {
109 | case 'initial':
110 | return (
111 |
120 | )
121 |
122 | case 'loading':
123 | return
124 |
125 | case 'finished':
126 | return
127 |
128 | default:
129 | router.push('/')
130 | setAppStatus('error')
131 | break
132 | }
133 | }
134 |
135 | return <>{renderLogic()}>
136 | }
137 |
138 | export default ProfileImageMinter
139 |
--------------------------------------------------------------------------------
/client/context/TwitterContext.js:
--------------------------------------------------------------------------------
1 | import { createContext, useEffect, useState } from 'react'
2 | import { useRouter } from 'next/router'
3 | import { client } from '../lib/client'
4 |
5 | export const TwitterContext = createContext()
6 |
7 | export const TwitterProvider = ({ children }) => {
8 | const [appStatus, setAppStatus] = useState('')
9 | const [currentAccount, setCurrentAccount] = useState('')
10 | const [currentUser, setCurrentUser] = useState({})
11 | const [tweets, setTweets] = useState([])
12 | const router = useRouter()
13 |
14 | useEffect(() => {
15 | checkIfWalletIsConnected()
16 | }, [])
17 |
18 | useEffect(() => {
19 | if (!currentAccount && appStatus == 'connected') return
20 | getCurrentUserDetails(currentAccount)
21 | fetchTweets()
22 | }, [currentAccount, appStatus])
23 |
24 | /**
25 | * Checks if there is an active wallet connection
26 | */
27 | const checkIfWalletIsConnected = async () => {
28 | if (!window.ethereum) return setAppStatus('noMetaMask')
29 | try {
30 | const addressArray = await window.ethereum.request({
31 | method: 'eth_accounts',
32 | })
33 | if (addressArray.length > 0) {
34 | setAppStatus('connected')
35 | setCurrentAccount(addressArray[0])
36 |
37 | createUserAccount(addressArray[0])
38 | } else {
39 | router.push('/')
40 | setAppStatus('notConnected')
41 | }
42 | } catch (err) {
43 | router.push('/')
44 | setAppStatus('error')
45 | }
46 | }
47 |
48 | /**
49 | * Initiates MetaMask wallet connection
50 | */
51 | const connectWallet = async () => {
52 | if (!window.ethereum) return setAppStatus('noMetaMask')
53 | try {
54 | setAppStatus('loading')
55 |
56 | const addressArray = await window.ethereum.request({
57 | method: 'eth_requestAccounts',
58 | })
59 |
60 | if (addressArray.length > 0) {
61 | setCurrentAccount(addressArray[0])
62 | createUserAccount(addressArray[0])
63 | } else {
64 | router.push('/')
65 | setAppStatus('notConnected')
66 | }
67 | } catch (err) {
68 | setAppStatus('error')
69 | }
70 | }
71 |
72 | /**
73 | * Creates an account in Sanity DB if the user does not already have one
74 | * @param {String} userAddress Wallet address of the currently logged in user
75 | */
76 | const createUserAccount = async (userAddress = currentAccount) => {
77 | if (!window.ethereum) return setAppStatus('noMetaMask')
78 | try {
79 | const userDoc = {
80 | _type: 'users',
81 | _id: userAddress,
82 | name: 'Unnamed',
83 | isProfileImageNft: false,
84 | profileImage:
85 | 'https://about.twitter.com/content/dam/about-twitter/en/brand-toolkit/brand-download-img-1.jpg.twimg.1920.jpg',
86 | walletAddress: userAddress,
87 | }
88 |
89 | await client.createIfNotExists(userDoc)
90 |
91 | setAppStatus('connected')
92 | } catch (error) {
93 | router.push('/')
94 | setAppStatus('error')
95 | }
96 | }
97 |
98 | /**
99 | * Generates NFT profile picture URL or returns the image URL if it's not an NFT
100 | * @param {String} imageUri If the user has minted a profile picture, an IPFS hash; if not then the URL of their profile picture
101 | * @param {Boolean} isNft Indicates whether the user has minted a profile picture
102 | * @returns A full URL to the profile picture
103 | */
104 | const getNftProfileImage = async (imageUri, isNft) => {
105 | if (isNft) {
106 | return `https://gateway.pinata.cloud/ipfs/${imageUri}`
107 | } else if (!isNft) {
108 | return imageUri
109 | }
110 | }
111 |
112 | /**
113 | * Gets all the tweets stored in Sanity DB.
114 | */
115 | const fetchTweets = async () => {
116 | const query = `
117 | *[_type == "tweets"]{
118 | "author": author->{name, walletAddress, profileImage, isProfileImageNft},
119 | tweet,
120 | timestamp
121 | }|order(timestamp desc)
122 | `
123 |
124 | // setTweets(await client.fetch(query))
125 |
126 | const sanityResponse = await client.fetch(query)
127 |
128 | setTweets([])
129 |
130 | /**
131 | * Async await not available with for..of loops.
132 | */
133 | sanityResponse.forEach(async item => {
134 | const profileImageUrl = await getNftProfileImage(
135 | item.author.profileImage,
136 | item.author.isProfileImageNft,
137 | )
138 |
139 | if (item.author.isProfileImageNft) {
140 | const newItem = {
141 | tweet: item.tweet,
142 | timestamp: item.timestamp,
143 | author: {
144 | name: item.author.name,
145 | walletAddress: item.author.walletAddress,
146 | profileImage: profileImageUrl,
147 | isProfileImageNft: item.author.isProfileImageNft,
148 | },
149 | }
150 |
151 | setTweets(prevState => [...prevState, newItem])
152 | } else {
153 | setTweets(prevState => [...prevState, item])
154 | }
155 | })
156 | }
157 |
158 | /**
159 | * Gets the current user details from Sanity DB.
160 | * @param {String} userAccount Wallet address of the currently logged in user
161 | * @returns null
162 | */
163 | const getCurrentUserDetails = async (userAccount = currentAccount) => {
164 | if (appStatus !== 'connected') return
165 |
166 | const query = `
167 | *[_type == "users" && _id == "${userAccount}"]{
168 | "tweets": tweets[]->{timestamp, tweet}|order(timestamp desc),
169 | name,
170 | profileImage,
171 | isProfileImageNft,
172 | coverImage,
173 | walletAddress
174 | }
175 | `
176 | const response = await client.fetch(query)
177 |
178 | const profileImageUri = await getNftProfileImage(
179 | response[0].profileImage,
180 | response[0].isProfileImageNft,
181 | )
182 |
183 | setCurrentUser({
184 | tweets: response[0].tweets,
185 | name: response[0].name,
186 | profileImage: profileImageUri,
187 | walletAddress: response[0].walletAddress,
188 | coverImage: response[0].coverImage,
189 | isProfileImageNft: response[0].isProfileImageNft,
190 | })
191 | }
192 |
193 | return (
194 |
207 | {children}
208 |
209 | )
210 | }
211 |
--------------------------------------------------------------------------------
/client/lib/ProfileImageNfts.json:
--------------------------------------------------------------------------------
1 | {
2 | "_format": "hh-sol-artifact-1",
3 | "contractName": "ProfileImageNfts",
4 | "sourceName": "contracts/MintProfileImage.sol",
5 | "abi": [
6 | {
7 | "inputs": [],
8 | "stateMutability": "nonpayable",
9 | "type": "constructor"
10 | },
11 | {
12 | "anonymous": false,
13 | "inputs": [
14 | {
15 | "indexed": true,
16 | "internalType": "address",
17 | "name": "owner",
18 | "type": "address"
19 | },
20 | {
21 | "indexed": true,
22 | "internalType": "address",
23 | "name": "approved",
24 | "type": "address"
25 | },
26 | {
27 | "indexed": true,
28 | "internalType": "uint256",
29 | "name": "tokenId",
30 | "type": "uint256"
31 | }
32 | ],
33 | "name": "Approval",
34 | "type": "event"
35 | },
36 | {
37 | "anonymous": false,
38 | "inputs": [
39 | {
40 | "indexed": true,
41 | "internalType": "address",
42 | "name": "owner",
43 | "type": "address"
44 | },
45 | {
46 | "indexed": true,
47 | "internalType": "address",
48 | "name": "operator",
49 | "type": "address"
50 | },
51 | {
52 | "indexed": false,
53 | "internalType": "bool",
54 | "name": "approved",
55 | "type": "bool"
56 | }
57 | ],
58 | "name": "ApprovalForAll",
59 | "type": "event"
60 | },
61 | {
62 | "anonymous": false,
63 | "inputs": [
64 | {
65 | "indexed": true,
66 | "internalType": "address",
67 | "name": "previousOwner",
68 | "type": "address"
69 | },
70 | {
71 | "indexed": true,
72 | "internalType": "address",
73 | "name": "newOwner",
74 | "type": "address"
75 | }
76 | ],
77 | "name": "OwnershipTransferred",
78 | "type": "event"
79 | },
80 | {
81 | "anonymous": false,
82 | "inputs": [
83 | {
84 | "indexed": true,
85 | "internalType": "address",
86 | "name": "from",
87 | "type": "address"
88 | },
89 | {
90 | "indexed": true,
91 | "internalType": "address",
92 | "name": "to",
93 | "type": "address"
94 | },
95 | {
96 | "indexed": true,
97 | "internalType": "uint256",
98 | "name": "tokenId",
99 | "type": "uint256"
100 | }
101 | ],
102 | "name": "Transfer",
103 | "type": "event"
104 | },
105 | {
106 | "inputs": [
107 | {
108 | "internalType": "address",
109 | "name": "to",
110 | "type": "address"
111 | },
112 | {
113 | "internalType": "uint256",
114 | "name": "tokenId",
115 | "type": "uint256"
116 | }
117 | ],
118 | "name": "approve",
119 | "outputs": [],
120 | "stateMutability": "nonpayable",
121 | "type": "function"
122 | },
123 | {
124 | "inputs": [
125 | {
126 | "internalType": "address",
127 | "name": "owner",
128 | "type": "address"
129 | }
130 | ],
131 | "name": "balanceOf",
132 | "outputs": [
133 | {
134 | "internalType": "uint256",
135 | "name": "",
136 | "type": "uint256"
137 | }
138 | ],
139 | "stateMutability": "view",
140 | "type": "function"
141 | },
142 | {
143 | "inputs": [],
144 | "name": "getAlltoken",
145 | "outputs": [
146 | {
147 | "components": [
148 | {
149 | "internalType": "uint256",
150 | "name": "id",
151 | "type": "uint256"
152 | },
153 | {
154 | "internalType": "string",
155 | "name": "uri",
156 | "type": "string"
157 | },
158 | {
159 | "internalType": "string",
160 | "name": "space",
161 | "type": "string"
162 | }
163 | ],
164 | "internalType": "struct ProfileImageNfts.RenderToken[]",
165 | "name": "",
166 | "type": "tuple[]"
167 | }
168 | ],
169 | "stateMutability": "view",
170 | "type": "function"
171 | },
172 | {
173 | "inputs": [
174 | {
175 | "internalType": "uint256",
176 | "name": "tokenId",
177 | "type": "uint256"
178 | }
179 | ],
180 | "name": "getApproved",
181 | "outputs": [
182 | {
183 | "internalType": "address",
184 | "name": "",
185 | "type": "address"
186 | }
187 | ],
188 | "stateMutability": "view",
189 | "type": "function"
190 | },
191 | {
192 | "inputs": [
193 | {
194 | "internalType": "address",
195 | "name": "owner",
196 | "type": "address"
197 | },
198 | {
199 | "internalType": "address",
200 | "name": "operator",
201 | "type": "address"
202 | }
203 | ],
204 | "name": "isApprovedForAll",
205 | "outputs": [
206 | {
207 | "internalType": "bool",
208 | "name": "",
209 | "type": "bool"
210 | }
211 | ],
212 | "stateMutability": "view",
213 | "type": "function"
214 | },
215 | {
216 | "inputs": [
217 | {
218 | "internalType": "address",
219 | "name": "recipents",
220 | "type": "address"
221 | },
222 | {
223 | "internalType": "string",
224 | "name": "_uri",
225 | "type": "string"
226 | }
227 | ],
228 | "name": "mint",
229 | "outputs": [
230 | {
231 | "internalType": "uint256",
232 | "name": "",
233 | "type": "uint256"
234 | }
235 | ],
236 | "stateMutability": "nonpayable",
237 | "type": "function"
238 | },
239 | {
240 | "inputs": [],
241 | "name": "name",
242 | "outputs": [
243 | {
244 | "internalType": "string",
245 | "name": "",
246 | "type": "string"
247 | }
248 | ],
249 | "stateMutability": "view",
250 | "type": "function"
251 | },
252 | {
253 | "inputs": [],
254 | "name": "owner",
255 | "outputs": [
256 | {
257 | "internalType": "address",
258 | "name": "",
259 | "type": "address"
260 | }
261 | ],
262 | "stateMutability": "view",
263 | "type": "function"
264 | },
265 | {
266 | "inputs": [
267 | {
268 | "internalType": "uint256",
269 | "name": "tokenId",
270 | "type": "uint256"
271 | }
272 | ],
273 | "name": "ownerOf",
274 | "outputs": [
275 | {
276 | "internalType": "address",
277 | "name": "",
278 | "type": "address"
279 | }
280 | ],
281 | "stateMutability": "view",
282 | "type": "function"
283 | },
284 | {
285 | "inputs": [],
286 | "name": "renounceOwnership",
287 | "outputs": [],
288 | "stateMutability": "nonpayable",
289 | "type": "function"
290 | },
291 | {
292 | "inputs": [
293 | {
294 | "internalType": "address",
295 | "name": "from",
296 | "type": "address"
297 | },
298 | {
299 | "internalType": "address",
300 | "name": "to",
301 | "type": "address"
302 | },
303 | {
304 | "internalType": "uint256",
305 | "name": "tokenId",
306 | "type": "uint256"
307 | }
308 | ],
309 | "name": "safeTransferFrom",
310 | "outputs": [],
311 | "stateMutability": "nonpayable",
312 | "type": "function"
313 | },
314 | {
315 | "inputs": [
316 | {
317 | "internalType": "address",
318 | "name": "from",
319 | "type": "address"
320 | },
321 | {
322 | "internalType": "address",
323 | "name": "to",
324 | "type": "address"
325 | },
326 | {
327 | "internalType": "uint256",
328 | "name": "tokenId",
329 | "type": "uint256"
330 | },
331 | {
332 | "internalType": "bytes",
333 | "name": "_data",
334 | "type": "bytes"
335 | }
336 | ],
337 | "name": "safeTransferFrom",
338 | "outputs": [],
339 | "stateMutability": "nonpayable",
340 | "type": "function"
341 | },
342 | {
343 | "inputs": [
344 | {
345 | "internalType": "address",
346 | "name": "operator",
347 | "type": "address"
348 | },
349 | {
350 | "internalType": "bool",
351 | "name": "approved",
352 | "type": "bool"
353 | }
354 | ],
355 | "name": "setApprovalForAll",
356 | "outputs": [],
357 | "stateMutability": "nonpayable",
358 | "type": "function"
359 | },
360 | {
361 | "inputs": [
362 | {
363 | "internalType": "bytes4",
364 | "name": "interfaceId",
365 | "type": "bytes4"
366 | }
367 | ],
368 | "name": "supportsInterface",
369 | "outputs": [
370 | {
371 | "internalType": "bool",
372 | "name": "",
373 | "type": "bool"
374 | }
375 | ],
376 | "stateMutability": "view",
377 | "type": "function"
378 | },
379 | {
380 | "inputs": [],
381 | "name": "symbol",
382 | "outputs": [
383 | {
384 | "internalType": "string",
385 | "name": "",
386 | "type": "string"
387 | }
388 | ],
389 | "stateMutability": "view",
390 | "type": "function"
391 | },
392 | {
393 | "inputs": [
394 | {
395 | "internalType": "uint256",
396 | "name": "tokenId",
397 | "type": "uint256"
398 | }
399 | ],
400 | "name": "tokenURI",
401 | "outputs": [
402 | {
403 | "internalType": "string",
404 | "name": "",
405 | "type": "string"
406 | }
407 | ],
408 | "stateMutability": "view",
409 | "type": "function"
410 | },
411 | {
412 | "inputs": [
413 | {
414 | "internalType": "address",
415 | "name": "from",
416 | "type": "address"
417 | },
418 | {
419 | "internalType": "address",
420 | "name": "to",
421 | "type": "address"
422 | },
423 | {
424 | "internalType": "uint256",
425 | "name": "tokenId",
426 | "type": "uint256"
427 | }
428 | ],
429 | "name": "transferFrom",
430 | "outputs": [],
431 | "stateMutability": "nonpayable",
432 | "type": "function"
433 | },
434 | {
435 | "inputs": [
436 | {
437 | "internalType": "address",
438 | "name": "newOwner",
439 | "type": "address"
440 | }
441 | ],
442 | "name": "transferOwnership",
443 | "outputs": [],
444 | "stateMutability": "nonpayable",
445 | "type": "function"
446 | }
447 | ],
448 | "bytecode": "0x60806040523480156200001157600080fd5b506040518060400160405280601081526020017f50726f66696c65496d6167654e667473000000000000000000000000000000008152506040518060400160405280600381526020017f50494e0000000000000000000000000000000000000000000000000000000000815250816000908051906020019062000096929190620001a6565b508060019080519060200190620000af929190620001a6565b505050620000d2620000c6620000d860201b60201c565b620000e060201b60201c565b620002bb565b600033905090565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b828054620001b49062000256565b90600052602060002090601f016020900481019282620001d8576000855562000224565b82601f10620001f357805160ff191683800117855562000224565b8280016001018555821562000224579182015b828111156200022357825182559160200191906001019062000206565b5b50905062000233919062000237565b5090565b5b808211156200025257600081600090555060010162000238565b5090565b600060028204905060018216806200026f57607f821691505b602082108114156200028657620002856200028c565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b612d3680620002cb6000396000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c8063715018a6116100a2578063b88d4fde11610071578063b88d4fde146102cd578063c87b56dd146102e9578063d0def52114610319578063e985e9c514610349578063f2fde38b1461037957610116565b8063715018a61461026b5780638da5cb5b1461027557806395d89b4114610293578063a22cb465146102b157610116565b806323b872dd116100e957806323b872dd146101b557806328904431146101d157806342842e0e146101ef5780636352211e1461020b57806370a082311461023b57610116565b806301ffc9a71461011b57806306fdde031461014b578063081812fc14610169578063095ea7b314610199575b600080fd5b61013560048036038101906101309190611d8c565b610395565b6040516101429190612287565b60405180910390f35b610153610477565b60405161016091906122a2565b60405180910390f35b610183600480360381019061017e9190611dde565b610509565b60405161019091906121fe565b60405180910390f35b6101b360048036038101906101ae9190611d50565b61058e565b005b6101cf60048036038101906101ca9190611bf6565b6106a6565b005b6101d9610706565b6040516101e69190612265565b60405180910390f35b61020960048036038101906102049190611bf6565b61086b565b005b61022560048036038101906102209190611dde565b61088b565b60405161023291906121fe565b60405180910390f35b61025560048036038101906102509190611b91565b61093d565b60405161026291906124c4565b60405180910390f35b6102736109f5565b005b61027d610a7d565b60405161028a91906121fe565b60405180910390f35b61029b610aa7565b6040516102a891906122a2565b60405180910390f35b6102cb60048036038101906102c69190611cc0565b610b39565b005b6102e760048036038101906102e29190611c45565b610b4f565b005b61030360048036038101906102fe9190611dde565b610bb1565b60405161031091906122a2565b60405180910390f35b610333600480360381019061032e9190611cfc565b610ca4565b60405161034091906124c4565b60405180910390f35b610363600480360381019061035e9190611bba565b610cdb565b6040516103709190612287565b60405180910390f35b610393600480360381019061038e9190611b91565b610d6f565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061046057507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610470575061046f82610e67565b5b9050919050565b60606000805461048690612728565b80601f01602080910402602001604051908101604052809291908181526020018280546104b290612728565b80156104ff5780601f106104d4576101008083540402835291602001916104ff565b820191906000526020600020905b8154815290600101906020018083116104e257829003601f168201915b5050505050905090565b600061051482610ed1565b610553576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161054a90612404565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006105998261088b565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561060a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060190612464565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610629610f3d565b73ffffffffffffffffffffffffffffffffffffffff161480610658575061065781610652610f3d565b610cdb565b5b610697576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161068e90612384565b60405180910390fd5b6106a18383610f45565b505050565b6106b76106b1610f3d565b82610ffe565b6106f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106ed90612484565b60405180910390fd5b6107018383836110dc565b505050565b606060006107146007611338565b905060008167ffffffffffffffff811115610758577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405190808252806020026020018201604052801561079157816020015b61077e611994565b8152602001906001900390816107765790505b50905060005b828111610862576107a781610ed1565b1561084f5760006107b782610bb1565b905060405180606001604052808381526020018281526020016040518060400160405280600181526020017f2000000000000000000000000000000000000000000000000000000000000000815250815250838381518110610842577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010181905250505b808061085a9061278b565b915050610797565b50809250505090565b61088683838360405180602001604052806000815250610b4f565b505050565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610934576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161092b906123c4565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156109ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109a5906123a4565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6109fd610f3d565b73ffffffffffffffffffffffffffffffffffffffff16610a1b610a7d565b73ffffffffffffffffffffffffffffffffffffffff1614610a71576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6890612424565b60405180910390fd5b610a7b6000611346565b565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060018054610ab690612728565b80601f0160208091040260200160405190810160405280929190818152602001828054610ae290612728565b8015610b2f5780601f10610b0457610100808354040283529160200191610b2f565b820191906000526020600020905b815481529060010190602001808311610b1257829003601f168201915b5050505050905090565b610b4b610b44610f3d565b838361140c565b5050565b610b60610b5a610f3d565b83610ffe565b610b9f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b9690612484565b60405180910390fd5b610bab84848484611579565b50505050565b6060610bbc82610ed1565b610bfb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bf2906124a4565b60405180910390fd5b6000600860008481526020019081526020016000208054610c1b90612728565b80601f0160208091040260200160405190810160405280929190818152602001828054610c4790612728565b8015610c945780601f10610c6957610100808354040283529160200191610c94565b820191906000526020600020905b815481529060010190602001808311610c7757829003601f168201915b5050505050905080915050919050565b600080610cb16007611338565b9050610cbd84826115d5565b610cc781846117a3565b610cd160076117cf565b8091505092915050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b610d77610f3d565b73ffffffffffffffffffffffffffffffffffffffff16610d95610a7d565b73ffffffffffffffffffffffffffffffffffffffff1614610deb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610de290612424565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610e5b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e52906122e4565b60405180910390fd5b610e6481611346565b50565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16610fb88361088b565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061100982610ed1565b611048576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161103f90612364565b60405180910390fd5b60006110538361088b565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806110c257508373ffffffffffffffffffffffffffffffffffffffff166110aa84610509565b73ffffffffffffffffffffffffffffffffffffffff16145b806110d357506110d28185610cdb565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff166110fc8261088b565b73ffffffffffffffffffffffffffffffffffffffff1614611152576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161114990612444565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156111c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111b990612324565b60405180910390fd5b6111cd8383836117e5565b6111d8600082610f45565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611228919061263e565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461127f91906125e8565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b600081600001549050919050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561147b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161147290612344565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161156c9190612287565b60405180910390a3505050565b6115848484846110dc565b611590848484846117ea565b6115cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115c6906122c4565b60405180910390fd5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611645576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161163c906123e4565b60405180910390fd5b61164e81610ed1565b1561168e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168590612304565b60405180910390fd5b61169a600083836117e5565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546116ea91906125e8565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b806008600084815260200190815260200160002090805190602001906117ca9291906119b5565b505050565b6001816000016000828254019250508190555050565b505050565b600061180b8473ffffffffffffffffffffffffffffffffffffffff16611981565b15611974578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611834610f3d565b8786866040518563ffffffff1660e01b81526004016118569493929190612219565b602060405180830381600087803b15801561187057600080fd5b505af19250505080156118a157506040513d601f19601f8201168201806040525081019061189e9190611db5565b60015b611924573d80600081146118d1576040519150601f19603f3d011682016040523d82523d6000602084013e6118d6565b606091505b5060008151141561191c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611913906122c4565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050611979565b600190505b949350505050565b600080823b905060008111915050919050565b60405180606001604052806000815260200160608152602001606081525090565b8280546119c190612728565b90600052602060002090601f0160209004810192826119e35760008555611a2a565b82601f106119fc57805160ff1916838001178555611a2a565b82800160010185558215611a2a579182015b82811115611a29578251825591602001919060010190611a0e565b5b509050611a379190611a3b565b5090565b5b80821115611a54576000816000905550600101611a3c565b5090565b6000611a6b611a6684612504565b6124df565b905082815260208101848484011115611a8357600080fd5b611a8e8482856126e6565b509392505050565b6000611aa9611aa484612535565b6124df565b905082815260208101848484011115611ac157600080fd5b611acc8482856126e6565b509392505050565b600081359050611ae381612ca4565b92915050565b600081359050611af881612cbb565b92915050565b600081359050611b0d81612cd2565b92915050565b600081519050611b2281612cd2565b92915050565b600082601f830112611b3957600080fd5b8135611b49848260208601611a58565b91505092915050565b600082601f830112611b6357600080fd5b8135611b73848260208601611a96565b91505092915050565b600081359050611b8b81612ce9565b92915050565b600060208284031215611ba357600080fd5b6000611bb184828501611ad4565b91505092915050565b60008060408385031215611bcd57600080fd5b6000611bdb85828601611ad4565b9250506020611bec85828601611ad4565b9150509250929050565b600080600060608486031215611c0b57600080fd5b6000611c1986828701611ad4565b9350506020611c2a86828701611ad4565b9250506040611c3b86828701611b7c565b9150509250925092565b60008060008060808587031215611c5b57600080fd5b6000611c6987828801611ad4565b9450506020611c7a87828801611ad4565b9350506040611c8b87828801611b7c565b925050606085013567ffffffffffffffff811115611ca857600080fd5b611cb487828801611b28565b91505092959194509250565b60008060408385031215611cd357600080fd5b6000611ce185828601611ad4565b9250506020611cf285828601611ae9565b9150509250929050565b60008060408385031215611d0f57600080fd5b6000611d1d85828601611ad4565b925050602083013567ffffffffffffffff811115611d3a57600080fd5b611d4685828601611b52565b9150509250929050565b60008060408385031215611d6357600080fd5b6000611d7185828601611ad4565b9250506020611d8285828601611b7c565b9150509250929050565b600060208284031215611d9e57600080fd5b6000611dac84828501611afe565b91505092915050565b600060208284031215611dc757600080fd5b6000611dd584828501611b13565b91505092915050565b600060208284031215611df057600080fd5b6000611dfe84828501611b7c565b91505092915050565b6000611e138383612189565b905092915050565b611e2481612672565b82525050565b6000611e3582612576565b611e3f81856125a4565b935083602082028501611e5185612566565b8060005b85811015611e8d5784840389528151611e6e8582611e07565b9450611e7983612597565b925060208a01995050600181019050611e55565b50829750879550505050505092915050565b611ea881612684565b82525050565b6000611eb982612581565b611ec381856125b5565b9350611ed38185602086016126f5565b611edc81612861565b840191505092915050565b6000611ef28261258c565b611efc81856125c6565b9350611f0c8185602086016126f5565b611f1581612861565b840191505092915050565b6000611f2b8261258c565b611f3581856125d7565b9350611f458185602086016126f5565b611f4e81612861565b840191505092915050565b6000611f666032836125d7565b9150611f7182612872565b604082019050919050565b6000611f896026836125d7565b9150611f94826128c1565b604082019050919050565b6000611fac601c836125d7565b9150611fb782612910565b602082019050919050565b6000611fcf6024836125d7565b9150611fda82612939565b604082019050919050565b6000611ff26019836125d7565b9150611ffd82612988565b602082019050919050565b6000612015602c836125d7565b9150612020826129b1565b604082019050919050565b60006120386038836125d7565b915061204382612a00565b604082019050919050565b600061205b602a836125d7565b915061206682612a4f565b604082019050919050565b600061207e6029836125d7565b915061208982612a9e565b604082019050919050565b60006120a16020836125d7565b91506120ac82612aed565b602082019050919050565b60006120c4602c836125d7565b91506120cf82612b16565b604082019050919050565b60006120e76020836125d7565b91506120f282612b65565b602082019050919050565b600061210a6029836125d7565b915061211582612b8e565b604082019050919050565b600061212d6021836125d7565b915061213882612bdd565b604082019050919050565b60006121506031836125d7565b915061215b82612c2c565b604082019050919050565b60006121736018836125d7565b915061217e82612c7b565b602082019050919050565b60006060830160008301516121a160008601826121e0565b50602083015184820360208601526121b98282611ee7565b915050604083015184820360408601526121d38282611ee7565b9150508091505092915050565b6121e9816126dc565b82525050565b6121f8816126dc565b82525050565b60006020820190506122136000830184611e1b565b92915050565b600060808201905061222e6000830187611e1b565b61223b6020830186611e1b565b61224860408301856121ef565b818103606083015261225a8184611eae565b905095945050505050565b6000602082019050818103600083015261227f8184611e2a565b905092915050565b600060208201905061229c6000830184611e9f565b92915050565b600060208201905081810360008301526122bc8184611f20565b905092915050565b600060208201905081810360008301526122dd81611f59565b9050919050565b600060208201905081810360008301526122fd81611f7c565b9050919050565b6000602082019050818103600083015261231d81611f9f565b9050919050565b6000602082019050818103600083015261233d81611fc2565b9050919050565b6000602082019050818103600083015261235d81611fe5565b9050919050565b6000602082019050818103600083015261237d81612008565b9050919050565b6000602082019050818103600083015261239d8161202b565b9050919050565b600060208201905081810360008301526123bd8161204e565b9050919050565b600060208201905081810360008301526123dd81612071565b9050919050565b600060208201905081810360008301526123fd81612094565b9050919050565b6000602082019050818103600083015261241d816120b7565b9050919050565b6000602082019050818103600083015261243d816120da565b9050919050565b6000602082019050818103600083015261245d816120fd565b9050919050565b6000602082019050818103600083015261247d81612120565b9050919050565b6000602082019050818103600083015261249d81612143565b9050919050565b600060208201905081810360008301526124bd81612166565b9050919050565b60006020820190506124d960008301846121ef565b92915050565b60006124e96124fa565b90506124f5828261275a565b919050565b6000604051905090565b600067ffffffffffffffff82111561251f5761251e612832565b5b61252882612861565b9050602081019050919050565b600067ffffffffffffffff8211156125505761254f612832565b5b61255982612861565b9050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b60006125f3826126dc565b91506125fe836126dc565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115612633576126326127d4565b5b828201905092915050565b6000612649826126dc565b9150612654836126dc565b925082821015612667576126666127d4565b5b828203905092915050565b600061267d826126bc565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156127135780820151818401526020810190506126f8565b83811115612722576000848401525b50505050565b6000600282049050600182168061274057607f821691505b6020821081141561275457612753612803565b5b50919050565b61276382612861565b810181811067ffffffffffffffff8211171561278257612781612832565b5b80604052505050565b6000612796826126dc565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156127c9576127c86127d4565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b7f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000602082015250565b7f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008201527f726f206164647265737300000000000000000000000000000000000000000000602082015250565b7f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460008201527f656e7420746f6b656e0000000000000000000000000000000000000000000000602082015250565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b7f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008201527f73206e6f74206f776e0000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008201527f776e6572206e6f7220617070726f766564000000000000000000000000000000602082015250565b7f555249206e6f74206578697374206f6e20746861742049440000000000000000600082015250565b612cad81612672565b8114612cb857600080fd5b50565b612cc481612684565b8114612ccf57600080fd5b50565b612cdb81612690565b8114612ce657600080fd5b50565b612cf2816126dc565b8114612cfd57600080fd5b5056fea2646970667358221220e021b3174a0c224a8d6e6d52546e7317d27c0a2ec7c898e28562f3689dc25af564736f6c63430008020033",
449 | "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101165760003560e01c8063715018a6116100a2578063b88d4fde11610071578063b88d4fde146102cd578063c87b56dd146102e9578063d0def52114610319578063e985e9c514610349578063f2fde38b1461037957610116565b8063715018a61461026b5780638da5cb5b1461027557806395d89b4114610293578063a22cb465146102b157610116565b806323b872dd116100e957806323b872dd146101b557806328904431146101d157806342842e0e146101ef5780636352211e1461020b57806370a082311461023b57610116565b806301ffc9a71461011b57806306fdde031461014b578063081812fc14610169578063095ea7b314610199575b600080fd5b61013560048036038101906101309190611d8c565b610395565b6040516101429190612287565b60405180910390f35b610153610477565b60405161016091906122a2565b60405180910390f35b610183600480360381019061017e9190611dde565b610509565b60405161019091906121fe565b60405180910390f35b6101b360048036038101906101ae9190611d50565b61058e565b005b6101cf60048036038101906101ca9190611bf6565b6106a6565b005b6101d9610706565b6040516101e69190612265565b60405180910390f35b61020960048036038101906102049190611bf6565b61086b565b005b61022560048036038101906102209190611dde565b61088b565b60405161023291906121fe565b60405180910390f35b61025560048036038101906102509190611b91565b61093d565b60405161026291906124c4565b60405180910390f35b6102736109f5565b005b61027d610a7d565b60405161028a91906121fe565b60405180910390f35b61029b610aa7565b6040516102a891906122a2565b60405180910390f35b6102cb60048036038101906102c69190611cc0565b610b39565b005b6102e760048036038101906102e29190611c45565b610b4f565b005b61030360048036038101906102fe9190611dde565b610bb1565b60405161031091906122a2565b60405180910390f35b610333600480360381019061032e9190611cfc565b610ca4565b60405161034091906124c4565b60405180910390f35b610363600480360381019061035e9190611bba565b610cdb565b6040516103709190612287565b60405180910390f35b610393600480360381019061038e9190611b91565b610d6f565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061046057507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610470575061046f82610e67565b5b9050919050565b60606000805461048690612728565b80601f01602080910402602001604051908101604052809291908181526020018280546104b290612728565b80156104ff5780601f106104d4576101008083540402835291602001916104ff565b820191906000526020600020905b8154815290600101906020018083116104e257829003601f168201915b5050505050905090565b600061051482610ed1565b610553576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161054a90612404565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006105998261088b565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561060a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060190612464565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610629610f3d565b73ffffffffffffffffffffffffffffffffffffffff161480610658575061065781610652610f3d565b610cdb565b5b610697576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161068e90612384565b60405180910390fd5b6106a18383610f45565b505050565b6106b76106b1610f3d565b82610ffe565b6106f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106ed90612484565b60405180910390fd5b6107018383836110dc565b505050565b606060006107146007611338565b905060008167ffffffffffffffff811115610758577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405190808252806020026020018201604052801561079157816020015b61077e611994565b8152602001906001900390816107765790505b50905060005b828111610862576107a781610ed1565b1561084f5760006107b782610bb1565b905060405180606001604052808381526020018281526020016040518060400160405280600181526020017f2000000000000000000000000000000000000000000000000000000000000000815250815250838381518110610842577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010181905250505b808061085a9061278b565b915050610797565b50809250505090565b61088683838360405180602001604052806000815250610b4f565b505050565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610934576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161092b906123c4565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156109ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109a5906123a4565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6109fd610f3d565b73ffffffffffffffffffffffffffffffffffffffff16610a1b610a7d565b73ffffffffffffffffffffffffffffffffffffffff1614610a71576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6890612424565b60405180910390fd5b610a7b6000611346565b565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060018054610ab690612728565b80601f0160208091040260200160405190810160405280929190818152602001828054610ae290612728565b8015610b2f5780601f10610b0457610100808354040283529160200191610b2f565b820191906000526020600020905b815481529060010190602001808311610b1257829003601f168201915b5050505050905090565b610b4b610b44610f3d565b838361140c565b5050565b610b60610b5a610f3d565b83610ffe565b610b9f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b9690612484565b60405180910390fd5b610bab84848484611579565b50505050565b6060610bbc82610ed1565b610bfb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bf2906124a4565b60405180910390fd5b6000600860008481526020019081526020016000208054610c1b90612728565b80601f0160208091040260200160405190810160405280929190818152602001828054610c4790612728565b8015610c945780601f10610c6957610100808354040283529160200191610c94565b820191906000526020600020905b815481529060010190602001808311610c7757829003601f168201915b5050505050905080915050919050565b600080610cb16007611338565b9050610cbd84826115d5565b610cc781846117a3565b610cd160076117cf565b8091505092915050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b610d77610f3d565b73ffffffffffffffffffffffffffffffffffffffff16610d95610a7d565b73ffffffffffffffffffffffffffffffffffffffff1614610deb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610de290612424565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610e5b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e52906122e4565b60405180910390fd5b610e6481611346565b50565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16610fb88361088b565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061100982610ed1565b611048576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161103f90612364565b60405180910390fd5b60006110538361088b565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806110c257508373ffffffffffffffffffffffffffffffffffffffff166110aa84610509565b73ffffffffffffffffffffffffffffffffffffffff16145b806110d357506110d28185610cdb565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff166110fc8261088b565b73ffffffffffffffffffffffffffffffffffffffff1614611152576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161114990612444565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156111c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111b990612324565b60405180910390fd5b6111cd8383836117e5565b6111d8600082610f45565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611228919061263e565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461127f91906125e8565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b600081600001549050919050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561147b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161147290612344565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161156c9190612287565b60405180910390a3505050565b6115848484846110dc565b611590848484846117ea565b6115cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115c6906122c4565b60405180910390fd5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611645576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161163c906123e4565b60405180910390fd5b61164e81610ed1565b1561168e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168590612304565b60405180910390fd5b61169a600083836117e5565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546116ea91906125e8565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b806008600084815260200190815260200160002090805190602001906117ca9291906119b5565b505050565b6001816000016000828254019250508190555050565b505050565b600061180b8473ffffffffffffffffffffffffffffffffffffffff16611981565b15611974578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611834610f3d565b8786866040518563ffffffff1660e01b81526004016118569493929190612219565b602060405180830381600087803b15801561187057600080fd5b505af19250505080156118a157506040513d601f19601f8201168201806040525081019061189e9190611db5565b60015b611924573d80600081146118d1576040519150601f19603f3d011682016040523d82523d6000602084013e6118d6565b606091505b5060008151141561191c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611913906122c4565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050611979565b600190505b949350505050565b600080823b905060008111915050919050565b60405180606001604052806000815260200160608152602001606081525090565b8280546119c190612728565b90600052602060002090601f0160209004810192826119e35760008555611a2a565b82601f106119fc57805160ff1916838001178555611a2a565b82800160010185558215611a2a579182015b82811115611a29578251825591602001919060010190611a0e565b5b509050611a379190611a3b565b5090565b5b80821115611a54576000816000905550600101611a3c565b5090565b6000611a6b611a6684612504565b6124df565b905082815260208101848484011115611a8357600080fd5b611a8e8482856126e6565b509392505050565b6000611aa9611aa484612535565b6124df565b905082815260208101848484011115611ac157600080fd5b611acc8482856126e6565b509392505050565b600081359050611ae381612ca4565b92915050565b600081359050611af881612cbb565b92915050565b600081359050611b0d81612cd2565b92915050565b600081519050611b2281612cd2565b92915050565b600082601f830112611b3957600080fd5b8135611b49848260208601611a58565b91505092915050565b600082601f830112611b6357600080fd5b8135611b73848260208601611a96565b91505092915050565b600081359050611b8b81612ce9565b92915050565b600060208284031215611ba357600080fd5b6000611bb184828501611ad4565b91505092915050565b60008060408385031215611bcd57600080fd5b6000611bdb85828601611ad4565b9250506020611bec85828601611ad4565b9150509250929050565b600080600060608486031215611c0b57600080fd5b6000611c1986828701611ad4565b9350506020611c2a86828701611ad4565b9250506040611c3b86828701611b7c565b9150509250925092565b60008060008060808587031215611c5b57600080fd5b6000611c6987828801611ad4565b9450506020611c7a87828801611ad4565b9350506040611c8b87828801611b7c565b925050606085013567ffffffffffffffff811115611ca857600080fd5b611cb487828801611b28565b91505092959194509250565b60008060408385031215611cd357600080fd5b6000611ce185828601611ad4565b9250506020611cf285828601611ae9565b9150509250929050565b60008060408385031215611d0f57600080fd5b6000611d1d85828601611ad4565b925050602083013567ffffffffffffffff811115611d3a57600080fd5b611d4685828601611b52565b9150509250929050565b60008060408385031215611d6357600080fd5b6000611d7185828601611ad4565b9250506020611d8285828601611b7c565b9150509250929050565b600060208284031215611d9e57600080fd5b6000611dac84828501611afe565b91505092915050565b600060208284031215611dc757600080fd5b6000611dd584828501611b13565b91505092915050565b600060208284031215611df057600080fd5b6000611dfe84828501611b7c565b91505092915050565b6000611e138383612189565b905092915050565b611e2481612672565b82525050565b6000611e3582612576565b611e3f81856125a4565b935083602082028501611e5185612566565b8060005b85811015611e8d5784840389528151611e6e8582611e07565b9450611e7983612597565b925060208a01995050600181019050611e55565b50829750879550505050505092915050565b611ea881612684565b82525050565b6000611eb982612581565b611ec381856125b5565b9350611ed38185602086016126f5565b611edc81612861565b840191505092915050565b6000611ef28261258c565b611efc81856125c6565b9350611f0c8185602086016126f5565b611f1581612861565b840191505092915050565b6000611f2b8261258c565b611f3581856125d7565b9350611f458185602086016126f5565b611f4e81612861565b840191505092915050565b6000611f666032836125d7565b9150611f7182612872565b604082019050919050565b6000611f896026836125d7565b9150611f94826128c1565b604082019050919050565b6000611fac601c836125d7565b9150611fb782612910565b602082019050919050565b6000611fcf6024836125d7565b9150611fda82612939565b604082019050919050565b6000611ff26019836125d7565b9150611ffd82612988565b602082019050919050565b6000612015602c836125d7565b9150612020826129b1565b604082019050919050565b60006120386038836125d7565b915061204382612a00565b604082019050919050565b600061205b602a836125d7565b915061206682612a4f565b604082019050919050565b600061207e6029836125d7565b915061208982612a9e565b604082019050919050565b60006120a16020836125d7565b91506120ac82612aed565b602082019050919050565b60006120c4602c836125d7565b91506120cf82612b16565b604082019050919050565b60006120e76020836125d7565b91506120f282612b65565b602082019050919050565b600061210a6029836125d7565b915061211582612b8e565b604082019050919050565b600061212d6021836125d7565b915061213882612bdd565b604082019050919050565b60006121506031836125d7565b915061215b82612c2c565b604082019050919050565b60006121736018836125d7565b915061217e82612c7b565b602082019050919050565b60006060830160008301516121a160008601826121e0565b50602083015184820360208601526121b98282611ee7565b915050604083015184820360408601526121d38282611ee7565b9150508091505092915050565b6121e9816126dc565b82525050565b6121f8816126dc565b82525050565b60006020820190506122136000830184611e1b565b92915050565b600060808201905061222e6000830187611e1b565b61223b6020830186611e1b565b61224860408301856121ef565b818103606083015261225a8184611eae565b905095945050505050565b6000602082019050818103600083015261227f8184611e2a565b905092915050565b600060208201905061229c6000830184611e9f565b92915050565b600060208201905081810360008301526122bc8184611f20565b905092915050565b600060208201905081810360008301526122dd81611f59565b9050919050565b600060208201905081810360008301526122fd81611f7c565b9050919050565b6000602082019050818103600083015261231d81611f9f565b9050919050565b6000602082019050818103600083015261233d81611fc2565b9050919050565b6000602082019050818103600083015261235d81611fe5565b9050919050565b6000602082019050818103600083015261237d81612008565b9050919050565b6000602082019050818103600083015261239d8161202b565b9050919050565b600060208201905081810360008301526123bd8161204e565b9050919050565b600060208201905081810360008301526123dd81612071565b9050919050565b600060208201905081810360008301526123fd81612094565b9050919050565b6000602082019050818103600083015261241d816120b7565b9050919050565b6000602082019050818103600083015261243d816120da565b9050919050565b6000602082019050818103600083015261245d816120fd565b9050919050565b6000602082019050818103600083015261247d81612120565b9050919050565b6000602082019050818103600083015261249d81612143565b9050919050565b600060208201905081810360008301526124bd81612166565b9050919050565b60006020820190506124d960008301846121ef565b92915050565b60006124e96124fa565b90506124f5828261275a565b919050565b6000604051905090565b600067ffffffffffffffff82111561251f5761251e612832565b5b61252882612861565b9050602081019050919050565b600067ffffffffffffffff8211156125505761254f612832565b5b61255982612861565b9050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b60006125f3826126dc565b91506125fe836126dc565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115612633576126326127d4565b5b828201905092915050565b6000612649826126dc565b9150612654836126dc565b925082821015612667576126666127d4565b5b828203905092915050565b600061267d826126bc565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156127135780820151818401526020810190506126f8565b83811115612722576000848401525b50505050565b6000600282049050600182168061274057607f821691505b6020821081141561275457612753612803565b5b50919050565b61276382612861565b810181811067ffffffffffffffff8211171561278257612781612832565b5b80604052505050565b6000612796826126dc565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156127c9576127c86127d4565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b7f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000602082015250565b7f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008201527f726f206164647265737300000000000000000000000000000000000000000000602082015250565b7f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460008201527f656e7420746f6b656e0000000000000000000000000000000000000000000000602082015250565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b7f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008201527f73206e6f74206f776e0000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008201527f776e6572206e6f7220617070726f766564000000000000000000000000000000602082015250565b7f555249206e6f74206578697374206f6e20746861742049440000000000000000600082015250565b612cad81612672565b8114612cb857600080fd5b50565b612cc481612684565b8114612ccf57600080fd5b50565b612cdb81612690565b8114612ce657600080fd5b50565b612cf2816126dc565b8114612cfd57600080fd5b5056fea2646970667358221220e021b3174a0c224a8d6e6d52546e7317d27c0a2ec7c898e28562f3689dc25af564736f6c63430008020033",
450 | "linkReferences": {},
451 | "deployedLinkReferences": {}
452 | }
453 |
--------------------------------------------------------------------------------
/client/lib/client.js:
--------------------------------------------------------------------------------
1 | import sanityClient from '@sanity/client'
2 |
3 | export const client = sanityClient({
4 | projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,
5 | dataset: 'production',
6 | apiVersion: 'v1',
7 | token: process.env.NEXT_PUBLIC_SANITY_TOKEN,
8 | useCdn: false,
9 | })
10 |
--------------------------------------------------------------------------------
/client/lib/constants.js:
--------------------------------------------------------------------------------
1 | import ProfileImageMinterContractAbi from './ProfileImageNfts.json'
2 |
3 | export const contractABI = ProfileImageMinterContractAbi.abi
4 | export const contractAddress = '0xA10F4e6054CF7C9d0aEa9428990691B4989AB185'
5 |
6 | export const customStyles = {
7 | content: {
8 | top: '30%',
9 | left: '50%',
10 | right: 'auto',
11 | bottom: 'auto',
12 | transform: 'translate(-50%, -50%)',
13 | backgroundColor: '',
14 | padding: 0,
15 | border: 'none',
16 | },
17 | overlay: {
18 | backgroundColor: '#334250a7',
19 | },
20 | }
21 |
--------------------------------------------------------------------------------
/client/lib/hexStyles.css:
--------------------------------------------------------------------------------
1 | .hex {
2 | display: grid;
3 | place-items: center;
4 | position: relative;
5 | overflow: hidden;
6 | width: 6.5rem;
7 | height: 6rem;
8 | box-sizing: border-box;
9 | clip-path: polygon(0% 50%, 25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%);
10 | -webkit-clip-path: polygon(
11 | 0% 50%,
12 | 25% 0%,
13 | 75% 0%,
14 | 100% 50%,
15 | 75% 100%,
16 | 25% 100%
17 | );
18 | -moz-clip-path: polygon(0% 50%, 25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%);
19 | }
20 |
21 | .smallHex {
22 | display: grid;
23 | place-items: center;
24 | position: relative;
25 | overflow: hidden;
26 | box-sizing: border-box;
27 | clip-path: polygon(0% 50%, 25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%);
28 | -webkit-clip-path: polygon(
29 | 0% 50%,
30 | 25% 0%,
31 | 75% 0%,
32 | 100% 50%,
33 | 75% 100%,
34 | 25% 100%
35 | );
36 | -moz-clip-path: polygon(0% 50%, 25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%);
37 | }
38 |
--------------------------------------------------------------------------------
/client/lib/pinata.js:
--------------------------------------------------------------------------------
1 | const key = process.env.NEXT_PUBLIC_PINATA_API_KEY
2 | const secret = process.env.NEXT_PUBLIC_PINATA_API_SECRET
3 |
4 | import axios from 'axios'
5 |
6 | export const pinJSONToIPFS = async json => {
7 | const url = `https://api.pinata.cloud/pinning/pinJSONToIPFS`
8 | return axios
9 | .post(url, json, {
10 | headers: {
11 | pinata_api_key: key,
12 | pinata_secret_api_key: secret,
13 | },
14 | })
15 | .then(function (response) {
16 | return response.data.IpfsHash
17 | })
18 | .catch(function (error) {
19 | console.log(error)
20 | })
21 | }
22 |
23 | export const pinFileToIPFS = async (file, pinataMetaData) => {
24 | const url = `https://api.pinata.cloud/pinning/pinFileToIPFS`
25 |
26 | let data = new FormData()
27 |
28 | data.append('file', file)
29 | data.append('pinataMetadata', JSON.stringify(pinataMetaData))
30 |
31 | return axios
32 | .post(url, data, {
33 | maxBodyLength: 'Infinity',
34 | headers: {
35 | 'Content-Type': `multipart/form-data; boundary=${data._boundary}`,
36 | pinata_api_key: key,
37 | pinata_secret_api_key: secret,
38 | },
39 | })
40 | .then(function (response) {
41 | return response.data.IpfsHash
42 | })
43 | .catch(function (error) {
44 | console.log(error)
45 | })
46 | }
47 |
--------------------------------------------------------------------------------
/client/lib/static.js:
--------------------------------------------------------------------------------
1 | export const news = [
2 | {
3 | category: 'Clever Programmer • LIVE',
4 | title: 'CP is live on YouTube!',
5 | image:
6 | 'https://kajabi-storefronts-production.kajabi-cdn.com/kajabi-storefronts-production/themes/284832/settings_images/rLlCifhXRJiT0RoN2FjK_Logo_roundbackground_black.png',
7 | },
8 | {
9 | category: 'Databases • Trending',
10 | title:
11 | 'Sanity is giving you free Boosted plan, use --coupon cleverprogrammer',
12 | image: 'https://avatars.githubusercontent.com/u/17177659?s=280&v=4',
13 | },
14 | {
15 | category: 'Web3.0 • Trending',
16 | title: 'Blockchain developers make over $150k',
17 | image:
18 | 'https://cloudfront-us-east-1.images.arcpublishing.com/coindesk/L424HUS65FGRVFPTYYPG24CIYI.jpg',
19 | },
20 | {
21 | category: 'ReactJS • Trending',
22 | title: 'Join Profit with React while spots last',
23 | image:
24 | 'https://kajabi-storefronts-production.kajabi-cdn.com/kajabi-storefronts-production/site/18907/products/cIkAZXNyRZimRw4uqXVX_gDvYTtwQsC33KZqCtbpB_image.jpg',
25 | },
26 | ]
27 |
28 | export const whoToFollow = [
29 | {
30 | name: 'Rafeh Qazi',
31 | handle: '@cleverqazi',
32 | avatar:
33 | 'https://pbs.twimg.com/profile_images/1472075657920221184/JhAI3WGm_400x400.jpg',
34 | },
35 | {
36 | name: 'David Rakosi',
37 | handle: '@0xDavidRakosi',
38 | avatar:
39 | 'https://pbs.twimg.com/profile_images/1282571486465855491/98xO6N0F_400x400.jpg',
40 | },
41 | {
42 | name: 'Sanity.io',
43 | handle: '@sanity_io',
44 | avatar: 'https://avatars.githubusercontent.com/u/17177659?s=280&v=4',
45 | },
46 | ]
47 |
--------------------------------------------------------------------------------
/client/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 |
--------------------------------------------------------------------------------
/client/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | reactStrictMode: true,
4 | }
5 |
6 | // module.exports = nextConfig
7 |
8 | // module.exports = {
9 | // webpack5: true,
10 | // webpack: config => {
11 | // config.resolve.fallback = { fs: false }
12 |
13 | // return config
14 | // },
15 | // reactStrictMode: true,
16 | // }
17 |
--------------------------------------------------------------------------------
/client/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "twitter-web3",
3 | "private": true,
4 | "scripts": {
5 | "dev": "next dev",
6 | "build": "next build",
7 | "start": "next start",
8 | "lint": "next lint"
9 | },
10 | "dependencies": {
11 | "@alch/alchemy-web3": "^1.2.3",
12 | "@sanity/client": "^3.0.4",
13 | "@types/react-modal": "^3.13.1",
14 | "axios": "^0.25.0",
15 | "dotenv": "^16.0.0",
16 | "ethers": "^5.5.4",
17 | "next": "12.0.10",
18 | "nft.storage": "^6.0.0",
19 | "react": "17.0.2",
20 | "react-dom": "17.0.2",
21 | "react-icons": "^4.3.1",
22 | "react-modal": "^3.14.4",
23 | "react-spinners": "^0.11.0",
24 | "timeago.js": "^4.0.2",
25 | "web3": "^1.7.0"
26 | },
27 | "devDependencies": {
28 | "@types/node": "17.0.14",
29 | "@types/react": "17.0.38",
30 | "autoprefixer": "^10.4.2",
31 | "eslint": "8.8.0",
32 | "eslint-config-next": "12.0.10",
33 | "postcss": "^8.4.6",
34 | "tailwindcss": "^3.0.18",
35 | "typescript": "4.5.5"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/client/pages/_app.tsx:
--------------------------------------------------------------------------------
1 | import '../styles/globals.css'
2 | import type { AppProps } from 'next/app'
3 | import { TwitterProvider } from '../context/TwitterContext'
4 | import '../lib/hexStyles.css'
5 |
6 | function MyApp({ Component, pageProps }: AppProps) {
7 | return (
8 |
9 |
10 |
11 | )
12 | }
13 |
14 | export default MyApp
15 |
--------------------------------------------------------------------------------
/client/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 |
--------------------------------------------------------------------------------
/client/pages/index.tsx:
--------------------------------------------------------------------------------
1 | import { useContext } from 'react'
2 | import { TwitterContext } from '../context/TwitterContext'
3 | import Feed from '../components/home/Feed'
4 | import Sidebar from '../components/Sidebar'
5 | import Widgets from '../components/Widgets'
6 | import metamaskLogo from '../assets/metamask.png'
7 | import errorImg from '../assets/error.png'
8 | import Image from 'next/image'
9 |
10 | const style = {
11 | wrapper: `flex justify-center h-screen w-screen select-none bg-[#15202b] text-white`,
12 | content: `max-w-[1400px] w-2/3 flex justify-between`,
13 | loginContainer: `w-full h-full flex flex-col justify-center items-center pb-48`,
14 | walletConnectButton: `text-2xl text-black bg-white font-bold mb-[-3rem] mt-[3rem] px-6 py-4 rounded-full cursor-pointer hover:bg-[#d7dbdc]`,
15 | loginContent: `text-3xl font-bold text-center mt-24`,
16 | }
17 |
18 | const Home = () => {
19 | const { appStatus, connectWallet } = useContext(TwitterContext)
20 |
21 | const app = (status = appStatus) => {
22 | switch (status) {
23 | case 'connected':
24 | return userLoggedIn
25 |
26 | case 'notConnected':
27 | return noUserFound
28 |
29 | case 'noMetaMask':
30 | return noMetaMaskFound
31 |
32 | case 'error':
33 | return error
34 |
35 | default:
36 | return loading
37 | }
38 | }
39 |
40 | const userLoggedIn = (
41 |
42 |
43 |
44 |
45 |
46 | )
47 |
48 | const noUserFound = (
49 |
50 |
51 |
connectWallet()}
54 | >
55 | Connect Wallet
56 |
57 |
Connect to Metamask.
58 |
59 | )
60 |
61 | const noMetaMaskFound = (
62 |
75 | )
76 |
77 | const error = (
78 |
79 |
80 |
81 | An error occurred. Please try again later or from another browser.
82 |
83 |
84 | )
85 |
86 | const loading = (
87 |
90 | )
91 |
92 | return {app(appStatus)}
93 | }
94 |
95 | export default Home
96 |
--------------------------------------------------------------------------------
/client/pages/profile.tsx:
--------------------------------------------------------------------------------
1 | import ProfileHeader from '../components/profile/ProfileHeader'
2 | import ProfileTweets from '../components/profile/ProfileTweets'
3 | import Sidebar from '../components/Sidebar'
4 | import Widgets from '../components/Widgets'
5 |
6 | const style = {
7 | wrapper: `flex justify-center h-screen w-screen select-none bg-[#15202b] text-white`,
8 | content: `max-w-[1400px] w-2/3 flex justify-between`,
9 | mainContent: `flex-[2] border-r border-l border-[#38444d] overflow-y-scroll`,
10 | }
11 |
12 | const profile = () => {
13 | return (
14 |
24 | )
25 | }
26 |
27 | export default profile
28 |
--------------------------------------------------------------------------------
/client/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/client/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CleverProgrammers/twitter-blockchain-youtube/a352cdb72195cf0d918277ebff3e1bbec7ccf878/client/public/favicon.ico
--------------------------------------------------------------------------------
/client/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/styles/Home.module.css:
--------------------------------------------------------------------------------
1 | .widgets__input {
2 | display: flex;
3 | align-items: center;
4 | background-color: #e6ecf0;
5 | padding: 10px;
6 | border-radius: 20px;
7 | margin-top: 10px;
8 | margin-left: 20px;
9 | }
10 |
11 | .widgets__input > input {
12 | border: none;
13 | background-color: #e6ecf0;
14 | }
15 |
16 | .widgets__searchIcon {
17 | color: gray;
18 | }
19 |
20 | .widgets__widgetContainer {
21 | margin-top: 15px;
22 | margin-left: 20px;
23 | padding: 20px;
24 | background-color: #f5f8fa;
25 | border-radius: 20px;
26 | }
27 |
28 | .widgets__widgetContainer > h2 {
29 | font-size: 18px;
30 | font-weight: 800;
31 | }
32 |
--------------------------------------------------------------------------------
/client/styles/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | /* Hide scrollbar for Chrome, Safari and Opera */
6 | .no-scrollbar::-webkit-scrollbar {
7 | display: none;
8 | }
9 |
10 | /* Hide scrollbar for IE, Edge and Firefox */
11 | .no-scrollbar {
12 | -ms-overflow-style: none; /* IE and Edge */
13 | scrollbar-width: none; /* Firefox */
14 | }
15 |
--------------------------------------------------------------------------------
/client/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 | },
9 | plugins: [],
10 | }
11 |
--------------------------------------------------------------------------------
/client/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 |
--------------------------------------------------------------------------------
/smart_contract/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CleverProgrammers/twitter-blockchain-youtube/a352cdb72195cf0d918277ebff3e1bbec7ccf878/smart_contract/.DS_Store
--------------------------------------------------------------------------------
/smart_contract/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .env
3 | coverage
4 | coverage.json
5 | typechain
6 |
7 | #Hardhat files
8 | cache
9 | artifacts
10 |
--------------------------------------------------------------------------------
/smart_contract/README.md:
--------------------------------------------------------------------------------
1 | # Basic Sample Hardhat Project
2 |
3 | This project demonstrates a basic Hardhat use case. It comes with a sample contract, a test for that contract, a sample script that deploys that contract, and an example of a task implementation, which simply lists the available accounts.
4 |
5 | Try running some of the following tasks:
6 |
7 | ```shell
8 | npx hardhat accounts
9 | npx hardhat compile
10 | npx hardhat clean
11 | npx hardhat test
12 | npx hardhat node
13 | node scripts/sample-script.js
14 | npx hardhat help
15 | ```
16 |
--------------------------------------------------------------------------------
/smart_contract/contracts/MintProfileImage.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity ^0.8.2;
3 |
4 | import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
5 | import "@openzeppelin/contracts/access/Ownable.sol";
6 | import "@openzeppelin/contracts/utils/Counters.sol";
7 |
8 | contract ProfileImageNfts is ERC721, Ownable {
9 |
10 | using Counters for Counters.Counter;
11 | using Strings for uint256;
12 |
13 | Counters.Counter _tokenIds;
14 | mapping(uint256 => string) _tokenURIs;
15 |
16 | struct RenderToken{
17 | uint256 id;
18 | string uri;
19 | string space;
20 | }
21 |
22 | constructor() ERC721("ProfileImageNfts","PIN"){}
23 |
24 | function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal {
25 | _tokenURIs[tokenId] = _tokenURI;
26 | }
27 |
28 | function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
29 | require(_exists(tokenId),"URI not exist on that ID");
30 | string memory _RUri = _tokenURIs[tokenId];
31 | return _RUri;
32 | }
33 |
34 | function getAlltoken() public view returns (RenderToken[] memory){
35 | uint256 latestId = _tokenIds.current();
36 | RenderToken[] memory res = new RenderToken[](latestId);
37 | for(uint256 i = 0; i <= latestId ; i++){
38 | if(_exists(i)){
39 | string memory uri = tokenURI(i);
40 | res[i] = RenderToken(i,uri," ");
41 | }
42 | }
43 | return res;
44 | }
45 |
46 | function mint(address recipents, string memory _uri) public returns (uint256){
47 | uint256 newId = _tokenIds.current();
48 | _mint(recipents,newId);
49 | _setTokenURI(newId,_uri);
50 | _tokenIds.increment();
51 | return newId;
52 | }
53 | }
--------------------------------------------------------------------------------
/smart_contract/hardhat.config.js:
--------------------------------------------------------------------------------
1 | require('@nomiclabs/hardhat-waffle')
2 |
3 | module.exports = {
4 | solidity: '0.8.2',
5 | networks: {
6 | rinkeby: {
7 | url: 'https://eth-rinkeby.alchemyapi.io/v2/_cqfxl5yx4HFvVpPh0HgNOwKHpYANpiX',
8 | accounts: [
9 | 'f2679263aadf9db7949246a5265f7cf0b0aece610ba4d84dcfc9304ccd050d0c',
10 | ],
11 | },
12 | },
13 | }
14 |
--------------------------------------------------------------------------------
/smart_contract/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "hardhat-project",
3 | "devDependencies": {
4 | "@nomiclabs/hardhat-ethers": "^2.0.4",
5 | "@nomiclabs/hardhat-waffle": "^2.0.2",
6 | "chai": "^4.3.6",
7 | "ethereum-waffle": "^3.4.0",
8 | "ethers": "^5.5.4",
9 | "hardhat": "^2.8.3"
10 | },
11 | "dependencies": {
12 | "@openzeppelin/contracts": "^4.4.2"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/smart_contract/scripts/deploy.js:
--------------------------------------------------------------------------------
1 | const main = async () => {
2 | const profileImageFactory = await hre.ethers.getContractFactory(
3 | 'ProfileImageNfts',
4 | )
5 | const profileImageContract = await profileImageFactory.deploy()
6 |
7 | await profileImageContract.deployed()
8 |
9 | console.log('Profile Image Minter deployed to:', profileImageContract.address)
10 | }
11 |
12 | ;(async () => {
13 | try {
14 | await main()
15 | process.exit(0)
16 | } catch (error) {
17 | console.error(error)
18 | process.exit(1)
19 | }
20 | })()
21 |
--------------------------------------------------------------------------------
/smart_contract/test/sample-test.js:
--------------------------------------------------------------------------------
1 | const { expect } = require("chai");
2 | const { ethers } = require("hardhat");
3 |
4 | describe("Greeter", function () {
5 | it("Should return the new greeting once it's changed", async function () {
6 | const Greeter = await ethers.getContractFactory("Greeter");
7 | const greeter = await Greeter.deploy("Hello, world!");
8 | await greeter.deployed();
9 |
10 | expect(await greeter.greet()).to.equal("Hello, world!");
11 |
12 | const setGreetingTx = await greeter.setGreeting("Hola, mundo!");
13 |
14 | // wait until the transaction is mined
15 | await setGreetingTx.wait();
16 |
17 | expect(await greeter.greet()).to.equal("Hola, mundo!");
18 | });
19 | });
20 |
--------------------------------------------------------------------------------
/studio/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CleverProgrammers/twitter-blockchain-youtube/a352cdb72195cf0d918277ebff3e1bbec7ccf878/studio/.DS_Store
--------------------------------------------------------------------------------
/studio/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@sanity/eslint-config-studio"
3 | }
4 |
--------------------------------------------------------------------------------
/studio/README.md:
--------------------------------------------------------------------------------
1 | # Sanity Clean Content Studio
2 |
3 | Congratulations, you have now installed the Sanity Content Studio, an open source real-time content editing environment connected to the Sanity backend.
4 |
5 | Now you can do the following things:
6 |
7 | - [Read “getting started” in the docs](https://www.sanity.io/docs/introduction/getting-started?utm_source=readme)
8 | - [Join the community Slack](https://slack.sanity.io/?utm_source=readme)
9 | - [Extend and build plugins](https://www.sanity.io/docs/content-studio/extending?utm_source=readme)
10 |
--------------------------------------------------------------------------------
/studio/config/.checksums:
--------------------------------------------------------------------------------
1 | {
2 | "#": "Used by Sanity to keep track of configuration file checksums, do not delete or modify!",
3 | "@sanity/default-layout": "bb034f391ba508a6ca8cd971967cbedeb131c4d19b17b28a0895f32db5d568ea",
4 | "@sanity/default-login": "6fb6d3800aa71346e1b84d95bbcaa287879456f2922372bb0294e30b968cd37f",
5 | "@sanity/form-builder": "b38478227ba5e22c91981da4b53436df22e48ff25238a55a973ed620be5068aa",
6 | "@sanity/data-aspects": "d199e2c199b3e26cd28b68dc84d7fc01c9186bf5089580f2e2446994d36b3cb6"
7 | }
8 |
--------------------------------------------------------------------------------
/studio/config/@sanity/data-aspects.json:
--------------------------------------------------------------------------------
1 | {
2 | "listOptions": {}
3 | }
4 |
--------------------------------------------------------------------------------
/studio/config/@sanity/default-layout.json:
--------------------------------------------------------------------------------
1 | {
2 | "toolSwitcher": {
3 | "order": [],
4 | "hidden": []
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/studio/config/@sanity/default-login.json:
--------------------------------------------------------------------------------
1 | {
2 | "providers": {
3 | "mode": "append",
4 | "redirectOnSingle": false,
5 | "entries": []
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/studio/config/@sanity/form-builder.json:
--------------------------------------------------------------------------------
1 | {
2 | "images": {
3 | "directUploads": true
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/studio/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "twitterclone",
3 | "private": true,
4 | "version": "1.0.0",
5 | "description": "",
6 | "main": "package.json",
7 | "author": "David Rakosi ",
8 | "license": "UNLICENSED",
9 | "scripts": {
10 | "start": "sanity start",
11 | "build": "sanity build"
12 | },
13 | "keywords": [
14 | "sanity"
15 | ],
16 | "dependencies": {
17 | "@sanity/base": "^2.26.0",
18 | "@sanity/core": "^2.26.0",
19 | "@sanity/default-layout": "^2.26.0",
20 | "@sanity/default-login": "^2.26.0",
21 | "@sanity/desk-tool": "^2.26.0",
22 | "@sanity/eslint-config-studio": "^2.0.0",
23 | "@sanity/vision": "^2.26.0",
24 | "eslint": "^8.6.0",
25 | "prop-types": "^15.7",
26 | "react": "^17.0",
27 | "react-dom": "^17.0",
28 | "styled-components": "^5.2.0"
29 | },
30 | "devDependencies": {}
31 | }
32 |
--------------------------------------------------------------------------------
/studio/plugins/.gitkeep:
--------------------------------------------------------------------------------
1 | User-specific packages can be placed here
2 |
--------------------------------------------------------------------------------
/studio/sanity.json:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 | "project": {
4 | "name": "twitter-clone"
5 | },
6 | "api": {
7 | "projectId": "kfzwap55",
8 | "dataset": "production"
9 | },
10 | "plugins": [
11 | "@sanity/base",
12 | "@sanity/default-layout",
13 | "@sanity/default-login",
14 | "@sanity/desk-tool"
15 | ],
16 | "env": {
17 | "development": {
18 | "plugins": [
19 | "@sanity/vision"
20 | ]
21 | }
22 | },
23 | "parts": [
24 | {
25 | "name": "part:@sanity/base/schema",
26 | "path": "./schemas/schema"
27 | }
28 | ]
29 | }
30 |
--------------------------------------------------------------------------------
/studio/schemas/schema.js:
--------------------------------------------------------------------------------
1 | import createSchema from 'part:@sanity/base/schema-creator'
2 | import schemaTypes from 'all:part:@sanity/base/schema-type'
3 |
4 | import { userSchema } from './userSchema'
5 | import { tweetSchema } from './tweetSchema'
6 |
7 | export default createSchema({
8 | name: 'default',
9 | types: schemaTypes.concat([userSchema, tweetSchema]),
10 | })
11 |
--------------------------------------------------------------------------------
/studio/schemas/tweetSchema.js:
--------------------------------------------------------------------------------
1 | export const tweetSchema = {
2 | name: 'tweets',
3 | type: 'document',
4 | title: 'Tweets',
5 | fields: [
6 | {
7 | name: 'tweet',
8 | type: 'string',
9 | title: 'Tweet',
10 | },
11 | {
12 | name: 'timestamp',
13 | type: 'datetime',
14 | title: 'Timestamp',
15 | },
16 | {
17 | name: 'author',
18 | title: 'Author',
19 | type: 'reference',
20 | to: [{ type: 'users' }],
21 | },
22 | ],
23 | }
24 |
--------------------------------------------------------------------------------
/studio/schemas/userSchema.js:
--------------------------------------------------------------------------------
1 | export const userSchema = {
2 | name: 'users',
3 | type: 'document',
4 | title: 'Users',
5 | fields: [
6 | {
7 | name: 'name',
8 | type: 'string',
9 | title: 'Name',
10 | },
11 | {
12 | name: 'walletAddress',
13 | type: 'string',
14 | title: 'Wallet Address',
15 | },
16 | {
17 | name: 'profileImage',
18 | type: 'string',
19 | title: 'Profile Image',
20 | },
21 | {
22 | name: 'isProfileImageNft',
23 | title: 'Is Profile Image NFT',
24 | type: 'boolean',
25 | },
26 | {
27 | name: 'coverImage',
28 | type: 'string',
29 | title: 'Cover Image',
30 | },
31 | {
32 | name: 'tweets',
33 | title: 'Tweets',
34 | type: 'array',
35 | of: [
36 | {
37 | type: 'reference',
38 | to: [{ type: 'tweets' }],
39 | },
40 | ],
41 | },
42 | ],
43 | }
44 |
--------------------------------------------------------------------------------
/studio/static/.gitkeep:
--------------------------------------------------------------------------------
1 | Files placed here will be served by the Sanity server under the `/static`-prefix
2 |
--------------------------------------------------------------------------------
/studio/static/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CleverProgrammers/twitter-blockchain-youtube/a352cdb72195cf0d918277ebff3e1bbec7ccf878/studio/static/favicon.ico
--------------------------------------------------------------------------------
/studio/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | // Note: This config is only used to help editors like VS Code understand/resolve
3 | // parts, the actual transpilation is done by babel. Any compiler configuration in
4 | // here will be ignored.
5 | "include": ["./node_modules/@sanity/base/types/**/*.ts", "./**/*.ts", "./**/*.tsx"]
6 | }
7 |
--------------------------------------------------------------------------------