├── .eslintrc.json ├── .gitignore ├── CODEOWNERS ├── README.md ├── assets ├── dropdown.png ├── friends.png ├── groups.png ├── marketplace.png ├── memories.png ├── sol.png └── watch.png ├── components ├── Comment.js ├── CommentSection.js ├── Contact.js ├── CreateComment.js ├── CreatePost.js ├── Feed.js ├── Header.js ├── Post.js ├── RightSidebar.js ├── Sidebar.js └── SignUp.js ├── context ├── WalletConnectionProvider.js ├── context.js └── useWalletBalance.js ├── facebook-clone ├── .gitignore ├── Anchor.toml ├── Cargo.lock ├── Cargo.toml ├── app │ └── start.ts ├── migrations │ └── deploy.ts ├── package.json ├── programs │ └── facebook-clone │ │ ├── Cargo.toml │ │ ├── Xargo.toml │ │ └── src │ │ └── lib.rs ├── tests │ └── facebook-clone.ts └── tsconfig.json ├── lib └── sanity.js ├── next.config.js ├── package.json ├── pages ├── _app.js ├── api │ ├── createUser.js │ └── fetchUsers.js └── index.js ├── postcss.config.js ├── public ├── favicon.ico └── vercel.svg ├── static └── static.js ├── studio ├── .eslintrc ├── README.md ├── config │ ├── .checksums │ └── @sanity │ │ ├── data-aspects.json │ │ ├── default-layout.json │ │ ├── default-login.json │ │ ├── form-builder.json │ │ └── vision.json ├── package.json ├── plugins │ └── .gitkeep ├── sanity.json ├── schemas │ ├── schema.js │ └── userSchema.js ├── static │ ├── .gitkeep │ └── favicon.ico └── tsconfig.json ├── styles ├── Login.css └── globals.css ├── tailwind.config.js └── utils ├── const.js ├── facebook_clone.json └── get-program.js /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | .pnp 6 | .pnp.js 7 | 8 | .env.local 9 | .env 10 | 11 | # testing 12 | coverage 13 | 14 | # next.js 15 | .next/ 16 | out/ 17 | 18 | # production 19 | build 20 | 21 | # misc 22 | .DS_Store 23 | *.pem 24 | 25 | # debug 26 | npm-debug.log* 27 | yarn-debug.log* 28 | yarn-error.log* 29 | .pnpm-debug.log* 30 | 31 | # local env files 32 | .env*.local 33 | 34 | # vercel 35 | .vercel 36 | 37 | # rust specific 38 | .anchor 39 | .DS_Store 40 | target 41 | **/*.rs.bk 42 | 43 | # Sanity IO 44 | # Logs 45 | logs 46 | *.log 47 | 48 | # Coverage directory used by tools like istanbul 49 | coverage 50 | 51 | # Compiled sanity studio 52 | dist 53 | 54 | # other 55 | yarn.lock 56 | yarn-error.log 57 | package-lock.json 58 | .dccache -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @davidrakosi -------------------------------------------------------------------------------- /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.js`. 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.js`. 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 | -------------------------------------------------------------------------------- /assets/dropdown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleverProgrammers/facebook-solana-blockchain/504d29ece92c52f43e94ce6af1125f7f8423cfb2/assets/dropdown.png -------------------------------------------------------------------------------- /assets/friends.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleverProgrammers/facebook-solana-blockchain/504d29ece92c52f43e94ce6af1125f7f8423cfb2/assets/friends.png -------------------------------------------------------------------------------- /assets/groups.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleverProgrammers/facebook-solana-blockchain/504d29ece92c52f43e94ce6af1125f7f8423cfb2/assets/groups.png -------------------------------------------------------------------------------- /assets/marketplace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleverProgrammers/facebook-solana-blockchain/504d29ece92c52f43e94ce6af1125f7f8423cfb2/assets/marketplace.png -------------------------------------------------------------------------------- /assets/memories.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleverProgrammers/facebook-solana-blockchain/504d29ece92c52f43e94ce6af1125f7f8423cfb2/assets/memories.png -------------------------------------------------------------------------------- /assets/sol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleverProgrammers/facebook-solana-blockchain/504d29ece92c52f43e94ce6af1125f7f8423cfb2/assets/sol.png -------------------------------------------------------------------------------- /assets/watch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleverProgrammers/facebook-solana-blockchain/504d29ece92c52f43e94ce6af1125f7f8423cfb2/assets/watch.png -------------------------------------------------------------------------------- /components/Comment.js: -------------------------------------------------------------------------------- 1 | import Image from 'next/image' 2 | import TimeAgo from 'javascript-time-ago' 3 | import en from 'javascript-time-ago/locale/en.json' 4 | 5 | TimeAgo.addDefaultLocale(en) 6 | 7 | const timeAgo = new TimeAgo('en-US') 8 | 9 | const Comment = ({ comment }) => { 10 | const style = { 11 | commentWrapper: `flex`, 12 | profileImageContainer: `object-cover mr-2`, 13 | profileImage: `rounded-full`, 14 | commentContainer: `bg-[#3a3b3c] rounded-2xl text-white py-2 px-3`, 15 | name: `text-[#a6aba4] text-sm font-semibold`, 16 | commentActionsContainer: `flex items-center gap-[1rem] ml-[3.4rem] mb-[1rem] mt-1`, 17 | actionItem: `text-[#a6aba4] text-sm font-bold cursor-pointer`, 18 | timestamp: `text-[#a6aba4] text-sm`, 19 | } 20 | 21 | return ( 22 | <> 23 |
24 |
25 | 31 |
32 |
33 |
{comment.commenterName}
34 |
{comment.text}
35 |
36 |
37 |
38 |
Like
39 |
Reply
40 |
41 | {timeAgo.format( 42 | new Date(comment.postTime.toNumber() * 1000), 43 | 'twitter-now', 44 | )} 45 |
46 |
47 | 48 | ) 49 | } 50 | 51 | export default Comment 52 | -------------------------------------------------------------------------------- /components/CommentSection.js: -------------------------------------------------------------------------------- 1 | import Comment from './Comment' 2 | import CreateComment from './CreateComment' 3 | 4 | const CommentSection = ({ 5 | comments, 6 | createCommentForPost, 7 | name, 8 | url, 9 | }) => { 10 | const style = { 11 | wrapper: `w-full rounded-b-lg p-[5px] flex justify-center-center flex-col border-t border-gray-300 border-[#3a3b3e] pt-4`, 12 | } 13 | 14 | return ( 15 |
16 | {comments.map((comment, index) => ( 17 | 18 | ))} 19 | 24 |
25 | ) 26 | } 27 | 28 | export default CommentSection 29 | -------------------------------------------------------------------------------- /components/Contact.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Image from 'next/image' 3 | 4 | const Contact = ({ user }) => { 5 | const style = { 6 | contact: `flex items-center my-2`, 7 | contactImage: `rounded-full object-cover`, 8 | contactName: `ml-4 text-[1rem]`, 9 | } 10 | return ( 11 |
12 | 18 |
{user.name}
19 |
20 | ) 21 | } 22 | 23 | export default Contact 24 | -------------------------------------------------------------------------------- /components/CreateComment.js: -------------------------------------------------------------------------------- 1 | import { useState } from 'react' 2 | import Image from 'next/image' 3 | import { MdInsertEmoticon } from 'react-icons/md' 4 | import { TiCameraOutline } from 'react-icons/ti' 5 | import { RiFileGifLine } from 'react-icons/ri' 6 | import { BiSticker } from 'react-icons/bi' 7 | 8 | const CreateComment = ({ createCommentForPost, name, url }) => { 9 | const [input, setInput] = useState('') 10 | 11 | const style = { 12 | wrapper: `flex items-center`, 13 | profileImage: `rounded-full`, 14 | inputContainer: `flex flex-1 h-10 bg-[#3a3b3c] rounded-full px-[1rem]`, 15 | form: `flex flex-1 items-center`, 16 | input: `w-full bg-transparent outline-none`, 17 | inputIcons: `flex items-center gap-[0.4rem]`, 18 | icon: `cursor-pointer text-[#a6a9ae]`, 19 | } 20 | 21 | const postComment = async event => { 22 | event.preventDefault() 23 | 24 | await createCommentForPost(input) 25 | setInput('') 26 | } 27 | 28 | return ( 29 |
30 |
31 | profile image 38 |
39 |
40 |
41 | setInput(e.target.value)} 46 | value={input} 47 | /> 48 |
49 |
50 | 51 | 52 | 53 | 54 |
55 |
56 |
57 | ) 58 | } 59 | 60 | export default CreateComment 61 | -------------------------------------------------------------------------------- /components/CreatePost.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react' 2 | import Image from 'next/image' 3 | import { BsFileImageFill, BsFillCameraVideoFill } from 'react-icons/bs' 4 | import { FiRefreshCw } from 'react-icons/fi' 5 | import 'react-simple-hook-modal/dist/styles.css' 6 | 7 | const CreatePost = ({ savePost, getAllPosts, name, url }) => { 8 | const [input, setInput] = useState('') 9 | 10 | const style = { 11 | wrapper: `w-[100%] flex mt-[1rem] flex-col rounded-[0.6rem] bg-[#252526] p-2 pt-4 pb-0 shadow-[0px 5px 7px -7px rgba(0, 0, 0, 0.75)]`, 12 | formContainer: `flex pb-3 mb-2 border-b border-[#404041]`, 13 | profileImage: `rounded-full object-cover`, 14 | form: `flex-1 flex items-center`, 15 | input: `flex-1 py-[0.6rem] px-[1rem] mx-[0.6rem] rounded-full bg-[#3a3b3d] outline-none border-none text-white`, 16 | hiddenSubmit: `invisible`, 17 | actionsContainer: `flex justify-evenly pb-2`, 18 | actionButton: `flex flex-1 items-center justify-center p-2 text-[#555] cursor-pointer hover:bg-[#404041] rounded-[0.5rem] transition-all duration-300 ease-in-out`, 19 | actionButtonTitle: `font-semibold ml-[0.6rem] text-lg text-[#afb3b8]`, 20 | videoCamIcon: `text-red-500`, 21 | photoIcon: `text-green-500`, 22 | refreshIcon: `text-blue-500`, 23 | spinner: `h-full w-full flex justify-center items-center`, 24 | } 25 | 26 | const handleSubmit = async event => { 27 | event.preventDefault() 28 | setInput('') 29 | 30 | await savePost(input) 31 | } 32 | 33 | return ( 34 |
35 |
36 | profile image 43 |
44 | setInput(event.target.value)} 47 | className={style.input} 48 | placeholder={`What's on your mind, ${name}?`} 49 | /> 50 | 51 |
58 | 59 |
60 |
61 | 62 |
Live Video
63 |
64 |
65 | 66 |
Photo/Video
67 |
68 |
getAllPosts()}> 69 | 70 |
Refresh Posts
71 |
72 |
73 |
74 | ) 75 | } 76 | 77 | export default CreatePost 78 | -------------------------------------------------------------------------------- /components/Feed.js: -------------------------------------------------------------------------------- 1 | import toast, { Toaster } from 'react-hot-toast' 2 | import { TOKEN_PROGRAM_ID } from '@solana/spl-token' 3 | import { useWallet } from '@solana/wallet-adapter-react' 4 | import { useEffect, useState } from 'react' 5 | import { SOLANA_HOST } from '../utils/const' 6 | import { getProgramInstance } from '../utils/get-program' 7 | import CreatePost from './CreatePost' 8 | import Post from './Post.js' 9 | 10 | const anchor = require('@project-serum/anchor') 11 | const { BN, web3 } = anchor 12 | const utf8 = anchor.utils.bytes.utf8 13 | const { SystemProgram } = web3 14 | 15 | const defaultAccounts = { 16 | tokenProgram: TOKEN_PROGRAM_ID, 17 | clock: anchor.web3.SYSVAR_CLOCK_PUBKEY, 18 | systemProgram: SystemProgram.programId, 19 | } 20 | 21 | const Feed = ({ connected, name, url }) => { 22 | const style = { 23 | wrapper: `flex-1 max-w-2xl mx-4`, 24 | } 25 | 26 | const wallet = useWallet() 27 | const connection = new anchor.web3.Connection(SOLANA_HOST) 28 | const program = getProgramInstance(connection, wallet) 29 | const [posts, setPosts] = useState([]) 30 | const [loading, setLoading] = useState(true) 31 | 32 | useEffect(() => { 33 | const interval = setInterval(async () => { 34 | await getAllPosts() 35 | }, 2000) 36 | getAllPosts() 37 | return () => clearInterval(interval) 38 | }, [connected, getAllPosts]) 39 | 40 | useEffect(() => { 41 | toast('Posts Refreshed!', { 42 | icon: '🔁', 43 | style: { 44 | borderRadius: '10px', 45 | background: '#252526', 46 | color: '#fffcf9', 47 | }, 48 | }) 49 | }, [posts.length]) 50 | 51 | const getAllPosts = async () => { 52 | try { 53 | const postsData = await program.account.postAccount.all() 54 | 55 | postsData.sort( 56 | (a, b) => b.account.postTime.toNumber() - a.account.postTime.toNumber(), 57 | ) 58 | 59 | setPosts(postsData) 60 | 61 | setLoading(false) 62 | } catch (error) { 63 | console.error(error) 64 | } 65 | } 66 | 67 | const getCommentsOnPost = async (index, oldPost) => { 68 | try { 69 | let [postSigner] = await anchor.web3.PublicKey.findProgramAddress( 70 | [utf8.encode('post'), index.toArrayLike(Buffer, 'be', 8)], 71 | program.programId, 72 | ) 73 | 74 | const post = await program.account.postAccount.fetch(postSigner) 75 | 76 | let commentSigners = [] 77 | 78 | for (let i = 0; i < post.commentCount.toNumber(); i++) { 79 | let [commentSigner] = await anchor.web3.PublicKey.findProgramAddress( 80 | [ 81 | utf8.encode('comment'), 82 | new BN(index).toArrayLike(Buffer, 'be', 8), 83 | new BN(i).toArrayLike(Buffer, 'be', 8), 84 | ], 85 | program.programId, 86 | ) 87 | 88 | commentSigners.push(commentSigner) 89 | } 90 | 91 | const comments = await program.account.commentAccount.fetchMultiple( 92 | commentSigners, 93 | ) 94 | 95 | comments.sort((a, b) => a.postTime.toNumber() - b.postTime.toNumber()) 96 | 97 | return comments 98 | } catch (error) { 99 | console.error(error) 100 | } 101 | } 102 | 103 | const savePost = async text => { 104 | let [stateSigner] = await anchor.web3.PublicKey.findProgramAddress( 105 | [utf8.encode('state')], 106 | program.programId, 107 | ) 108 | 109 | let stateInfo 110 | 111 | try { 112 | stateInfo = await program.account.stateAccount.fetch(stateSigner) 113 | } catch (error) { 114 | await program.rpc.createState({ 115 | accounts: { 116 | state: stateSigner, 117 | authority: wallet.publicKey, 118 | ...defaultAccounts, 119 | }, 120 | }) 121 | 122 | return 123 | } 124 | 125 | let [postSigner] = await anchor.web3.PublicKey.findProgramAddress( 126 | [utf8.encode('post'), stateInfo.postCount.toArrayLike(Buffer, 'be', 8)], 127 | program.programId, 128 | ) 129 | 130 | try { 131 | await program.account.postAccount.fetch(postSigner) 132 | } catch { 133 | await program.rpc.createPost(text, name, url, { 134 | accounts: { 135 | state: stateSigner, 136 | post: postSigner, 137 | authority: wallet.publicKey, 138 | ...defaultAccounts, 139 | }, 140 | }) 141 | 142 | setPosts(await program.account.postAccount.all()) 143 | } 144 | } 145 | 146 | const saveComment = async (text, index, count) => { 147 | let [postSigner] = await anchor.web3.PublicKey.findProgramAddress( 148 | [utf8.encode('post'), index.toArrayLike(Buffer, 'be', 8)], 149 | program.programId, 150 | ) 151 | 152 | try { 153 | let [commentSigner] = await anchor.web3.PublicKey.findProgramAddress( 154 | [ 155 | utf8.encode('comment'), 156 | index.toArrayLike(Buffer, 'be', 8), 157 | count.toArrayLike(Buffer, 'be', 8), 158 | ], 159 | program.programId, 160 | ) 161 | 162 | await program.rpc.createComment(text, name, url, { 163 | accounts: { 164 | post: postSigner, 165 | comment: commentSigner, 166 | authority: wallet.publicKey, 167 | ...defaultAccounts, 168 | }, 169 | }) 170 | 171 | await program.account.commentAccount.fetch(commentSigner) 172 | } catch (error) { 173 | console.error(error) 174 | } 175 | } 176 | 177 | return ( 178 |
179 | 180 |
181 | {loading ? ( 182 |
Loading...
183 | ) : ( 184 |
185 | 191 | 192 | {posts.map(post => ( 193 | 201 | ))} 202 |
203 | )} 204 |
205 |
206 | ) 207 | } 208 | 209 | export default Feed 210 | -------------------------------------------------------------------------------- /components/Header.js: -------------------------------------------------------------------------------- 1 | import { useState } from 'react' 2 | import Image from 'next/image' 3 | import { AiOutlineSearch, AiFillHome } from 'react-icons/ai' 4 | import { BsDisplay } from 'react-icons/bs' 5 | import { RiGroup2Line } from 'react-icons/ri' 6 | import { SiFacebookgaming } from 'react-icons/si' 7 | import solanaLogo from '../assets/sol.png' 8 | import useWalletBalance from '../context/useWalletBalance' 9 | import { WalletMultiButton } from '@solana/wallet-adapter-react-ui' 10 | require('@solana/wallet-adapter-react-ui/styles.css') 11 | 12 | const Header = ({ name, url }) => { 13 | const [balance] = useWalletBalance() 14 | 15 | const style = { 16 | wrapper: `flex items-center w-full h-[4rem] justify-around px-[1rem] py-[0.2rem] sticky top-0 bg-[#252526] shadow-[0px 5px 8px -9px rgba(0, 0, 0, 0.75)] z-20`, 17 | headerLeft: `flex justify-center gap-[0.6rem]`, 18 | facebookLogo: `items-center flex object-contain`, 19 | searchContainer: `flex items-center bg-[#3a3b3d] max-w-[18rem] rounded-full py-2 px-2 text-[#b0b3b8]`, 20 | searchInput: `border-none px-[0.6rem] bg-transparent outline-none w-[18rem] text-white placeholder:text-[#b0b3b8]`, 21 | headerCenterContainer: `flex-1 flex items-center justify-center h-full`, 22 | headerCenterWrapper: `flex justify-center h-full py-2`, 23 | centerNavIconContainer: `flex items-center px-[1.8rem] cursor-pointer duration-[0.5s] hover:bg-[#555657] rounded-[10px]`, 24 | centerNavIcon: `text-2xl text-[#666]`, 25 | headerRight: `flex h-min`, 26 | headerRightButton: `flex items-center px-3 mx-2 rounded-[0.2rem] cursor-pointer`, 27 | userInfo: `bg-[#31e3bd] hover:bg-[#438791]`, 28 | userName: `font-bold ml-2 text-black`, 29 | userImage: `rounded-full object-cover`, 30 | balanceContainer: `bg-[#ec55bc] hover:bg-[#572079] text-black`, 31 | balanceIcon: `object-covers`, 32 | balanceText: `text-white font-bold ml-2`, 33 | } 34 | return ( 35 |
36 |
37 | 44 |
45 | 46 | 51 |
52 |
53 |
54 |
55 |
56 | 57 |
58 |
59 | 60 |
61 |
62 | 63 |
64 |
65 | 66 |
67 |
68 |
69 |
70 | {name && ( 71 |
72 | user image 79 |
{name}
80 |
81 | )} 82 | 83 |
84 | solana logo 91 |
{balance.toFixed(2)} SOL
92 |
93 |
94 |
95 | ) 96 | } 97 | 98 | export default Header 99 | -------------------------------------------------------------------------------- /components/Post.js: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from 'react' 2 | import Image from 'next/image' 3 | import { BiLike } from 'react-icons/bi' 4 | import { FaRegCommentAlt } from 'react-icons/fa' 5 | import { FiRefreshCw } from 'react-icons/fi' 6 | import CommentSection from './CommentSection' 7 | import TimeAgo from 'javascript-time-ago' 8 | import en from 'javascript-time-ago/locale/en.json' 9 | 10 | TimeAgo.addDefaultLocale(en) 11 | 12 | const timeAgo = new TimeAgo('en-US') 13 | 14 | const Post = ({ post, viewDetail, createComment, name, url }) => { 15 | const style = { 16 | wrapper: `w-[100%] mt-[1rem] rounded-[0.6rem] bg-[#252526] text-white p-[0.4rem] pb-0`, 17 | postPublisher: `flex position-relative items-center`, 18 | avatar: `rounded-full`, 19 | publisherDetails: `flex flex-col ml-[0.5rem]`, 20 | name: `text-sm`, 21 | timestamp: `text-sm text-[#777]`, 22 | text: `py-[1rem] px-[1.2rem]`, 23 | reactionsContainer: `border-t border-[#3a3b3e] text-[18px] flex justify-evenly text-[#b0b3b8] cursor-pointer py-1`, 24 | reactionItem: `flex flex-1 items-center justify-center rounded-[0.4rem] hover:bg-[#404041] py-2`, 25 | reactionsText: `ml-[1rem]`, 26 | refreshIcon: `text-blue-500`, 27 | } 28 | 29 | const [isCommentSectionOpened, setIsCommentSectionOpened] = useState(false) 30 | const [comments, setComments] = useState([]) 31 | 32 | useEffect(() => { 33 | postDetail() 34 | }, [postDetail]) 35 | 36 | useEffect(() => { 37 | if (comments.length > 0) { 38 | setIsCommentSectionOpened(true) 39 | } 40 | }, [comments]) 41 | 42 | const clockToDateString = timestamp => 43 | timeAgo.format(new Date(timestamp.toNumber() * 1000), 'twitter-now') 44 | 45 | const postDetail = async () => { 46 | const result = await viewDetail(post.index, post) 47 | 48 | setComments(await result) 49 | } 50 | 51 | const createCommentForPost = async text => { 52 | createComment(text, post.index, post.commentCount) 53 | } 54 | 55 | return ( 56 |
57 |
58 | publisher profile image 65 |
66 |
{post.posterName}
67 |
68 | {clockToDateString(post.postTime)} 69 |
70 |
71 |
72 | 73 |
74 |
{post.text}
75 |
76 | 77 |
78 |
79 | 80 |
Like
81 |
82 |
setIsCommentSectionOpened(!isCommentSectionOpened)} 85 | > 86 | 87 |
Comment
88 |
89 |
90 | 91 |
Refresh Comments
92 |
93 |
94 | {isCommentSectionOpened && ( 95 | 101 | )} 102 |
103 | ) 104 | } 105 | 106 | export default Post 107 | -------------------------------------------------------------------------------- /components/RightSidebar.js: -------------------------------------------------------------------------------- 1 | import { useEffect } from 'react' 2 | import Image from 'next/image' 3 | import Contact from './Contact' 4 | 5 | const RightSidebar = ({ getUsers, users }) => { 6 | const style = { 7 | wrapper: `w-[24rem] text-lg text-white`, 8 | title: `text-[#afb3b8] font-semibold`, 9 | adsContainer: ``, 10 | ad: `flex items-center my-3 mr-[1rem] p-2 rounded-lg`, 11 | adImageContainer: `h-full w-[50%] flex items-center mr-[0.5rem]`, 12 | adImage: `object-cover`, 13 | adLink: `text-[#b0b3b8] text-sm`, 14 | divider: `w-[95%] border-b border-[0.5px] border-[#3e4042] my-2`, 15 | contact: `flex items-center my-2`, 16 | contactImage: `rounded-full object-cover`, 17 | contactName: `ml-4 text-[1rem]`, 18 | } 19 | 20 | useEffect(() => { 21 | ;(async () => { 22 | await getUsers() 23 | })() 24 | }, []) 25 | 26 | return ( 27 |
28 |
Sponsored
29 |
30 |
31 |
32 | cp logo 41 | ˚ 42 |
43 |
44 |
The #1 Channel for Blockchain Development
45 |
cleverprogrammer.com
46 |
47 |
48 |
49 |
50 | solana logo 59 |
60 |
61 |
Powerful for developers. Fast for everyone.
62 |
solana.com
63 |
64 |
65 |
66 |
Contacts
67 |
68 | {users.map(user => { 69 | return 70 | })} 71 |
72 |
73 |
74 | ) 75 | } 76 | 77 | export default RightSidebar 78 | -------------------------------------------------------------------------------- /components/Sidebar.js: -------------------------------------------------------------------------------- 1 | import Image from 'next/image' 2 | import { sidebarData } from '../static/static' 3 | 4 | const Sidebar = ({ name, url }) => { 5 | const style = { 6 | wrapper: `py-[25px] px-[10px] w-[24rem] `, 7 | sidebarRow: `flex w-full mb-[20px] hover:bg-[#2a2b2c] transition-all duration-300 ease-in-out rounded-lg p-[5px] gap-[10px] cursor-pointer`, 8 | profileImage: `rounded-full object-cover`, 9 | sidebarItem: `text-white font-semibold flex items-center flex-col justify-center text-sm `, 10 | } 11 | return ( 12 |
13 |
14 | profile image 21 |
{name}
22 |
23 | {sidebarData.map((sidebarDataItem, index) => ( 24 |
25 | sidebar icon 32 |
{sidebarDataItem.title}
33 |
34 | ))} 35 |
36 | ) 37 | } 38 | 39 | export default Sidebar 40 | -------------------------------------------------------------------------------- /components/SignUp.js: -------------------------------------------------------------------------------- 1 | import Image from 'next/image' 2 | 3 | const SignUp = ({ setRegistered, name, setName, url, setUrl }) => { 4 | const style = { 5 | wrapper: `flex flex-col p-4 justify-center items-center h-full w-full bg-[#252526] w-min h-min rounded-2xl`, 6 | title: `text-[#afb3b8] font-semibold text-lg`, 7 | form: `flex flex-col items-center`, 8 | fieldContainer: `my-4 `, 9 | inputTitle: `text-[#afb3b8] font-semibold mb-2 ml-3`, 10 | inputContainer: `flex items-center w-[20rem] bg-[#3a3b3d] rounded-full`, 11 | inputField: `bg-transparent flex-1 m-2 outline-none text-white px-2`, 12 | randomUrl: `h-full bg-[#2d2d2d] hover:bg-[#252626] text-white px-2 py-1 mx-1 hover:px-3 rounded-full cursor-pointer duration-[0.2s] ease-in-out`, 13 | submitButton: `bg-[#3a3b3d] text-white font-semibold px-4 py-2 hover:px-6 rounded-full cursor-pointer duration-[0.2s] ease-in-out`, 14 | } 15 | 16 | const createUser = async event => { 17 | setRegistered(true) 18 | 19 | const resp = await window.solana.connect() 20 | const walletAddress = resp.publicKey.toString() 21 | 22 | try { 23 | await fetch(`/api/createUser`, { 24 | method: 'POST', 25 | headers: { 26 | 'Content-Type': 'application/json', 27 | }, 28 | body: JSON.stringify({ 29 | userWalletAddress: walletAddress, 30 | name: name, 31 | profileImage: event.target.url.value, 32 | }), 33 | }) 34 | } catch (error) { 35 | console.error(error) 36 | } 37 | } 38 | 39 | const generateRandomProfileImageUrl = () => 40 | setUrl( 41 | `https://avatars.dicebear.com/api/pixel-art-neutral/${Math.floor( 42 | Math.random() * 100, 43 | )}.svg`, 44 | ) 45 | 46 | return ( 47 |
48 |
49 | facebook logo 55 |
56 |
Please sign up to use Facebook
57 |
58 |
59 |
Name
60 |
61 | setName(event.target.value)} 64 | required 65 | className={style.inputField} 66 | /> 67 |
68 |
69 |
70 |
Profile Image URL
71 |
72 | setUrl(event.target.value)} 75 | required 76 | className={style.inputField} 77 | /> 78 |
generateRandomProfileImageUrl()} 81 | > 82 | Random 83 |
84 |
85 |
86 | 89 |
90 |
91 | ) 92 | } 93 | 94 | export default SignUp 95 | -------------------------------------------------------------------------------- /context/WalletConnectionProvider.js: -------------------------------------------------------------------------------- 1 | import { 2 | ConnectionProvider, 3 | WalletProvider, 4 | } from '@solana/wallet-adapter-react' 5 | import { WalletModalProvider } from '@solana/wallet-adapter-react-ui' 6 | import { PhantomWalletAdapter } from '@solana/wallet-adapter-wallets' 7 | import { useMemo } from 'react' 8 | 9 | 10 | const WalletConnectionProvider = ({ children }) => { 11 | const endpoint = useMemo(() => 'https://api.devnet.solana.com', []) 12 | 13 | const wallets = useMemo(() => [new PhantomWalletAdapter()], []) 14 | 15 | return ( 16 | 17 | 18 | {children} 19 | 20 | 21 | ) 22 | } 23 | 24 | export default WalletConnectionProvider 25 | -------------------------------------------------------------------------------- /context/context.js: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react' 2 | 3 | export const FacebookContext = createContext() 4 | 5 | export const FacebookProvider = ({ children }) => { 6 | const requestToCreateUserProfile = async (walletAddress, name) => { 7 | try { 8 | await fetch(`/api/createUser`, { 9 | method: 'POST', 10 | headers: { 11 | 'Content-Type': 'application/json', 12 | }, 13 | body: JSON.stringify({ 14 | userWalletAddress: walletAddress, 15 | name: name, 16 | }), 17 | }) 18 | } catch (error) { 19 | console.error(error) 20 | } 21 | } 22 | 23 | return ( 24 | 29 | {children} 30 | 31 | ) 32 | } 33 | -------------------------------------------------------------------------------- /context/useWalletBalance.js: -------------------------------------------------------------------------------- 1 | import { useWallet } from '@solana/wallet-adapter-react' 2 | import { LAMPORTS_PER_SOL } from '@solana/web3.js' 3 | import { createContext, useContext, useEffect, useState } from 'react' 4 | import * as anchor from '@project-serum/anchor' 5 | import { SOLANA_HOST } from '../utils/const' 6 | 7 | const BalanceContext = createContext(null) 8 | 9 | const connection = new anchor.web3.Connection(SOLANA_HOST) 10 | 11 | export default function useWalletBalance() { 12 | const [balance, setBalance] = useContext(BalanceContext) 13 | return [balance, setBalance] 14 | } 15 | 16 | export const WalletBalanceProvider = ({ children }) => { 17 | const wallet = useWallet() 18 | const [balance, setBalance] = useState(0) 19 | 20 | useEffect(() => { 21 | ;(async () => { 22 | if (wallet?.publicKey) { 23 | const balance = await connection.getBalance(wallet.publicKey) 24 | setBalance(balance / LAMPORTS_PER_SOL) 25 | } 26 | })() 27 | }, [wallet, connection]) 28 | 29 | return ( 30 | 31 | {children} 32 | 33 | ) 34 | } 35 | -------------------------------------------------------------------------------- /facebook-clone/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .anchor 3 | .DS_Store 4 | target 5 | **/*.rs.bk 6 | node_modules 7 | -------------------------------------------------------------------------------- /facebook-clone/Anchor.toml: -------------------------------------------------------------------------------- 1 | [features] 2 | seeds = false 3 | [programs.devnet] 4 | facebook_clone = "GNSDgX32cCeuuN96GRiBmFE4BAXqgFpftqxSCzDrdkTd" 5 | 6 | [registry] 7 | url = "https://anchor.projectserum.com" 8 | 9 | [provider] 10 | cluster = "devnet" 11 | wallet = "~/.config/solana/id.json" 12 | 13 | [scripts] 14 | test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" 15 | start = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 app/start.ts" 16 | -------------------------------------------------------------------------------- /facebook-clone/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "ahash" 7 | version = "0.7.6" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" 10 | dependencies = [ 11 | "getrandom 0.2.6", 12 | "once_cell", 13 | "version_check", 14 | ] 15 | 16 | [[package]] 17 | name = "aho-corasick" 18 | version = "0.7.18" 19 | source = "registry+https://github.com/rust-lang/crates.io-index" 20 | checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" 21 | dependencies = [ 22 | "memchr", 23 | ] 24 | 25 | [[package]] 26 | name = "anchor-attribute-access-control" 27 | version = "0.21.0" 28 | source = "registry+https://github.com/rust-lang/crates.io-index" 29 | checksum = "8573731461c6e39febd16026fe95cbc99955585b08acddc0baaeefb803da191b" 30 | dependencies = [ 31 | "anchor-syn", 32 | "anyhow", 33 | "proc-macro2", 34 | "quote", 35 | "regex", 36 | "syn", 37 | ] 38 | 39 | [[package]] 40 | name = "anchor-attribute-account" 41 | version = "0.21.0" 42 | source = "registry+https://github.com/rust-lang/crates.io-index" 43 | checksum = "537c6e7014f727f3396759f73a847bdbca92379499d918c99ae1c7075d6d32e3" 44 | dependencies = [ 45 | "anchor-syn", 46 | "anyhow", 47 | "bs58 0.4.0", 48 | "proc-macro2", 49 | "quote", 50 | "rustversion", 51 | "syn", 52 | ] 53 | 54 | [[package]] 55 | name = "anchor-attribute-constant" 56 | version = "0.21.0" 57 | source = "registry+https://github.com/rust-lang/crates.io-index" 58 | checksum = "4fce62e28b84fe3622044d5777e6962cf090049ef45d1bc29d0fbbc027b848d8" 59 | dependencies = [ 60 | "anchor-syn", 61 | "proc-macro2", 62 | "syn", 63 | ] 64 | 65 | [[package]] 66 | name = "anchor-attribute-error" 67 | version = "0.21.0" 68 | source = "registry+https://github.com/rust-lang/crates.io-index" 69 | checksum = "2cd2fe5dd4d1e82ff9d0b948170ab4ad3b12fa16ad6f45a3a3ce4dd97e543935" 70 | dependencies = [ 71 | "anchor-syn", 72 | "proc-macro2", 73 | "quote", 74 | "syn", 75 | ] 76 | 77 | [[package]] 78 | name = "anchor-attribute-event" 79 | version = "0.21.0" 80 | source = "registry+https://github.com/rust-lang/crates.io-index" 81 | checksum = "8437fd23a6c92e0d7ee6378aef4e95596976008eb3a0be100ac832b7b3eaf240" 82 | dependencies = [ 83 | "anchor-syn", 84 | "anyhow", 85 | "proc-macro2", 86 | "quote", 87 | "syn", 88 | ] 89 | 90 | [[package]] 91 | name = "anchor-attribute-interface" 92 | version = "0.21.0" 93 | source = "registry+https://github.com/rust-lang/crates.io-index" 94 | checksum = "8567efb892ec10df7cb479dc0246257f896b2de1406c6901621d5437080fc041" 95 | dependencies = [ 96 | "anchor-syn", 97 | "anyhow", 98 | "heck", 99 | "proc-macro2", 100 | "quote", 101 | "syn", 102 | ] 103 | 104 | [[package]] 105 | name = "anchor-attribute-program" 106 | version = "0.21.0" 107 | source = "registry+https://github.com/rust-lang/crates.io-index" 108 | checksum = "4b8674fa15f24b311451294595034617b96348faed14c821fe191183d46258af" 109 | dependencies = [ 110 | "anchor-syn", 111 | "anyhow", 112 | "proc-macro2", 113 | "quote", 114 | "syn", 115 | ] 116 | 117 | [[package]] 118 | name = "anchor-attribute-state" 119 | version = "0.21.0" 120 | source = "registry+https://github.com/rust-lang/crates.io-index" 121 | checksum = "e3921cd5b29b8fe7ff10368a5dd8398f37b1dabef489d18a01a4befd86ce09d6" 122 | dependencies = [ 123 | "anchor-syn", 124 | "anyhow", 125 | "proc-macro2", 126 | "quote", 127 | "syn", 128 | ] 129 | 130 | [[package]] 131 | name = "anchor-derive-accounts" 132 | version = "0.21.0" 133 | source = "registry+https://github.com/rust-lang/crates.io-index" 134 | checksum = "5f41be15286b4fc2753cd2dab130ca7c87d81a2817adb7d0af5316715ddf4b46" 135 | dependencies = [ 136 | "anchor-syn", 137 | "anyhow", 138 | "proc-macro2", 139 | "quote", 140 | "syn", 141 | ] 142 | 143 | [[package]] 144 | name = "anchor-lang" 145 | version = "0.21.0" 146 | source = "registry+https://github.com/rust-lang/crates.io-index" 147 | checksum = "f4300d151a09cb0c0775cdd63100040c8dba325b406c55ffb4f845f4b78d9e9b" 148 | dependencies = [ 149 | "anchor-attribute-access-control", 150 | "anchor-attribute-account", 151 | "anchor-attribute-constant", 152 | "anchor-attribute-error", 153 | "anchor-attribute-event", 154 | "anchor-attribute-interface", 155 | "anchor-attribute-program", 156 | "anchor-attribute-state", 157 | "anchor-derive-accounts", 158 | "arrayref", 159 | "base64 0.13.0", 160 | "bincode", 161 | "borsh", 162 | "bytemuck", 163 | "solana-program", 164 | "thiserror", 165 | ] 166 | 167 | [[package]] 168 | name = "anchor-spl" 169 | version = "0.21.0" 170 | source = "registry+https://github.com/rust-lang/crates.io-index" 171 | checksum = "cc245f1d18992ad44236dc15717a9875e1184a164b931c506ba9dc7a2258804f" 172 | dependencies = [ 173 | "anchor-lang", 174 | "solana-program", 175 | "spl-associated-token-account", 176 | "spl-token", 177 | ] 178 | 179 | [[package]] 180 | name = "anchor-syn" 181 | version = "0.21.0" 182 | source = "registry+https://github.com/rust-lang/crates.io-index" 183 | checksum = "7c8a4e39f655a9e32037c238f51f09b168a7d56ab6a2727777da81849559c77c" 184 | dependencies = [ 185 | "anyhow", 186 | "bs58 0.3.1", 187 | "heck", 188 | "proc-macro2", 189 | "proc-macro2-diagnostics", 190 | "quote", 191 | "serde", 192 | "serde_json", 193 | "sha2", 194 | "syn", 195 | "thiserror", 196 | ] 197 | 198 | [[package]] 199 | name = "anyhow" 200 | version = "1.0.56" 201 | source = "registry+https://github.com/rust-lang/crates.io-index" 202 | checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27" 203 | 204 | [[package]] 205 | name = "arrayref" 206 | version = "0.3.6" 207 | source = "registry+https://github.com/rust-lang/crates.io-index" 208 | checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" 209 | 210 | [[package]] 211 | name = "arrayvec" 212 | version = "0.5.2" 213 | source = "registry+https://github.com/rust-lang/crates.io-index" 214 | checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" 215 | 216 | [[package]] 217 | name = "atty" 218 | version = "0.2.14" 219 | source = "registry+https://github.com/rust-lang/crates.io-index" 220 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 221 | dependencies = [ 222 | "hermit-abi", 223 | "libc", 224 | "winapi", 225 | ] 226 | 227 | [[package]] 228 | name = "autocfg" 229 | version = "1.1.0" 230 | source = "registry+https://github.com/rust-lang/crates.io-index" 231 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 232 | 233 | [[package]] 234 | name = "base64" 235 | version = "0.12.3" 236 | source = "registry+https://github.com/rust-lang/crates.io-index" 237 | checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" 238 | 239 | [[package]] 240 | name = "base64" 241 | version = "0.13.0" 242 | source = "registry+https://github.com/rust-lang/crates.io-index" 243 | checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" 244 | 245 | [[package]] 246 | name = "bincode" 247 | version = "1.3.3" 248 | source = "registry+https://github.com/rust-lang/crates.io-index" 249 | checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" 250 | dependencies = [ 251 | "serde", 252 | ] 253 | 254 | [[package]] 255 | name = "blake3" 256 | version = "0.3.8" 257 | source = "registry+https://github.com/rust-lang/crates.io-index" 258 | checksum = "b64485778c4f16a6a5a9d335e80d449ac6c70cdd6a06d2af18a6f6f775a125b3" 259 | dependencies = [ 260 | "arrayref", 261 | "arrayvec", 262 | "cc", 263 | "cfg-if 0.1.10", 264 | "constant_time_eq", 265 | "crypto-mac", 266 | "digest 0.9.0", 267 | ] 268 | 269 | [[package]] 270 | name = "block-buffer" 271 | version = "0.9.0" 272 | source = "registry+https://github.com/rust-lang/crates.io-index" 273 | checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" 274 | dependencies = [ 275 | "block-padding", 276 | "generic-array 0.14.5", 277 | ] 278 | 279 | [[package]] 280 | name = "block-padding" 281 | version = "0.2.1" 282 | source = "registry+https://github.com/rust-lang/crates.io-index" 283 | checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" 284 | 285 | [[package]] 286 | name = "borsh" 287 | version = "0.9.3" 288 | source = "registry+https://github.com/rust-lang/crates.io-index" 289 | checksum = "15bf3650200d8bffa99015595e10f1fbd17de07abbc25bb067da79e769939bfa" 290 | dependencies = [ 291 | "borsh-derive", 292 | "hashbrown", 293 | ] 294 | 295 | [[package]] 296 | name = "borsh-derive" 297 | version = "0.9.3" 298 | source = "registry+https://github.com/rust-lang/crates.io-index" 299 | checksum = "6441c552f230375d18e3cc377677914d2ca2b0d36e52129fe15450a2dce46775" 300 | dependencies = [ 301 | "borsh-derive-internal", 302 | "borsh-schema-derive-internal", 303 | "proc-macro-crate 0.1.5", 304 | "proc-macro2", 305 | "syn", 306 | ] 307 | 308 | [[package]] 309 | name = "borsh-derive-internal" 310 | version = "0.9.3" 311 | source = "registry+https://github.com/rust-lang/crates.io-index" 312 | checksum = "5449c28a7b352f2d1e592a8a28bf139bc71afb0764a14f3c02500935d8c44065" 313 | dependencies = [ 314 | "proc-macro2", 315 | "quote", 316 | "syn", 317 | ] 318 | 319 | [[package]] 320 | name = "borsh-schema-derive-internal" 321 | version = "0.9.3" 322 | source = "registry+https://github.com/rust-lang/crates.io-index" 323 | checksum = "cdbd5696d8bfa21d53d9fe39a714a18538bad11492a42d066dbbc395fb1951c0" 324 | dependencies = [ 325 | "proc-macro2", 326 | "quote", 327 | "syn", 328 | ] 329 | 330 | [[package]] 331 | name = "bs58" 332 | version = "0.3.1" 333 | source = "registry+https://github.com/rust-lang/crates.io-index" 334 | checksum = "476e9cd489f9e121e02ffa6014a8ef220ecb15c05ed23fc34cca13925dc283fb" 335 | 336 | [[package]] 337 | name = "bs58" 338 | version = "0.4.0" 339 | source = "registry+https://github.com/rust-lang/crates.io-index" 340 | checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" 341 | 342 | [[package]] 343 | name = "bv" 344 | version = "0.11.1" 345 | source = "registry+https://github.com/rust-lang/crates.io-index" 346 | checksum = "8834bb1d8ee5dc048ee3124f2c7c1afcc6bc9aed03f11e9dfd8c69470a5db340" 347 | dependencies = [ 348 | "feature-probe", 349 | "serde", 350 | ] 351 | 352 | [[package]] 353 | name = "bytemuck" 354 | version = "1.8.0" 355 | source = "registry+https://github.com/rust-lang/crates.io-index" 356 | checksum = "0e851ca7c24871e7336801608a4797d7376545b6928a10d32d75685687141ead" 357 | dependencies = [ 358 | "bytemuck_derive", 359 | ] 360 | 361 | [[package]] 362 | name = "bytemuck_derive" 363 | version = "1.0.1" 364 | source = "registry+https://github.com/rust-lang/crates.io-index" 365 | checksum = "8e215f8c2f9f79cb53c8335e687ffd07d5bfcb6fe5fc80723762d0be46e7cc54" 366 | dependencies = [ 367 | "proc-macro2", 368 | "quote", 369 | "syn", 370 | ] 371 | 372 | [[package]] 373 | name = "byteorder" 374 | version = "1.4.3" 375 | source = "registry+https://github.com/rust-lang/crates.io-index" 376 | checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" 377 | 378 | [[package]] 379 | name = "cc" 380 | version = "1.0.73" 381 | source = "registry+https://github.com/rust-lang/crates.io-index" 382 | checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" 383 | 384 | [[package]] 385 | name = "cfg-if" 386 | version = "0.1.10" 387 | source = "registry+https://github.com/rust-lang/crates.io-index" 388 | checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 389 | 390 | [[package]] 391 | name = "cfg-if" 392 | version = "1.0.0" 393 | source = "registry+https://github.com/rust-lang/crates.io-index" 394 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 395 | 396 | [[package]] 397 | name = "constant_time_eq" 398 | version = "0.1.5" 399 | source = "registry+https://github.com/rust-lang/crates.io-index" 400 | checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" 401 | 402 | [[package]] 403 | name = "cpufeatures" 404 | version = "0.2.2" 405 | source = "registry+https://github.com/rust-lang/crates.io-index" 406 | checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" 407 | dependencies = [ 408 | "libc", 409 | ] 410 | 411 | [[package]] 412 | name = "crunchy" 413 | version = "0.2.2" 414 | source = "registry+https://github.com/rust-lang/crates.io-index" 415 | checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" 416 | 417 | [[package]] 418 | name = "crypto-mac" 419 | version = "0.8.0" 420 | source = "registry+https://github.com/rust-lang/crates.io-index" 421 | checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" 422 | dependencies = [ 423 | "generic-array 0.14.5", 424 | "subtle", 425 | ] 426 | 427 | [[package]] 428 | name = "curve25519-dalek" 429 | version = "2.1.3" 430 | source = "registry+https://github.com/rust-lang/crates.io-index" 431 | checksum = "4a9b85542f99a2dfa2a1b8e192662741c9859a846b296bef1c92ef9b58b5a216" 432 | dependencies = [ 433 | "byteorder", 434 | "digest 0.8.1", 435 | "rand_core", 436 | "subtle", 437 | "zeroize", 438 | ] 439 | 440 | [[package]] 441 | name = "digest" 442 | version = "0.8.1" 443 | source = "registry+https://github.com/rust-lang/crates.io-index" 444 | checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" 445 | dependencies = [ 446 | "generic-array 0.12.4", 447 | ] 448 | 449 | [[package]] 450 | name = "digest" 451 | version = "0.9.0" 452 | source = "registry+https://github.com/rust-lang/crates.io-index" 453 | checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" 454 | dependencies = [ 455 | "generic-array 0.14.5", 456 | ] 457 | 458 | [[package]] 459 | name = "either" 460 | version = "1.6.1" 461 | source = "registry+https://github.com/rust-lang/crates.io-index" 462 | checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" 463 | 464 | [[package]] 465 | name = "env_logger" 466 | version = "0.8.4" 467 | source = "registry+https://github.com/rust-lang/crates.io-index" 468 | checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3" 469 | dependencies = [ 470 | "atty", 471 | "humantime", 472 | "log", 473 | "regex", 474 | "termcolor", 475 | ] 476 | 477 | [[package]] 478 | name = "facebook-clone" 479 | version = "0.1.0" 480 | dependencies = [ 481 | "anchor-lang", 482 | "anchor-spl", 483 | ] 484 | 485 | [[package]] 486 | name = "feature-probe" 487 | version = "0.1.1" 488 | source = "registry+https://github.com/rust-lang/crates.io-index" 489 | checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" 490 | 491 | [[package]] 492 | name = "generic-array" 493 | version = "0.12.4" 494 | source = "registry+https://github.com/rust-lang/crates.io-index" 495 | checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" 496 | dependencies = [ 497 | "typenum", 498 | ] 499 | 500 | [[package]] 501 | name = "generic-array" 502 | version = "0.14.5" 503 | source = "registry+https://github.com/rust-lang/crates.io-index" 504 | checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" 505 | dependencies = [ 506 | "serde", 507 | "typenum", 508 | "version_check", 509 | ] 510 | 511 | [[package]] 512 | name = "getrandom" 513 | version = "0.1.16" 514 | source = "registry+https://github.com/rust-lang/crates.io-index" 515 | checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" 516 | dependencies = [ 517 | "cfg-if 1.0.0", 518 | "libc", 519 | "wasi 0.9.0+wasi-snapshot-preview1", 520 | ] 521 | 522 | [[package]] 523 | name = "getrandom" 524 | version = "0.2.6" 525 | source = "registry+https://github.com/rust-lang/crates.io-index" 526 | checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" 527 | dependencies = [ 528 | "cfg-if 1.0.0", 529 | "libc", 530 | "wasi 0.10.2+wasi-snapshot-preview1", 531 | ] 532 | 533 | [[package]] 534 | name = "hashbrown" 535 | version = "0.11.2" 536 | source = "registry+https://github.com/rust-lang/crates.io-index" 537 | checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" 538 | dependencies = [ 539 | "ahash", 540 | ] 541 | 542 | [[package]] 543 | name = "heck" 544 | version = "0.3.3" 545 | source = "registry+https://github.com/rust-lang/crates.io-index" 546 | checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" 547 | dependencies = [ 548 | "unicode-segmentation", 549 | ] 550 | 551 | [[package]] 552 | name = "hermit-abi" 553 | version = "0.1.19" 554 | source = "registry+https://github.com/rust-lang/crates.io-index" 555 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 556 | dependencies = [ 557 | "libc", 558 | ] 559 | 560 | [[package]] 561 | name = "hex" 562 | version = "0.4.3" 563 | source = "registry+https://github.com/rust-lang/crates.io-index" 564 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 565 | 566 | [[package]] 567 | name = "hmac" 568 | version = "0.8.1" 569 | source = "registry+https://github.com/rust-lang/crates.io-index" 570 | checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" 571 | dependencies = [ 572 | "crypto-mac", 573 | "digest 0.9.0", 574 | ] 575 | 576 | [[package]] 577 | name = "hmac-drbg" 578 | version = "0.3.0" 579 | source = "registry+https://github.com/rust-lang/crates.io-index" 580 | checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" 581 | dependencies = [ 582 | "digest 0.9.0", 583 | "generic-array 0.14.5", 584 | "hmac", 585 | ] 586 | 587 | [[package]] 588 | name = "humantime" 589 | version = "2.1.0" 590 | source = "registry+https://github.com/rust-lang/crates.io-index" 591 | checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" 592 | 593 | [[package]] 594 | name = "itertools" 595 | version = "0.9.0" 596 | source = "registry+https://github.com/rust-lang/crates.io-index" 597 | checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" 598 | dependencies = [ 599 | "either", 600 | ] 601 | 602 | [[package]] 603 | name = "itoa" 604 | version = "1.0.1" 605 | source = "registry+https://github.com/rust-lang/crates.io-index" 606 | checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" 607 | 608 | [[package]] 609 | name = "keccak" 610 | version = "0.1.0" 611 | source = "registry+https://github.com/rust-lang/crates.io-index" 612 | checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" 613 | 614 | [[package]] 615 | name = "lazy_static" 616 | version = "1.4.0" 617 | source = "registry+https://github.com/rust-lang/crates.io-index" 618 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 619 | 620 | [[package]] 621 | name = "libc" 622 | version = "0.2.121" 623 | source = "registry+https://github.com/rust-lang/crates.io-index" 624 | checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f" 625 | 626 | [[package]] 627 | name = "libsecp256k1" 628 | version = "0.5.0" 629 | source = "registry+https://github.com/rust-lang/crates.io-index" 630 | checksum = "bd1137239ab33b41aa9637a88a28249e5e70c40a42ccc92db7f12cc356c1fcd7" 631 | dependencies = [ 632 | "arrayref", 633 | "base64 0.12.3", 634 | "digest 0.9.0", 635 | "hmac-drbg", 636 | "libsecp256k1-core", 637 | "libsecp256k1-gen-ecmult", 638 | "libsecp256k1-gen-genmult", 639 | "rand", 640 | "serde", 641 | "sha2", 642 | "typenum", 643 | ] 644 | 645 | [[package]] 646 | name = "libsecp256k1-core" 647 | version = "0.2.2" 648 | source = "registry+https://github.com/rust-lang/crates.io-index" 649 | checksum = "d0f6ab710cec28cef759c5f18671a27dae2a5f952cdaaee1d8e2908cb2478a80" 650 | dependencies = [ 651 | "crunchy", 652 | "digest 0.9.0", 653 | "subtle", 654 | ] 655 | 656 | [[package]] 657 | name = "libsecp256k1-gen-ecmult" 658 | version = "0.2.1" 659 | source = "registry+https://github.com/rust-lang/crates.io-index" 660 | checksum = "ccab96b584d38fac86a83f07e659f0deafd0253dc096dab5a36d53efe653c5c3" 661 | dependencies = [ 662 | "libsecp256k1-core", 663 | ] 664 | 665 | [[package]] 666 | name = "libsecp256k1-gen-genmult" 667 | version = "0.2.1" 668 | source = "registry+https://github.com/rust-lang/crates.io-index" 669 | checksum = "67abfe149395e3aa1c48a2beb32b068e2334402df8181f818d3aee2b304c4f5d" 670 | dependencies = [ 671 | "libsecp256k1-core", 672 | ] 673 | 674 | [[package]] 675 | name = "log" 676 | version = "0.4.16" 677 | source = "registry+https://github.com/rust-lang/crates.io-index" 678 | checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" 679 | dependencies = [ 680 | "cfg-if 1.0.0", 681 | ] 682 | 683 | [[package]] 684 | name = "memchr" 685 | version = "2.4.1" 686 | source = "registry+https://github.com/rust-lang/crates.io-index" 687 | checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" 688 | 689 | [[package]] 690 | name = "memmap2" 691 | version = "0.1.0" 692 | source = "registry+https://github.com/rust-lang/crates.io-index" 693 | checksum = "d9b70ca2a6103ac8b665dc150b142ef0e4e89df640c9e6cf295d189c3caebe5a" 694 | dependencies = [ 695 | "libc", 696 | ] 697 | 698 | [[package]] 699 | name = "num-derive" 700 | version = "0.3.3" 701 | source = "registry+https://github.com/rust-lang/crates.io-index" 702 | checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" 703 | dependencies = [ 704 | "proc-macro2", 705 | "quote", 706 | "syn", 707 | ] 708 | 709 | [[package]] 710 | name = "num-traits" 711 | version = "0.2.14" 712 | source = "registry+https://github.com/rust-lang/crates.io-index" 713 | checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" 714 | dependencies = [ 715 | "autocfg", 716 | ] 717 | 718 | [[package]] 719 | name = "num_enum" 720 | version = "0.5.7" 721 | source = "registry+https://github.com/rust-lang/crates.io-index" 722 | checksum = "cf5395665662ef45796a4ff5486c5d41d29e0c09640af4c5f17fd94ee2c119c9" 723 | dependencies = [ 724 | "num_enum_derive", 725 | ] 726 | 727 | [[package]] 728 | name = "num_enum_derive" 729 | version = "0.5.7" 730 | source = "registry+https://github.com/rust-lang/crates.io-index" 731 | checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce" 732 | dependencies = [ 733 | "proc-macro-crate 1.1.3", 734 | "proc-macro2", 735 | "quote", 736 | "syn", 737 | ] 738 | 739 | [[package]] 740 | name = "once_cell" 741 | version = "1.10.0" 742 | source = "registry+https://github.com/rust-lang/crates.io-index" 743 | checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" 744 | 745 | [[package]] 746 | name = "opaque-debug" 747 | version = "0.3.0" 748 | source = "registry+https://github.com/rust-lang/crates.io-index" 749 | checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" 750 | 751 | [[package]] 752 | name = "ppv-lite86" 753 | version = "0.2.16" 754 | source = "registry+https://github.com/rust-lang/crates.io-index" 755 | checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" 756 | 757 | [[package]] 758 | name = "proc-macro-crate" 759 | version = "0.1.5" 760 | source = "registry+https://github.com/rust-lang/crates.io-index" 761 | checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" 762 | dependencies = [ 763 | "toml", 764 | ] 765 | 766 | [[package]] 767 | name = "proc-macro-crate" 768 | version = "1.1.3" 769 | source = "registry+https://github.com/rust-lang/crates.io-index" 770 | checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" 771 | dependencies = [ 772 | "thiserror", 773 | "toml", 774 | ] 775 | 776 | [[package]] 777 | name = "proc-macro2" 778 | version = "1.0.36" 779 | source = "registry+https://github.com/rust-lang/crates.io-index" 780 | checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" 781 | dependencies = [ 782 | "unicode-xid", 783 | ] 784 | 785 | [[package]] 786 | name = "proc-macro2-diagnostics" 787 | version = "0.9.1" 788 | source = "registry+https://github.com/rust-lang/crates.io-index" 789 | checksum = "4bf29726d67464d49fa6224a1d07936a8c08bb3fba727c7493f6cf1616fdaada" 790 | dependencies = [ 791 | "proc-macro2", 792 | "quote", 793 | "syn", 794 | "version_check", 795 | "yansi", 796 | ] 797 | 798 | [[package]] 799 | name = "quote" 800 | version = "1.0.17" 801 | source = "registry+https://github.com/rust-lang/crates.io-index" 802 | checksum = "632d02bff7f874a36f33ea8bb416cd484b90cc66c1194b1a1110d067a7013f58" 803 | dependencies = [ 804 | "proc-macro2", 805 | ] 806 | 807 | [[package]] 808 | name = "rand" 809 | version = "0.7.3" 810 | source = "registry+https://github.com/rust-lang/crates.io-index" 811 | checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" 812 | dependencies = [ 813 | "getrandom 0.1.16", 814 | "libc", 815 | "rand_chacha", 816 | "rand_core", 817 | "rand_hc", 818 | ] 819 | 820 | [[package]] 821 | name = "rand_chacha" 822 | version = "0.2.2" 823 | source = "registry+https://github.com/rust-lang/crates.io-index" 824 | checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" 825 | dependencies = [ 826 | "ppv-lite86", 827 | "rand_core", 828 | ] 829 | 830 | [[package]] 831 | name = "rand_core" 832 | version = "0.5.1" 833 | source = "registry+https://github.com/rust-lang/crates.io-index" 834 | checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" 835 | dependencies = [ 836 | "getrandom 0.1.16", 837 | ] 838 | 839 | [[package]] 840 | name = "rand_hc" 841 | version = "0.2.0" 842 | source = "registry+https://github.com/rust-lang/crates.io-index" 843 | checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" 844 | dependencies = [ 845 | "rand_core", 846 | ] 847 | 848 | [[package]] 849 | name = "regex" 850 | version = "1.5.5" 851 | source = "registry+https://github.com/rust-lang/crates.io-index" 852 | checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" 853 | dependencies = [ 854 | "aho-corasick", 855 | "memchr", 856 | "regex-syntax", 857 | ] 858 | 859 | [[package]] 860 | name = "regex-syntax" 861 | version = "0.6.25" 862 | source = "registry+https://github.com/rust-lang/crates.io-index" 863 | checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" 864 | 865 | [[package]] 866 | name = "rustc_version" 867 | version = "0.2.3" 868 | source = "registry+https://github.com/rust-lang/crates.io-index" 869 | checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" 870 | dependencies = [ 871 | "semver", 872 | ] 873 | 874 | [[package]] 875 | name = "rustversion" 876 | version = "1.0.6" 877 | source = "registry+https://github.com/rust-lang/crates.io-index" 878 | checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" 879 | 880 | [[package]] 881 | name = "ryu" 882 | version = "1.0.9" 883 | source = "registry+https://github.com/rust-lang/crates.io-index" 884 | checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" 885 | 886 | [[package]] 887 | name = "semver" 888 | version = "0.9.0" 889 | source = "registry+https://github.com/rust-lang/crates.io-index" 890 | checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" 891 | dependencies = [ 892 | "semver-parser", 893 | ] 894 | 895 | [[package]] 896 | name = "semver-parser" 897 | version = "0.7.0" 898 | source = "registry+https://github.com/rust-lang/crates.io-index" 899 | checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" 900 | 901 | [[package]] 902 | name = "serde" 903 | version = "1.0.136" 904 | source = "registry+https://github.com/rust-lang/crates.io-index" 905 | checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" 906 | dependencies = [ 907 | "serde_derive", 908 | ] 909 | 910 | [[package]] 911 | name = "serde_bytes" 912 | version = "0.11.5" 913 | source = "registry+https://github.com/rust-lang/crates.io-index" 914 | checksum = "16ae07dd2f88a366f15bd0632ba725227018c69a1c8550a927324f8eb8368bb9" 915 | dependencies = [ 916 | "serde", 917 | ] 918 | 919 | [[package]] 920 | name = "serde_derive" 921 | version = "1.0.136" 922 | source = "registry+https://github.com/rust-lang/crates.io-index" 923 | checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" 924 | dependencies = [ 925 | "proc-macro2", 926 | "quote", 927 | "syn", 928 | ] 929 | 930 | [[package]] 931 | name = "serde_json" 932 | version = "1.0.79" 933 | source = "registry+https://github.com/rust-lang/crates.io-index" 934 | checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" 935 | dependencies = [ 936 | "itoa", 937 | "ryu", 938 | "serde", 939 | ] 940 | 941 | [[package]] 942 | name = "sha2" 943 | version = "0.9.9" 944 | source = "registry+https://github.com/rust-lang/crates.io-index" 945 | checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" 946 | dependencies = [ 947 | "block-buffer", 948 | "cfg-if 1.0.0", 949 | "cpufeatures", 950 | "digest 0.9.0", 951 | "opaque-debug", 952 | ] 953 | 954 | [[package]] 955 | name = "sha3" 956 | version = "0.9.1" 957 | source = "registry+https://github.com/rust-lang/crates.io-index" 958 | checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" 959 | dependencies = [ 960 | "block-buffer", 961 | "digest 0.9.0", 962 | "keccak", 963 | "opaque-debug", 964 | ] 965 | 966 | [[package]] 967 | name = "solana-frozen-abi" 968 | version = "1.8.16" 969 | source = "registry+https://github.com/rust-lang/crates.io-index" 970 | checksum = "425be155319bda665dc3483f0c0267ac0fc89017812d0c5d9816b1c7a26c1532" 971 | dependencies = [ 972 | "bs58 0.3.1", 973 | "bv", 974 | "generic-array 0.14.5", 975 | "log", 976 | "memmap2", 977 | "rustc_version", 978 | "serde", 979 | "serde_derive", 980 | "sha2", 981 | "solana-frozen-abi-macro", 982 | "solana-logger", 983 | "thiserror", 984 | ] 985 | 986 | [[package]] 987 | name = "solana-frozen-abi-macro" 988 | version = "1.8.16" 989 | source = "registry+https://github.com/rust-lang/crates.io-index" 990 | checksum = "8d97737c34380c42c9b3e060cf68d1929ad81fea5a3c00887bb82314b788ba13" 991 | dependencies = [ 992 | "proc-macro2", 993 | "quote", 994 | "rustc_version", 995 | "syn", 996 | ] 997 | 998 | [[package]] 999 | name = "solana-logger" 1000 | version = "1.8.16" 1001 | source = "registry+https://github.com/rust-lang/crates.io-index" 1002 | checksum = "659d836ac49f5a53481ead26f4ea78b688a91dedcbe6c51454169491e1648ceb" 1003 | dependencies = [ 1004 | "env_logger", 1005 | "lazy_static", 1006 | "log", 1007 | ] 1008 | 1009 | [[package]] 1010 | name = "solana-program" 1011 | version = "1.8.16" 1012 | source = "registry+https://github.com/rust-lang/crates.io-index" 1013 | checksum = "00b2b6d99b5c662975ead69a60ead75b820f2eaa42eb4512c79a919e91807d43" 1014 | dependencies = [ 1015 | "base64 0.13.0", 1016 | "bincode", 1017 | "blake3", 1018 | "borsh", 1019 | "borsh-derive", 1020 | "bs58 0.3.1", 1021 | "bv", 1022 | "bytemuck", 1023 | "curve25519-dalek", 1024 | "hex", 1025 | "itertools", 1026 | "lazy_static", 1027 | "libsecp256k1", 1028 | "log", 1029 | "num-derive", 1030 | "num-traits", 1031 | "rand", 1032 | "rustc_version", 1033 | "rustversion", 1034 | "serde", 1035 | "serde_bytes", 1036 | "serde_derive", 1037 | "sha2", 1038 | "sha3", 1039 | "solana-frozen-abi", 1040 | "solana-frozen-abi-macro", 1041 | "solana-logger", 1042 | "solana-sdk-macro", 1043 | "thiserror", 1044 | ] 1045 | 1046 | [[package]] 1047 | name = "solana-sdk-macro" 1048 | version = "1.8.16" 1049 | source = "registry+https://github.com/rust-lang/crates.io-index" 1050 | checksum = "a122a01e936f3b69064f0800e0488617833fc6a4dd86294cf7cc75f34511d6b5" 1051 | dependencies = [ 1052 | "bs58 0.3.1", 1053 | "proc-macro2", 1054 | "quote", 1055 | "rustversion", 1056 | "syn", 1057 | ] 1058 | 1059 | [[package]] 1060 | name = "spl-associated-token-account" 1061 | version = "1.0.3" 1062 | source = "registry+https://github.com/rust-lang/crates.io-index" 1063 | checksum = "393e2240d521c3dd770806bff25c2c00d761ac962be106e14e22dd912007f428" 1064 | dependencies = [ 1065 | "solana-program", 1066 | "spl-token", 1067 | ] 1068 | 1069 | [[package]] 1070 | name = "spl-token" 1071 | version = "3.2.0" 1072 | source = "registry+https://github.com/rust-lang/crates.io-index" 1073 | checksum = "93bfdd5bd7c869cb565c7d7635c4fafe189b988a0bdef81063cd9585c6b8dc01" 1074 | dependencies = [ 1075 | "arrayref", 1076 | "num-derive", 1077 | "num-traits", 1078 | "num_enum", 1079 | "solana-program", 1080 | "thiserror", 1081 | ] 1082 | 1083 | [[package]] 1084 | name = "subtle" 1085 | version = "2.4.1" 1086 | source = "registry+https://github.com/rust-lang/crates.io-index" 1087 | checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" 1088 | 1089 | [[package]] 1090 | name = "syn" 1091 | version = "1.0.90" 1092 | source = "registry+https://github.com/rust-lang/crates.io-index" 1093 | checksum = "704df27628939572cd88d33f171cd6f896f4eaca85252c6e0a72d8d8287ee86f" 1094 | dependencies = [ 1095 | "proc-macro2", 1096 | "quote", 1097 | "unicode-xid", 1098 | ] 1099 | 1100 | [[package]] 1101 | name = "termcolor" 1102 | version = "1.1.3" 1103 | source = "registry+https://github.com/rust-lang/crates.io-index" 1104 | checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" 1105 | dependencies = [ 1106 | "winapi-util", 1107 | ] 1108 | 1109 | [[package]] 1110 | name = "thiserror" 1111 | version = "1.0.30" 1112 | source = "registry+https://github.com/rust-lang/crates.io-index" 1113 | checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" 1114 | dependencies = [ 1115 | "thiserror-impl", 1116 | ] 1117 | 1118 | [[package]] 1119 | name = "thiserror-impl" 1120 | version = "1.0.30" 1121 | source = "registry+https://github.com/rust-lang/crates.io-index" 1122 | checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" 1123 | dependencies = [ 1124 | "proc-macro2", 1125 | "quote", 1126 | "syn", 1127 | ] 1128 | 1129 | [[package]] 1130 | name = "toml" 1131 | version = "0.5.8" 1132 | source = "registry+https://github.com/rust-lang/crates.io-index" 1133 | checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" 1134 | dependencies = [ 1135 | "serde", 1136 | ] 1137 | 1138 | [[package]] 1139 | name = "typenum" 1140 | version = "1.15.0" 1141 | source = "registry+https://github.com/rust-lang/crates.io-index" 1142 | checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" 1143 | 1144 | [[package]] 1145 | name = "unicode-segmentation" 1146 | version = "1.9.0" 1147 | source = "registry+https://github.com/rust-lang/crates.io-index" 1148 | checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" 1149 | 1150 | [[package]] 1151 | name = "unicode-xid" 1152 | version = "0.2.2" 1153 | source = "registry+https://github.com/rust-lang/crates.io-index" 1154 | checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" 1155 | 1156 | [[package]] 1157 | name = "version_check" 1158 | version = "0.9.4" 1159 | source = "registry+https://github.com/rust-lang/crates.io-index" 1160 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 1161 | 1162 | [[package]] 1163 | name = "wasi" 1164 | version = "0.9.0+wasi-snapshot-preview1" 1165 | source = "registry+https://github.com/rust-lang/crates.io-index" 1166 | checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" 1167 | 1168 | [[package]] 1169 | name = "wasi" 1170 | version = "0.10.2+wasi-snapshot-preview1" 1171 | source = "registry+https://github.com/rust-lang/crates.io-index" 1172 | checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" 1173 | 1174 | [[package]] 1175 | name = "winapi" 1176 | version = "0.3.9" 1177 | source = "registry+https://github.com/rust-lang/crates.io-index" 1178 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1179 | dependencies = [ 1180 | "winapi-i686-pc-windows-gnu", 1181 | "winapi-x86_64-pc-windows-gnu", 1182 | ] 1183 | 1184 | [[package]] 1185 | name = "winapi-i686-pc-windows-gnu" 1186 | version = "0.4.0" 1187 | source = "registry+https://github.com/rust-lang/crates.io-index" 1188 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1189 | 1190 | [[package]] 1191 | name = "winapi-util" 1192 | version = "0.1.5" 1193 | source = "registry+https://github.com/rust-lang/crates.io-index" 1194 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 1195 | dependencies = [ 1196 | "winapi", 1197 | ] 1198 | 1199 | [[package]] 1200 | name = "winapi-x86_64-pc-windows-gnu" 1201 | version = "0.4.0" 1202 | source = "registry+https://github.com/rust-lang/crates.io-index" 1203 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1204 | 1205 | [[package]] 1206 | name = "yansi" 1207 | version = "0.5.1" 1208 | source = "registry+https://github.com/rust-lang/crates.io-index" 1209 | checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" 1210 | 1211 | [[package]] 1212 | name = "zeroize" 1213 | version = "1.5.4" 1214 | source = "registry+https://github.com/rust-lang/crates.io-index" 1215 | checksum = "7eb5728b8afd3f280a869ce1d4c554ffaed35f45c231fc41bfbd0381bef50317" 1216 | -------------------------------------------------------------------------------- /facebook-clone/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | "programs/*" 4 | ] 5 | -------------------------------------------------------------------------------- /facebook-clone/app/start.ts: -------------------------------------------------------------------------------- 1 | 2 | import { FacebookClone } from "../target/types/facebook_clone"; 3 | 4 | const anchor = require('@project-serum/anchor'); 5 | const { TOKEN_PROGRAM_ID } = require("@solana/spl-token"); 6 | const _ = require('lodash') 7 | const { web3 } = anchor 8 | const { SystemProgram } = web3 9 | const assert = require("assert"); 10 | const utf8 = anchor.utils.bytes.utf8; 11 | const provider = anchor.Provider.local() 12 | 13 | 14 | const defaultAccounts = { 15 | tokenProgram: TOKEN_PROGRAM_ID, 16 | systemProgram: SystemProgram.programId, 17 | } 18 | 19 | // Configure the client to use the local cluster. 20 | anchor.setProvider(provider); 21 | const program = anchor.workspace.FacebookClone as Program; 22 | let creatorKey = provider.wallet.publicKey; 23 | let stateSigner; 24 | 25 | const run = async () => { 26 | [stateSigner] = await anchor.web3.PublicKey.findProgramAddress( 27 | [utf8.encode('state')], 28 | program.programId 29 | ); 30 | 31 | try{ 32 | const stateInfo = await program.account.stateAccount.fetch(stateSigner); 33 | console.log(stateInfo); 34 | } 35 | catch{ 36 | await program.rpc.createState({ 37 | accounts: { 38 | state: stateSigner, 39 | authority: creatorKey, 40 | ...defaultAccounts 41 | }, 42 | }) 43 | 44 | const stateInfo = await program.account.stateAccount.fetch(stateSigner); 45 | console.log(stateInfo); 46 | assert(stateInfo.authority.toString() === creatorKey.toString(), "State Creator is Invalid"); 47 | } 48 | } 49 | 50 | run(); -------------------------------------------------------------------------------- /facebook-clone/migrations/deploy.ts: -------------------------------------------------------------------------------- 1 | // Migrations are an early feature. Currently, they're nothing more than this 2 | // single deploy script that's invoked from the CLI, injecting a provider 3 | // configured from the workspace's Anchor.toml. 4 | 5 | const anchor = require("@project-serum/anchor"); 6 | 7 | module.exports = async function (provider) { 8 | // Configure client to use the provider. 9 | anchor.setProvider(provider); 10 | 11 | // Add your deploy script here. 12 | }; 13 | -------------------------------------------------------------------------------- /facebook-clone/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "@project-serum/anchor": "^0.23.0", 4 | "@project-serum/common": "^0.0.1-beta.3", 5 | "bn": "^1.0.5", 6 | "lodash": "^4.17.21" 7 | }, 8 | "devDependencies": { 9 | "@types/chai": "^4.3.0", 10 | "@types/mocha": "^9.0.0", 11 | "chai": "^4.3.4", 12 | "mocha": "^9.0.3", 13 | "ts-mocha": "^8.0.0", 14 | "typescript": "^4.3.5" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /facebook-clone/programs/facebook-clone/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "facebook-clone" 3 | version = "0.1.0" 4 | description = "Created with Anchor" 5 | edition = "2018" 6 | 7 | [lib] 8 | crate-type = ["cdylib", "lib"] 9 | name = "facebook_clone" 10 | 11 | [features] 12 | no-entrypoint = [] 13 | no-idl = [] 14 | no-log-ix-name = [] 15 | cpi = ["no-entrypoint"] 16 | default = [] 17 | 18 | [dependencies] 19 | anchor-lang = "0.21.0" 20 | anchor-spl = "0.21.0" 21 | -------------------------------------------------------------------------------- /facebook-clone/programs/facebook-clone/Xargo.toml: -------------------------------------------------------------------------------- 1 | [target.bpfel-unknown-unknown.dependencies.std] 2 | features = [] 3 | -------------------------------------------------------------------------------- /facebook-clone/programs/facebook-clone/src/lib.rs: -------------------------------------------------------------------------------- 1 | /// Include libraries for program 2 | use anchor_lang::prelude::*; 3 | use anchor_spl::token::{self, Token}; 4 | use std::mem::size_of; 5 | 6 | // Declare program ID 7 | declare_id!("GNSDgX32cCeuuN96GRiBmFE4BAXqgFpftqxSCzDrdkTd"); 8 | 9 | // Post and comment text length 10 | const TEXT_LENGTH: usize = 1024; 11 | // Username length 12 | const USER_NAME_LENGTH: usize = 100; 13 | // User profile imaage url length 14 | const USER_URL_LENGTH: usize = 255; 15 | 16 | /// Facebook Clone program 17 | #[program] 18 | pub mod facebook_clone { 19 | use super::*; 20 | 21 | /// Create state to save the post counts 22 | /// There is only one state in the program 23 | /// This account should be initialized before post 24 | pub fn create_state( 25 | ctx: Context, 26 | ) -> ProgramResult { 27 | // Get state from context 28 | let state = &mut ctx.accounts.state; 29 | // Save authority to state 30 | state.authority = ctx.accounts.authority.key(); 31 | // Set post count as 0 when initializing 32 | state.post_count = 0; 33 | Ok(()) 34 | } 35 | 36 | /// Create post 37 | /// @param text: text of post 38 | /// @param poster_name: name of post creator 39 | /// @param poster_url: url of post creator avatar 40 | pub fn create_post( 41 | ctx: Context, 42 | text: String, 43 | poster_name: String, 44 | poster_url: String, 45 | ) -> ProgramResult { 46 | // Get State 47 | let state = &mut ctx.accounts.state; 48 | 49 | // Get post 50 | let post = &mut ctx.accounts.post; 51 | // Set authority 52 | post.authority = ctx.accounts.authority.key(); 53 | // Set text 54 | post.text = text; 55 | // Set poster name 56 | post.poster_name = poster_name; 57 | // Set poster avatar url 58 | post.poster_url = poster_url; 59 | // Set comment count as 0 60 | post.comment_count = 0; 61 | // Set post index as state's post count 62 | post.index = state.post_count; 63 | // Set post time 64 | post.post_time = ctx.accounts.clock.unix_timestamp; 65 | 66 | // Increase state's post count by 1 67 | state.post_count += 1; 68 | Ok(()) 69 | } 70 | 71 | /// Create comment for post 72 | /// @param text: text of comment 73 | /// @param commenter_name: name of comment creator 74 | /// @param commenter_url: url of comment creator avatar 75 | pub fn create_comment( 76 | ctx: Context, 77 | text: String, 78 | commenter_name: String, 79 | commenter_url: String, 80 | ) -> ProgramResult { 81 | 82 | // Get post 83 | let post = &mut ctx.accounts.post; 84 | 85 | // Get comment 86 | let comment = &mut ctx.accounts.comment; 87 | // Set authority to comment 88 | comment.authority = ctx.accounts.authority.key(); 89 | // Set comment text 90 | comment.text = text; 91 | // Set commenter name 92 | comment.commenter_name = commenter_name; 93 | // Set commenter url 94 | comment.commenter_url = commenter_url; 95 | // Set comment index to post's comment count 96 | comment.index = post.comment_count; 97 | // Set post time 98 | comment.post_time = ctx.accounts.clock.unix_timestamp; 99 | 100 | // Increase post's comment count by 1 101 | post.comment_count += 1; 102 | 103 | Ok(()) 104 | } 105 | } 106 | 107 | /// Contexts 108 | /// CreateState context 109 | #[derive(Accounts)] 110 | pub struct CreateState<'info> { 111 | // Authenticating state account 112 | #[account( 113 | init, 114 | seeds = [b"state".as_ref()], 115 | bump, 116 | payer = authority, 117 | space = size_of::() + 8 118 | )] 119 | pub state: Account<'info, StateAccount>, 120 | 121 | // Authority (this is signer who paid transaction fee) 122 | #[account(mut)] 123 | pub authority: Signer<'info>, 124 | 125 | /// System program 126 | pub system_program: UncheckedAccount<'info>, 127 | 128 | // Token program 129 | #[account(constraint = token_program.key == &token::ID)] 130 | pub token_program: Program<'info, Token>, 131 | } 132 | 133 | /// CreatePost context 134 | #[derive(Accounts)] 135 | pub struct CreatePost<'info> { 136 | // Authenticate state account 137 | #[account(mut, seeds = [b"state".as_ref()], bump)] 138 | pub state: Account<'info, StateAccount>, 139 | 140 | // Authenticate post account 141 | #[account( 142 | init, 143 | // Post account use string "post" and index of post as seeds 144 | seeds = [b"post".as_ref(), state.post_count.to_be_bytes().as_ref()], 145 | bump, 146 | payer = authority, 147 | space = size_of::() + TEXT_LENGTH + USER_NAME_LENGTH + USER_URL_LENGTH 148 | )] 149 | pub post: Account<'info, PostAccount>, 150 | 151 | // Authority (this is signer who paid transaction fee) 152 | #[account(mut)] 153 | pub authority: Signer<'info>, 154 | 155 | /// System program 156 | pub system_program: UncheckedAccount<'info>, 157 | 158 | // Token program 159 | #[account(constraint = token_program.key == &token::ID)] 160 | pub token_program: Program<'info, Token>, 161 | 162 | // Clock to save time 163 | pub clock: Sysvar<'info, Clock>, 164 | } 165 | 166 | /// CreateComment context 167 | #[derive(Accounts)] 168 | pub struct CreateComment<'info> { 169 | // Authenticate post account 170 | #[account(mut, seeds = [b"post".as_ref(), post.index.to_be_bytes().as_ref()], bump)] 171 | pub post: Account<'info, PostAccount>, 172 | 173 | // Authenticate comment account 174 | #[account( 175 | init, 176 | // Post account use string "comment", index of post and index of comment per post as seeds 177 | seeds = [b"comment".as_ref(), post.index.to_be_bytes().as_ref(), post.comment_count.to_be_bytes().as_ref()], 178 | bump, 179 | payer = authority, 180 | space = size_of::() + TEXT_LENGTH + USER_NAME_LENGTH + USER_URL_LENGTH 181 | )] 182 | pub comment: Account<'info, CommentAccount>, 183 | 184 | // Authority (this is signer who paid transaction fee) 185 | #[account(mut)] 186 | pub authority: Signer<'info>, 187 | 188 | /// System program 189 | pub system_program: UncheckedAccount<'info>, 190 | 191 | // Token program 192 | #[account(constraint = token_program.key == &token::ID)] 193 | pub token_program: Program<'info, Token>, 194 | 195 | // Clock to save time 196 | pub clock: Sysvar<'info, Clock>, 197 | } 198 | 199 | // State Account Structure 200 | #[account] 201 | pub struct StateAccount { 202 | // Signer address 203 | pub authority: Pubkey, 204 | 205 | // Post count 206 | pub post_count: u64, 207 | } 208 | 209 | // Post Account Structure 210 | #[account] 211 | pub struct PostAccount { 212 | // Signer address 213 | pub authority: Pubkey, 214 | 215 | // Post text 216 | pub text: String, 217 | 218 | // Post creator name 219 | pub poster_name: String, 220 | 221 | // Post creator url 222 | pub poster_url: String, 223 | 224 | // Comment counts of post 225 | pub comment_count: u64, 226 | 227 | // Post index 228 | pub index: u64, 229 | 230 | // Post time 231 | pub post_time: i64, 232 | } 233 | 234 | // Comment Account Structure 235 | #[account] 236 | pub struct CommentAccount { 237 | // Signer address 238 | pub authority: Pubkey, 239 | 240 | // Comment text 241 | pub text: String, 242 | 243 | // commenter_name 244 | pub commenter_name: String, 245 | 246 | // commenter_url 247 | pub commenter_url: String, 248 | 249 | // Comment index 250 | pub index: u64, 251 | 252 | // Post time 253 | pub post_time: i64, 254 | } 255 | -------------------------------------------------------------------------------- /facebook-clone/tests/facebook-clone.ts: -------------------------------------------------------------------------------- 1 | import { FacebookClone } from '../target/types/facebook_clone' 2 | 3 | const anchor = require('@project-serum/anchor') 4 | const { TOKEN_PROGRAM_ID } = require('@solana/spl-token') 5 | const _ = require('lodash') 6 | const { web3 } = anchor 7 | const { SystemProgram } = web3 8 | const assert = require('assert') 9 | const utf8 = anchor.utils.bytes.utf8 10 | const provider = anchor.Provider.local() 11 | 12 | const defaultAccounts = { 13 | tokenProgram: TOKEN_PROGRAM_ID, 14 | clock: anchor.web3.SYSVAR_CLOCK_PUBKEY, 15 | systemProgram: SystemProgram.programId, 16 | // rent: anchor.web3.SYSVAR_RENT_PUBKEY, 17 | } 18 | // Configure the client to use the local cluster. 19 | anchor.setProvider(provider) 20 | const program = anchor.workspace.FacebookClone as Program 21 | let creatorKey = provider.wallet.publicKey 22 | let stateSigner 23 | 24 | describe('facebook-clone', () => { 25 | it('Create State', async () => { 26 | ;[stateSigner] = await anchor.web3.PublicKey.findProgramAddress( 27 | [utf8.encode('state')], 28 | program.programId, 29 | ) 30 | 31 | try { 32 | const stateInfo = await program.account.stateAccount.fetch(stateSigner) 33 | } catch { 34 | await program.rpc.createState({ 35 | accounts: { 36 | state: stateSigner, 37 | authority: creatorKey, 38 | ...defaultAccounts, 39 | }, 40 | }) 41 | 42 | const stateInfo = await program.account.stateAccount.fetch(stateSigner) 43 | assert( 44 | stateInfo.authority.toString() === creatorKey.toString(), 45 | 'State Creator is Invalid', 46 | ) 47 | } 48 | }) 49 | 50 | // it("Create First Post", async () => { 51 | // const stateInfo = await program.account.stateAccount.fetch(stateSigner); 52 | // console.log(stateInfo.postCount); 53 | 54 | // if (stateInfo.postCount > 0) { 55 | // return; 56 | // } 57 | 58 | // [postSigner] = await anchor.web3.PublicKey.findProgramAddress( 59 | // [utf8.encode('post'), stateInfo.postCount.toBuffer("be", 8)], 60 | // program.programId 61 | // ); 62 | 63 | // try{ 64 | // const postInfo = await program.account.postAccount.fetch(postSigner); 65 | // console.log(postInfo); 66 | // } 67 | // catch{ 68 | // await program.rpc.createPost("this is first post", "first", "https://first.com", { 69 | // accounts: { 70 | // state: stateSigner, 71 | // post: postSigner, 72 | // authority: creatorKey, 73 | // ...defaultAccounts 74 | // }, 75 | // }) 76 | 77 | // const postInfo = await program.account.postAccount.fetch(postSigner); 78 | // console.log(postInfo); 79 | // assert(postInfo.authority.toString() === creatorKey.toString(), "Post Creator is Invalid"); 80 | // } 81 | // }); 82 | 83 | // it("Fetch All Posts",async () => { 84 | // try{ 85 | // const postInfo = await program.account.postAccount.all(); 86 | // console.log(postInfo); 87 | // } 88 | // catch (e) { 89 | // console.log(e); 90 | // } 91 | // }); 92 | 93 | // it("Create Second Post", async () => { 94 | // const stateInfo = await program.account.stateAccount.fetch(stateSigner); 95 | // console.log(stateInfo.postCount); 96 | 97 | // if (stateInfo.postCount > 1) { 98 | // return; 99 | // } 100 | 101 | // [postSigner] = await anchor.web3.PublicKey.findProgramAddress( 102 | // [utf8.encode('post'), stateInfo.postCount.toBuffer("be", 8)], 103 | // program.programId 104 | // ); 105 | 106 | // try{ 107 | // const postInfo = await program.account.postAccount.fetch(postSigner); 108 | // console.log(postInfo); 109 | // } 110 | // catch{ 111 | // await program.rpc.createPost("this is second post", "second", "https://second.com", { 112 | // accounts: { 113 | // state: stateSigner, 114 | // post: postSigner, 115 | // authority: creatorKey, 116 | // ...defaultAccounts 117 | // }, 118 | // }) 119 | 120 | // const postInfo = await program.account.postAccount.fetch(postSigner); 121 | // console.log(postInfo); 122 | // assert(postInfo.authority.toString() === creatorKey.toString(), "Post Creator is Invalid"); 123 | // } 124 | // }); 125 | 126 | // it("Create Comment to first", async () => { 127 | // [postSigner] = await anchor.web3.PublicKey.findProgramAddress( 128 | // [utf8.encode('post'), new BN(0).toBuffer("be", 8)], 129 | // program.programId 130 | // ); 131 | 132 | // try{ 133 | // const postInfo = await program.account.postAccount.fetch(postSigner); 134 | // console.log(postInfo); 135 | 136 | // let [commentSigner] = await anchor.web3.PublicKey.findProgramAddress( 137 | // [utf8.encode('comment'), postInfo.index.toBuffer("be", 8), postInfo.commentCount.toBuffer("be", 8)], 138 | // program.programId 139 | // ); 140 | 141 | // console.log(commentSigner); 142 | 143 | // await program.rpc.createComment("this is great", "second", "https://second.com", { 144 | // accounts: { 145 | // post: postSigner, 146 | // comment: commentSigner, 147 | // authority: creatorKey, 148 | // ...defaultAccounts 149 | // }, 150 | // }); 151 | 152 | // const commentInfo = await program.account.commentAccount.fetch(commentSigner); 153 | // console.log(commentInfo); 154 | // assert(postInfo.authority.toString() === creatorKey.toString(), "Comment Creator is Invalid"); 155 | // } 156 | // catch{ 157 | // assert(false, "Comment create failed") 158 | // } 159 | // }); 160 | 161 | // it("Fetch All Comments",async () => { 162 | // try{ 163 | // const commentList = await program.account.commentAccount.all(); 164 | // console.log(commentList); 165 | // } 166 | // catch (e) { 167 | // console.log(e); 168 | // } 169 | // }); 170 | }) 171 | -------------------------------------------------------------------------------- /facebook-clone/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "types": ["mocha", "chai"], 4 | "typeRoots": ["./node_modules/@types"], 5 | "lib": ["es2015"], 6 | "module": "commonjs", 7 | "target": "es6", 8 | "esModuleInterop": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lib/sanity.js: -------------------------------------------------------------------------------- 1 | import sanityClient from '@sanity/client' 2 | 3 | export const client = sanityClient({ 4 | projectId: process.env.SANITY_PROJECT_ID, 5 | dataset: 'production', 6 | apiVersion: 'v1', 7 | token: process.env.SANITY_TOKEN, 8 | useCdn: false, 9 | }) 10 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | reactStrictMode: true, 4 | images: { 5 | domains: [ 6 | 'avatars.dicebear.com', 7 | 'avatars.githubusercontent.com', 8 | 'upload.wikimedia.org', 9 | 'www.dmarge.com', 10 | 'cdn-icons.flaticon.com', 11 | 'kajabi-storefronts-production.kajabi-cdn.com', 12 | 'www.cityam.com', 13 | 'yt3.ggpht.com', 14 | 'media-exp1.licdn.com', 15 | 'scontent-lax3-1.xx.fbcdn.net', 16 | ], 17 | }, 18 | } 19 | 20 | module.exports = nextConfig 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontend", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@project-serum/anchor": "^0.23.0", 13 | "@sanity/client": "^3.3.0", 14 | "@solana/spl-token": "^0.2.0", 15 | "@solana/wallet-adapter-react": "^0.15.4", 16 | "@solana/wallet-adapter-react-ui": "^0.9.6", 17 | "@solana/wallet-adapter-wallets": "^0.15.5", 18 | "@solana/web3.js": "^1.37.0", 19 | "bootstrap": "^5.1.3", 20 | "firebase": "^9.6.10", 21 | "javascript-time-ago": "^2.3.13", 22 | "next": "12.1.4", 23 | "react": "18.0.0", 24 | "react-bootstrap": "^2.2.2", 25 | "react-dom": "18.0.0", 26 | "react-hot-toast": "^2.2.0", 27 | "react-icons": "^4.3.1", 28 | "react-simple-hook-modal": "^1.1.0", 29 | "react-spinners": "^0.11.0" 30 | }, 31 | "devDependencies": { 32 | "autoprefixer": "^10.4.4", 33 | "eslint": "8.12.0", 34 | "eslint-config-next": "12.1.4", 35 | "postcss": "^8.4.12", 36 | "tailwindcss": "^3.0.23" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /pages/_app.js: -------------------------------------------------------------------------------- 1 | import dynamic from 'next/dynamic' 2 | import '../styles/globals.css' 3 | import { WalletBalanceProvider } from '../context/useWalletBalance' 4 | import { ModalProvider } from 'react-simple-hook-modal' 5 | 6 | const WalletConnectionProvider = dynamic( 7 | () => import('../context/WalletConnectionProvider'), 8 | { 9 | ssr: false, 10 | }, 11 | ) 12 | 13 | function MyApp({ Component, pageProps }) { 14 | return ( 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | ) 23 | } 24 | 25 | export default MyApp 26 | -------------------------------------------------------------------------------- /pages/api/createUser.js: -------------------------------------------------------------------------------- 1 | import { client } from '../../lib/sanity' 2 | 3 | const createUserOnSanity = async (req, res) => { 4 | try { 5 | const userDoc = { 6 | _type: 'users', 7 | _id: req.body.userWalletAddress, 8 | name: req.body.name, 9 | walletAddress: req.body.userWalletAddress, 10 | profileImage: req.body.profileImage, 11 | } 12 | 13 | await client.createIfNotExists(userDoc) 14 | 15 | res.status(200).send({ message: 'success' }) 16 | } catch (error) { 17 | res.status(500).send({ message: 'error', data: error.message }) 18 | } 19 | } 20 | 21 | export default createUserOnSanity 22 | -------------------------------------------------------------------------------- /pages/api/fetchUsers.js: -------------------------------------------------------------------------------- 1 | import { client } from '../../lib/sanity' 2 | 3 | const getUserInfo = async (req, res) => { 4 | try { 5 | const query = ` 6 | *[_type == "users"]{ 7 | name, 8 | walletAddress, 9 | profileImage, 10 | } 11 | ` 12 | 13 | const sanityResponse = await client.fetch(query) 14 | 15 | res.status(200).send({ message: 'success', data: sanityResponse }) 16 | } catch (error) { 17 | res.status(500).send({ message: 'error', data: error.message }) 18 | } 19 | } 20 | 21 | export default getUserInfo 22 | -------------------------------------------------------------------------------- /pages/index.js: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from 'react' 2 | import { useWallet } from '@solana/wallet-adapter-react' 3 | import SignUp from '../components/SignUp' 4 | import Header from '../components/Header' 5 | import Feed from '../components/Feed' 6 | import RightSidebar from '../components/RightSidebar' 7 | import Sidebar from '../components/Sidebar' 8 | 9 | const style = { 10 | wrapper: `bg-[#18191a] min-h-screen duration-[0.5s]`, 11 | homeWrapper: `flex`, 12 | center: `flex-1`, 13 | main: `flex-1 flex justify-center`, 14 | signupContainer: `flex items-center justify-center w-screen h-[70vh]`, 15 | } 16 | 17 | export default function Home() { 18 | const [registered, setRegistered] = useState(false) 19 | const [name, setName] = useState('') 20 | const [url, setUrl] = useState('') 21 | const [users, setUsers] = useState([]) 22 | 23 | useEffect(() => { 24 | ;(async () => { 25 | await requestUsersData() 26 | })() 27 | }, []) 28 | 29 | const wallet = useWallet() 30 | 31 | const requestUsersData = async activeAccount => { 32 | try { 33 | const response = await fetch(`/api/fetchUsers`) 34 | const data = await response.json() 35 | 36 | setUsers(data.data) 37 | } catch (error) { 38 | console.error(error) 39 | } 40 | } 41 | 42 | return ( 43 |
44 |
45 | 46 | {registered ? ( 47 |
48 | 49 |
50 | 51 |
52 | 57 |
58 | ) : ( 59 |
60 | 67 |
68 | )} 69 |
70 | ) 71 | } 72 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleverProgrammers/facebook-solana-blockchain/504d29ece92c52f43e94ce6af1125f7f8423cfb2/public/favicon.ico -------------------------------------------------------------------------------- /public/vercel.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /static/static.js: -------------------------------------------------------------------------------- 1 | import friendsIcon from '../assets/friends.png' 2 | import groupsIcon from '../assets/groups.png' 3 | import marketplaceIcon from '../assets/marketplace.png' 4 | import memoriesIcon from '../assets/memories.png' 5 | import watchIcon from '../assets/watch.png' 6 | import dropdownIcon from '../assets/dropdown.png' 7 | 8 | export const sidebarData = [ 9 | { 10 | icon: friendsIcon, 11 | title: `Friends`, 12 | }, 13 | { 14 | icon: groupsIcon, 15 | title: `Groups`, 16 | }, 17 | { 18 | icon: marketplaceIcon, 19 | title: `Marketplace`, 20 | }, 21 | { 22 | icon: watchIcon, 23 | title: `Watch`, 24 | }, 25 | { 26 | icon: memoriesIcon, 27 | title: `Memories`, 28 | }, 29 | { 30 | icon: dropdownIcon, 31 | title: `See more`, 32 | }, 33 | ] 34 | -------------------------------------------------------------------------------- /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": "e2ed4e51e97331c0699ba7cf9f67cbf76f1c6a5f806d6eabf8259b2bcb5f1002", 5 | "@sanity/form-builder": "b38478227ba5e22c91981da4b53436df22e48ff25238a55a973ed620be5068aa", 6 | "@sanity/data-aspects": "d199e2c199b3e26cd28b68dc84d7fc01c9186bf5089580f2e2446994d36b3cb6", 7 | "@sanity/vision": "da5b6ed712703ecd04bf4df560570c668aa95252c6bc1c41d6df1bda9b8b8f60" 8 | } 9 | -------------------------------------------------------------------------------- /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 | "loginMethod": "dual" 8 | } 9 | -------------------------------------------------------------------------------- /studio/config/@sanity/form-builder.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": { 3 | "directUploads": true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /studio/config/@sanity/vision.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultApiVersion": "2021-10-21" 3 | } 4 | -------------------------------------------------------------------------------- /studio/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "facebookclone", 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.29.3", 18 | "@sanity/core": "^2.29.3", 19 | "@sanity/default-layout": "^2.29.3", 20 | "@sanity/default-login": "^2.29.3", 21 | "@sanity/desk-tool": "^2.29.4", 22 | "@sanity/eslint-config-studio": "^2.0.0", 23 | "@sanity/vision": "^2.29.3", 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": "facebook-clone" 5 | }, 6 | "api": { 7 | "projectId": "jq3scfjr", 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 | import { userSchema } from './userSchema' 4 | 5 | export default createSchema({ 6 | name: 'default', 7 | types: schemaTypes.concat([userSchema]), 8 | }) 9 | -------------------------------------------------------------------------------- /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 | } 23 | -------------------------------------------------------------------------------- /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/facebook-solana-blockchain/504d29ece92c52f43e94ce6af1125f7f8423cfb2/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 | -------------------------------------------------------------------------------- /styles/Login.css: -------------------------------------------------------------------------------- 1 | .login { 2 | display: grid; 3 | place-items: center; 4 | height: 100vh; 5 | } 6 | .login div img { 7 | object-fit: contain; 8 | height: 150px; 9 | } 10 | 11 | .login button { 12 | width: 300px; 13 | text-transform: none; 14 | background-color: #2e81f4; 15 | border: 1px solid #2e81f4; 16 | color: #eff2f5; 17 | font-size: 16px; 18 | } 19 | .login button:hover { 20 | background-color: #fff; 21 | color: #2e81f4; 22 | } 23 | .login div { 24 | display: flex; 25 | flex-direction: column; 26 | } 27 | -------------------------------------------------------------------------------- /styles/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | * { 6 | -webkit-touch-callout: none; 7 | -webkit-user-select: none; 8 | -khtml-user-select: none; 9 | -moz-user-select: none; 10 | -ms-user-select: none; 11 | user-select: none; 12 | } 13 | 14 | html, 15 | body { 16 | padding: 0; 17 | margin: 0; 18 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, 19 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; 20 | } 21 | 22 | a { 23 | color: inherit; 24 | text-decoration: none; 25 | } 26 | 27 | * { 28 | box-sizing: border-box; 29 | } 30 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /utils/const.js: -------------------------------------------------------------------------------- 1 | import { clusterApiUrl, PublicKey } from '@solana/web3.js' 2 | import facebook_clone from './facebook_clone.json' 3 | 4 | export const CLUSTER = 5 | process.env.REACT_APP_CLUSTER === 'mainnet' 6 | ? 'mainnet' 7 | : process.env.REACT_APP_CLUSTER === 'testnet' 8 | ? 'testnet' 9 | : 'devnet' 10 | 11 | export const SOLANA_HOST = process.env.REACT_APP_SOLANA_API_URL 12 | ? process.env.REACT_APP_SOLANA_API_URL 13 | : CLUSTER === 'mainnet' 14 | ? clusterApiUrl('mainnet-beta') 15 | : CLUSTER === 'testnet' 16 | ? clusterApiUrl('devnet') 17 | : 'https://api.devnet.solana.com' 18 | 19 | export const STABLE_POOL_PROGRAM_ID = new PublicKey( 20 | '6b5cvMWLE1LwRzzv4dtiz1w5yHTnpbt3A2s3UtbvZkWt', 21 | ) 22 | 23 | export const STABLE_POOL_IDL = facebook_clone 24 | -------------------------------------------------------------------------------- /utils/facebook_clone.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.1.0", 3 | "name": "facebook_clone", 4 | "instructions": [ 5 | { 6 | "name": "createState", 7 | "accounts": [ 8 | { 9 | "name": "state", 10 | "isMut": true, 11 | "isSigner": false 12 | }, 13 | { 14 | "name": "authority", 15 | "isMut": true, 16 | "isSigner": true 17 | }, 18 | { 19 | "name": "systemProgram", 20 | "isMut": false, 21 | "isSigner": false 22 | }, 23 | { 24 | "name": "tokenProgram", 25 | "isMut": false, 26 | "isSigner": false 27 | } 28 | ], 29 | "args": [] 30 | }, 31 | { 32 | "name": "createPost", 33 | "accounts": [ 34 | { 35 | "name": "state", 36 | "isMut": true, 37 | "isSigner": false 38 | }, 39 | { 40 | "name": "post", 41 | "isMut": true, 42 | "isSigner": false 43 | }, 44 | { 45 | "name": "authority", 46 | "isMut": true, 47 | "isSigner": true 48 | }, 49 | { 50 | "name": "systemProgram", 51 | "isMut": false, 52 | "isSigner": false 53 | }, 54 | { 55 | "name": "tokenProgram", 56 | "isMut": false, 57 | "isSigner": false 58 | }, 59 | { 60 | "name": "clock", 61 | "isMut": false, 62 | "isSigner": false 63 | } 64 | ], 65 | "args": [ 66 | { 67 | "name": "text", 68 | "type": "string" 69 | }, 70 | { 71 | "name": "posterName", 72 | "type": "string" 73 | }, 74 | { 75 | "name": "posterUrl", 76 | "type": "string" 77 | } 78 | ] 79 | }, 80 | { 81 | "name": "createComment", 82 | "accounts": [ 83 | { 84 | "name": "post", 85 | "isMut": true, 86 | "isSigner": false 87 | }, 88 | { 89 | "name": "comment", 90 | "isMut": true, 91 | "isSigner": false 92 | }, 93 | { 94 | "name": "authority", 95 | "isMut": true, 96 | "isSigner": true 97 | }, 98 | { 99 | "name": "systemProgram", 100 | "isMut": false, 101 | "isSigner": false 102 | }, 103 | { 104 | "name": "tokenProgram", 105 | "isMut": false, 106 | "isSigner": false 107 | }, 108 | { 109 | "name": "clock", 110 | "isMut": false, 111 | "isSigner": false 112 | } 113 | ], 114 | "args": [ 115 | { 116 | "name": "text", 117 | "type": "string" 118 | }, 119 | { 120 | "name": "commenterName", 121 | "type": "string" 122 | }, 123 | { 124 | "name": "commenterUrl", 125 | "type": "string" 126 | } 127 | ] 128 | } 129 | ], 130 | "accounts": [ 131 | { 132 | "name": "StateAccount", 133 | "type": { 134 | "kind": "struct", 135 | "fields": [ 136 | { 137 | "name": "authority", 138 | "type": "publicKey" 139 | }, 140 | { 141 | "name": "postCount", 142 | "type": "u64" 143 | } 144 | ] 145 | } 146 | }, 147 | { 148 | "name": "PostAccount", 149 | "type": { 150 | "kind": "struct", 151 | "fields": [ 152 | { 153 | "name": "authority", 154 | "type": "publicKey" 155 | }, 156 | { 157 | "name": "text", 158 | "type": "string" 159 | }, 160 | { 161 | "name": "posterName", 162 | "type": "string" 163 | }, 164 | { 165 | "name": "posterUrl", 166 | "type": "string" 167 | }, 168 | { 169 | "name": "commentCount", 170 | "type": "u64" 171 | }, 172 | { 173 | "name": "index", 174 | "type": "u64" 175 | }, 176 | { 177 | "name": "postTime", 178 | "type": "i64" 179 | } 180 | ] 181 | } 182 | }, 183 | { 184 | "name": "CommentAccount", 185 | "type": { 186 | "kind": "struct", 187 | "fields": [ 188 | { 189 | "name": "authority", 190 | "type": "publicKey" 191 | }, 192 | { 193 | "name": "text", 194 | "type": "string" 195 | }, 196 | { 197 | "name": "commenterName", 198 | "type": "string" 199 | }, 200 | { 201 | "name": "commenterUrl", 202 | "type": "string" 203 | }, 204 | { 205 | "name": "index", 206 | "type": "u64" 207 | }, 208 | { 209 | "name": "postTime", 210 | "type": "i64" 211 | } 212 | ] 213 | } 214 | } 215 | ], 216 | "metadata": { 217 | "address": "6b5cvMWLE1LwRzzv4dtiz1w5yHTnpbt3A2s3UtbvZkWt" 218 | } 219 | } -------------------------------------------------------------------------------- /utils/get-program.js: -------------------------------------------------------------------------------- 1 | import * as anchor from '@project-serum/anchor' 2 | import { WalletNotConnectedError } from '@solana/wallet-adapter-base' 3 | import { STABLE_POOL_IDL, STABLE_POOL_PROGRAM_ID } from './const' 4 | 5 | export function getProgramInstance(connection, wallet) { 6 | if (!wallet.publicKey) throw new WalletNotConnectedError() 7 | 8 | const provider = new anchor.Provider( 9 | connection, 10 | wallet, 11 | anchor.Provider.defaultOptions(), 12 | ) 13 | 14 | const idl = STABLE_POOL_IDL 15 | 16 | const programId = STABLE_POOL_PROGRAM_ID 17 | 18 | const program = new anchor.Program(idl, programId, provider) 19 | 20 | return program 21 | } 22 | --------------------------------------------------------------------------------