diff --git a/public/index.html b/public/index.html index c3e6397b0..9e6d4360b 100644 --- a/public/index.html +++ b/public/index.html @@ -23,21 +23,21 @@ work correctly both with client-side routing and a non-root public URL. Learn how to configure a non-root public URL by running `npm run build`. --> - My GIF Portal - - + Clarkezone Photoverse Collection + + - + - + diff --git a/src/App.js b/src/App.js index 3c4d64d91..63982d727 100644 --- a/src/App.js +++ b/src/App.js @@ -1,19 +1,226 @@ +import { useEffect, useState } from 'react'; import twitterLogo from './assets/twitter-logo.svg'; import './App.css'; +import { Connection, PublicKey, clusterApiUrl } from '@solana/web3.js'; +import { Program, Provider, web3 } from '@project-serum/anchor'; +import kp from './keypair.json'; +import idl from './idl.json'; + +const {SystemProgram, Keypair} = web3; + +const arr = Object.values(kp._keypair.secretKey); +const secret = new Uint8Array(arr); +const baseAccount = web3.Keypair.fromSecretKey(secret); + +const programID = new PublicKey(idl.metadata.address); + +const network = clusterApiUrl('devnet'); + +const opts = { + preflightCommitment: "processed" +} // Constants -const TWITTER_HANDLE = '_buildspace'; +const TWITTER_HANDLE = 'clarkezone'; const TWITTER_LINK = `https://twitter.com/${TWITTER_HANDLE}`; +const TEST_GIFS = [ + 'https://i.giphy.com/media/eIG0HfouRQJQr1wBzz/giphy.webp', + 'https://media3.giphy.com/media/L71a8LW2UrKwPaWNYM/giphy.gif?cid=ecf05e47rr9qizx2msjucl1xyvuu47d7kf25tqt2lvo024uo&rid=giphy.gif&ct=g', + 'https://media4.giphy.com/media/AeFmQjHMtEySooOc8K/giphy.gif?cid=ecf05e47qdzhdma2y3ugn32lkgi972z9mpfzocjj6z1ro4ec&rid=giphy.gif&ct=g', + 'https://i.giphy.com/media/PAqjdPkJLDsmBRSYUp/giphy.webp' +] const App = () => { + const [walletAddress, setWalletAddress] = useState(null); + const [inputValue, setInputValue] = useState(''); + const [gifList, setGifList] = useState([]); + const checkIfWalletIsConnected = async () => { + try { + const { solana } = window; + + if (solana) { + if (solana.isPhantom) { + console.log('Phantom wallet found!'); + + const response = await solana.connect({ onlyIfTrusted: true }); + console.log( + 'Connected with Public Key:', + response.publicKey.toString() + ); + setWalletAddress(response.publicKey.toString()); + } + } else { + alert('Solana object not found! Get a Phantom Wallet 👻'); + } + } catch (error) { + console.error(error); + } + }; + + + + const connectWallet = async () => { + const { solana } = window; + + if (solana) { + const response = await solana.connect(); + console.log('Connected with Public Key:', response.publicKey.toString()); + setWalletAddress(response.publicKey.toString()); + } + + }; + + useEffect(() => { + window.addEventListener('load', async (event) => { + await checkIfWalletIsConnected(); + }); + }, []); + + + const getGifList = async() => { + try { + const provider = getProvider(); + const program = new Program(idl, programID, provider); + const account = await program.account.baseAccount.fetch(baseAccount.publicKey); + + console.log("got the account", account); + setGifList(account.pictureList); + } catch (error) { + console.log("Error in getFigs: ", error); + setGifList(null); + } + + } + + useEffect(() => { + if (walletAddress) { + console.log('Fetching GIF list...'); + getGifList() + } + }, [walletAddress]); + + const renderConnectedContainer = () => { + // If we hit this, it means the program account hasn't be initialized. + if (gifList === null) { + return ( +
+ +
+ ) + } + // Otherwise, we're good! Account exists. User can submit GIFs. + else { + return( +
+
{ + event.preventDefault(); + sendGif(); + }} + > + + +
+
+ {/* We use index as the key instead, also, the src is now item.gifLink */} + {gifList.map((item, index) => ( +
+ +
+ ))} +
+
+ ) + } + } + + const onInputChange = (event) => { + const { value } = event.target; + setInputValue(value); + }; + + const getProvider = () => { + const connection = new Connection(network, opts.preflightCommitment); + const provider = new Provider( + connection, window.solana, opts.preflightCommitment, + ); + return provider; + } + + const createGifAccount = async () => { + try { + const provider = getProvider(); + const program = new Program(idl, programID, provider); + console.log("ping") + await program.rpc.startStuffOff({ + accounts: { + baseAccount: baseAccount.publicKey, + user: provider.wallet.publicKey, + systemProgram: SystemProgram.programId, + }, + signers: [baseAccount] + }); + console.log("Created a new BaseAccount w/ address:", baseAccount.publicKey.toString()) + await getGifList(); + + } catch(error) { + console.log("Error creating BaseAccount account:", error) + } + } + + const sendGif = async () => { + if (inputValue.length === 0) { + console.log("No gif link given!") + return + } + console.log('Gif link:', inputValue); + try { + const provider = getProvider(); + const program = new Program(idl, programID, provider); + + await program.rpc.addPicture(inputValue, { + accounts: { + baseAccount: baseAccount.publicKey, + user: provider.wallet.publicKey, + }, + }); + console.log("GIF successfully sent to program", inputValue) + + await getGifList(); + } catch (error) { + console.log("Error sending GIF:", error) + } + }; + + const renderNotConnectedContainer = () => ( + + ); + return (
-
+
-

🖼 GIF Portal

+

🖼 Photoverse

- View your GIF collection in the metaverse ✨ + View the Clarkezone photoverse ✨

+ {/* Render your connect to wallet button right here */} + {!walletAddress && renderNotConnectedContainer()} + {walletAddress && renderConnectedContainer()}
Twitter Logo @@ -22,7 +229,7 @@ const App = () => { href={TWITTER_LINK} target="_blank" rel="noreferrer" - >{`built on @${TWITTER_HANDLE}`} + >{`@${TWITTER_HANDLE}`}
diff --git a/src/createKeyPair.js b/src/createKeyPair.js new file mode 100644 index 000000000..991e36060 --- /dev/null +++ b/src/createKeyPair.js @@ -0,0 +1,9 @@ +// Shoutout to Nader Dabit for helping w/ this! +// https://twitter.com/dabit3 + +const fs = require('fs') +const anchor = require("@project-serum/anchor") + +const account = anchor.web3.Keypair.generate() + +fs.writeFileSync('./keypair.json', JSON.stringify(account)) \ No newline at end of file diff --git a/src/idl.json b/src/idl.json new file mode 100644 index 000000000..e46853b30 --- /dev/null +++ b/src/idl.json @@ -0,0 +1,86 @@ +{ + "version": "0.0.0", + "name": "myepicproject2", + "instructions": [ + { + "name": "startStuffOff", + "accounts": [ + { + "name": "baseAccount", + "isMut": true, + "isSigner": true + }, + { + "name": "user", + "isMut": true, + "isSigner": true + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [] + }, + { + "name": "addPicture", + "accounts": [ + { + "name": "baseAccount", + "isMut": true, + "isSigner": false + } + ], + "args": [ + { + "name": "pictureLink", + "type": "string" + } + ] + } + ], + "accounts": [ + { + "name": "BaseAccount", + "type": { + "kind": "struct", + "fields": [ + { + "name": "totalPictures", + "type": "u64" + }, + { + "name": "pictureList", + "type": { + "vec": { + "defined": "ItemStruct" + } + } + } + ] + } + } + ], + "types": [ + { + "name": "ItemStruct", + "type": { + "kind": "struct", + "fields": [ + { + "name": "pictureLink", + "type": "string" + }, + { + "name": "userAddress", + "type": "publicKey" + } + ] + } + } + ], + "metadata": { + "address": "GAE6uLmRpzy794wz8UQvDkK89LbLyzVadopBMhLKHofW" + } +} \ No newline at end of file