Skip to content

Commit

Permalink
Basic working thing
Browse files Browse the repository at this point in the history
  • Loading branch information
clarkezone committed Nov 13, 2021
1 parent f780547 commit d49def3
Show file tree
Hide file tree
Showing 4 changed files with 312 additions and 10 deletions.
10 changes: 5 additions & 5 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
-->
<title>My GIF Portal</title>
<meta name="title" content="GIF Portal" />
<meta name="description" content="Create a GIF collection with the Metaverse!" />
<title>Clarkezone Photoverse Collection</title>
<meta name="title" content="Clarkezone Photoverse" />
<meta name="description" content="Collect amazing landscapes!" />

<!-- Facebook -->
<meta property="og:type" content="website">
<meta property="og:url" content="https://buildspace.so/">
<meta property="og:title" content="GIF Portal">
<meta property="og:title" content="Clarkezone Photoverse">
<meta property="og:description" content="Create a GIF collection with the Metaverse!">
<meta property="og:image" content="https://s3.amazonaws.com/cdn.buildspace.so/courses/web3-solana-app/metadata.png">

<!-- Twitter -->
<meta property="twitter:card" content="summary_large_image">
<meta property="twitter:url" content="https://buildspace.so/">
<meta property="twitter:title" content="GIF Portal">
<meta property="twitter:title" content="Clarkezone Photoverse">
<meta property="twitter:description" content="Create a GIF collection with the Metaverse!">
<meta property="twitter:image" content="https://s3.amazonaws.com/cdn.buildspace.so/courses/web3-solana-app/metadata.png">
</head>
Expand Down
217 changes: 212 additions & 5 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -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 (
<div className="connected-container">
<button className="cta-button submit-gif-button" onClick={createGifAccount}>
Do One-Time Initialization For GIF Program Account
</button>
</div>
)
}
// Otherwise, we're good! Account exists. User can submit GIFs.
else {
return(
<div className="connected-container">
<form
onSubmit={(event) => {
event.preventDefault();
sendGif();
}}
>
<input
type="text"
placeholder="Enter gif link!"
value={inputValue}
onChange={onInputChange}
/>
<button type="submit" className="cta-button submit-gif-button">
Submit
</button>
</form>
<div className="gif-grid">
{/* We use index as the key instead, also, the src is now item.gifLink */}
{gifList.map((item, index) => (
<div className="gif-item" key={index}>
<img src={item.pictureLink} />
</div>
))}
</div>
</div>
)
}
}

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 = () => (
<button
className="cta-button connect-wallet-button"
onClick={connectWallet}
>
Connect to Wallet
</button>
);

return (
<div className="App">
<div className="container">
<div className={walletAddress ? 'authed-container' : 'container'}>
<div className="header-container">
<p className="header">🖼 GIF Portal</p>
<p className="header">🖼 Photoverse</p>
<p className="sub-text">
View your GIF collection in the metaverse
View the Clarkezone photoverse
</p>
{/* Render your connect to wallet button right here */}
{!walletAddress && renderNotConnectedContainer()}
{walletAddress && renderConnectedContainer()}
</div>
<div className="footer-container">
<img alt="Twitter Logo" className="twitter-logo" src={twitterLogo} />
Expand All @@ -22,7 +229,7 @@ const App = () => {
href={TWITTER_LINK}
target="_blank"
rel="noreferrer"
>{`built on @${TWITTER_HANDLE}`}</a>
>{`@${TWITTER_HANDLE}`}</a>
</div>
</div>
</div>
Expand Down
9 changes: 9 additions & 0 deletions src/createKeyPair.js
Original file line number Diff line number Diff line change
@@ -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))
86 changes: 86 additions & 0 deletions src/idl.json
Original file line number Diff line number Diff line change
@@ -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"
}
}

0 comments on commit d49def3

Please sign in to comment.